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