scope-info.h 14.2 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_SCOPE_INFO_H_
#define V8_OBJECTS_SCOPE_INFO_H_

8
#include "src/common/globals.h"
9
#include "src/objects/fixed-array.h"
10 11
#include "src/objects/function-kind.h"
#include "src/objects/objects.h"
12
#include "src/utils/utils.h"
13
#include "testing/gtest/include/gtest/gtest_prod.h"  // nogncheck
14
#include "torque-generated/bit-fields.h"
15

16 17 18
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

19 20 21
namespace v8 {
namespace internal {

marja's avatar
marja committed
22 23
template <typename T>
class Handle;
24
class Isolate;
marja's avatar
marja committed
25 26
template <typename T>
class MaybeHandle;
27
class SourceTextModuleInfo;
28
class Scope;
29
class StringSet;
30 31 32 33 34 35 36 37 38
class Zone;

// ScopeInfo represents information about different scopes of a source
// program  and the allocation of the scope's variables. Scope information
// is stored in a compressed form in ScopeInfo objects and is used
// at runtime (stack dumps, deoptimization, etc.).

// This object provides quick access to scope info details for runtime
// routines.
39
class ScopeInfo : public FixedArray {
40
 public:
41 42
  DEFINE_TORQUE_GENERATED_SCOPE_FLAGS()

43
  DECL_CAST(ScopeInfo)
44
  DECL_PRINTER(ScopeInfo)
45 46

  // Return the type of this scope.
47
  ScopeType scope_type() const;
48 49

  // Return the language mode of this scope.
50
  LanguageMode language_mode() const;
51 52

  // True if this scope is a (var) declaration scope.
53
  bool is_declaration_scope() const;
54

55 56 57
  // True if this scope is a class scope.
  bool is_class_scope() const;

58
  // Does this scope make a sloppy eval call?
59
  bool SloppyEvalCanExtendVars() const;
60 61 62

  // Return the number of context slots for code if a context is allocated. This
  // number consists of three parts:
63
  //  1. Size of header for every context.
64 65 66 67
  //  2. One context slot per context allocated local.
  //  3. One context slot for the function name if it is context allocated.
  // Parameters allocated in the context count as context allocated locals. If
  // no contexts are allocated for this scope ContextLength returns 0.
68
  int ContextLength() const;
69
  int ContextHeaderLength() const;
70

71 72
  bool HasContextExtensionSlot() const;

73
  // Does this scope declare a "this" binding?
74
  bool HasReceiver() const;
75 76 77

  // Does this scope declare a "this" binding, and the "this" binding is stack-
  // or context-allocated?
78
  bool HasAllocatedReceiver() const;
79

80 81 82
  // Does this scope has class brand (for private methods)?
  bool HasClassBrand() const;

83 84 85 86
  // Does this scope contains a saved class variable context local slot index
  // for checking receivers of static private methods?
  bool HasSavedClassVariableIndex() const;

87
  // Does this scope declare a "new.target" binding?
88
  bool HasNewTarget() const;
89 90

  // Is this scope the scope of a named function expression?
91
  V8_EXPORT_PRIVATE bool HasFunctionName() const;
92

93
  // See SharedFunctionInfo::HasSharedName.
94
  V8_EXPORT_PRIVATE bool HasSharedFunctionName() const;
95

96
  V8_EXPORT_PRIVATE bool HasInferredFunctionName() const;
97

98
  void SetFunctionName(Object name);
99
  void SetInferredFunctionName(String name);
100

101 102 103
  // Does this scope belong to a function?
  bool HasPositionInfo() const;

104
  // Return if contexts are allocated for this scope.
105
  bool HasContext() const;
106 107

  // Return if this is a function scope with "use asm".
108
  inline bool IsAsmModule() const;
109

110
  inline bool HasSimpleParameters() const;
111 112

