// 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/globals.h"
#include "src/objects.h"
#include "src/objects/fixed-array.h"
#include "src/utils.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 ModuleInfo;
class Scope;
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:
  DECL_CAST(ScopeInfo)

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

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

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

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

  // Return the total number of locals allocated on the stack and in the
  // context. This includes the parameters that are allocated in the context.
  int LocalCount();

  // Return the number of stack slots for code. This number consists of two
  // parts:
  //  1. One stack slot per stack allocated local.
  //  2. One stack slot for the function name if it is stack allocated.
  int StackSlotCount();

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

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

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

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

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

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

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

  inline bool HasSimpleParameters();

  // Return the function_name if present.
  String* FunctionName();

  ModuleInfo* ModuleDescriptorInfo();

  // Return the name of the given parameter.
  String* ParameterName(int var);

  // Return the name of the given local.
  String* LocalName(int var);

  // Return the name of the given stack local.
  String* StackLocalName(int var);

  // Return the name of the given stack local.
  int StackLocalIndex(int var);

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

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

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

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

  // 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
  // the stack slot index for a given slot name if the slot is
  // present; otherwise returns a value < 0. The name must be an internalized
  // string.
  int StackSlotIndex(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(Handle<ScopeInfo> scope_info, Handle<String> name,
                              VariableMode* mode, InitializationFlag* init_flag,
                              MaybeAssignedFlag* maybe_assigned_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(Handle<String> name, VariableMode* mode,
                  InitializationFlag* init_flag,
                  MaybeAssignedFlag* maybe_assigned_flag);

  // Lookup support for serialized scope info. Returns the
  // parameter index for a given parameter name if the parameter is present;
  // otherwise returns a value < 0. The name must be an internalized string.
  int ParameterIndex(String* name);

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

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

  FunctionKind function_kind();

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

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

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

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

  static Handle<ScopeInfo> Create(Isolate* isolate, Zone* zone, Scope* scope,
                                  MaybeHandle<ScopeInfo> outer_scope);
  static Handle<ScopeInfo> CreateForWithScope(
      Isolate* isolate, MaybeHandle<ScopeInfo> outer_scope);
  static Handle<ScopeInfo> CreateGlobalThisBinding(Isolate* isolate);

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

#ifdef DEBUG
  void Print();
#endif

// 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 variables allocated on the stack.
// 4. 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(StackLocalCount)                         \
  V(ContextLocalCount)

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

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

 private:
  // The layout of the variable part of a ScopeInfo is as follows:
  // 1. ParameterNames:
  //    This part stores the names of the parameters for function scopes. One
  //    slot is used per parameter, so in total this part occupies
  //    ParameterCount() slots in the array. For other scopes than function
  //    scopes ParameterCount() is 0.
  // 2. StackLocalFirstSlot:
  //    Index of a first stack slot for stack local. Stack locals belonging to
  //    this scope are located on a stack at slots starting from this index.
  // 3. StackLocalNames:
  //    Contains the names of local variables that are allocated on the stack,
  //    in increasing order of the stack slot index. First local variable has a
  //    stack slot index defined in StackLocalFirstSlot (point 2 above).
  //    One slot is used per stack local, so in total this part occupies
  //    StackLocalCount() slots in the array.
  // 4. 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.
  // 5. 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.
  // 6. ReceiverInfo:
  //    If the scope binds a "this" value, one slot is reserved to hold the
  //    context or stack slot index for the variable.
  // 7. 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.
  // 8. OuterScopeInfoIndex:
  //    The outer scope's ScopeInfo or the hole if there's none.
  // 9. ModuleInfo, ModuleVariableCount, and ModuleVariables:
  //    For a module scope, this part contains the ModuleInfo, the number of
  //    MODULE-allocated variables, and the metadata of those variables.  For
  //    non-module scopes it is empty.
  int ParameterNamesIndex();
  int StackLocalFirstSlotIndex();
  int StackLocalNamesIndex();
  int ContextLocalNamesIndex();
  int ContextLocalInfosIndex();
  int ReceiverInfoIndex();
  int FunctionNameInfoIndex();
  int OuterScopeInfoIndex();
  int ModuleInfoIndex();
  int ModuleVariableCountIndex();
  int ModuleVariablesIndex();

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

  // Used for the function name variable for named function expressions, and for
  // the receiver.
  enum VariableAllocationInfo { NONE, STACK, CONTEXT, UNUSED };

  // Properties of scopes.
  class ScopeTypeField : public BitField<ScopeType, 0, 4> {};
  class CallsSloppyEvalField : public BitField<bool, ScopeTypeField::kNext, 1> {
  };
  STATIC_ASSERT(LanguageModeSize == 2);
  class LanguageModeField
      : public BitField<LanguageMode, CallsSloppyEvalField::kNext, 1> {};
  class DeclarationScopeField
      : public BitField<bool, LanguageModeField::kNext, 1> {};
  class ReceiverVariableField
      : public BitField<VariableAllocationInfo, DeclarationScopeField::kNext,
                        2> {};
  class HasNewTargetField
      : public BitField<bool, ReceiverVariableField::kNext, 1> {};
  class FunctionVariableField
      : public BitField<VariableAllocationInfo, HasNewTargetField::kNext, 2> {};
  class AsmModuleField
      : public BitField<bool, FunctionVariableField::kNext, 1> {};
  class HasSimpleParametersField
      : public BitField<bool, AsmModuleField::kNext, 1> {};
  class FunctionKindField
      : public BitField<FunctionKind, HasSimpleParametersField::kNext, 11> {};
  class HasOuterScopeInfoField
      : public BitField<bool, FunctionKindField::kNext, 1> {};
  class IsDebugEvaluateScopeField
      : public BitField<bool, HasOuterScopeInfoField::kNext, 1> {};

  STATIC_ASSERT(kLastFunctionKind <= FunctionKindField::kMax);

  // Properties of variables.
  class VariableModeField : public BitField<VariableMode, 0, 3> {};
  class InitFlagField : public BitField<InitializationFlag, 3, 1> {};
  class MaybeAssignedFlagField : public BitField<MaybeAssignedFlag, 4, 1> {};

  friend class ScopeIterator;
};

}  // namespace internal
}  // namespace v8

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

#endif  // V8_OBJECTS_SCOPE_INFO_H_
