Line data Source code
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?
50 320128 : 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".
91 3613936 : inline bool IsAsmModule() { return AsmModuleField::decode(Flags()); }
92 :
93 : // Return if this is a nested function within an asm module scope.
94 3314894 : inline bool IsAsmFunction() { return AsmFunctionField::decode(Flags()); }
95 :
96 : inline bool HasSimpleParameters() {
97 97580 : 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 455181452 : 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_
|