  // Return the function_name if present.
113
  V8_EXPORT_PRIVATE Object FunctionName() const;
114

115 116
  // The function's name if it is non-empty, otherwise the inferred name or an
  // empty string.
117
  String FunctionDebugName() const;
118

119 120
  // Return the function's inferred name if present.
  // See SharedFunctionInfo::function_identifier.
121
  V8_EXPORT_PRIVATE Object InferredFunctionName() const;
122

123
  // Position information accessors.
124 125
  int StartPosition() const;
  int EndPosition() const;
126 127
  void SetPositionInfo(int start, int end);

128
  SourceTextModuleInfo ModuleDescriptorInfo() const;
129 130

  // Return the name of the given context local.
131
  String ContextLocalName(int var) const;
132 133

  // Return the mode of the given context local.
134
  VariableMode ContextLocalMode(int var) const;
135

136 137 138
  // Return whether the given context local variable is static.
  IsStaticFlag ContextLocalIsStaticFlag(int var) const;

139
  // Return the initialization flag of the given context local.
140
  InitializationFlag ContextLocalInitFlag(int var) const;
141

142 143 144
  bool ContextLocalIsParameter(int var) const;
  uint32_t ContextLocalParameterNumber(int var) const;

145
  // Return the initialization flag of the given context local.
146
  MaybeAssignedFlag ContextLocalMaybeAssignedFlag(int var) const;
147 148 149

  // Return true if this local was introduced by the compiler, and should not be
  // exposed to the user in a debugger.
150
  static bool VariableIsSynthetic(String name);
151 152 153 154

  // Lookup support for serialized scope info. Returns the local context slot
  // index for a given slot name if the slot is present; otherwise
  // returns a value < 0. The name must be an internalized string.
155
  // If the slot is present and mode != nullptr, sets *mode to the corresponding
156
  // mode for that variable.
157
  static int ContextSlotIndex(ScopeInfo scope_info, String name,
158
                              VariableMode* mode, InitializationFlag* init_flag,
159 160
                              MaybeAssignedFlag* maybe_assigned_flag,
                              IsStaticFlag* is_static_flag);
161 162 163 164

  // Lookup metadata of a MODULE-allocated variable.  Return 0 if there is no
  // module variable with the given name (the index value of a MODULE variable
  // is never 0).
165
  int ModuleIndex(String name, VariableMode* mode,
166 167 168 169 170 171 172
                  InitializationFlag* init_flag,
                  MaybeAssignedFlag* maybe_assigned_flag);

  // Lookup support for serialized scope info. Returns the function context
  // slot index if the function name is present and context-allocated (named
  // function expressions, only), otherwise returns a value < 0. The name
  // must be an internalized string.
173
  int FunctionContextSlotIndex(String name) const;
174 175 176 177

  // Lookup support for serialized scope info.  Returns the receiver context
  // slot index if scope has a "this" binding, and the binding is
  // context-allocated.  Otherwise returns a value < 0.
178
  int ReceiverContextSlotIndex() const;
179

180 181 182 183 184 185
  // Lookup support for serialized scope info.  Returns the index of the
  // saved class variable in context local slots if scope is a class scope
  // and it contains static private methods that may be accessed.
  // Otherwise returns a value < 0.
  int SavedClassVariableContextLocalIndex() const;

186
  FunctionKind function_kind() const;
187 188

  // Returns true if this ScopeInfo is linked to a outer ScopeInfo.
189
  bool HasOuterScopeInfo() const;
190 191

  // Returns true if this ScopeInfo was created for a debug-evaluate scope.
192
  bool IsDebugEvaluateScope() const;
193 194 195 196 197 198

  // Can be used to mark a ScopeInfo that looks like a with-scope as actually
  // being a debug-evaluate scope.
  void SetIsDebugEvaluateScope();

