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