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? CallsSloppyEval()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". IsAsmModule()91 inline bool IsAsmModule() { return AsmModuleField::decode(Flags()); } 92 93 // Return if this is a nested function within an asm module scope. IsAsmFunction()94 inline bool IsAsmFunction() { return AsmFunctionField::decode(Flags()); } 95 HasSimpleParameters()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