  // Return the outer ScopeInfo if present.
199
  ScopeInfo OuterScopeInfo() const;
200

201 202
  bool is_script_scope() const;

Dan Elphick's avatar
Dan Elphick committed
203 204 205
  // Returns true if this ScopeInfo has a blocklist attached containing stack
  // allocated local variables.
  V8_EXPORT_PRIVATE bool HasLocalsBlockList() const;
206 207 208
  // Returns a list of stack-allocated locals of parent scopes.
  // Used during local debug-evalute to decide whether a context lookup
  // can continue upwards after checking this scope.
Dan Elphick's avatar
Dan Elphick committed
209
  V8_EXPORT_PRIVATE StringSet LocalsBlockList() const;
210

211 212 213 214
  // Returns true if this ScopeInfo was created for a scope that skips the
  // closest outer class when resolving private names.
  bool PrivateNameLookupSkipsOuterClass() const;

Simon Zünd's avatar
Simon Zünd committed
215 216 217 218
  // REPL mode scopes allow re-declaraction of let variables. They come from
  // debug evaluate but are different to IsDebugEvaluateScope().
  bool IsReplModeScope() const;

219
#ifdef DEBUG
220
  bool Equals(ScopeInfo other) const;
221 222
#endif

223 224 225 226
  template <typename LocalIsolate>
  static Handle<ScopeInfo> Create(LocalIsolate* isolate, Zone* zone,
                                  Scope* scope,
                                  MaybeHandle<ScopeInfo> outer_scope);
227 228
  static Handle<ScopeInfo> CreateForWithScope(
      Isolate* isolate, MaybeHandle<ScopeInfo> outer_scope);
229 230
  V8_EXPORT_PRIVATE static Handle<ScopeInfo> CreateForEmptyFunction(
      Isolate* isolate);
231
  static Handle<ScopeInfo> CreateForNativeContext(Isolate* isolate);
232 233
  static Handle<ScopeInfo> CreateGlobalThisBinding(Isolate* isolate);

Dan Elphick's avatar
Dan Elphick committed
234
  // Creates a copy of a {ScopeInfo} but with the provided locals blocklist
235
  // attached. Does nothing if the original {ScopeInfo} already has a field
Dan Elphick's avatar
Dan Elphick committed
236 237
  // for a blocklist reserved.
  V8_EXPORT_PRIVATE static Handle<ScopeInfo> RecreateWithBlockList(
238
      Isolate* isolate, Handle<ScopeInfo> original,
Dan Elphick's avatar
Dan Elphick committed
239
      Handle<StringSet> blocklist);
240

241
  // Serializes empty scope info.
242
  V8_EXPORT_PRIVATE static ScopeInfo Empty(Isolate* isolate);
243 244 245 246 247

// The layout of the static part of a ScopeInfo is as follows. Each entry is
// numeric and occupies one array slot.
// 1. A set of properties of the scope.
// 2. The number of parameters. For non-function scopes this is 0.
248
// 3. The number of non-parameter and parameter variables allocated in the
249 250 251 252 253 254
//    context.
#define FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(V) \
  V(Flags)                                   \
  V(ParameterCount)                          \
  V(ContextLocalCount)

255 256
#define FIELD_ACCESSORS(name)       \
  inline void Set##name(int value); \
257
  inline int name() const;
258 259 260
  FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS)
#undef FIELD_ACCESSORS

261
  enum Fields {
262 263 264 265 266 267
#define DECL_INDEX(name) k##name,
    FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(DECL_INDEX)
#undef DECL_INDEX
        kVariablePartIndex
  };

268 269
  static const int kFlagsOffset = OffsetOfElementAt(Fields::kFlags);

270 271
  STATIC_ASSERT(LanguageModeSize == 1 << LanguageModeBit::kSize);
  STATIC_ASSERT(kLastFunctionKind <= FunctionKindBits::kMax);
272

273 274
 private:
  // The layout of the variable part of a ScopeInfo is as follows:
275
  // 1. ContextLocalNames:
276 277 278 279 280
  //    Contains the names of local variables and parameters that are allocated
  //    in the context. They are stored in increasing order of the context slot
  //    index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
  //    context local, so in total this part occupies ContextLocalCount() slots
  //    in the array.
281
  // 2. ContextLocalInfos:
282 283 284 285
  //    Contains the variable modes and initialization flags corresponding to
  //    the context locals in ContextLocalNames. One slot is used per
  //    context local, so in total this part occupies ContextLocalCount()
  //    slots in the array.
286 287 288 289 290
  // 3. SavedClassVariableInfo:
  //    If the scope is a class scope and it has static private methods that
  //    may be accessed directly or through eval, one slot is reserved to hold
  //    the context slot index for the class variable.
  // 4. ReceiverInfo:
291 292
  //    If the scope binds a "this" value, one slot is reserved to hold the
  //    context or stack slot index for the variable.
293
  // 5. FunctionNameInfo:
294 295 296 297
  //    If the scope belongs to a named function expression this part contains
  //    information about the function variable. It always occupies two array
  //    slots:  a. The name of the function variable.
  //            b. The context or stack slot index for the variable.
298
  // 6. InferredFunctionName:
299
  //    Contains the function's inferred name.
300
  // 7. SourcePosition:
301 302
  //    Contains two slots with a) the startPosition and b) the endPosition if
  //    the scope belongs to a function or script.
303
  // 8. OuterScopeInfoIndex:
304
  //    The outer scope's ScopeInfo or the hole if there's none.
Dan Elphick's avatar
Dan Elphick committed
305
  // 9. LocalsBlockList: List of stack allocated local variables. Used by
306 307 308 309 310 311
  //    debug evaluate to properly abort variable lookup when a name clashes
  //    with a stack allocated local that can't be materialized.
  // 10. SourceTextModuleInfo, ModuleVariableCount, and ModuleVariables:
  //     For a module scope, this part contains the SourceTextModuleInfo, the
  //     number of MODULE-allocated variables, and the metadata of those
  //     variables.  For non-module scopes it is empty.
312 313
  int ContextLocalNamesIndex() const;
  int ContextLocalInfosIndex() const;
314
  int SavedClassVariableInfoIndex() const;
315 316
  int ReceiverInfoIndex() const;
  int FunctionNameInfoIndex() const;
317
  int InferredFunctionNameIndex() const;
318
  int PositionInfoIndex() const;
319
  int OuterScopeInfoIndex() const;
Dan Elphick's avatar
Dan Elphick committed
320
  V8_EXPORT_PRIVATE int LocalsBlockListIndex() const;
321 322 323
  int ModuleInfoIndex() const;
  int ModuleVariableCountIndex() const;
  int ModuleVariablesIndex() const;
324

325
  static bool NeedsPositionInfo(ScopeType type);
326 327

