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