LCOV - code coverage report
Current view: top level - src/objects - scope-info.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 284 304 93.4 %
Date: 2017-10-20 Functions: 49 56 87.5 %

          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             :       }
      54             :     }
      55             :   }
      56             :   return true;
      57             : }
      58             : #endif
      59             : 
      60    15118566 : Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
      61             :                                     MaybeHandle<ScopeInfo> outer_scope) {
      62             :   // Collect variables.
      63             :   int stack_local_count = 0;
      64             :   int context_local_count = 0;
      65             :   int module_vars_count = 0;
      66             :   // Stack allocated block scope variables are allocated in the parent
      67             :   // declaration scope, but are recorded in the block scope's scope info. First
      68             :   // slot index indicates at which offset a particular scope starts in the
      69             :   // parent declaration scope.
      70             :   int first_slot_index = 0;
      71    37262146 :   for (Variable* var : *scope->locals()) {
      72    15424441 :     switch (var->location()) {
      73             :       case VariableLocation::LOCAL:
      74     5827684 :         if (stack_local_count == 0) first_slot_index = var->index();
      75     5827684 :         stack_local_count++;
      76     5827684 :         break;
      77             :       case VariableLocation::CONTEXT:
      78     2391806 :         context_local_count++;
      79     2391806 :         break;
      80             :       case VariableLocation::MODULE:
      81       19141 :         module_vars_count++;
      82       19141 :         break;
      83             :       default:
      84             :         break;
      85             :     }
      86             :   }
      87             :   DCHECK(module_vars_count == 0 || scope->is_module_scope());
      88             : 
      89             :   // Make sure we allocate the correct amount.
      90             :   DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
      91             : 
      92             :   // Determine use and location of the "this" binding if it is present.
      93             :   VariableAllocationInfo receiver_info;
      94     4796844 :   if (scope->is_declaration_scope() &&
      95     2277083 :       scope->AsDeclarationScope()->has_this_declaration()) {
      96     1076846 :     Variable* var = scope->AsDeclarationScope()->receiver();
      97     1076846 :     if (!var->is_used()) {
      98             :       receiver_info = UNUSED;
      99      220463 :     } else if (var->IsContextSlot()) {
     100             :       receiver_info = CONTEXT;
     101             :     } else {
     102             :       DCHECK(var->IsParameter());
     103             :       receiver_info = STACK;
     104             :     }
     105             :   } else {
     106             :     receiver_info = NONE;
     107             :   }
     108             : 
     109             :   bool has_new_target =
     110     4796844 :       scope->is_declaration_scope() &&
     111     2277083 :       scope->AsDeclarationScope()->new_target_var() != nullptr;
     112             : 
     113             :   // Determine use and location of the function variable if it is present.
     114             :   VariableAllocationInfo function_name_info;
     115     3731462 :   if (scope->is_function_scope() &&
     116     1211701 :       scope->AsDeclarationScope()->function_var() != nullptr) {
     117       76081 :     Variable* var = scope->AsDeclarationScope()->function_var();
     118       76081 :     if (!var->is_used()) {
     119             :       function_name_info = UNUSED;
     120       76081 :     } else if (var->IsContextSlot()) {
     121             :       function_name_info = CONTEXT;
     122             :     } else {
     123             :       DCHECK(var->IsStackLocal());
     124             :       function_name_info = STACK;
     125             :     }
     126             :   } else {
     127             :     function_name_info = NONE;
     128             :   }
     129             : 
     130     2519761 :   const bool has_function_name = function_name_info != NONE;
     131     2519761 :   const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT;
     132     2519761 :   const int parameter_count = scope->num_parameters();
     133     2519761 :   const bool has_outer_scope_info = !outer_scope.is_null();
     134     5039522 :   const int length = kVariablePartIndex + parameter_count +
     135     5039522 :                      (1 + stack_local_count) + 2 * context_local_count +
     136     2519761 :                      (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0) +
     137     2521485 :                      (has_outer_scope_info ? 1 : 0) +
     138             :                      (scope->is_module_scope()
     139        1724 :                           ? 2 + kModuleVariableEntryLength * module_vars_count
     140     2519761 :                           : 0);
     141             : 
     142             :   Factory* factory = isolate->factory();
     143     2519761 :   Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
     144             : 
     145             :   bool has_simple_parameters = false;
     146             :   bool asm_module = false;
     147             :   bool calls_sloppy_eval = false;
     148     2519761 :   if (scope->is_function_scope()) {
     149     1211701 :     DeclarationScope* function_scope = scope->AsDeclarationScope();
     150             :     has_simple_parameters = function_scope->has_simple_parameters();
     151             :     asm_module = function_scope->asm_module();
     152             :   }
     153             :   FunctionKind function_kind = kNormalFunction;
     154     2519761 :   if (scope->is_declaration_scope()) {
     155     2277083 :     function_kind = scope->AsDeclarationScope()->function_kind();
     156     2277083 :     calls_sloppy_eval = scope->AsDeclarationScope()->calls_sloppy_eval();
     157             :   }
     158             : 
     159             :   // Encode the flags.
     160             :   int flags =
     161     2519761 :       ScopeTypeField::encode(scope->scope_type()) |
     162     2519761 :       CallsSloppyEvalField::encode(calls_sloppy_eval) |
     163     2519761 :       LanguageModeField::encode(scope->language_mode()) |
     164     2519761 :       DeclarationScopeField::encode(scope->is_declaration_scope()) |
     165     2519761 :       ReceiverVariableField::encode(receiver_info) |
     166     2519761 :       HasNewTargetField::encode(has_new_target) |
     167     2519761 :       FunctionVariableField::encode(function_name_info) |
     168     2519761 :       AsmModuleField::encode(asm_module) |
     169     2519761 :       HasSimpleParametersField::encode(has_simple_parameters) |
     170     2519761 :       FunctionKindField::encode(function_kind) |
     171     2519761 :       HasOuterScopeInfoField::encode(has_outer_scope_info) |
     172     2519761 :       IsDebugEvaluateScopeField::encode(scope->is_debug_evaluate_scope());
     173             :   scope_info->SetFlags(flags);
     174             : 
     175             :   scope_info->SetParameterCount(parameter_count);
     176             :   scope_info->SetStackLocalCount(stack_local_count);
     177             :   scope_info->SetContextLocalCount(context_local_count);
     178             : 
     179             :   int index = kVariablePartIndex;
     180             :   // Add parameters.
     181             :   DCHECK_EQ(index, scope_info->ParameterNamesIndex());
     182     2519761 :   if (scope->is_declaration_scope()) {
     183     2854048 :     for (int i = 0; i < parameter_count; ++i) {
     184             :       scope_info->set(index++,
     185    11416192 :                       *scope->AsDeclarationScope()->parameter(i)->name());
     186             :     }
     187             :   }
     188             : 
     189             :   // Add stack locals' names, context locals' names and info, module variables'
     190             :   // names and info. We are assuming that the stack locals' slots are allocated
     191             :   // in increasing order, so we can simply add them to the ScopeInfo object.
     192             :   // Context locals are added using their index.
     193             :   DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
     194     2519761 :   scope_info->set(index++, Smi::FromInt(first_slot_index));
     195             :   DCHECK_EQ(index, scope_info->StackLocalNamesIndex());
     196             : 
     197             :   int stack_local_base = index;
     198     2519761 :   int context_local_base = stack_local_base + stack_local_count;
     199     2519761 :   int context_local_info_base = context_local_base + context_local_count;
     200             :   int module_var_entry = scope_info->ModuleVariablesIndex();
     201             : 
     202    52384807 :   for (Variable* var : *scope->locals()) {
     203    15424441 :     switch (var->location()) {
     204             :       case VariableLocation::LOCAL: {
     205     5827684 :         int local_index = var->index() - first_slot_index;
     206             :         DCHECK_LE(0, local_index);
     207             :         DCHECK_LT(local_index, stack_local_count);
     208    11655368 :         scope_info->set(stack_local_base + local_index, *var->name());
     209     5827684 :         break;
     210             :       }
     211             :       case VariableLocation::CONTEXT: {
     212             :         // Due to duplicate parameters, context locals aren't guaranteed to come
     213             :         // in order.
     214     2391806 :         int local_index = var->index() - Context::MIN_CONTEXT_SLOTS;
     215             :         DCHECK_LE(0, local_index);
     216             :         DCHECK_LT(local_index, context_local_count);
     217     2391806 :         uint32_t info = VariableModeField::encode(var->mode()) |
     218             :                         InitFlagField::encode(var->initialization_flag()) |
     219     2391806 :                         MaybeAssignedFlagField::encode(var->maybe_assigned());
     220     4783612 :         scope_info->set(context_local_base + local_index, *var->name());
     221             :         scope_info->set(context_local_info_base + local_index,
     222     4783612 :                         Smi::FromInt(info));
     223             :         break;
     224             :       }
     225             :       case VariableLocation::MODULE: {
     226             :         scope_info->set(module_var_entry + kModuleVariableNameOffset,
     227       19141 :                         *var->name());
     228             :         scope_info->set(module_var_entry + kModuleVariableIndexOffset,
     229             :                         Smi::FromInt(var->index()));
     230             :         uint32_t properties =
     231       19141 :             VariableModeField::encode(var->mode()) |
     232             :             InitFlagField::encode(var->initialization_flag()) |
     233       19141 :             MaybeAssignedFlagField::encode(var->maybe_assigned());
     234             :         scope_info->set(module_var_entry + kModuleVariablePropertiesOffset,
     235       19141 :                         Smi::FromInt(properties));
     236             :         module_var_entry += kModuleVariableEntryLength;
     237       19141 :         break;
     238             :       }
     239             :       default:
     240             :         break;
     241             :     }
     242             :   }
     243             : 
     244     2519761 :   index += stack_local_count + 2 * context_local_count;
     245             : 
     246             :   // If the receiver is allocated, add its index.
     247             :   DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
     248     2519761 :   if (has_receiver) {
     249      220463 :     int var_index = scope->AsDeclarationScope()->receiver()->index();
     250      220463 :     scope_info->set(index++, Smi::FromInt(var_index));
     251             :     // ?? DCHECK(receiver_info != CONTEXT || var_index ==
     252             :     // scope_info->ContextLength() - 1);
     253             :   }
     254             : 
     255             :   // If present, add the function variable name and its index.
     256             :   DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
     257     2519761 :   if (has_function_name) {
     258       76081 :     int var_index = scope->AsDeclarationScope()->function_var()->index();
     259             :     scope_info->set(index++,
     260      228243 :                     *scope->AsDeclarationScope()->function_var()->name());
     261       76081 :     scope_info->set(index++, Smi::FromInt(var_index));
     262             :     DCHECK(function_name_info != CONTEXT ||
     263             :            var_index == scope_info->ContextLength() - 1);
     264             :   }
     265             : 
     266             :   // If present, add the outer scope info.
     267             :   DCHECK(index == scope_info->OuterScopeInfoIndex());
     268     2519761 :   if (has_outer_scope_info) {
     269     2407670 :     scope_info->set(index++, *outer_scope.ToHandleChecked());
     270             :   }
     271             : 
     272             :   // Module-specific information (only for module scopes).
     273     2519761 :   if (scope->is_module_scope()) {
     274             :     Handle<ModuleInfo> module_info =
     275        1724 :         ModuleInfo::New(isolate, zone, scope->AsModuleScope()->module());
     276             :     DCHECK_EQ(index, scope_info->ModuleInfoIndex());
     277        3448 :     scope_info->set(index++, *module_info);
     278             :     DCHECK_EQ(index, scope_info->ModuleVariableCountIndex());
     279             :     scope_info->set(index++, Smi::FromInt(module_vars_count));
     280             :     DCHECK_EQ(index, scope_info->ModuleVariablesIndex());
     281             :     // The variable entries themselves have already been written above.
     282             :     index += kModuleVariableEntryLength * module_vars_count;
     283             :   }
     284             : 
     285             :   DCHECK_EQ(index, scope_info->length());
     286             :   DCHECK_EQ(scope->num_parameters(), scope_info->ParameterCount());
     287             :   DCHECK_EQ(scope->num_heap_slots(), scope_info->ContextLength());
     288     2519761 :   return scope_info;
     289             : }
     290             : 
     291       10922 : Handle<ScopeInfo> ScopeInfo::CreateForWithScope(
     292             :     Isolate* isolate, MaybeHandle<ScopeInfo> outer_scope) {
     293       10922 :   const bool has_outer_scope_info = !outer_scope.is_null();
     294       10922 :   const int length = kVariablePartIndex + 1 + (has_outer_scope_info ? 1 : 0);
     295             : 
     296             :   Factory* factory = isolate->factory();
     297       10922 :   Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
     298             : 
     299             :   // Encode the flags.
     300             :   int flags =
     301             :       ScopeTypeField::encode(WITH_SCOPE) | CallsSloppyEvalField::encode(false) |
     302             :       LanguageModeField::encode(LanguageMode::kSloppy) |
     303             :       DeclarationScopeField::encode(false) |
     304             :       ReceiverVariableField::encode(NONE) | HasNewTargetField::encode(false) |
     305             :       FunctionVariableField::encode(NONE) | AsmModuleField::encode(false) |
     306             :       HasSimpleParametersField::encode(true) |
     307       10922 :       FunctionKindField::encode(kNormalFunction) |
     308             :       HasOuterScopeInfoField::encode(has_outer_scope_info) |
     309       10922 :       IsDebugEvaluateScopeField::encode(false);
     310             :   scope_info->SetFlags(flags);
     311             : 
     312             :   scope_info->SetParameterCount(0);
     313             :   scope_info->SetStackLocalCount(0);
     314             :   scope_info->SetContextLocalCount(0);
     315             : 
     316             :   int index = kVariablePartIndex;
     317             :   DCHECK_EQ(index, scope_info->ParameterNamesIndex());
     318             :   DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
     319             :   scope_info->set(index++, Smi::kZero);
     320             :   DCHECK_EQ(index, scope_info->StackLocalNamesIndex());
     321             :   DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
     322             :   DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
     323             :   DCHECK(index == scope_info->OuterScopeInfoIndex());
     324       10922 :   if (has_outer_scope_info) {
     325        1978 :     scope_info->set(index++, *outer_scope.ToHandleChecked());
     326             :   }
     327             :   DCHECK_EQ(index, scope_info->length());
     328             :   DCHECK_EQ(0, scope_info->ParameterCount());
     329             :   DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, scope_info->ContextLength());
     330       10922 :   return scope_info;
     331             : }
     332             : 
     333          61 : Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
     334             :   DCHECK(isolate->bootstrapper()->IsActive());
     335             : 
     336             :   const int stack_local_count = 0;
     337             :   const int context_local_count = 1;
     338             :   const bool has_simple_parameters = true;
     339             :   const VariableAllocationInfo receiver_info = CONTEXT;
     340             :   const VariableAllocationInfo function_name_info = NONE;
     341             :   const bool has_function_name = false;
     342             :   const bool has_receiver = true;
     343             :   const bool has_outer_scope_info = false;
     344             :   const int parameter_count = 0;
     345             :   const int length = kVariablePartIndex + parameter_count +
     346             :                      (1 + stack_local_count) + 2 * context_local_count +
     347             :                      (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0) +
     348             :                      (has_outer_scope_info ? 1 : 0);
     349             : 
     350             :   Factory* factory = isolate->factory();
     351          61 :   Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
     352             : 
     353             :   // Encode the flags.
     354             :   int flags = ScopeTypeField::encode(SCRIPT_SCOPE) |
     355             :               CallsSloppyEvalField::encode(false) |
     356             :               LanguageModeField::encode(LanguageMode::kSloppy) |
     357             :               DeclarationScopeField::encode(true) |
     358             :               ReceiverVariableField::encode(receiver_info) |
     359             :               FunctionVariableField::encode(function_name_info) |
     360             :               AsmModuleField::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         122 :   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          61 :   return scope_info;
     397             : }
     398             : 
     399    15792844 : ScopeInfo* ScopeInfo::Empty(Isolate* isolate) {
     400    15792844 :   return isolate->heap()->empty_scope_info();
     401             : }
     402             : 
     403     8384225 : ScopeType ScopeInfo::scope_type() {
     404             :   DCHECK_LT(0, length());
     405    17635741 :   return ScopeTypeField::decode(Flags());
     406             : }
     407             : 
     408     2006499 : bool ScopeInfo::CallsSloppyEval() {
     409             :   bool calls_sloppy_eval =
     410     4012998 :       length() > 0 && CallsSloppyEvalField::decode(Flags());
     411             :   DCHECK_IMPLIES(calls_sloppy_eval, is_sloppy(language_mode()));
     412             :   DCHECK_IMPLIES(calls_sloppy_eval, is_declaration_scope());
     413     2006499 :   return calls_sloppy_eval;
     414             : }
     415             : 
     416     1844931 : LanguageMode ScopeInfo::language_mode() {
     417     1844931 :   return length() > 0 ? LanguageModeField::decode(Flags())
     418     3689862 :                       : LanguageMode::kSloppy;
     419             : }
     420             : 
     421       94634 : bool ScopeInfo::is_declaration_scope() {
     422      194626 :   return DeclarationScopeField::decode(Flags());
     423             : }
     424             : 
     425       30259 : int ScopeInfo::LocalCount() { return StackLocalCount() + ContextLocalCount(); }
     426             : 
     427           0 : int ScopeInfo::StackSlotCount() {
     428           0 :   if (length() > 0) {
     429             :     bool function_name_stack_slot =
     430           0 :         FunctionVariableField::decode(Flags()) == STACK;
     431           0 :     return StackLocalCount() + (function_name_stack_slot ? 1 : 0);
     432             :   }
     433             :   return 0;
     434             : }
     435             : 
     436     2154618 : int ScopeInfo::ContextLength() {
     437     2154618 :   if (length() > 0) {
     438     2154618 :     int context_locals = ContextLocalCount();
     439             :     bool function_name_context_slot =
     440     4309236 :         FunctionVariableField::decode(Flags()) == CONTEXT;
     441     2356364 :     bool has_context = context_locals > 0 || function_name_context_slot ||
     442      171455 :                        scope_type() == WITH_SCOPE ||
     443       19236 :                        (scope_type() == BLOCK_SCOPE && CallsSloppyEval() &&
     444      166097 :                         is_declaration_scope()) ||
     445      312234 :                        (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) ||
     446     2464281 :                        (scope_type() == FUNCTION_SCOPE && IsAsmModule()) ||
     447             :                        scope_type() == MODULE_SCOPE;
     448             : 
     449     2154618 :     if (has_context) {
     450     1991092 :       return Context::MIN_CONTEXT_SLOTS + context_locals +
     451     1991092 :              (function_name_context_slot ? 1 : 0);
     452             :     }
     453             :   }
     454             :   return 0;
     455             : }
     456             : 
     457        9914 : bool ScopeInfo::HasReceiver() {
     458        9914 :   if (length() > 0) {
     459       19828 :     return NONE != ReceiverVariableField::decode(Flags());
     460             :   } else {
     461             :     return false;
     462             :   }
     463             : }
     464             : 
     465     3135093 : bool ScopeInfo::HasAllocatedReceiver() {
     466     3135093 :   if (length() > 0) {
     467     3135093 :     VariableAllocationInfo allocation = ReceiverVariableField::decode(Flags());
     468     3135093 :     return allocation == STACK || allocation == CONTEXT;
     469             :   } else {
     470             :     return false;
     471             :   }
     472             : }
     473             : 
     474         710 : bool ScopeInfo::HasNewTarget() { return HasNewTargetField::decode(Flags()); }
     475             : 
     476     3038321 : bool ScopeInfo::HasFunctionName() {
     477     3038321 :   if (length() > 0) {
     478     6075286 :     return NONE != FunctionVariableField::decode(Flags());
     479             :   } else {
     480             :     return false;
     481             :   }
     482             : }
     483             : 
     484     4396451 : bool ScopeInfo::HasOuterScopeInfo() {
     485     4396451 :   if (length() > 0) {
     486     8792902 :     return HasOuterScopeInfoField::decode(Flags());
     487             :   } else {
     488             :     return false;
     489             :   }
     490             : }
     491             : 
     492       25600 : bool ScopeInfo::IsDebugEvaluateScope() {
     493       25600 :   if (length() > 0) {
     494       51200 :     return IsDebugEvaluateScopeField::decode(Flags());
     495             :   } else {
     496             :     return false;
     497             :   }
     498             : }
     499             : 
     500       10892 : void ScopeInfo::SetIsDebugEvaluateScope() {
     501       10892 :   if (length() > 0) {
     502             :     DCHECK_EQ(scope_type(), WITH_SCOPE);
     503       10892 :     SetFlags(Flags() | IsDebugEvaluateScopeField::encode(true));
     504             :   } else {
     505           0 :     UNREACHABLE();
     506             :   }
     507       10892 : }
     508             : 
     509      195580 : bool ScopeInfo::HasContext() { return ContextLength() > 0; }
     510             : 
     511      103305 : String* ScopeInfo::FunctionName() {
     512             :   DCHECK(HasFunctionName());
     513      206610 :   return String::cast(get(FunctionNameInfoIndex()));
     514             : }
     515             : 
     516      482160 : ScopeInfo* ScopeInfo::OuterScopeInfo() {
     517             :   DCHECK(HasOuterScopeInfo());
     518      964320 :   return ScopeInfo::cast(get(OuterScopeInfoIndex()));
     519             : }
     520             : 
     521       14369 : ModuleInfo* ScopeInfo::ModuleDescriptorInfo() {
     522             :   DCHECK(scope_type() == MODULE_SCOPE);
     523       28738 :   return ModuleInfo::cast(get(ModuleInfoIndex()));
     524             : }
     525             : 
     526       43917 : String* ScopeInfo::ParameterName(int var) {
     527             :   DCHECK_LE(0, var);
     528             :   DCHECK_LT(var, ParameterCount());
     529       43917 :   int info_index = ParameterNamesIndex() + var;
     530       43917 :   return String::cast(get(info_index));
     531             : }
     532             : 
     533      127700 : String* ScopeInfo::LocalName(int var) {
     534             :   DCHECK_LE(0, var);
     535             :   DCHECK_LT(var, LocalCount());
     536             :   DCHECK(StackLocalNamesIndex() + StackLocalCount() ==
     537             :          ContextLocalNamesIndex());
     538      127700 :   int info_index = StackLocalNamesIndex() + var;
     539      127700 :   return String::cast(get(info_index));
     540             : }
     541             : 
     542     3419224 : String* ScopeInfo::StackLocalName(int var) {
     543             :   DCHECK_LE(0, var);
     544             :   DCHECK_LT(var, StackLocalCount());
     545     3419224 :   int info_index = StackLocalNamesIndex() + var;
     546     3419224 :   return String::cast(get(info_index));
     547             : }
     548             : 
     549     3378916 : int ScopeInfo::StackLocalIndex(int var) {
     550             :   DCHECK_LE(0, var);
     551             :   DCHECK_LT(var, StackLocalCount());
     552             :   int first_slot_index = Smi::ToInt(get(StackLocalFirstSlotIndex()));
     553     3378916 :   return first_slot_index + var;
     554             : }
     555             : 
     556     1715216 : String* ScopeInfo::ContextLocalName(int var) {
     557             :   DCHECK_LE(0, var);
     558             :   DCHECK_LT(var, ContextLocalCount());
     559     1715216 :   int info_index = ContextLocalNamesIndex() + var;
     560     1715216 :   return String::cast(get(info_index));
     561             : }
     562             : 
     563      775573 : VariableMode ScopeInfo::ContextLocalMode(int var) {
     564             :   DCHECK_LE(0, var);
     565             :   DCHECK_LT(var, ContextLocalCount());
     566      775573 :   int info_index = ContextLocalInfosIndex() + var;
     567             :   int value = Smi::ToInt(get(info_index));
     568      775573 :   return VariableModeField::decode(value);
     569             : }
     570             : 
     571      395935 : InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
     572             :   DCHECK_LE(0, var);
     573             :   DCHECK_LT(var, ContextLocalCount());
     574      395935 :   int info_index = ContextLocalInfosIndex() + var;
     575             :   int value = Smi::ToInt(get(info_index));
     576      791870 :   return InitFlagField::decode(value);
     577             : }
     578             : 
     579      398946 : MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) {
     580             :   DCHECK_LE(0, var);
     581             :   DCHECK_LT(var, ContextLocalCount());
     582      398946 :   int info_index = ContextLocalInfosIndex() + var;
     583             :   int value = Smi::ToInt(get(info_index));
     584      797892 :   return MaybeAssignedFlagField::decode(value);
     585             : }
     586             : 
     587     7174584 : bool ScopeInfo::VariableIsSynthetic(String* name) {
     588             :   // There's currently no flag stored on the ScopeInfo to indicate that a
     589             :   // variable is a compiler-introduced temporary. However, to avoid conflict
     590             :   // with user declarations, the current temporaries like .generator_object and
     591             :   // .result start with a dot, so we can use that as a flag. It's a hack!
     592    21374795 :   return name->length() == 0 || name->Get(0) == '.' ||
     593    14250144 :          name->Equals(name->GetHeap()->this_string());
     594             : }
     595             : 
     596           0 : int ScopeInfo::StackSlotIndex(String* name) {
     597             :   DCHECK(name->IsInternalizedString());
     598           0 :   if (length() > 0) {
     599             :     int first_slot_index = Smi::ToInt(get(StackLocalFirstSlotIndex()));
     600             :     int start = StackLocalNamesIndex();
     601           0 :     int end = start + StackLocalCount();
     602           0 :     for (int i = start; i < end; ++i) {
     603           0 :       if (name == get(i)) {
     604           0 :         return i - start + first_slot_index;
     605             :       }
     606             :     }
     607             :   }
     608             :   return -1;
     609             : }
     610             : 
     611        3290 : int ScopeInfo::ModuleIndex(Handle<String> name, VariableMode* mode,
     612             :                            InitializationFlag* init_flag,
     613             :                            MaybeAssignedFlag* maybe_assigned_flag) {
     614             :   DCHECK_EQ(scope_type(), MODULE_SCOPE);
     615             :   DCHECK_NOT_NULL(mode);
     616             :   DCHECK_NOT_NULL(init_flag);
     617             :   DCHECK_NOT_NULL(maybe_assigned_flag);
     618             : 
     619             :   int module_vars_count = Smi::ToInt(get(ModuleVariableCountIndex()));
     620             :   int entry = ModuleVariablesIndex();
     621        6353 :   for (int i = 0; i < module_vars_count; ++i) {
     622             :     String* var_name = String::cast(get(entry + kModuleVariableNameOffset));
     623        3760 :     if (name->Equals(var_name)) {
     624             :       int index;
     625         697 :       ModuleVariable(i, nullptr, &index, mode, init_flag, maybe_assigned_flag);
     626         697 :       return index;
     627             :     }
     628        3063 :     entry += kModuleVariableEntryLength;
     629             :   }
     630             : 
     631             :   return 0;
     632             : }
     633             : 
     634    16758352 : int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
     635             :                                 Handle<String> name, VariableMode* mode,
     636             :                                 InitializationFlag* init_flag,
     637             :                                 MaybeAssignedFlag* maybe_assigned_flag) {
     638             :   DCHECK(name->IsInternalizedString());
     639             :   DCHECK_NOT_NULL(mode);
     640             :   DCHECK_NOT_NULL(init_flag);
     641             :   DCHECK_NOT_NULL(maybe_assigned_flag);
     642             : 
     643    16758352 :   if (scope_info->length() > 0) {
     644             :     ContextSlotCache* context_slot_cache =
     645    16758352 :         scope_info->GetIsolate()->context_slot_cache();
     646             :     int result = context_slot_cache->Lookup(*scope_info, *name, mode, init_flag,
     647    16758352 :                                             maybe_assigned_flag);
     648    16758353 :     if (result != ContextSlotCache::kNotFound) {
     649             :       DCHECK_LT(result, scope_info->ContextLength());
     650             :       return result;
     651             :     }
     652             : 
     653     3648193 :     int start = scope_info->ContextLocalNamesIndex();
     654     3648194 :     int end = start + scope_info->ContextLocalCount();
     655    35794395 :     for (int i = start; i < end; ++i) {
     656    32542136 :       if (*name == scope_info->get(i)) {
     657      395935 :         int var = i - start;
     658      395935 :         *mode = scope_info->ContextLocalMode(var);
     659      395935 :         *init_flag = scope_info->ContextLocalInitFlag(var);
     660      395935 :         *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var);
     661      395935 :         result = Context::MIN_CONTEXT_SLOTS + var;
     662             : 
     663             :         context_slot_cache->Update(scope_info, name, *mode, *init_flag,
     664      791870 :                                    *maybe_assigned_flag, result);
     665             :         DCHECK_LT(result, scope_info->ContextLength());
     666      395935 :         return result;
     667             :       }
     668             :     }
     669             :     // Cache as not found. Mode, init flag and maybe assigned flag don't matter.
     670             :     context_slot_cache->Update(scope_info, name, TEMPORARY,
     671     3252259 :                                kNeedsInitialization, kNotAssigned, -1);
     672             :   }
     673             : 
     674             :   return -1;
     675             : }
     676             : 
     677           0 : int ScopeInfo::ParameterIndex(String* name) {
     678             :   DCHECK(name->IsInternalizedString());
     679           0 :   if (length() > 0) {
     680             :     // We must read parameters from the end since for
     681             :     // multiply declared parameters the value of the
     682             :     // last declaration of that parameter is used
     683             :     // inside a function (and thus we need to look
     684             :     // at the last index). Was bug# 1110337.
     685             :     int start = ParameterNamesIndex();
     686           0 :     int end = start + ParameterCount();
     687           0 :     for (int i = end - 1; i >= start; --i) {
     688           0 :       if (name == get(i)) {
     689           0 :         return i - start;
     690             :       }
     691             :     }
     692             :   }
     693             :   return -1;
     694             : }
     695             : 
     696      560850 : int ScopeInfo::ReceiverContextSlotIndex() {
     697     1121700 :   if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT)
     698      337762 :     return Smi::ToInt(get(ReceiverInfoIndex()));
     699             :   return -1;
     700             : }
     701             : 
     702     3349830 : int ScopeInfo::FunctionContextSlotIndex(String* name) {
     703             :   DCHECK(name->IsInternalizedString());
     704     3349830 :   if (length() > 0) {
     705     6801604 :     if (FunctionVariableField::decode(Flags()) == CONTEXT &&
     706      101944 :         FunctionName() == name) {
     707        2080 :       return Smi::ToInt(get(FunctionNameInfoIndex() + 1));
     708             :     }
     709             :   }
     710             :   return -1;
     711             : }
     712             : 
     713     1740272 : FunctionKind ScopeInfo::function_kind() {
     714     3480544 :   return FunctionKindField::decode(Flags());
     715             : }
     716             : 
     717           0 : int ScopeInfo::ParameterNamesIndex() {
     718             :   DCHECK_LT(0, length());
     719           0 :   return kVariablePartIndex;
     720             : }
     721             : 
     722           0 : int ScopeInfo::StackLocalFirstSlotIndex() {
     723    17163677 :   return ParameterNamesIndex() + ParameterCount();
     724             : }
     725             : 
     726    13784761 : int ScopeInfo::StackLocalNamesIndex() { return StackLocalFirstSlotIndex() + 1; }
     727             : 
     728    10237837 : int ScopeInfo::ContextLocalNamesIndex() {
     729    10237837 :   return StackLocalNamesIndex() + StackLocalCount();
     730             : }
     731             : 
     732     4874428 : int ScopeInfo::ContextLocalInfosIndex() {
     733     4874428 :   return ContextLocalNamesIndex() + ContextLocalCount();
     734             : }
     735             : 
     736     3303974 : int ScopeInfo::ReceiverInfoIndex() {
     737     3303974 :   return ContextLocalInfosIndex() + ContextLocalCount();
     738             : }
     739             : 
     740     3135093 : int ScopeInfo::FunctionNameInfoIndex() {
     741     3135093 :   return ReceiverInfoIndex() + (HasAllocatedReceiver() ? 1 : 0);
     742             : }
     743             : 
     744     3030748 : int ScopeInfo::OuterScopeInfoIndex() {
     745     3030748 :   return FunctionNameInfoIndex() + (HasFunctionName() ? 2 : 0);
     746             : }
     747             : 
     748     2548588 : int ScopeInfo::ModuleInfoIndex() {
     749     2548588 :   return OuterScopeInfoIndex() + (HasOuterScopeInfo() ? 1 : 0);
     750             : }
     751             : 
     752     2534219 : int ScopeInfo::ModuleVariableCountIndex() { return ModuleInfoIndex() + 1; }
     753             : 
     754     2528494 : int ScopeInfo::ModuleVariablesIndex() { return ModuleVariableCountIndex() + 1; }
     755             : 
     756        5443 : void ScopeInfo::ModuleVariable(int i, String** name, int* index,
     757             :                                VariableMode* mode,
     758             :                                InitializationFlag* init_flag,
     759             :                                MaybeAssignedFlag* maybe_assigned_flag) {
     760             :   DCHECK_LE(0, i);
     761             :   DCHECK_LT(i, Smi::ToInt(get(ModuleVariableCountIndex())));
     762             : 
     763        5443 :   int entry = ModuleVariablesIndex() + i * kModuleVariableEntryLength;
     764        5443 :   int properties = Smi::ToInt(get(entry + kModuleVariablePropertiesOffset));
     765             : 
     766        5443 :   if (name != nullptr) {
     767        4746 :     *name = String::cast(get(entry + kModuleVariableNameOffset));
     768             :   }
     769        5443 :   if (index != nullptr) {
     770       10886 :     *index = Smi::ToInt(get(entry + kModuleVariableIndexOffset));
     771             :     DCHECK_NE(*index, 0);
     772             :   }
     773        5443 :   if (mode != nullptr) {
     774         697 :     *mode = VariableModeField::decode(properties);
     775             :   }
     776        5443 :   if (init_flag != nullptr) {
     777        1394 :     *init_flag = InitFlagField::decode(properties);
     778             :   }
     779        5443 :   if (maybe_assigned_flag != nullptr) {
     780        1394 :     *maybe_assigned_flag = MaybeAssignedFlagField::decode(properties);
     781             :   }
     782        5443 : }
     783             : 
     784             : #ifdef DEBUG
     785             : 
     786             : static void PrintList(const char* list_name, int nof_internal_slots, int start,
     787             :                       int end, ScopeInfo* scope_info) {
     788             :   if (start < end) {
     789             :     PrintF("\n  // %s\n", list_name);
     790             :     if (nof_internal_slots > 0) {
     791             :       PrintF("  %2d - %2d [internal slots]\n", 0, nof_internal_slots - 1);
     792             :     }
     793             :     for (int i = nof_internal_slots; start < end; ++i, ++start) {
     794             :       PrintF("  %2d ", i);
     795             :       String::cast(scope_info->get(start))->ShortPrint();
     796             :       PrintF("\n");
     797             :     }
     798             :   }
     799             : }
     800             : 
     801             : void ScopeInfo::Print() {
     802             :   PrintF("ScopeInfo ");
     803             :   if (HasFunctionName()) {
     804             :     FunctionName()->ShortPrint();
     805             :   } else {
     806             :     PrintF("/* no function name */");
     807             :   }
     808             :   PrintF("{");
     809             : 
     810             :   if (length() > 0) {
     811             :     PrintList("parameters", 0, ParameterNamesIndex(),
     812             :               ParameterNamesIndex() + ParameterCount(), this);
     813             :     PrintList("stack slots", 0, StackLocalNamesIndex(),
     814             :               StackLocalNamesIndex() + StackLocalCount(), this);
     815             :     PrintList("context slots", Context::MIN_CONTEXT_SLOTS,
     816             :               ContextLocalNamesIndex(),
     817             :               ContextLocalNamesIndex() + ContextLocalCount(), this);
     818             :     // TODO(neis): Print module stuff if present.
     819             :   }
     820             : 
     821             :   PrintF("}\n");
     822             : }
     823             : #endif  // DEBUG
     824             : 
     825        1245 : Handle<ModuleInfoEntry> ModuleInfoEntry::New(Isolate* isolate,
     826             :                                              Handle<Object> export_name,
     827             :                                              Handle<Object> local_name,
     828             :                                              Handle<Object> import_name,
     829             :                                              int module_request, int cell_index,
     830             :                                              int beg_pos, int end_pos) {
     831             :   Handle<ModuleInfoEntry> result = Handle<ModuleInfoEntry>::cast(
     832        1245 :       isolate->factory()->NewStruct(MODULE_INFO_ENTRY_TYPE, TENURED));
     833        1245 :   result->set_export_name(*export_name);
     834        1245 :   result->set_local_name(*local_name);
     835        1245 :   result->set_import_name(*import_name);
     836             :   result->set_module_request(module_request);
     837             :   result->set_cell_index(cell_index);
     838             :   result->set_beg_pos(beg_pos);
     839             :   result->set_end_pos(end_pos);
     840        1245 :   return result;
     841             : }
     842             : 
     843        1724 : Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, Zone* zone,
     844             :                                    ModuleDescriptor* descr) {
     845             :   // Serialize module requests.
     846        1724 :   int size = static_cast<int>(descr->module_requests().size());
     847        1724 :   Handle<FixedArray> module_requests = isolate->factory()->NewFixedArray(size);
     848             :   Handle<FixedArray> module_request_positions =
     849        1724 :       isolate->factory()->NewFixedArray(size);
     850        4394 :   for (const auto& elem : descr->module_requests()) {
     851        2838 :     module_requests->set(elem.second.index, *elem.first->string());
     852             :     module_request_positions->set(elem.second.index,
     853        1892 :                                   Smi::FromInt(elem.second.position));
     854             :   }
     855             : 
     856             :   // Serialize special exports.
     857             :   Handle<FixedArray> special_exports = isolate->factory()->NewFixedArray(
     858        3448 :       static_cast<int>(descr->special_exports().size()));
     859             :   {
     860             :     int i = 0;
     861        3632 :     for (auto entry : descr->special_exports()) {
     862         184 :       Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
     863         368 :       special_exports->set(i++, *serialized_entry);
     864             :     }
     865             :   }
     866             : 
     867             :   // Serialize namespace imports.
     868             :   Handle<FixedArray> namespace_imports = isolate->factory()->NewFixedArray(
     869        3448 :       static_cast<int>(descr->namespace_imports().size()));
     870             :   {
     871             :     int i = 0;
     872        3538 :     for (auto entry : descr->namespace_imports()) {
     873          90 :       Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
     874         180 :       namespace_imports->set(i++, *serialized_entry);
     875             :     }
     876             :   }
     877             : 
     878             :   // Serialize regular exports.
     879             :   Handle<FixedArray> regular_exports =
     880        1724 :       descr->SerializeRegularExports(isolate, zone);
     881             : 
     882             :   // Serialize regular imports.
     883             :   Handle<FixedArray> regular_imports = isolate->factory()->NewFixedArray(
     884        1724 :       static_cast<int>(descr->regular_imports().size()));
     885             :   {
     886             :     int i = 0;
     887        4419 :     for (const auto& elem : descr->regular_imports()) {
     888             :       Handle<ModuleInfoEntry> serialized_entry =
     889         971 :           elem.second->Serialize(isolate);
     890        1942 :       regular_imports->set(i++, *serialized_entry);
     891             :     }
     892             :   }
     893             : 
     894        1724 :   Handle<ModuleInfo> result = isolate->factory()->NewModuleInfo();
     895        1724 :   result->set(kModuleRequestsIndex, *module_requests);
     896        1724 :   result->set(kSpecialExportsIndex, *special_exports);
     897        1724 :   result->set(kRegularExportsIndex, *regular_exports);
     898        1724 :   result->set(kNamespaceImportsIndex, *namespace_imports);
     899        1724 :   result->set(kRegularImportsIndex, *regular_imports);
     900        1724 :   result->set(kModuleRequestPositionsIndex, *module_request_positions);
     901        1724 :   return result;
     902             : }
     903             : 
     904       10748 : int ModuleInfo::RegularExportCount() const {
     905             :   DCHECK_EQ(regular_exports()->length() % kRegularExportLength, 0);
     906       10748 :   return regular_exports()->length() / kRegularExportLength;
     907             : }
     908             : 
     909        6864 : String* ModuleInfo::RegularExportLocalName(int i) const {
     910             :   return String::cast(regular_exports()->get(i * kRegularExportLength +
     911       13728 :                                              kRegularExportLocalNameOffset));
     912             : }
     913             : 
     914       38015 : int ModuleInfo::RegularExportCellIndex(int i) const {
     915       38015 :   return Smi::cast(regular_exports()->get(i * kRegularExportLength +
     916             :                                           kRegularExportCellIndexOffset))
     917       76030 :       ->value();
     918             : }
     919             : 
     920       38015 : FixedArray* ModuleInfo::RegularExportExportNames(int i) const {
     921             :   return FixedArray::cast(regular_exports()->get(
     922       76030 :       i * kRegularExportLength + kRegularExportExportNamesOffset));
     923             : }
     924             : 
     925             : }  // namespace internal
     926             : }  // namespace v8

Generated by: LCOV version 1.10