// Copyright 2019 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. extern macro EmptyScopeInfoConstant(): ScopeInfo; const kEmptyScopeInfo: ScopeInfo = EmptyScopeInfoConstant(); extern enum ScopeType extends uint32 { CLASS_SCOPE, // Also used for the empty scope (for NativeContext & builtins). EVAL_SCOPE, FUNCTION_SCOPE, MODULE_SCOPE, SCRIPT_SCOPE, CATCH_SCOPE, BLOCK_SCOPE, WITH_SCOPE } extern enum VariableAllocationInfo extends uint32 { NONE, STACK, CONTEXT, UNUSED } extern enum VariableMode extends uint32 { kLet, kConst, kVar, kTemporary, kDynamic, kDynamicGlobal, kDynamicLocal, kPrivateMethod, kPrivateSetterOnly, kPrivateGetterOnly, kPrivateGetterAndSetter } extern enum InitializationFlag extends uint32 { kNeedsInitialization, kCreatedInitialized } extern enum IsStaticFlag extends uint32 { kNotStatic, kStatic } extern enum MaybeAssignedFlag extends uint32 { kNotAssigned, kMaybeAssigned } // Properties of scopes. bitfield struct ScopeFlags extends uint31 { scope_type: ScopeType: 4 bit; sloppy_eval_can_extend_vars: bool: 1 bit; language_mode: LanguageMode: 1 bit; declaration_scope: bool: 1 bit; receiver_variable: VariableAllocationInfo: 2 bit; has_class_brand: bool: 1 bit; has_saved_class_variable_index: bool: 1 bit; has_new_target: bool: 1 bit; // TODO(cbruni): Combine with function variable field when only storing the // function name. function_variable: VariableAllocationInfo: 2 bit; has_inferred_function_name: bool: 1 bit; is_asm_module: bool: 1 bit; has_simple_parameters: bool: 1 bit; function_kind: FunctionKind: 5 bit; has_outer_scope_info: bool: 1 bit; is_debug_evaluate_scope: bool: 1 bit; force_context_allocation: bool: 1 bit; private_name_lookup_skips_outer_class: bool: 1 bit; has_context_extension_slot: bool: 1 bit; is_repl_mode_scope: bool: 1 bit; has_locals_block_list: bool: 1 bit; is_empty: bool: 1 bit; } struct PositionInfo { start: Smi; end: Smi; } struct FunctionNameInfo { function_variable_name: String|Zero; function_variable_context_or_stack_slot_index: Smi; } bitfield struct VariableProperties extends uint31 { variable_mode: VariableMode: 4 bit; init_flag: InitializationFlag: 1 bit; maybe_assigned_flag: MaybeAssignedFlag: 1 bit; parameter_number: uint32: 16 bit; is_static_flag: IsStaticFlag: 1 bit; } struct ModuleVariable { name: String; index: Smi; properties: SmiTagged<VariableProperties>; } @generateCppClass @generateBodyDescriptor extern class ScopeInfo extends FixedArrayBase { const flags: SmiTagged<ScopeFlags>; // The number of parameters. For non-function scopes this is 0. parameter_count: Smi; // The number of non-parameter and parameter variables allocated in the // context. const context_local_count: Smi; // 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. context_local_names[context_local_count]: String; // Contains the variable modes and initialization flags corresponding to // the context locals in ContextLocalNames. context_local_infos[context_local_count]: SmiTagged<VariableProperties>; // 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. saved_class_variable_info[flags.has_saved_class_variable_index ? 1 : 0]: Smi; // If the scope binds a "this" value, one slot is reserved to hold the // context or stack slot index for the variable. receiver_info[ flags.receiver_variable == FromConstexpr<VariableAllocationInfo>(VariableAllocationInfo::STACK) || flags.receiver_variable == FromConstexpr<VariableAllocationInfo>(VariableAllocationInfo::CONTEXT) ? 1 : 0]: Smi; // 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. function_name_info[flags.function_variable != FromConstexpr<VariableAllocationInfo>(VariableAllocationInfo::NONE) ? 1 : 0]: FunctionNameInfo; inferred_function_name[flags.has_inferred_function_name ? 1 : 0]: String| Undefined; // Contains two slots with a) the startPosition and b) the endPosition if // the scope belongs to a function or script. position_info[flags.scope_type == ScopeType::FUNCTION_SCOPE || flags.scope_type == ScopeType::SCRIPT_SCOPE || flags.scope_type == ScopeType::EVAL_SCOPE || flags.scope_type == ScopeType::MODULE_SCOPE ? 1 : 0]: PositionInfo; outer_scope_info[flags.has_outer_scope_info ? 1 : 0]: ScopeInfo|TheHole; // List of stack allocated local variables. Used by debug evaluate to properly // abort variable lookup when a name clashes with a stack allocated local that // can't be materialized. locals_block_list[flags.has_locals_block_list ? 1 : 0]: HashTable; // 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. module_info[flags.scope_type == ScopeType::MODULE_SCOPE ? 1 : 0]: SourceTextModuleInfo; const module_variable_count[flags.scope_type == ScopeType::MODULE_SCOPE ? 1 : 0]: Smi; module_variables[flags.scope_type == ScopeType::MODULE_SCOPE ? module_variable_count[0] : 0]: ModuleVariable; }