Home | History | Annotate | Download | only in objects
      1 // Copyright 2015 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 #ifndef V8_OBJECTS_SCOPE_INFO_H_
      6 #define V8_OBJECTS_SCOPE_INFO_H_
      7 
      8 #include "src/globals.h"
      9 #include "src/objects.h"
     10 #include "src/objects/fixed-array.h"
     11 #include "src/utils.h"
     12 
     13 // Has to be the last include (doesn't have include guards):
     14 #include "src/objects/object-macros.h"
     15 
     16 namespace v8 {
     17 namespace internal {
     18 
     19 template <typename T>
     20 class Handle;
     21 class Isolate;
     22 template <typename T>
     23 class MaybeHandle;
     24 class ModuleInfo;
     25 class Scope;
     26 class Zone;
     27 
     28 // ScopeInfo represents information about different scopes of a source
     29 // program  and the allocation of the scope's variables. Scope information
     30 // is stored in a compressed form in ScopeInfo objects and is used
     31 // at runtime (stack dumps, deoptimization, etc.).
     32 
     33 // This object provides quick access to scope info details for runtime
     34 // routines.
     35 class ScopeInfo : public FixedArray {
     36  public:
     37   DECL_CAST(ScopeInfo)
     38   DECL_PRINTER(ScopeInfo)
     39 
     40   // Return the type of this scope.
     41   ScopeType scope_type() const;
     42 
     43   // Return the language mode of this scope.
     44   LanguageMode language_mode() const;
     45 
     46   // True if this scope is a (var) declaration scope.
     47   bool is_declaration_scope() const;
     48 
     49   // Does this scope make a sloppy eval call?
     50   bool CallsSloppyEval() const;
     51 
     52   // Return the number of context slots for code if a context is allocated. This
     53   // number consists of three parts:
     54   //  1. Size of fixed header for every context: Context::MIN_CONTEXT_SLOTS
     55   //  2. One context slot per context allocated local.
     56   //  3. One context slot for the function name if it is context allocated.
     57   // Parameters allocated in the context count as context allocated locals. If
     58   // no contexts are allocated for this scope ContextLength returns 0.
     59   int ContextLength() const;
     60 
     61   // Does this scope declare a "this" binding?
     62   bool HasReceiver() const;
     63 
     64   // Does this scope declare a "this" binding, and the "this" binding is stack-
     65   // or context-allocated?
     66   bool HasAllocatedReceiver() const;
     67 
     68   // Does this scope declare a "new.target" binding?
     69   bool HasNewTarget() const;
     70 
     71   // Is this scope the scope of a named function expression?
     72   bool HasFunctionName() const;
     73 
     74   // See SharedFunctionInfo::HasSharedName.
     75   bool HasSharedFunctionName() const;
     76 
     77   bool HasInferredFunctionName() const;
     78 
     79   void SetFunctionName(Object* name);
     80   void SetInferredFunctionName(String* name);
     81 
     82   // Does this scope belong to a function?
     83   bool HasPositionInfo() const;
     84 
     85   // Return if contexts are allocated for this scope.
     86   bool HasContext() const;
     87 
     88   // Return if this is a function scope with "use asm".
     89   inline bool IsAsmModule() const;
     90 
     91   inline bool HasSimpleParameters() const;
     92 
     93   // Return the function_name if present.
     94   Object* FunctionName() const;
     95 
     96   // The function's name if it is non-empty, otherwise the inferred name or an
     97   // empty string.
     98   String* FunctionDebugName() const;
     99 
    100   // Return the function's inferred name if present.
    101   // See SharedFunctionInfo::function_identifier.
    102   Object* InferredFunctionName() const;
    103 
    104   // Position information accessors.
    105   int StartPosition() const;
    106   int EndPosition() const;
    107   void SetPositionInfo(int start, int end);
    108 
    109   ModuleInfo* ModuleDescriptorInfo() const;
    110 
    111   // Return the name of the given context local.
    112   String* ContextLocalName(int var) const;
    113 
    114   // Return the mode of the given context local.
    115   VariableMode ContextLocalMode(int var) const;
    116 
    117   // Return the initialization flag of the given context local.
    118   InitializationFlag ContextLocalInitFlag(int var) const;
    119 
    120   bool ContextLocalIsParameter(int var) const;
    121   uint32_t ContextLocalParameterNumber(int var) const;
    122 
    123   // Return the initialization flag of the given context local.
    124   MaybeAssignedFlag ContextLocalMaybeAssignedFlag(int var) const;
    125 
    126   // Return true if this local was introduced by the compiler, and should not be
    127   // exposed to the user in a debugger.
    128   static bool VariableIsSynthetic(String* name);
    129 
    130   // Lookup support for serialized scope info. Returns the local context slot
    131   // index for a given slot name if the slot is present; otherwise
    132   // returns a value < 0. The name must be an internalized string.
    133   // If the slot is present and mode != nullptr, sets *mode to the corresponding
    134   // mode for that variable.
    135   static int ContextSlotIndex(Handle<ScopeInfo> scope_info, Handle<String> name,
    136                               VariableMode* mode, InitializationFlag* init_flag,
    137                               MaybeAssignedFlag* maybe_assigned_flag);
    138 
    139   // Lookup metadata of a MODULE-allocated variable.  Return 0 if there is no
    140   // module variable with the given name (the index value of a MODULE variable
    141   // is never 0).
    142   int ModuleIndex(Handle<String> name, VariableMode* mode,
    143                   InitializationFlag* init_flag,
    144                   MaybeAssignedFlag* maybe_assigned_flag);
    145 
    146   // Lookup support for serialized scope info. Returns the function context
    147   // slot index if the function name is present and context-allocated (named
    148   // function expressions, only), otherwise returns a value < 0. The name
    149   // must be an internalized string.
    150   int FunctionContextSlotIndex(String* name) const;
    151 
    152   // Lookup support for serialized scope info.  Returns the receiver context
    153   // slot index if scope has a "this" binding, and the binding is
    154   // context-allocated.  Otherwise returns a value < 0.
    155   int ReceiverContextSlotIndex() const;
    156 
    157   FunctionKind function_kind() const;
    158 
    159   // Returns true if this ScopeInfo is linked to a outer ScopeInfo.
    160   bool HasOuterScopeInfo() const;
    161 
    162   // Returns true if this ScopeInfo was created for a debug-evaluate scope.
    163   bool IsDebugEvaluateScope() const;
    164 
    165   // Can be used to mark a ScopeInfo that looks like a with-scope as actually
    166   // being a debug-evaluate scope.
    167   void SetIsDebugEvaluateScope();
    168 
    169   // Return the outer ScopeInfo if present.
    170   ScopeInfo* OuterScopeInfo() const;
    171 
    172 #ifdef DEBUG
    173   bool Equals(ScopeInfo* other) const;
    174 #endif
    175 
    176   static Handle<ScopeInfo> Create(Isolate* isolate, Zone* zone, Scope* scope,
    177                                   MaybeHandle<ScopeInfo> outer_scope);
    178   static Handle<ScopeInfo> CreateForWithScope(
    179       Isolate* isolate, MaybeHandle<ScopeInfo> outer_scope);
    180   static Handle<ScopeInfo> CreateForEmptyFunction(Isolate* isolate);
    181   static Handle<ScopeInfo> CreateGlobalThisBinding(Isolate* isolate);
    182 
    183   // Serializes empty scope info.
    184   V8_EXPORT_PRIVATE static ScopeInfo* Empty(Isolate* isolate);
    185 
    186 // The layout of the static part of a ScopeInfo is as follows. Each entry is
    187 // numeric and occupies one array slot.
    188 // 1. A set of properties of the scope.
    189 // 2. The number of parameters. For non-function scopes this is 0.
    190 // 3. The number of non-parameter and parameter variables allocated in the
    191 //    context.
    192 #define FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(V) \
    193   V(Flags)                                   \
    194   V(ParameterCount)                          \
    195   V(ContextLocalCount)
    196 
    197 #define FIELD_ACCESSORS(name)       \
    198   inline void Set##name(int value); \
    199   inline int name() const;
    200   FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS)
    201 #undef FIELD_ACCESSORS
    202 
    203   enum {
    204 #define DECL_INDEX(name) k##name,
    205     FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(DECL_INDEX)
    206 #undef DECL_INDEX
    207         kVariablePartIndex
    208   };
    209 
    210  private:
    211   // The layout of the variable part of a ScopeInfo is as follows:
    212   // 1. ContextLocalNames:
    213   //    Contains the names of local variables and parameters that are allocated
    214   //    in the context. They are stored in increasing order of the context slot
    215   //    index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
    216   //    context local, so in total this part occupies ContextLocalCount() slots
    217   //    in the array.
    218   // 2. ContextLocalInfos:
    219   //    Contains the variable modes and initialization flags corresponding to
    220   //    the context locals in ContextLocalNames. One slot is used per
    221   //    context local, so in total this part occupies ContextLocalCount()
    222   //    slots in the array.
    223   // 3. ReceiverInfo:
    224   //    If the scope binds a "this" value, one slot is reserved to hold the
    225   //    context or stack slot index for the variable.
    226   // 4. FunctionNameInfo:
    227   //    If the scope belongs to a named function expression this part contains
    228   //    information about the function variable. It always occupies two array
    229   //    slots:  a. The name of the function variable.
    230   //            b. The context or stack slot index for the variable.
    231   // 5. InferredFunctionName:
    232   //    Contains the function's inferred name.
    233   // 6. SourcePosition:
    234   //    Contains two slots with a) the startPosition and b) the endPosition if
    235   //    the scope belongs to a function or script.
    236   // 7. OuterScopeInfoIndex:
    237   //    The outer scope's ScopeInfo or the hole if there's none.
    238   // 8. ModuleInfo, ModuleVariableCount, and ModuleVariables:
    239   //    For a module scope, this part contains the ModuleInfo, the number of
    240   //    MODULE-allocated variables, and the metadata of those variables.  For
    241   //    non-module scopes it is empty.
    242   int ContextLocalNamesIndex() const;
    243   int ContextLocalInfosIndex() const;
    244   int ReceiverInfoIndex() const;
    245   int FunctionNameInfoIndex() const;
    246   int InferredFunctionNameIndex() const;
    247   int PositionInfoIndex() const;
    248   int OuterScopeInfoIndex() const;
    249   int ModuleInfoIndex() const;
    250   int ModuleVariableCountIndex() const;
    251   int ModuleVariablesIndex() const;
    252 
    253   static bool NeedsPositionInfo(ScopeType type);
    254   static Handle<ScopeInfo> CreateForBootstrapping(Isolate* isolate,
    255                                                   ScopeType type);
    256 
    257   int Lookup(Handle<String> name, int start, int end, VariableMode* mode,
    258              VariableLocation* location, InitializationFlag* init_flag,
    259              MaybeAssignedFlag* maybe_assigned_flag);
    260 
    261   // Get metadata of i-th MODULE-allocated variable, where 0 <= i <
    262   // ModuleVariableCount.  The metadata is returned via out-arguments, which may
    263   // be nullptr if the corresponding information is not requested
    264   void ModuleVariable(int i, String** name, int* index,
    265                       VariableMode* mode = nullptr,
    266                       InitializationFlag* init_flag = nullptr,
    267                       MaybeAssignedFlag* maybe_assigned_flag = nullptr);
    268 
    269   // Used for the function name variable for named function expressions, and for
    270   // the receiver.
    271   enum VariableAllocationInfo { NONE, STACK, CONTEXT, UNUSED };
    272 
    273   static const int kFunctionNameEntries = 2;
    274   static const int kPositionInfoEntries = 2;
    275 
    276   // Properties of scopes.
    277   class ScopeTypeField : public BitField<ScopeType, 0, 4> {};
    278   class CallsSloppyEvalField : public BitField<bool, ScopeTypeField::kNext, 1> {
    279   };
    280   STATIC_ASSERT(LanguageModeSize == 2);
    281   class LanguageModeField
    282       : public BitField<LanguageMode, CallsSloppyEvalField::kNext, 1> {};
    283   class DeclarationScopeField
    284       : public BitField<bool, LanguageModeField::kNext, 1> {};
    285   class ReceiverVariableField
    286       : public BitField<VariableAllocationInfo, DeclarationScopeField::kNext,
    287                         2> {};
    288   class HasNewTargetField
    289       : public BitField<bool, ReceiverVariableField::kNext, 1> {};
    290   class FunctionVariableField
    291       : public BitField<VariableAllocationInfo, HasNewTargetField::kNext, 2> {};
    292   // TODO(cbruni): Combine with function variable field when only storing the
    293   // function name.
    294   class HasInferredFunctionNameField
    295       : public BitField<bool, FunctionVariableField::kNext, 1> {};
    296   class AsmModuleField
    297       : public BitField<bool, HasInferredFunctionNameField::kNext, 1> {};
    298   class HasSimpleParametersField
    299       : public BitField<bool, AsmModuleField::kNext, 1> {};
    300   class FunctionKindField
    301       : public BitField<FunctionKind, HasSimpleParametersField::kNext, 5> {};
    302   class HasOuterScopeInfoField
    303       : public BitField<bool, FunctionKindField::kNext, 1> {};
    304   class IsDebugEvaluateScopeField
    305       : public BitField<bool, HasOuterScopeInfoField::kNext, 1> {};
    306 
    307   STATIC_ASSERT(kLastFunctionKind <= FunctionKindField::kMax);
    308 
    309   // Properties of variables.
    310   class VariableModeField : public BitField<VariableMode, 0, 3> {};
    311   class InitFlagField : public BitField<InitializationFlag, 3, 1> {};
    312   class MaybeAssignedFlagField : public BitField<MaybeAssignedFlag, 4, 1> {};
    313   class ParameterNumberField
    314       : public BitField<uint32_t, MaybeAssignedFlagField::kNext, 16> {};
    315 
    316   friend class ScopeIterator;
    317   friend std::ostream& operator<<(std::ostream& os,
    318                                   ScopeInfo::VariableAllocationInfo var);
    319 };
    320 
    321 std::ostream& operator<<(std::ostream& os,
    322                          ScopeInfo::VariableAllocationInfo var);
    323 
    324 }  // namespace internal
    325 }  // namespace v8
    326 
    327 #include "src/objects/object-macros-undef.h"
    328 
    329 #endif  // V8_OBJECTS_SCOPE_INFO_H_
    330