// 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_

#include "src/common/globals.h"
#include "src/objects/fixed-array.h"
#include "src/objects/function-kind.h"
#include "src/objects/objects.h"
#include "src/utils/utils.h"
#include "testing/gtest/include/gtest/gtest_prod.h"  // nogncheck
#include "torque-generated/bit-fields.h"

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

namespace v8 {
namespace internal {

template <typename T>
class Handle;
class Isolate;
template <typename T>
class MaybeHandle;
class SourceTextModuleInfo;
class Scope;
class StringSet;
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.
class ScopeInfo : public FixedArray {
 public:
  DEFINE_TORQUE_GENERATED_SCOPE_FLAGS()

  DECL_CAST(ScopeInfo)
  DECL_PRINTER(ScopeInfo)

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

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

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

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

  // Does this scope make a sloppy eval call?
  bool SloppyEvalCanExtendVars() const;

  // Return the number of context slots for code if a context is allocated. This
  // number consists of three parts:
  //  1. Size of header for every context.
  //  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.
  int ContextLength() const;
  int ContextHeaderLength() const;

  bool HasContextExtensionSlot() const;

  // Does this scope declare a "this" binding?
  bool HasReceiver() const;

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

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

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

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

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

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

  V8_EXPORT_PRIVATE bool HasInferredFunctionName() const;

  void SetFunctionName(Object name);
  void SetInferredFunctionName(String name);

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

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

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

  inline bool HasSimpleParameters() const;

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

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

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

  // Position information accessors.
  int StartPosition() const;
  int EndPosition() const;
  void SetPositionInfo(int start, int end);

  SourceTextModuleInfo ModuleDescriptorInfo() const;

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

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

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

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

  bool ContextLocalIsParameter(int var) const;
  uint32_t ContextLocalParameterNumber(int var) const;

  // Return the initialization flag of the given context local.
  MaybeAssignedFlag ContextLocalMaybeAssignedFlag(int var) const;

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

  // 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.
  // If the slot is present and mode != nullptr, sets *mode to the corresponding
  // mode for that variable.
  static int ContextSlotIndex(ScopeInfo scope_info, String name,
                              VariableMode* mode, InitializationFlag* init_flag,
                              MaybeAssignedFlag* maybe_assigned_flag,
                              IsStaticFlag* is_static_flag);

  // 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).
  int ModuleIndex(String name, VariableMode* mode,
                  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.
  int FunctionContextSlotIndex(String name) const;

  // 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.
  int ReceiverContextSlotIndex() const;

  // 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;

  FunctionKind function_kind() const;

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

  // Returns true if this ScopeInfo was created for a debug-evaluate scope.
  bool IsDebugEvaluateScope() const;

  // 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.
  ScopeInfo OuterScopeInfo() const;

  bool is_script_scope() const;

  // Returns true if this ScopeInfo has a blocklist attached containing stack
  // allocated local variables.
  V8_EXPORT_PRIVATE bool HasLocalsBlockList() const;
  // 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.
  V8_EXPORT_PRIVATE StringSet LocalsBlockList() const;

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

  // REPL mode scopes allow re-declaraction of let variables. They come from
  // debug evaluate but are different to IsDebugEvaluateScope().
  bool IsReplModeScope() const;

#ifdef DEBUG
  bool Equals(ScopeInfo other) const;
#endif

  template <typename LocalIsolate>
  static Handle<ScopeInfo> Create(LocalIsolate* isolate, Zone* zone,
                                  Scope* scope,
                                  MaybeHandle<ScopeInfo> outer_scope);
  static Handle<ScopeInfo> CreateForWithScope(
      Isolate* isolate, MaybeHandle<ScopeInfo> outer_scope);
  V8_EXPORT_PRIVATE static Handle<ScopeInfo> CreateForEmptyFunction(
      Isolate* isolate);
  static Handle<ScopeInfo> CreateForNativeContext(Isolate* isolate);
  static Handle<ScopeInfo> CreateGlobalThisBinding(Isolate* isolate);

  // Creates a copy of a {ScopeInfo} but with the provided locals blocklist
  // attached. Does nothing if the original {ScopeInfo} already has a field
  // for a blocklist reserved.
  V8_EXPORT_PRIVATE static Handle<ScopeInfo> RecreateWithBlockList(
      Isolate* isolate, Handle<ScopeInfo> original,
      Handle<StringSet> blocklist);

  // Serializes empty scope info.
  V8_EXPORT_PRIVATE static ScopeInfo Empty(Isolate* isolate);

// 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.
// 3. The number of non-parameter and parameter variables allocated in the
//    context.
#define FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(V) \
  V(Flags)                                   \
  V(ParameterCount)                          \
  V(ContextLocalCount)

#define FIELD_ACCESSORS(name)       \
  inline void Set##name(int value); \
  inline int name() const;
  FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS)
#undef FIELD_ACCESSORS

  enum Fields {
#define DECL_INDEX(name) k##name,
    FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(DECL_INDEX)
#undef DECL_INDEX
        kVariablePartIndex
  };

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

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

 private:
  // The layout of the variable part of a ScopeInfo is as follows:
  // 1. ContextLocalNames:
  //    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.
  // 2. ContextLocalInfos:
  //    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.
  // 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:
  //    If the scope binds a "this" value, one slot is reserved to hold the
  //    context or stack slot index for the variable.
  // 5. FunctionNameInfo:
  //    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.
  // 6. InferredFunctionName:
  //    Contains the function's inferred name.
  // 7. SourcePosition:
  //    Contains two slots with a) the startPosition and b) the endPosition if
  //    the scope belongs to a function or script.
  // 8. OuterScopeInfoIndex:
  //    The outer scope's ScopeInfo or the hole if there's none.
  // 9. LocalsBlockList: 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.
  // 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.
  int ContextLocalNamesIndex() const;
  int ContextLocalInfosIndex() const;
  int SavedClassVariableInfoIndex() const;
  int ReceiverInfoIndex() const;
  int FunctionNameInfoIndex() const;
  int InferredFunctionNameIndex() const;
  int PositionInfoIndex() const;
  int OuterScopeInfoIndex() const;
  V8_EXPORT_PRIVATE int LocalsBlockListIndex() const;
  int ModuleInfoIndex() const;
  int ModuleVariableCountIndex() const;
  int ModuleVariablesIndex() const;

  static bool NeedsPositionInfo(ScopeType type);

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

  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
  void ModuleVariable(int i, String* name, int* index,
                      VariableMode* mode = nullptr,
                      InitializationFlag* init_flag = nullptr,
                      MaybeAssignedFlag* maybe_assigned_flag = nullptr);

  static const int kFunctionNameEntries = 2;
  static const int kPositionInfoEntries = 2;

  // Properties of variables.
  using VariableModeField = base::BitField<VariableMode, 0, 4>;
  using InitFlagField = VariableModeField::Next<InitializationFlag, 1>;
  using MaybeAssignedFlagField = InitFlagField::Next<MaybeAssignedFlag, 1>;
  using ParameterNumberField = MaybeAssignedFlagField::Next<uint32_t, 16>;
  using IsStaticFlagField = ParameterNumberField::Next<IsStaticFlag, 1>;

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

  OBJECT_CONSTRUCTORS(ScopeInfo, FixedArray);
  FRIEND_TEST(TestWithNativeContext, RecreateScopeInfoWithLocalsBlocklistWorks);
};

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

}  // namespace internal
}  // namespace v8

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

#endif  // V8_OBJECTS_SCOPE_INFO_H_
