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