diff options
Diffstat (limited to 'src/objects/scope-info.h')
-rw-r--r-- | src/objects/scope-info.h | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/src/objects/scope-info.h b/src/objects/scope-info.h new file mode 100644 index 00000000..75a374d5 --- /dev/null +++ b/src/objects/scope-info.h @@ -0,0 +1,348 @@ +// 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/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 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: + DECLARE_CAST(ScopeInfo) + + // Return the type of this scope. + ScopeType scope_type(); + + // Does this scope call eval? + bool CallsEval(); + + // Return the language mode of this scope. + LanguageMode language_mode(); + + // True if this scope is a (var) declaration scope. + bool is_declaration_scope(); + + // Does this scope make a sloppy eval call? + bool CallsSloppyEval() { return CallsEval() && is_sloppy(language_mode()); } + + // Return the total number of locals allocated on the stack and in the + // context. This includes the parameters that are allocated in the context. + int LocalCount(); + + // Return the number of stack slots for code. This number consists of two + // parts: + // 1. One stack slot per stack allocated local. + // 2. One stack slot for the function name if it is stack allocated. + int StackSlotCount(); + + // 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(); + + // Does this scope declare a "this" binding? + bool HasReceiver(); + + // Does this scope declare a "this" binding, and the "this" binding is stack- + // or context-allocated? + bool HasAllocatedReceiver(); + + // Does this scope declare a "new.target" binding? + bool HasNewTarget(); + + // Is this scope the scope of a named function expression? + bool HasFunctionName(); + + // Return if this has context allocated locals. + bool HasHeapAllocatedLocals(); + + // Return if contexts are allocated for this scope. + bool HasContext(); + + // Return if this is a function scope with "use asm". + inline bool IsAsmModule() { return AsmModuleField::decode(Flags()); } + + // Return if this is a nested function within an asm module scope. + inline bool IsAsmFunction() { return AsmFunctionField::decode(Flags()); } + + inline bool HasSimpleParameters() { + return HasSimpleParametersField::decode(Flags()); + } + + // Return the function_name if present. + String* FunctionName(); + + ModuleInfo* ModuleDescriptorInfo(); + + // Return the name of the given parameter. + String* ParameterName(int var); + + // Return the name of the given local. + String* LocalName(int var); + + // Return the name of the given stack local. + String* StackLocalName(int var); + + // Return the name of the given stack local. + int StackLocalIndex(int var); + + // Return the name of the given context local. + String* ContextLocalName(int var); + + // Return the mode of the given context local. + VariableMode ContextLocalMode(int var); + + // Return the initialization flag of the given context local. + InitializationFlag ContextLocalInitFlag(int var); + + // Return the initialization flag of the given context local. + MaybeAssignedFlag ContextLocalMaybeAssignedFlag(int var); + + // 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 + // the stack slot index for a given slot name if the slot is + // present; otherwise returns a value < 0. The name must be an internalized + // string. + int StackSlotIndex(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 != NULL, 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 the name of a certain context slot by its index. + String* ContextSlotName(int slot_index); + + // Lookup support for serialized scope info. Returns the + // parameter index for a given parameter name if the parameter is present; + // otherwise returns a value < 0. The name must be an internalized string. + int ParameterIndex(String* name); + + // 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); + + // 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(); + + FunctionKind function_kind(); + + // Returns true if this ScopeInfo is linked to a outer ScopeInfo. + bool HasOuterScopeInfo(); + + // Returns true if this ScopeInfo was created for a debug-evaluate scope. + bool IsDebugEvaluateScope(); + + // 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(); + +#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> CreateGlobalThisBinding(Isolate* isolate); + + // Serializes empty scope info. + V8_EXPORT_PRIVATE static ScopeInfo* Empty(Isolate* isolate); + +#ifdef DEBUG + void Print(); +#endif + +// 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 variables allocated on the stack. +// 4. 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(StackLocalCount) \ + V(ContextLocalCount) + +#define FIELD_ACCESSORS(name) \ + inline void Set##name(int value) { set(k##name, Smi::FromInt(value)); } \ + inline int name() { \ + if (length() > 0) { \ + return Smi::cast(get(k##name))->value(); \ + } else { \ + return 0; \ + } \ + } + + 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. ParameterNames: + // This part stores the names of the parameters for function scopes. One + // slot is used per parameter, so in total this part occupies + // ParameterCount() slots in the array. For other scopes than function + // scopes ParameterCount() is 0. + // 2. StackLocalFirstSlot: + // Index of a first stack slot for stack local. Stack locals belonging to + // this scope are located on a stack at slots starting from this index. + // 3. StackLocalNames: + // Contains the names of local variables that are allocated on the stack, + // in increasing order of the stack slot index. First local variable has a + // stack slot index defined in StackLocalFirstSlot (point 2 above). + // One slot is used per stack local, so in total this part occupies + // StackLocalCount() slots in the array. + // 4. 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. + // 5. 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. + // 6. ReceiverInfo: + // If the scope binds a "this" value, one slot is reserved to hold the + // context or stack slot index for the variable. + // 7. 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. + // 8. OuterScopeInfoIndex: + // The outer scope's ScopeInfo or the hole if there's none. + // 9. 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 ParameterNamesIndex(); + int StackLocalFirstSlotIndex(); + int StackLocalNamesIndex(); + int ContextLocalNamesIndex(); + int ContextLocalInfosIndex(); + int ReceiverInfoIndex(); + int FunctionNameInfoIndex(); + int OuterScopeInfoIndex(); + int ModuleInfoIndex(); + int ModuleVariableCountIndex(); + int ModuleVariablesIndex(); + + 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 }; + + // Properties of scopes. + class ScopeTypeField : public BitField<ScopeType, 0, 4> {}; + class CallsEvalField : public BitField<bool, ScopeTypeField::kNext, 1> {}; + STATIC_ASSERT(LANGUAGE_END == 2); + class LanguageModeField + : public BitField<LanguageMode, CallsEvalField::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> {}; + class AsmModuleField + : public BitField<bool, FunctionVariableField::kNext, 1> {}; + class AsmFunctionField : public BitField<bool, AsmModuleField::kNext, 1> {}; + class HasSimpleParametersField + : public BitField<bool, AsmFunctionField::kNext, 1> {}; + class FunctionKindField + : public BitField<FunctionKind, HasSimpleParametersField::kNext, 10> {}; + class HasOuterScopeInfoField + : public BitField<bool, FunctionKindField::kNext, 1> {}; + class IsDebugEvaluateScopeField + : public BitField<bool, HasOuterScopeInfoField::kNext, 1> {}; + + // Properties of variables. + class VariableModeField : public BitField<VariableMode, 0, 3> {}; + class InitFlagField : public BitField<InitializationFlag, 3, 1> {}; + class MaybeAssignedFlagField : public BitField<MaybeAssignedFlag, 4, 1> {}; + + friend class ScopeIterator; +}; + +} // namespace internal +} // namespace v8 + +#include "src/objects/object-macros-undef.h" + +#endif // V8_OBJECTS_SCOPE_INFO_H_ |