  enum class BootstrappingType { kScript, kFunction, kNative };
328
  static Handle<ScopeInfo> CreateForBootstrapping(Isolate* isolate,
329
                                                  BootstrappingType type);
330

331 332 333 334 335 336 337
  int Lookup(Handle<String> name, int start, int end, VariableMode* mode,
             VariableLocation* location, InitializationFlag* init_flag,
             MaybeAssignedFlag* maybe_assigned_flag);

  // Get metadata of i-th MODULE-allocated variable, where 0 <= i <
  // ModuleVariableCount.  The metadata is returned via out-arguments, which may
  // be nullptr if the corresponding information is not requested
338
  void ModuleVariable(int i, String* name, int* index,
339 340 341 342
                      VariableMode* mode = nullptr,
                      InitializationFlag* init_flag = nullptr,
                      MaybeAssignedFlag* maybe_assigned_flag = nullptr);

343 344 345
  static const int kFunctionNameEntries = 2;
  static const int kPositionInfoEntries = 2;

346
  // Properties of variables.
347
  using VariableModeField = base::BitField<VariableMode, 0, 4>;
348 349 350
  using InitFlagField = VariableModeField::Next<InitializationFlag, 1>;
  using MaybeAssignedFlagField = InitFlagField::Next<MaybeAssignedFlag, 1>;
  using ParameterNumberField = MaybeAssignedFlagField::Next<uint32_t, 16>;
351
  using IsStaticFlagField = ParameterNumberField::Next<IsStaticFlag, 1>;
352 353

  friend class ScopeIterator;
354
  friend std::ostream& operator<<(std::ostream& os, VariableAllocationInfo var);
355

356
  OBJECT_CONSTRUCTORS(ScopeInfo, FixedArray);
Dan Elphick's avatar
Dan Elphick committed
357
  FRIEND_TEST(TestWithNativeContext, RecreateScopeInfoWithLocalsBlocklistWorks);
358 359
};

360
std::ostream& operator<<(std::ostream& os, VariableAllocationInfo var);
361

362 363 364 365 366 367
}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_SCOPE_INFO_H_