LCOV - code coverage report
Current view: top level - src/objects - scope-info.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 354 373 94.9 %
Date: 2019-01-20 Functions: 57 65 87.7 %

          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/scopes.h"
      10             : #include "src/ast/variables.h"
      11             : #include "src/bootstrapper.h"
      12             : 
      13             : #include "src/objects-inl.h"
      14             : #include "src/objects/module-inl.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19             : // An entry in ModuleVariableEntries consists of several slots:
      20             : enum ModuleVariableEntryOffset {
      21             :   kModuleVariableNameOffset,
      22             :   kModuleVariableIndexOffset,
      23             :   kModuleVariablePropertiesOffset,
      24             :   kModuleVariableEntryLength  // Sentinel value.
      25             : };
      26             : 
      27             : #ifdef DEBUG
      28             : bool ScopeInfo::Equals(ScopeInfo other) const {
      29             :   if (length() != other->length()) return false;
      30             :   for (int index = 0; index < length(); ++index) {
      31             :     Object entry = get(index);
      32             :     Object other_entry = other->get(index);
      33             :     if (entry->IsSmi()) {
      34             :       if (entry != other_entry) return false;
      35             :     } else {
      36             :       if (HeapObject::cast(entry)->map()->instance_type() !=
      37             :           HeapObject::cast(other_entry)->map()->instance_type()) {
      38             :         return false;
      39             :       }
      40             :       if (entry->IsString()) {
      41             :         if (!String::cast(entry)->Equals(String::cast(other_entry))) {
      42             :           return false;
      43             :         }
      44             :       } else if (entry->IsScopeInfo()) {
      45             :         if (!ScopeInfo::cast(entry)->Equals(ScopeInfo::cast(other_entry))) {
      46             :           return false;
      47             :         }
      48             :       } else if (entry->IsModuleInfo()) {
      49             :         if (!ModuleInfo::cast(entry)->Equals(ModuleInfo::cast(other_entry))) {
      50             :           return false;
      51             :         }
      52             :       } else {
      53             :         UNREACHABLE();
      54             :       }
      55             :     }
      56             :   }
      57             :   return true;
      58             : }
      59             : #endif
      60             : 
      61             : // static
      62    19685365 : Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
      63             :                                     MaybeHandle<ScopeInfo> outer_scope) {
      64             :   // Collect variables.
      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    14578070 :   for (Variable* var : *scope->locals()) {
      72    10148080 :     switch (var->location()) {
      73             :       case VariableLocation::CONTEXT:
      74     1909603 :         context_local_count++;
      75     1909603 :         break;
      76             :       case VariableLocation::MODULE:
      77       17986 :         module_vars_count++;
      78       17986 :         break;
      79             :       default:
      80             :         break;
      81             :     }
      82             :   }
      83             :   DCHECK(module_vars_count == 0 || scope->is_module_scope());
      84             : 
      85             :   // Make sure we allocate the correct amount.
      86             :   DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
      87             : 
      88             :   // Determine use and location of the "this" binding if it is present.
      89             :   VariableAllocationInfo receiver_info;
      90     4307592 :   if (scope->is_declaration_scope() &&
      91     2092600 :       scope->AsDeclarationScope()->has_this_declaration()) {
      92      892218 :     Variable* var = scope->AsDeclarationScope()->receiver();
      93      892218 :     if (!var->is_used()) {
      94             :       receiver_info = UNUSED;
      95      180331 :     } else if (var->IsContextSlot()) {
      96             :       receiver_info = CONTEXT;
      97             :     } else {
      98             :       DCHECK(var->IsParameter());
      99             :       receiver_info = STACK;
     100             :     }
     101             :   } else {
     102             :     receiver_info = NONE;
     103             :   }
     104             : 
     105             :   const bool has_new_target =
     106     4307609 :       scope->is_declaration_scope() &&
     107     2092604 :       scope->AsDeclarationScope()->new_target_var() != nullptr;
     108             :   // TODO(cbruni): Don't always waste a field for the inferred name.
     109             :   const bool has_inferred_function_name = scope->is_function_scope();
     110             : 
     111             :   // Determine use and location of the function variable if it is present.
     112             :   VariableAllocationInfo function_name_info;
     113     2215005 :   if (scope->is_function_scope()) {
     114     1082829 :     if (scope->AsDeclarationScope()->function_var() != nullptr) {
     115       24677 :       Variable* var = scope->AsDeclarationScope()->function_var();
     116       24677 :       if (!var->is_used()) {
     117             :         function_name_info = UNUSED;
     118       24677 :       } else if (var->IsContextSlot()) {
     119             :         function_name_info = CONTEXT;
     120             :       } else {
     121             :         DCHECK(var->IsStackLocal());
     122             :         function_name_info = STACK;
     123             :       }
     124             :     } else {
     125             :       // Always reserve space for the debug name in the scope info.
     126             :       function_name_info = UNUSED;
     127             :     }
     128     1132176 :   } else if (scope->is_module_scope() || scope->is_script_scope() ||
     129             :              scope->is_eval_scope()) {
     130             :     // Always reserve space for the debug name in the scope info.
     131             :     function_name_info = UNUSED;
     132             :   } else {
     133             :     function_name_info = NONE;
     134             :   }
     135             : 
     136     2215001 :   const bool has_function_name = function_name_info != NONE;
     137             :   const bool has_position_info = NeedsPositionInfo(scope->scope_type());
     138     2215001 :   const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT;
     139     2215001 :   const int parameter_count = scope->num_parameters();
     140     2215007 :   const bool has_outer_scope_info = !outer_scope.is_null();
     141     2215007 :   const int length = kVariablePartIndex + 2 * context_local_count +
     142     2215007 :                      (has_receiver ? 1 : 0) +
     143     2215007 :                      (has_function_name ? kFunctionNameEntries : 0) +
     144     2215007 :                      (has_inferred_function_name ? 1 : 0) +
     145     2215007 :                      (has_position_info ? kPositionInfoEntries : 0) +
     146     2216105 :                      (has_outer_scope_info ? 1 : 0) +
     147             :                      (scope->is_module_scope()
     148        1098 :                           ? 2 + kModuleVariableEntryLength * module_vars_count
     149     2215007 :                           : 0);
     150             : 
     151             :   Factory* factory = isolate->factory();
     152     2215007 :   Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
     153             : 
     154             :   bool has_simple_parameters = false;
     155             :   bool is_asm_module = false;
     156             :   bool calls_sloppy_eval = false;
     157     2215012 :   if (scope->is_function_scope()) {
     158     1082838 :     DeclarationScope* function_scope = scope->AsDeclarationScope();
     159             :     has_simple_parameters = function_scope->has_simple_parameters();
     160             :     is_asm_module = function_scope->is_asm_module();
     161             :   }
     162             :   FunctionKind function_kind = kNormalFunction;
     163     2215014 :   if (scope->is_declaration_scope()) {
     164     2092614 :     function_kind = scope->AsDeclarationScope()->function_kind();
     165     2092615 :     calls_sloppy_eval = scope->AsDeclarationScope()->calls_sloppy_eval();
     166             :   }
     167             : 
     168             :   // Encode the flags.
     169             :   int flags =
     170     2215017 :       ScopeTypeField::encode(scope->scope_type()) |
     171     2215017 :       CallsSloppyEvalField::encode(calls_sloppy_eval) |
     172     2215017 :       LanguageModeField::encode(scope->language_mode()) |
     173     2215017 :       DeclarationScopeField::encode(scope->is_declaration_scope()) |
     174     2215017 :       ReceiverVariableField::encode(receiver_info) |
     175     2215017 :       HasNewTargetField::encode(has_new_target) |
     176     2215017 :       FunctionVariableField::encode(function_name_info) |
     177     2215017 :       HasInferredFunctionNameField::encode(has_inferred_function_name) |
     178     2215017 :       IsAsmModuleField::encode(is_asm_module) |
     179     2215017 :       HasSimpleParametersField::encode(has_simple_parameters) |
     180     2215017 :       FunctionKindField::encode(function_kind) |
     181     2215017 :       HasOuterScopeInfoField::encode(has_outer_scope_info) |
     182     2215017 :       IsDebugEvaluateScopeField::encode(scope->is_debug_evaluate_scope()) |
     183     2215017 :       ForceContextAllocationField::encode(scope->ForceContextForLanguageMode());
     184             :   scope_info->SetFlags(flags);
     185             : 
     186             :   scope_info->SetParameterCount(parameter_count);
     187             :   scope_info->SetContextLocalCount(context_local_count);
     188             : 
     189             :   int index = kVariablePartIndex;
     190             : 
     191             :   // Add context locals' names and info, module variables' names and info.
     192             :   // Context locals are added using their index.
     193             :   int context_local_base = index;
     194     2215022 :   int context_local_info_base = context_local_base + context_local_count;
     195     4430052 :   int module_var_entry = scope_info->ModuleVariablesIndex();
     196             : 
     197    18451519 :   for (Variable* var : *scope->locals()) {
     198    10148309 :     switch (var->location()) {
     199             :       case VariableLocation::CONTEXT: {
     200             :         // Due to duplicate parameters, context locals aren't guaranteed to come
     201             :         // in order.
     202     1909590 :         int local_index = var->index() - Context::MIN_CONTEXT_SLOTS;
     203             :         DCHECK_LE(0, local_index);
     204             :         DCHECK_LT(local_index, context_local_count);
     205             :         uint32_t info =
     206     1909590 :             VariableModeField::encode(var->mode()) |
     207     1909590 :             InitFlagField::encode(var->initialization_flag()) |
     208             :             MaybeAssignedFlagField::encode(var->maybe_assigned()) |
     209     1909590 :             ParameterNumberField::encode(ParameterNumberField::kMax);
     210     3819216 :         scope_info->set(context_local_base + local_index, *var->name());
     211             :         scope_info->set(context_local_info_base + local_index,
     212     3819216 :                         Smi::FromInt(info));
     213     1909608 :         break;
     214             :       }
     215             :       case VariableLocation::MODULE: {
     216       35972 :         scope_info->set(module_var_entry + kModuleVariableNameOffset,
     217       53958 :                         *var->name());
     218             :         scope_info->set(module_var_entry + kModuleVariableIndexOffset,
     219             :                         Smi::FromInt(var->index()));
     220             :         uint32_t properties =
     221       17986 :             VariableModeField::encode(var->mode()) |
     222       17986 :             InitFlagField::encode(var->initialization_flag()) |
     223             :             MaybeAssignedFlagField::encode(var->maybe_assigned()) |
     224       17986 :             ParameterNumberField::encode(ParameterNumberField::kMax);
     225             :         scope_info->set(module_var_entry + kModuleVariablePropertiesOffset,
     226       17986 :                         Smi::FromInt(properties));
     227             :         module_var_entry += kModuleVariableEntryLength;
     228       17986 :         break;
     229             :       }
     230             :       default:
     231             :         break;
     232             :     }
     233             :   }
     234             : 
     235     2215045 :   if (scope->is_declaration_scope()) {
     236             :     // Mark contexts slots with the parameter number they represent. We walk the
     237             :     // list of parameters. That can include duplicate entries if a parameter
     238             :     // name is repeated. By walking upwards, we'll automatically mark the
     239             :     // context slot with the highest parameter number that uses this variable.
     240             :     // That will be the parameter number that is represented by the context
     241             :     // slot. All lower parameters will only be available on the stack through
     242             :     // the arguments object.
     243     2335970 :     for (int i = 0; i < parameter_count; i++) {
     244     4712923 :       Variable* parameter = scope->AsDeclarationScope()->parameter(i);
     245     2335970 :       if (parameter->location() != VariableLocation::CONTEXT) continue;
     246       40982 :       int index = parameter->index() - Context::MIN_CONTEXT_SLOTS;
     247       40982 :       int info_index = context_local_info_base + index;
     248       40982 :       int info = Smi::ToInt(scope_info->get(info_index));
     249       81964 :       info = ParameterNumberField::update(info, i);
     250             :       scope_info->set(info_index, Smi::FromInt(info));
     251             :     }
     252             :   }
     253             : 
     254             :   index += 2 * context_local_count;
     255             : 
     256             :   // If the receiver is allocated, add its index.
     257             :   DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
     258     2215044 :   if (has_receiver) {
     259      180339 :     int var_index = scope->AsDeclarationScope()->receiver()->index();
     260      180339 :     scope_info->set(index++, Smi::FromInt(var_index));
     261             :     // ?? DCHECK(receiver_info != CONTEXT || var_index ==
     262             :     // scope_info->ContextLength() - 1);
     263             :   }
     264             : 
     265             :   // If present, add the function variable name and its index.
     266             :   DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
     267     2215047 :   if (has_function_name) {
     268             :     DisallowHeapAllocation no_gc;
     269     2114833 :     Variable* var = scope->AsDeclarationScope()->function_var();
     270             :     int var_index = -1;
     271     2090163 :     Object name = Smi::kZero;
     272     2090163 :     if (var != nullptr) {
     273             :       var_index = var->index();
     274       24677 :       name = *var->name();
     275             :     }
     276     4180329 :     scope_info->set(index++, name);
     277     2090142 :     scope_info->set(index++, Smi::FromInt(var_index));
     278             :     DCHECK(function_name_info != CONTEXT ||
     279             :            var_index == scope_info->ContextLength() - 1);
     280             :   }
     281             : 
     282             :   DCHECK_EQ(index, scope_info->InferredFunctionNameIndex());
     283     2215032 :   if (has_inferred_function_name) {
     284             :     // The inferred function name is taken from the SFI.
     285     1082840 :     index++;
     286             :   }
     287             : 
     288             :   DCHECK_EQ(index, scope_info->PositionInfoIndex());
     289     2215032 :   if (has_position_info) {
     290     2090143 :     scope_info->set(index++, Smi::FromInt(scope->start_position()));
     291     2090146 :     scope_info->set(index++, Smi::FromInt(scope->end_position()));
     292             :   }
     293             : 
     294             :   // If present, add the outer scope info.
     295             :   DCHECK(index == scope_info->OuterScopeInfoIndex());
     296     2215035 :   if (has_outer_scope_info) {
     297     2190668 :     scope_info->set(index++, *outer_scope.ToHandleChecked());
     298             :   }
     299             : 
     300             :   // Module-specific information (only for module scopes).
     301     2215039 :   if (scope->is_module_scope()) {
     302             :     Handle<ModuleInfo> module_info =
     303        1098 :         ModuleInfo::New(isolate, zone, scope->AsModuleScope()->module());
     304             :     DCHECK_EQ(index, scope_info->ModuleInfoIndex());
     305        2196 :     scope_info->set(index++, *module_info);
     306             :     DCHECK_EQ(index, scope_info->ModuleVariableCountIndex());
     307             :     scope_info->set(index++, Smi::FromInt(module_vars_count));
     308             :     DCHECK_EQ(index, scope_info->ModuleVariablesIndex());
     309             :     // The variable entries themselves have already been written above.
     310             :     index += kModuleVariableEntryLength * module_vars_count;
     311             :   }
     312             : 
     313             :   DCHECK_EQ(index, scope_info->length());
     314             :   DCHECK_EQ(scope->num_parameters(), scope_info->ParameterCount());
     315             :   DCHECK_EQ(scope->num_heap_slots(), scope_info->ContextLength());
     316     2215039 :   return scope_info;
     317             : }
     318             : 
     319             : // static
     320       12424 : Handle<ScopeInfo> ScopeInfo::CreateForWithScope(
     321             :     Isolate* isolate, MaybeHandle<ScopeInfo> outer_scope) {
     322       12424 :   const bool has_outer_scope_info = !outer_scope.is_null();
     323       12424 :   const int length = kVariablePartIndex + (has_outer_scope_info ? 1 : 0);
     324             : 
     325             :   Factory* factory = isolate->factory();
     326       12424 :   Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
     327             : 
     328             :   // Encode the flags.
     329             :   int flags =
     330             :       ScopeTypeField::encode(WITH_SCOPE) | CallsSloppyEvalField::encode(false) |
     331             :       LanguageModeField::encode(LanguageMode::kSloppy) |
     332             :       DeclarationScopeField::encode(false) |
     333             :       ReceiverVariableField::encode(NONE) | HasNewTargetField::encode(false) |
     334             :       FunctionVariableField::encode(NONE) | IsAsmModuleField::encode(false) |
     335             :       HasSimpleParametersField::encode(true) |
     336       12424 :       FunctionKindField::encode(kNormalFunction) |
     337             :       HasOuterScopeInfoField::encode(has_outer_scope_info) |
     338       12424 :       IsDebugEvaluateScopeField::encode(false);
     339             :   scope_info->SetFlags(flags);
     340             : 
     341             :   scope_info->SetParameterCount(0);
     342             :   scope_info->SetContextLocalCount(0);
     343             : 
     344             :   int index = kVariablePartIndex;
     345             :   DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
     346             :   DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
     347             :   DCHECK_EQ(index, scope_info->InferredFunctionNameIndex());
     348             :   DCHECK_EQ(index, scope_info->PositionInfoIndex());
     349             :   DCHECK(index == scope_info->OuterScopeInfoIndex());
     350       12424 :   if (has_outer_scope_info) {
     351        4708 :     scope_info->set(index++, *outer_scope.ToHandleChecked());
     352             :   }
     353             :   DCHECK_EQ(index, scope_info->length());
     354             :   DCHECK_EQ(0, scope_info->ParameterCount());
     355             :   DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, scope_info->ContextLength());
     356       12424 :   return scope_info;
     357             : }
     358             : 
     359             : // static
     360         111 : Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
     361         111 :   return CreateForBootstrapping(isolate, SCRIPT_SCOPE);
     362             : }
     363             : 
     364             : // static
     365         113 : Handle<ScopeInfo> ScopeInfo::CreateForEmptyFunction(Isolate* isolate) {
     366         113 :   return CreateForBootstrapping(isolate, FUNCTION_SCOPE);
     367             : }
     368             : 
     369             : // static
     370         224 : Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate,
     371             :                                                     ScopeType type) {
     372             :   DCHECK(type == SCRIPT_SCOPE || type == FUNCTION_SCOPE);
     373             : 
     374             :   const int parameter_count = 0;
     375         224 :   const bool is_empty_function = type == FUNCTION_SCOPE;
     376         224 :   const int context_local_count = is_empty_function ? 0 : 1;
     377             :   const bool has_receiver = !is_empty_function;
     378             :   const bool has_inferred_function_name = is_empty_function;
     379             :   const bool has_position_info = true;
     380         224 :   const int length = kVariablePartIndex + 2 * context_local_count +
     381         224 :                      (has_receiver ? 1 : 0) +
     382         224 :                      (is_empty_function ? kFunctionNameEntries : 0) +
     383             :                      (has_inferred_function_name ? 1 : 0) +
     384         224 :                      (has_position_info ? kPositionInfoEntries : 0);
     385             : 
     386             :   Factory* factory = isolate->factory();
     387         224 :   Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
     388             : 
     389             :   // Encode the flags.
     390             :   int flags =
     391             :       ScopeTypeField::encode(type) | CallsSloppyEvalField::encode(false) |
     392         224 :       LanguageModeField::encode(LanguageMode::kSloppy) |
     393         224 :       DeclarationScopeField::encode(true) |
     394         224 :       ReceiverVariableField::encode(is_empty_function ? UNUSED : CONTEXT) |
     395         224 :       HasNewTargetField::encode(false) |
     396         448 :       FunctionVariableField::encode(is_empty_function ? UNUSED : NONE) |
     397             :       HasInferredFunctionNameField::encode(has_inferred_function_name) |
     398         224 :       IsAsmModuleField::encode(false) | HasSimpleParametersField::encode(true) |
     399             :       FunctionKindField::encode(FunctionKind::kNormalFunction) |
     400             :       HasOuterScopeInfoField::encode(false) |
     401         224 :       IsDebugEvaluateScopeField::encode(false);
     402             :   scope_info->SetFlags(flags);
     403             :   scope_info->SetParameterCount(parameter_count);
     404             :   scope_info->SetContextLocalCount(context_local_count);
     405             : 
     406             :   int index = kVariablePartIndex;
     407             : 
     408             :   // Here we add info for context-allocated "this".
     409             :   DCHECK_EQ(index, scope_info->ContextLocalNamesIndex());
     410         224 :   if (context_local_count) {
     411         222 :     scope_info->set(index++, ReadOnlyRoots(isolate).this_string());
     412             :   }
     413             :   DCHECK_EQ(index, scope_info->ContextLocalInfosIndex());
     414         224 :   if (context_local_count) {
     415             :     const uint32_t value =
     416             :         VariableModeField::encode(VariableMode::kConst) |
     417             :         InitFlagField::encode(kCreatedInitialized) |
     418             :         MaybeAssignedFlagField::encode(kNotAssigned) |
     419             :         ParameterNumberField::encode(ParameterNumberField::kMax);
     420         111 :     scope_info->set(index++, Smi::FromInt(value));
     421             :   }
     422             : 
     423             :   // And here we record that this scopeinfo binds a receiver.
     424             :   DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
     425             :   const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0;
     426         224 :   if (!is_empty_function) {
     427         111 :     scope_info->set(index++, Smi::FromInt(receiver_index));
     428             :   }
     429             : 
     430             :   DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
     431         224 :   if (is_empty_function) {
     432         226 :     scope_info->set(index++, *isolate->factory()->empty_string());
     433         226 :     scope_info->set(index++, Smi::kZero);
     434             :   }
     435             :   DCHECK_EQ(index, scope_info->InferredFunctionNameIndex());
     436         224 :   if (has_inferred_function_name) {
     437         226 :     scope_info->set(index++, *isolate->factory()->empty_string());
     438             :   }
     439             :   DCHECK_EQ(index, scope_info->PositionInfoIndex());
     440             :   // Store dummy position to be in sync with the {scope_type}.
     441         448 :   scope_info->set(index++, Smi::kZero);
     442         224 :   scope_info->set(index++, Smi::kZero);
     443             :   DCHECK_EQ(index, scope_info->OuterScopeInfoIndex());
     444             :   DCHECK_EQ(index, scope_info->length());
     445             :   DCHECK_EQ(scope_info->ParameterCount(), parameter_count);
     446             :   if (type == FUNCTION_SCOPE) {
     447             :     DCHECK_EQ(scope_info->ContextLength(), 0);
     448             :   } else {
     449             :     DCHECK_EQ(scope_info->ContextLength(), Context::MIN_CONTEXT_SLOTS + 1);
     450             :   }
     451             : 
     452         224 :   return scope_info;
     453             : }
     454             : 
     455     4099293 : ScopeInfo ScopeInfo::Empty(Isolate* isolate) {
     456     4099292 :   return ReadOnlyRoots(isolate).empty_scope_info();
     457             : }
     458             : 
     459     4517590 : ScopeType ScopeInfo::scope_type() const {
     460             :   DCHECK_LT(0, length());
     461    18471552 :   return ScopeTypeField::decode(Flags());
     462             : }
     463             : 
     464     1089038 : bool ScopeInfo::CallsSloppyEval() const {
     465             :   bool calls_sloppy_eval =
     466     2178086 :       length() > 0 && CallsSloppyEvalField::decode(Flags());
     467             :   DCHECK_IMPLIES(calls_sloppy_eval, is_sloppy(language_mode()));
     468             :   DCHECK_IMPLIES(calls_sloppy_eval, is_declaration_scope());
     469     1089043 :   return calls_sloppy_eval;
     470             : }
     471             : 
     472     5036108 : LanguageMode ScopeInfo::language_mode() const {
     473     5036125 :   return length() > 0 ? LanguageModeField::decode(Flags())
     474    10072245 :                       : LanguageMode::kSloppy;
     475             : }
     476             : 
     477      182122 : bool ScopeInfo::is_declaration_scope() const {
     478      369053 :   return DeclarationScopeField::decode(Flags());
     479             : }
     480             : 
     481     1315539 : int ScopeInfo::ContextLength() const {
     482     1315540 :   if (length() > 0) {
     483     1315543 :     int context_locals = ContextLocalCount();
     484             :     bool function_name_context_slot =
     485     2631092 :         FunctionVariableField::decode(Flags()) == CONTEXT;
     486     1315545 :     bool force_context = ForceContextAllocationField::decode(Flags());
     487     1337360 :     bool has_context = context_locals > 0 || force_context ||
     488       21700 :                        function_name_context_slot ||
     489        6482 :                        scope_type() == WITH_SCOPE ||
     490        9602 :                        (scope_type() == BLOCK_SCOPE && CallsSloppyEval() &&
     491        1681 :                         is_declaration_scope()) ||
     492        2404 :                        (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) ||
     493     1316409 :                        (scope_type() == FUNCTION_SCOPE && IsAsmModule()) ||
     494             :                        scope_type() == MODULE_SCOPE;
     495             : 
     496     1315537 :     if (has_context) {
     497     1315396 :       return Context::MIN_CONTEXT_SLOTS + context_locals +
     498     1315396 :              (function_name_context_slot ? 1 : 0);
     499             :     }
     500             :   }
     501             :   return 0;
     502             : }
     503             : 
     504           0 : bool ScopeInfo::HasReceiver() const {
     505           0 :   if (length() == 0) return false;
     506           0 :   return NONE != ReceiverVariableField::decode(Flags());
     507             : }
     508             : 
     509    18490924 : bool ScopeInfo::HasAllocatedReceiver() const {
     510    18490938 :   if (length() == 0) return false;
     511    18490963 :   VariableAllocationInfo allocation = ReceiverVariableField::decode(Flags());
     512    18490966 :   return allocation == STACK || allocation == CONTEXT;
     513             : }
     514             : 
     515           0 : bool ScopeInfo::HasNewTarget() const {
     516           0 :   return HasNewTargetField::decode(Flags());
     517             : }
     518             : 
     519    13210047 : bool ScopeInfo::HasFunctionName() const {
     520    13210047 :   if (length() == 0) return false;
     521    26417743 :   return NONE != FunctionVariableField::decode(Flags());
     522             : }
     523             : 
     524    10836896 : bool ScopeInfo::HasInferredFunctionName() const {
     525    10836899 :   if (length() == 0) return false;
     526    21673812 :   return HasInferredFunctionNameField::decode(Flags());
     527             : }
     528             : 
     529    12969946 : bool ScopeInfo::HasPositionInfo() const {
     530    12969942 :   if (length() == 0) return false;
     531     9405605 :   return NeedsPositionInfo(scope_type());
     532             : }
     533             : 
     534             : // static
     535           0 : bool ScopeInfo::NeedsPositionInfo(ScopeType type) {
     536    14632591 :   return type == FUNCTION_SCOPE || type == SCRIPT_SCOPE || type == EVAL_SCOPE ||
     537     3011985 :          type == MODULE_SCOPE;
     538             : }
     539             : 
     540     3162963 : bool ScopeInfo::HasSharedFunctionName() const {
     541     6325928 :   return FunctionName() != SharedFunctionInfo::kNoSharedNameSentinel;
     542             : }
     543             : 
     544     2089483 : void ScopeInfo::SetFunctionName(Object name) {
     545             :   DCHECK(HasFunctionName());
     546             :   DCHECK(name->IsString() || name == SharedFunctionInfo::kNoSharedNameSentinel);
     547     2089483 :   set(FunctionNameInfoIndex(), name);
     548     2089484 : }
     549             : 
     550       53050 : void ScopeInfo::SetInferredFunctionName(String name) {
     551             :   DCHECK(HasInferredFunctionName());
     552       53050 :   set(InferredFunctionNameIndex(), name);
     553       53050 : }
     554             : 
     555     3405238 : bool ScopeInfo::HasOuterScopeInfo() const {
     556     3405250 :   if (length() == 0) return false;
     557     6810514 :   return HasOuterScopeInfoField::decode(Flags());
     558             : }
     559             : 
     560       14727 : bool ScopeInfo::IsDebugEvaluateScope() const {
     561       14727 :   if (length() == 0) return false;
     562       29454 :   return IsDebugEvaluateScopeField::decode(Flags());
     563             : }
     564             : 
     565       12400 : void ScopeInfo::SetIsDebugEvaluateScope() {
     566       12400 :   if (length() > 0) {
     567             :     DCHECK_EQ(scope_type(), WITH_SCOPE);
     568       12400 :     SetFlags(Flags() | IsDebugEvaluateScopeField::encode(true));
     569             :   } else {
     570           0 :     UNREACHABLE();
     571             :   }
     572       12400 : }
     573             : 
     574           0 : bool ScopeInfo::HasContext() const { return ContextLength() > 0; }
     575             : 
     576     6284888 : Object ScopeInfo::FunctionName() const {
     577             :   DCHECK(HasFunctionName());
     578    12569779 :   return get(FunctionNameInfoIndex());
     579             : }
     580             : 
     581      619314 : Object ScopeInfo::InferredFunctionName() const {
     582             :   DCHECK(HasInferredFunctionName());
     583     1238628 :   return get(InferredFunctionNameIndex());
     584             : }
     585             : 
     586       18191 : String ScopeInfo::FunctionDebugName() const {
     587       18191 :   Object name = FunctionName();
     588       36382 :   if (name->IsString() && String::cast(name)->length() > 0) {
     589             :     return String::cast(name);
     590             :   }
     591        9765 :   if (HasInferredFunctionName()) {
     592        1884 :     name = InferredFunctionName();
     593        1884 :     if (name->IsString()) return String::cast(name);
     594             :   }
     595       18676 :   return GetReadOnlyRoots().empty_string();
     596             : }
     597             : 
     598     6286722 : int ScopeInfo::StartPosition() const {
     599             :   DCHECK(HasPositionInfo());
     600    12573448 :   return Smi::ToInt(get(PositionInfoIndex()));
     601             : }
     602             : 
     603      483135 : int ScopeInfo::EndPosition() const {
     604             :   DCHECK(HasPositionInfo());
     605      966270 :   return Smi::ToInt(get(PositionInfoIndex() + 1));
     606             : }
     607             : 
     608        1067 : void ScopeInfo::SetPositionInfo(int start, int end) {
     609             :   DCHECK(HasPositionInfo());
     610             :   DCHECK_LE(start, end);
     611        1067 :   set(PositionInfoIndex(), Smi::FromInt(start));
     612        1067 :   set(PositionInfoIndex() + 1, Smi::FromInt(end));
     613        1067 : }
     614             : 
     615      435447 : ScopeInfo ScopeInfo::OuterScopeInfo() const {
     616             :   DCHECK(HasOuterScopeInfo());
     617      870904 :   return ScopeInfo::cast(get(OuterScopeInfoIndex()));
     618             : }
     619             : 
     620       12928 : ModuleInfo ScopeInfo::ModuleDescriptorInfo() const {
     621             :   DCHECK(scope_type() == MODULE_SCOPE);
     622       25856 :   return ModuleInfo::cast(get(ModuleInfoIndex()));
     623             : }
     624             : 
     625     1587302 : String ScopeInfo::ContextLocalName(int var) const {
     626             :   DCHECK_LE(0, var);
     627             :   DCHECK_LT(var, ContextLocalCount());
     628     1587302 :   int info_index = ContextLocalNamesIndex() + var;
     629     1587302 :   return String::cast(get(info_index));
     630             : }
     631             : 
     632     3058891 : VariableMode ScopeInfo::ContextLocalMode(int var) const {
     633             :   DCHECK_LE(0, var);
     634             :   DCHECK_LT(var, ContextLocalCount());
     635     3058894 :   int info_index = ContextLocalInfosIndex() + var;
     636     3058894 :   int value = Smi::ToInt(get(info_index));
     637     3058897 :   return VariableModeField::decode(value);
     638             : }
     639             : 
     640     2177595 : InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) const {
     641             :   DCHECK_LE(0, var);
     642             :   DCHECK_LT(var, ContextLocalCount());
     643     2177598 :   int info_index = ContextLocalInfosIndex() + var;
     644     2177598 :   int value = Smi::ToInt(get(info_index));
     645     4355196 :   return InitFlagField::decode(value);
     646             : }
     647             : 
     648         129 : bool ScopeInfo::ContextLocalIsParameter(int var) const {
     649             :   DCHECK_LE(0, var);
     650             :   DCHECK_LT(var, ContextLocalCount());
     651         129 :   int info_index = ContextLocalInfosIndex() + var;
     652         129 :   int value = Smi::ToInt(get(info_index));
     653         258 :   return ParameterNumberField::decode(value) != ParameterNumberField::kMax;
     654             : }
     655             : 
     656         129 : uint32_t ScopeInfo::ContextLocalParameterNumber(int var) const {
     657             :   DCHECK(ContextLocalIsParameter(var));
     658         129 :   int info_index = ContextLocalInfosIndex() + var;
     659         129 :   int value = Smi::ToInt(get(info_index));
     660         258 :   return ParameterNumberField::decode(value);
     661             : }
     662             : 
     663     2179444 : MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) const {
     664             :   DCHECK_LE(0, var);
     665             :   DCHECK_LT(var, ContextLocalCount());
     666     2179446 :   int info_index = ContextLocalInfosIndex() + var;
     667     2179446 :   int value = Smi::ToInt(get(info_index));
     668     4358892 :   return MaybeAssignedFlagField::decode(value);
     669             : }
     670             : 
     671             : // static
     672     7189530 : bool ScopeInfo::VariableIsSynthetic(String name) {
     673             :   // There's currently no flag stored on the ScopeInfo to indicate that a
     674             :   // variable is a compiler-introduced temporary. However, to avoid conflict
     675             :   // with user declarations, the current temporaries like .generator_object and
     676             :   // .result start with a dot, so we can use that as a flag. It's a hack!
     677    21443035 :   return name->length() == 0 || name->Get(0) == '.' ||
     678    21322242 :          name->Equals(name->GetReadOnlyRoots().this_string());
     679             : }
     680             : 
     681        2282 : int ScopeInfo::ModuleIndex(Handle<String> name, VariableMode* mode,
     682             :                            InitializationFlag* init_flag,
     683             :                            MaybeAssignedFlag* maybe_assigned_flag) {
     684             :   DCHECK(name->IsInternalizedString());
     685             :   DCHECK_EQ(scope_type(), MODULE_SCOPE);
     686             :   DCHECK_NOT_NULL(mode);
     687             :   DCHECK_NOT_NULL(init_flag);
     688             :   DCHECK_NOT_NULL(maybe_assigned_flag);
     689             : 
     690        2282 :   int module_vars_count = Smi::ToInt(get(ModuleVariableCountIndex()));
     691             :   int entry = ModuleVariablesIndex();
     692        6559 :   for (int i = 0; i < module_vars_count; ++i) {
     693        4951 :     String var_name = String::cast(get(entry + kModuleVariableNameOffset));
     694        4951 :     if (name->Equals(var_name)) {
     695             :       int index;
     696         674 :       ModuleVariable(i, nullptr, &index, mode, init_flag, maybe_assigned_flag);
     697         674 :       return index;
     698             :     }
     699        4277 :     entry += kModuleVariableEntryLength;
     700             :   }
     701             : 
     702             :   return 0;
     703             : }
     704             : 
     705             : // static
     706    20066430 : int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
     707             :                                 Handle<String> name, VariableMode* mode,
     708             :                                 InitializationFlag* init_flag,
     709             :                                 MaybeAssignedFlag* maybe_assigned_flag) {
     710             :   DCHECK(name->IsInternalizedString());
     711             :   DCHECK_NOT_NULL(mode);
     712             :   DCHECK_NOT_NULL(init_flag);
     713             :   DCHECK_NOT_NULL(maybe_assigned_flag);
     714             : 
     715    20066447 :   if (scope_info->length() == 0) return -1;
     716             : 
     717             :   int start = scope_info->ContextLocalNamesIndex();
     718    20066448 :   int end = start + scope_info->ContextLocalCount();
     719   134146100 :   for (int i = start; i < end; ++i) {
     720   116257242 :     if (*name == scope_info->get(i)) {
     721     2177594 :       int var = i - start;
     722     2177595 :       *mode = scope_info->ContextLocalMode(var);
     723     2177596 :       *init_flag = scope_info->ContextLocalInitFlag(var);
     724     2177598 :       *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var);
     725     2177594 :       int result = Context::MIN_CONTEXT_SLOTS + var;
     726             : 
     727             :       DCHECK_LT(result, scope_info->ContextLength());
     728     2177594 :       return result;
     729             :     }
     730             :   }
     731             : 
     732             :   return -1;
     733             : }
     734             : 
     735      394497 : int ScopeInfo::ReceiverContextSlotIndex() const {
     736      788996 :   if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT) {
     737      259522 :     return Smi::ToInt(get(ReceiverInfoIndex()));
     738             :   }
     739             :   return -1;
     740             : }
     741             : 
     742     3941758 : int ScopeInfo::FunctionContextSlotIndex(String name) const {
     743             :   DCHECK(name->IsInternalizedString());
     744     3941761 :   if (length() > 0) {
     745    15767061 :     if (FunctionVariableField::decode(Flags()) == CONTEXT &&
     746     3962453 :         FunctionName() == name) {
     747        2404 :       return Smi::ToInt(get(FunctionNameInfoIndex() + 1));
     748             :     }
     749             :   }
     750             :   return -1;
     751             : }
     752             : 
     753      873450 : FunctionKind ScopeInfo::function_kind() const {
     754     1746901 :   return FunctionKindField::decode(Flags());
     755             : }
     756             : 
     757           0 : int ScopeInfo::ContextLocalNamesIndex() const {
     758             :   DCHECK_LT(0, length());
     759           0 :   return kVariablePartIndex;
     760             : }
     761             : 
     762           0 : int ScopeInfo::ContextLocalInfosIndex() const {
     763    26036864 :   return ContextLocalNamesIndex() + ContextLocalCount();
     764             : }
     765             : 
     766    18620676 : int ScopeInfo::ReceiverInfoIndex() const {
     767    18620685 :   return ContextLocalInfosIndex() + ContextLocalCount();
     768             : }
     769             : 
     770    18490914 : int ScopeInfo::FunctionNameInfoIndex() const {
     771    18490914 :   return ReceiverInfoIndex() + (HasAllocatedReceiver() ? 1 : 0);
     772             : }
     773             : 
     774    10115344 : int ScopeInfo::InferredFunctionNameIndex() const {
     775    20230734 :   return FunctionNameInfoIndex() +
     776    20230773 :          (HasFunctionName() ? kFunctionNameEntries : 0);
     777             : }
     778             : 
     779     9442975 : int ScopeInfo::PositionInfoIndex() const {
     780     9442975 :   return InferredFunctionNameIndex() + (HasInferredFunctionName() ? 1 : 0);
     781             : }
     782             : 
     783     2670989 : int ScopeInfo::OuterScopeInfoIndex() const {
     784     2670989 :   return PositionInfoIndex() + (HasPositionInfo() ? kPositionInfoEntries : 0);
     785             : }
     786             : 
     787     2235539 : int ScopeInfo::ModuleInfoIndex() const {
     788     2235539 :   return OuterScopeInfoIndex() + (HasOuterScopeInfo() ? 1 : 0);
     789             : }
     790             : 
     791         753 : int ScopeInfo::ModuleVariableCountIndex() const {
     792     2222621 :   return ModuleInfoIndex() + 1;
     793             : }
     794             : 
     795           0 : int ScopeInfo::ModuleVariablesIndex() const {
     796     2219588 :   return ModuleVariableCountIndex() + 1;
     797             : }
     798             : 
     799        2279 : void ScopeInfo::ModuleVariable(int i, String* name, int* index,
     800             :                                VariableMode* mode,
     801             :                                InitializationFlag* init_flag,
     802             :                                MaybeAssignedFlag* maybe_assigned_flag) {
     803             :   DCHECK_LE(0, i);
     804             :   DCHECK_LT(i, Smi::ToInt(get(ModuleVariableCountIndex())));
     805             : 
     806        2279 :   int entry = ModuleVariablesIndex() + i * kModuleVariableEntryLength;
     807        4558 :   int properties = Smi::ToInt(get(entry + kModuleVariablePropertiesOffset));
     808             : 
     809        2279 :   if (name != nullptr) {
     810        1605 :     *name = String::cast(get(entry + kModuleVariableNameOffset));
     811             :   }
     812        2279 :   if (index != nullptr) {
     813        4558 :     *index = Smi::ToInt(get(entry + kModuleVariableIndexOffset));
     814             :     DCHECK_NE(*index, 0);
     815             :   }
     816        2279 :   if (mode != nullptr) {
     817         674 :     *mode = VariableModeField::decode(properties);
     818             :   }
     819        2279 :   if (init_flag != nullptr) {
     820        1348 :     *init_flag = InitFlagField::decode(properties);
     821             :   }
     822        2279 :   if (maybe_assigned_flag != nullptr) {
     823        1348 :     *maybe_assigned_flag = MaybeAssignedFlagField::decode(properties);
     824             :   }
     825        2279 : }
     826             : 
     827           0 : std::ostream& operator<<(std::ostream& os,
     828             :                          ScopeInfo::VariableAllocationInfo var_info) {
     829           0 :   switch (var_info) {
     830             :     case ScopeInfo::VariableAllocationInfo::NONE:
     831           0 :       return os << "NONE";
     832             :     case ScopeInfo::VariableAllocationInfo::STACK:
     833           0 :       return os << "STACK";
     834             :     case ScopeInfo::VariableAllocationInfo::CONTEXT:
     835           0 :       return os << "CONTEXT";
     836             :     case ScopeInfo::VariableAllocationInfo::UNUSED:
     837           0 :       return os << "UNUSED";
     838             :   }
     839           0 :   UNREACHABLE();
     840             :   return os;
     841             : }
     842             : 
     843         723 : Handle<ModuleInfoEntry> ModuleInfoEntry::New(Isolate* isolate,
     844             :                                              Handle<Object> export_name,
     845             :                                              Handle<Object> local_name,
     846             :                                              Handle<Object> import_name,
     847             :                                              int module_request, int cell_index,
     848             :                                              int beg_pos, int end_pos) {
     849             :   Handle<ModuleInfoEntry> result = Handle<ModuleInfoEntry>::cast(
     850         723 :       isolate->factory()->NewStruct(MODULE_INFO_ENTRY_TYPE, TENURED));
     851         723 :   result->set_export_name(*export_name);
     852         723 :   result->set_local_name(*local_name);
     853         723 :   result->set_import_name(*import_name);
     854             :   result->set_module_request(module_request);
     855             :   result->set_cell_index(cell_index);
     856             :   result->set_beg_pos(beg_pos);
     857             :   result->set_end_pos(end_pos);
     858         723 :   return result;
     859             : }
     860             : 
     861        1098 : Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, Zone* zone,
     862             :                                    ModuleDescriptor* descr) {
     863             :   // Serialize module requests.
     864        1098 :   int size = static_cast<int>(descr->module_requests().size());
     865        1098 :   Handle<FixedArray> module_requests = isolate->factory()->NewFixedArray(size);
     866             :   Handle<FixedArray> module_request_positions =
     867        1098 :       isolate->factory()->NewFixedArray(size);
     868        2810 :   for (const auto& elem : descr->module_requests()) {
     869        1842 :     module_requests->set(elem.second.index, *elem.first->string());
     870             :     module_request_positions->set(elem.second.index,
     871        1228 :                                   Smi::FromInt(elem.second.position));
     872             :   }
     873             : 
     874             :   // Serialize special exports.
     875             :   Handle<FixedArray> special_exports = isolate->factory()->NewFixedArray(
     876        2196 :       static_cast<int>(descr->special_exports().size()));
     877             :   {
     878             :     int i = 0;
     879        2351 :     for (auto entry : descr->special_exports()) {
     880         155 :       Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
     881         310 :       special_exports->set(i++, *serialized_entry);
     882             :     }
     883             :   }
     884             : 
     885             :   // Serialize namespace imports.
     886             :   Handle<FixedArray> namespace_imports = isolate->factory()->NewFixedArray(
     887        2196 :       static_cast<int>(descr->namespace_imports().size()));
     888             :   {
     889             :     int i = 0;
     890        2326 :     for (auto entry : descr->namespace_imports()) {
     891         130 :       Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
     892         260 :       namespace_imports->set(i++, *serialized_entry);
     893             :     }
     894             :   }
     895             : 
     896             :   // Serialize regular exports.
     897             :   Handle<FixedArray> regular_exports =
     898        1098 :       descr->SerializeRegularExports(isolate, zone);
     899             : 
     900             :   // Serialize regular imports.
     901             :   Handle<FixedArray> regular_imports = isolate->factory()->NewFixedArray(
     902        1098 :       static_cast<int>(descr->regular_imports().size()));
     903             :   {
     904             :     int i = 0;
     905        2634 :     for (const auto& elem : descr->regular_imports()) {
     906             :       Handle<ModuleInfoEntry> serialized_entry =
     907         438 :           elem.second->Serialize(isolate);
     908         876 :       regular_imports->set(i++, *serialized_entry);
     909             :     }
     910             :   }
     911             : 
     912        1098 :   Handle<ModuleInfo> result = isolate->factory()->NewModuleInfo();
     913        2196 :   result->set(kModuleRequestsIndex, *module_requests);
     914        2196 :   result->set(kSpecialExportsIndex, *special_exports);
     915        2196 :   result->set(kRegularExportsIndex, *regular_exports);
     916        2196 :   result->set(kNamespaceImportsIndex, *namespace_imports);
     917        2196 :   result->set(kRegularImportsIndex, *regular_imports);
     918        2196 :   result->set(kModuleRequestPositionsIndex, *module_request_positions);
     919        1098 :   return result;
     920             : }
     921             : 
     922        8176 : int ModuleInfo::RegularExportCount() const {
     923             :   DCHECK_EQ(regular_exports()->length() % kRegularExportLength, 0);
     924       16352 :   return regular_exports()->length() / kRegularExportLength;
     925             : }
     926             : 
     927        3754 : String ModuleInfo::RegularExportLocalName(int i) const {
     928             :   return String::cast(regular_exports()->get(i * kRegularExportLength +
     929        7508 :                                              kRegularExportLocalNameOffset));
     930             : }
     931             : 
     932       35083 : int ModuleInfo::RegularExportCellIndex(int i) const {
     933       35083 :   return Smi::ToInt(regular_exports()->get(i * kRegularExportLength +
     934       70166 :                                            kRegularExportCellIndexOffset));
     935             : }
     936             : 
     937       35083 : FixedArray ModuleInfo::RegularExportExportNames(int i) const {
     938             :   return FixedArray::cast(regular_exports()->get(
     939       70166 :       i * kRegularExportLength + kRegularExportExportNamesOffset));
     940             : }
     941             : 
     942             : }  // namespace internal
     943      183867 : }  // namespace v8

Generated by: LCOV version 1.10