• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 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
5extern macro EmptyScopeInfoConstant(): ScopeInfo;
6const kEmptyScopeInfo: ScopeInfo = EmptyScopeInfoConstant();
7
8extern enum ScopeType extends uint32 {
9  // The empty scope info for builtins and NativeContexts is allocated
10  // in a way that it gets the first scope type in line, see
11  // Heap::CreateInitialMaps(). It's always guarded with the IsEmpty
12  // bit, so it doesn't matter what scope type it gets.
13  CLASS_SCOPE,
14  EVAL_SCOPE,
15  FUNCTION_SCOPE,
16  MODULE_SCOPE,
17  SCRIPT_SCOPE,
18  CATCH_SCOPE,
19  BLOCK_SCOPE,
20  WITH_SCOPE
21}
22
23extern enum VariableAllocationInfo extends uint32 {
24  NONE,
25  STACK,
26  CONTEXT,
27  UNUSED
28}
29
30extern enum VariableMode extends uint32 {
31  kLet,
32  kConst,
33  kVar,
34  kTemporary,
35  kDynamic,
36  kDynamicGlobal,
37  kDynamicLocal,
38  kPrivateMethod,
39  kPrivateSetterOnly,
40  kPrivateGetterOnly,
41  kPrivateGetterAndSetter
42}
43
44extern enum InitializationFlag extends uint32 {
45  kNeedsInitialization,
46  kCreatedInitialized
47}
48
49extern enum IsStaticFlag extends uint32 { kNotStatic, kStatic }
50
51extern enum MaybeAssignedFlag extends uint32 { kNotAssigned, kMaybeAssigned }
52
53// Properties of scopes.
54bitfield struct ScopeFlags extends uint31 {
55  scope_type: ScopeType: 4 bit;
56  sloppy_eval_can_extend_vars: bool: 1 bit;
57  language_mode: LanguageMode: 1 bit;
58  declaration_scope: bool: 1 bit;
59  receiver_variable: VariableAllocationInfo: 2 bit;
60  // In class scope, this indicates whether the class has a private brand.
61  // In constructor scope, this indicates whether the constructor needs
62  // private brand initialization.
63  class_scope_has_private_brand: bool: 1 bit;
64  has_saved_class_variable: bool: 1 bit;
65  has_new_target: bool: 1 bit;
66  // TODO(cbruni): Combine with function variable field when only storing the
67  // function name.
68  function_variable: VariableAllocationInfo: 2 bit;
69  has_inferred_function_name: bool: 1 bit;
70  is_asm_module: bool: 1 bit;
71  has_simple_parameters: bool: 1 bit;
72  function_kind: FunctionKind: 5 bit;
73  has_outer_scope_info: bool: 1 bit;
74  is_debug_evaluate_scope: bool: 1 bit;
75  force_context_allocation: bool: 1 bit;
76  private_name_lookup_skips_outer_class: bool: 1 bit;
77  has_context_extension_slot: bool: 1 bit;
78  is_repl_mode_scope: bool: 1 bit;
79  has_locals_block_list: bool: 1 bit;
80  is_empty: bool: 1 bit;
81}
82
83struct PositionInfo {
84  start: Smi;
85  end: Smi;
86}
87
88struct FunctionVariableInfo {
89  name: String|Zero;
90  context_or_stack_slot_index: Smi;
91}
92
93bitfield struct VariableProperties extends uint31 {
94  variable_mode: VariableMode: 4 bit;
95  init_flag: InitializationFlag: 1 bit;
96  maybe_assigned_flag: MaybeAssignedFlag: 1 bit;
97  parameter_number: uint32: 16 bit;
98  is_static_flag: IsStaticFlag: 1 bit;
99}
100
101struct ModuleVariable {
102  name: String;
103  index: Smi;
104  properties: SmiTagged<VariableProperties>;
105}
106
107const kMaxInlinedLocalNamesSize:
108    constexpr int32 generates 'kScopeInfoMaxInlinedLocalNamesSize';
109
110@generateBodyDescriptor
111extern class ScopeInfo extends HeapObject {
112  const flags: SmiTagged<ScopeFlags>;
113
114  // The number of parameters. For non-function scopes this is 0.
115  parameter_count: Smi;
116
117  // The number of non-parameter and parameter variables allocated in the
118  // context.
119  const context_local_count: Smi;
120
121  // Contains the names of inlined local variables and parameters that are
122  // allocated in the context. They are stored in increasing order of the
123  // context slot index starting with Context::MIN_CONTEXT_SLOTS.
124  context_local_names[Convert<intptr>(context_local_count) < kMaxInlinedLocalNamesSize ? context_local_count : 0]:
125      String;
126
127  // Contains a hash_map from local names to context slot index.
128  // This is only used when local names are not inlined in the scope info.
129  context_local_names_hashtable?
130      [kMaxInlinedLocalNamesSize <= Convert<intptr>(context_local_count)]:
131          NameToIndexHashTable;
132
133  // Contains the variable modes and initialization flags corresponding to
134  // the context locals in ContextLocalNames.
135  context_local_infos[context_local_count]: SmiTagged<VariableProperties>;
136
137  // If the scope is a class scope and it has static private methods that
138  // may be accessed directly or through eval, one slot is reserved to hold
139  // the offset in the field storage of the hash table (or the slot index if
140  // local names are inlined) for the class variable.
141  saved_class_variable_info?[flags.has_saved_class_variable]: Smi;
142
143  // If the scope belongs to a named function expression this part contains
144  // information about the function variable. It always occupies two array
145  // slots:  a. The name of the function variable.
146  //         b. The context or stack slot index for the variable.
147  function_variable_info?
148      [flags.function_variable !=
149       FromConstexpr<VariableAllocationInfo>(VariableAllocationInfo::NONE)]:
150          FunctionVariableInfo;
151
152  inferred_function_name?[flags.has_inferred_function_name]: String|Undefined;
153
154  // Contains two slots with a) the startPosition and b) the endPosition if
155  // the scope belongs to a function or script.
156  position_info?
157      [flags.scope_type == ScopeType::FUNCTION_SCOPE ||
158       flags.scope_type == ScopeType::SCRIPT_SCOPE ||
159       flags.scope_type == ScopeType::EVAL_SCOPE ||
160       flags.scope_type == ScopeType::MODULE_SCOPE ||
161       (flags.is_empty ? false : flags.scope_type == ScopeType::CLASS_SCOPE)]:
162          PositionInfo;
163
164  outer_scope_info?[flags.has_outer_scope_info]: ScopeInfo|TheHole;
165
166  // List of stack allocated local variables. Used by debug evaluate to properly
167  // abort variable lookup when a name clashes with a stack allocated local that
168  // can't be materialized.
169  locals_block_list?[flags.has_locals_block_list]: HashTable;
170
171  // For a module scope, this part contains the SourceTextModuleInfo, the
172  // number of MODULE-allocated variables, and the metadata of those
173  // variables.  For non-module scopes it is empty.
174  module_info?
175      [flags.scope_type == ScopeType::MODULE_SCOPE]: SourceTextModuleInfo;
176  const module_variable_count?
177      [flags.scope_type == ScopeType::MODULE_SCOPE]: Smi;
178  module_variables[flags.scope_type == ScopeType::MODULE_SCOPE ? module_variable_count : 0]:
179      ModuleVariable;
180}
181
182extern macro NameToIndexHashTableLookup(
183    NameToIndexHashTable, Name): intptr labels NotFound;
184
185macro IndexOfInlinedLocalName(
186    scopeInfo: ScopeInfo, name: Name): intptr labels NotFound {
187  const count: intptr = Convert<intptr>(scopeInfo.context_local_count);
188  for (let i: intptr = 0; i < count; ++i) {
189    if (TaggedEqual(name, scopeInfo.context_local_names[i])) {
190      return i;
191    }
192  }
193  goto NotFound;
194}
195
196// Returns the index of the named local in a ScopeInfo.
197// Assumes that the given name is internalized; uses pointer comparisons.
198@export
199macro IndexOfLocalName(scopeInfo: ScopeInfo, name: Name):
200    intptr labels NotFound {
201  const count: intptr = Convert<intptr>(scopeInfo.context_local_count);
202  if (count < kMaxInlinedLocalNamesSize) {
203    return IndexOfInlinedLocalName(scopeInfo, name) otherwise goto NotFound;
204  } else {
205    return NameToIndexHashTableLookup(
206        scopeInfo.context_local_names_hashtable, name) otherwise goto NotFound;
207  }
208}
209