| // Copyright 2015 the V8 project authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef V8_OBJECTS_SCOPE_INFO_H_ | |
| #define V8_OBJECTS_SCOPE_INFO_H_ | |
| #include "src/globals.h" | |
| #include "src/objects.h" | |
| #include "src/objects/fixed-array.h" | |
| #include "src/utils.h" | |
| // Has to be the last include (doesn't have include guards): | |
| #include "src/objects/object-macros.h" | |
| namespace v8 { | |
| namespace internal { | |
| template <typename T> | |
| class Handle; | |
| class Isolate; | |
| template <typename T> | |
| class MaybeHandle; | |
| class ModuleInfo; | |
| class Scope; | |
| class Zone; | |
| // ScopeInfo represents information about different scopes of a source | |
| // program and the allocation of the scope's variables. Scope information | |
| // is stored in a compressed form in ScopeInfo objects and is used | |
| // at runtime (stack dumps, deoptimization, etc.). | |
| // This object provides quick access to scope info details for runtime | |
| // routines. | |
| class ScopeInfo : public FixedArray { | |
| public: | |
| DECL_CAST(ScopeInfo) | |
| DECL_PRINTER(ScopeInfo) | |
| // Return the type of this scope. | |
| ScopeType scope_type() const; | |
| // Return the language mode of this scope. | |
| LanguageMode language_mode() const; | |
| // True if this scope is a (var) declaration scope. | |
| bool is_declaration_scope() const; | |
| // Does this scope make a sloppy eval call? | |
| bool CallsSloppyEval() const; | |
| // Return the number of context slots for code if a context is allocated. This | |
| // number consists of three parts: | |
| // 1. Size of fixed header for every context: Context::MIN_CONTEXT_SLOTS | |
| // 2. One context slot per context allocated local. | |
| // 3. One context slot for the function name if it is context allocated. | |
| // Parameters allocated in the context count as context allocated locals. If | |
| // no contexts are allocated for this scope ContextLength returns 0. | |
| int ContextLength() const; | |
| // Does this scope declare a "this" binding? | |
| bool HasReceiver() const; | |
| // Does this scope declare a "this" binding, and the "this" binding is stack- | |
| // or context-allocated? | |
| bool HasAllocatedReceiver() const; | |
| // Does this scope declare a "new.target" binding? | |
| bool HasNewTarget() const; | |
| // Is this scope the scope of a named function expression? | |
| bool HasFunctionName() const; | |
| // See SharedFunctionInfo::HasSharedName. | |
| bool HasSharedFunctionName() const; | |
| bool HasInferredFunctionName() const; | |
| void SetFunctionName(Object* name); | |
| void SetInferredFunctionName(String* name); | |
| // Does this scope belong to a function? | |
| bool HasPositionInfo() const; | |
| // Return if contexts are allocated for this scope. | |
| bool HasContext() const; | |
| // Return if this is a function scope with "use asm". | |
| inline bool IsAsmModule() const; | |
| inline bool HasSimpleParameters() const; | |
| // Return the function_name if present. | |
| Object* FunctionName() const; | |
| // The function's name if it is non-empty, otherwise the inferred name or an | |
| // empty string. | |
| String* FunctionDebugName() const; | |
| // Return the function's inferred name if present. | |
| // See SharedFunctionInfo::function_identifier. | |
| Object* InferredFunctionName() const; | |
| // Position information accessors. | |
| int StartPosition() const; | |
| int EndPosition() const; | |
| void SetPositionInfo(int start, int end); | |
| ModuleInfo* ModuleDescriptorInfo() const; | |
| // Return the name of the given context local. | |
| String* ContextLocalName(int var) const; | |
| // Return the mode of the given context local. | |
| VariableMode ContextLocalMode(int var) const; | |
| // Return the initialization flag of the given context local. | |
| InitializationFlag ContextLocalInitFlag(int var) const; | |
| bool ContextLocalIsParameter(int var) const; | |
| uint32_t ContextLocalParameterNumber(int var) const; | |
| // Return the initialization flag of the given context local. | |
| MaybeAssignedFlag ContextLocalMaybeAssignedFlag(int var) const; | |
| // Return true if this local was introduced by the compiler, and should not be | |
| // exposed to the user in a debugger. | |
| static bool VariableIsSynthetic(String* name); | |
| // Lookup support for serialized scope info. Returns the local context slot | |
| // index for a given slot name if the slot is present; otherwise | |
| // returns a value < 0. The name must be an internalized string. | |
| // If the slot is present and mode != nullptr, sets *mode to the corresponding | |
| // mode for that variable. | |
| static int ContextSlotIndex(Handle<ScopeInfo> scope_info, Handle<String> name, | |
| VariableMode* mode, InitializationFlag* init_flag, | |
| MaybeAssignedFlag* maybe_assigned_flag); | |
| // Lookup metadata of a MODULE-allocated variable. Return 0 if there is no | |
| // module variable with the given name (the index value of a MODULE variable | |
| // is never 0). | |
| int ModuleIndex(Handle<String> name, VariableMode* mode, | |
| InitializationFlag* init_flag, | |
| MaybeAssignedFlag* maybe_assigned_flag); | |
| // Lookup support for serialized scope info. Returns the function context | |
| // slot index if the function name is present and context-allocated (named | |
| // function expressions, only), otherwise returns a value < 0. The name | |
| // must be an internalized string. | |
| int FunctionContextSlotIndex(String* name) const; | |
| // Lookup support for serialized scope info. Returns the receiver context | |
| // slot index if scope has a "this" binding, and the binding is | |
| // context-allocated. Otherwise returns a value < 0. | |
| int ReceiverContextSlotIndex() const; | |
| FunctionKind function_kind() const; | |
| // Returns true if this ScopeInfo is linked to a outer ScopeInfo. | |
| bool HasOuterScopeInfo() const; | |
| // Returns true if this ScopeInfo was created for a debug-evaluate scope. | |
| bool IsDebugEvaluateScope() const; | |
| // Can be used to mark a ScopeInfo that looks like a with-scope as actually | |
| // being a debug-evaluate scope. | |
| void SetIsDebugEvaluateScope(); | |
| // Return the outer ScopeInfo if present. | |
| ScopeInfo* OuterScopeInfo() const; | |
| #ifdef DEBUG | |
| bool Equals(ScopeInfo* other) const; | |
| #endif | |
| static Handle<ScopeInfo> Create(Isolate* isolate, Zone* zone, Scope* scope, | |
| MaybeHandle<ScopeInfo> outer_scope); | |
| static Handle<ScopeInfo> CreateForWithScope( | |
| Isolate* isolate, MaybeHandle<ScopeInfo> outer_scope); | |
| static Handle<ScopeInfo> CreateForEmptyFunction(Isolate* isolate); | |
| static Handle<ScopeInfo> CreateGlobalThisBinding(Isolate* isolate); | |
| // Serializes empty scope info. | |
| V8_EXPORT_PRIVATE static ScopeInfo* Empty(Isolate* isolate); | |
| // The layout of the static part of a ScopeInfo is as follows. Each entry is | |
| // numeric and occupies one array slot. | |
| // 1. A set of properties of the scope. | |
| // 2. The number of parameters. For non-function scopes this is 0. | |
| // 3. The number of non-parameter and parameter variables allocated in the | |
| // context. | |
| #define FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(V) \ | |
| V(Flags) \ | |
| V(ParameterCount) \ | |
| V(ContextLocalCount) | |
| #define FIELD_ACCESSORS(name) \ | |
| inline void Set##name(int value); \ | |
| inline int name() const; | |
| FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS) | |
| #undef FIELD_ACCESSORS | |
| enum { | |
| #define DECL_INDEX(name) k##name, | |
| FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(DECL_INDEX) | |
| #undef DECL_INDEX | |
| kVariablePartIndex | |
| }; | |
| private: | |
| // The layout of the variable part of a ScopeInfo is as follows: | |
| // 1. ContextLocalNames: | |
| // Contains the names of local variables and parameters that are allocated | |
| // in the context. They are stored in increasing order of the context slot | |
| // index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per | |
| // context local, so in total this part occupies ContextLocalCount() slots | |
| // in the array. | |
| // 2. ContextLocalInfos: | |
| // Contains the variable modes and initialization flags corresponding to | |
| // the context locals in ContextLocalNames. One slot is used per | |
| // context local, so in total this part occupies ContextLocalCount() | |
| // slots in the array. | |
| // 3. ReceiverInfo: | |
| // If the scope binds a "this" value, one slot is reserved to hold the | |
| // context or stack slot index for the variable. | |
| // 4. FunctionNameInfo: | |
| // If the scope belongs to a named function expression this part contains | |
| // information about the function variable. It always occupies two array | |
| // slots: a. The name of the function variable. | |
| // b. The context or stack slot index for the variable. | |
| // 5. InferredFunctionName: | |
| // Contains the function's inferred name. | |
| // 6. SourcePosition: | |
| // Contains two slots with a) the startPosition and b) the endPosition if | |
| // the scope belongs to a function or script. | |
| // 7. OuterScopeInfoIndex: | |
| // The outer scope's ScopeInfo or the hole if there's none. | |
| // 8. ModuleInfo, ModuleVariableCount, and ModuleVariables: | |
| // For a module scope, this part contains the ModuleInfo, the number of | |
| // MODULE-allocated variables, and the metadata of those variables. For | |
| // non-module scopes it is empty. | |
| int ContextLocalNamesIndex() const; | |
| int ContextLocalInfosIndex() const; | |
| int ReceiverInfoIndex() const; | |
| int FunctionNameInfoIndex() const; | |
| int InferredFunctionNameIndex() const; | |
| int PositionInfoIndex() const; | |
| int OuterScopeInfoIndex() const; | |
| int ModuleInfoIndex() const; | |
| int ModuleVariableCountIndex() const; | |
| int ModuleVariablesIndex() const; | |
| static bool NeedsPositionInfo(ScopeType type); | |
| static Handle<ScopeInfo> CreateForBootstrapping(Isolate* isolate, | |
| ScopeType type); | |
| int Lookup(Handle<String> name, int start, int end, VariableMode* mode, | |
| VariableLocation* location, InitializationFlag* init_flag, | |
| MaybeAssignedFlag* maybe_assigned_flag); | |
| // Get metadata of i-th MODULE-allocated variable, where 0 <= i < | |
| // ModuleVariableCount. The metadata is returned via out-arguments, which may | |
| // be nullptr if the corresponding information is not requested | |
| void ModuleVariable(int i, String** name, int* index, | |
| VariableMode* mode = nullptr, | |
| InitializationFlag* init_flag = nullptr, | |
| MaybeAssignedFlag* maybe_assigned_flag = nullptr); | |
| // Used for the function name variable for named function expressions, and for | |
| // the receiver. | |
| enum VariableAllocationInfo { NONE, STACK, CONTEXT, UNUSED }; | |
| static const int kFunctionNameEntries = 2; | |
| static const int kPositionInfoEntries = 2; | |
| // Properties of scopes. | |
| class ScopeTypeField : public BitField<ScopeType, 0, 4> {}; | |
| class CallsSloppyEvalField : public BitField<bool, ScopeTypeField::kNext, 1> { | |
| }; | |
| STATIC_ASSERT(LanguageModeSize == 2); | |
| class LanguageModeField | |
| : public BitField<LanguageMode, CallsSloppyEvalField::kNext, 1> {}; | |
| class DeclarationScopeField | |
| : public BitField<bool, LanguageModeField::kNext, 1> {}; | |
| class ReceiverVariableField | |
| : public BitField<VariableAllocationInfo, DeclarationScopeField::kNext, | |
| 2> {}; | |
| class HasNewTargetField | |
| : public BitField<bool, ReceiverVariableField::kNext, 1> {}; | |
| class FunctionVariableField | |
| : public BitField<VariableAllocationInfo, HasNewTargetField::kNext, 2> {}; | |
| // TODO(cbruni): Combine with function variable field when only storing the | |
| // function name. | |
| class HasInferredFunctionNameField | |
| : public BitField<bool, FunctionVariableField::kNext, 1> {}; | |
| class AsmModuleField | |
| : public BitField<bool, HasInferredFunctionNameField::kNext, 1> {}; | |
| class HasSimpleParametersField | |
| : public BitField<bool, AsmModuleField::kNext, 1> {}; | |
| class FunctionKindField | |
| : public BitField<FunctionKind, HasSimpleParametersField::kNext, 5> {}; | |
| class HasOuterScopeInfoField | |
| : public BitField<bool, FunctionKindField::kNext, 1> {}; | |
| class IsDebugEvaluateScopeField | |
| : public BitField<bool, HasOuterScopeInfoField::kNext, 1> {}; | |
| STATIC_ASSERT(kLastFunctionKind <= FunctionKindField::kMax); | |
| // Properties of variables. | |
| class VariableModeField : public BitField<VariableMode, 0, 3> {}; | |
| class InitFlagField : public BitField<InitializationFlag, 3, 1> {}; | |
| class MaybeAssignedFlagField : public BitField<MaybeAssignedFlag, 4, 1> {}; | |
| class ParameterNumberField | |
| : public BitField<uint32_t, MaybeAssignedFlagField::kNext, 16> {}; | |
| friend class ScopeIterator; | |
| friend std::ostream& operator<<(std::ostream& os, | |
| ScopeInfo::VariableAllocationInfo var); | |
| }; | |
| std::ostream& operator<<(std::ostream& os, | |
| ScopeInfo::VariableAllocationInfo var); | |
| } // namespace internal | |
| } // namespace v8 | |
| #include "src/objects/object-macros-undef.h" | |
| #endif // V8_OBJECTS_SCOPE_INFO_H_ |