text: //-------------------------------------------------------------------------------------------------------
  // Copyright (C) Microsoft. All rights reserved.
  // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  //-------------------------------------------------------------------------------------------------------
  
  #pragma once
  
  // forward decls
  class AsmJsJITInfo;
  class JITTimeProfileInfo;
  class FunctionJITRuntimeInfo;
  class JITRecyclableObject;
  
  class JITTimeFunctionBody
  {
  public:
      JITTimeFunctionBody(FunctionBodyDataIDL * bodyData);
  
      static void InitializeJITFunctionData(
          __in ArenaAllocator * arena,
          __in Js::FunctionBody * functionBody,
          __out FunctionBodyDataIDL * jitBody);
  
      intptr_t GetAddr() const;
  
      uint GetFunctionNumber() const;
      uint GetSourceContextId() const;
      uint GetNestedCount() const;
      uint GetScopeSlotArraySize() const;
      uint GetParamScopeSlotArraySize() const;
      uint GetByteCodeCount() const;
      uint GetByteCodeInLoopCount() const;
      uint GetNonLoadByteCodeCount() const;
      uint GetLoopCount() const;
      uint GetByteCodeLength() const;
      uint GetInnerScopeCount() const;
      uint GetInlineCacheCount() const;
      uint GetRecursiveCallSiteCount() const;
      uint GetForInLoopDepth() const;
      Js::RegSlot GetYieldReg() const;
      Js::RegSlot GetLocalFrameDisplayReg() const;
      Js::RegSlot GetLocalClosureReg() const;
      Js::RegSlot GetEnvReg() const;
      Js::RegSlot GetFirstTmpReg() const;
      Js::RegSlot GetFirstInnerScopeReg() const;
      Js::RegSlot GetVarCount() const;
      Js::RegSlot GetConstCount() const;
      Js::RegSlot GetLocalsCount() const;
      Js::RegSlot GetTempCount() const;
      Js::RegSlot GetFuncExprScopeReg() const;
      Js::RegSlot GetThisRegForEventHandler() const;
      Js::RegSlot GetFirstNonTempLocalIndex() const;
      Js::RegSlot GetEndNonTempLocalIndex() const;
      Js::RegSlot GetNonTempLocalVarCount() const;
      Js::RegSlot GetRestParamRegSlot() const;
      Js::RegSlot GetParamClosureReg() const;
  
      Js::PropertyId GetPropertyIdFromCacheId(uint cacheId) const;
      Js::PropertyId GetReferencedPropertyId(uint index) const;
  
      uint16 GetEnvDepth() const;
      uint16 GetArgUsedForBranch() const;
      Js::ProfileId GetProfiledCallSiteCount() const;
      Js::ArgSlot GetInParamsCount() const;
  
      bool DoStackNestedFunc() const;
      bool DoStackClosure() const;
      bool DoBackendArgumentsOptimization() const;
      bool IsLibraryCode() const;
      bool HasTry() const;
      bool HasThis() const;
      bool HasFinally() const;
      bool HasOrParentHasArguments() const;
      bool IsGenerator() const;
      bool IsCoroutine() const;
      bool IsLambda() const;
      bool IsAsmJsMode() const;
      bool IsWasmFunction() const;
      bool UsesWAsmJsFastVirtualBuffer() const;
      bool IsStrictMode() const;
      bool IsEval() const;
      bool HasImplicitArgIns() const;
      bool HasRestParameter() const;
      bool HasScopeObject() const;
      bool HasCachedScopePropIds() const;
      bool HasInlineCachesOnFunctionObject() const;
      bool DoInterruptProbe() const;
      bool IsGlobalFunc() const;
      void DisableInlineApply();
      bool IsInlineApplyDisabled() const;
      bool IsNonTempLocalVar(uint32 varIndex) const;
      bool DoJITLoopBody() const;
      bool IsInlineSpreadDisabled() const;
      void DisableInlineSpread();
      bool HasLoops() const;
      bool HasNonBuiltInCallee() const;
      bool HasNestedLoop() const;
      bool UsesArgumentsObject() const;
      bool IsParamAndBodyScopeMerged() const;
      bool CanInlineRecursively(uint depth, bool tryAggressive = true) const;
      bool NeedScopeObjectForArguments(bool hasNonSimpleParams) const;
      bool GetDoScopeObjectCreation() const;
      void EnsureConsistentConstCount() const;
      bool HasComputedName() const;
      bool HasHomeObj() const;
      bool RegIsConstant(Js::RegSlot reg) const;
  
      const byte * GetByteCodeBuffer() const;
      StatementMapIDL * GetFullStatementMap() const;
      uint GetFullStatementMapCount() const;
      void * ReadFromAuxData(uint offset) const;
      void * ReadFromAuxContextData(uint offset) const;
      Js::FunctionInfoPtrPtr GetNestedFuncRef(uint index) const;
      intptr_t GetConstantVar(Js::RegSlot location) const;
      JITRecyclableObject * GetConstantContent(Js::RegSlot location) const;
  
      template<class T>
      T* GetConstAsT(Js::RegSlot location) const
      {
          Assert(m_bodyData.constTableContent != nullptr);
          Assert(m_bodyData.constTableContent->content != nullptr);
          Assert(location < GetConstCount());
          Assert(location != 0);
  
          auto obj = m_bodyData.constTableContent->content[location - Js::FunctionBody::FirstRegSlot];
          Assert(obj);
          obj->vtbl = VirtualTableInfo<T>::Address;
          //Assert(T::Is(obj));
          return (T*)obj;
      }
  
      template<>
      Js::JavascriptNumber* GetConstAsT<Js::JavascriptNumber>(Js::RegSlot location) const
      {
          Assert(m_bodyData.constTableContent != nullptr);
          Assert(m_bodyData.constTableContent->content != nullptr);
          Assert(location < GetConstCount());
          Assert(location != 0);
  
  #if !FLOATVAR
          auto obj = m_bodyData.constTableContent->content[location - Js::FunctionBody::FirstRegSlot];
          if (!obj)
          {
  #endif
              Js::JavascriptNumber* num = (Js::JavascriptNumber*)GetConstantVar(location);
              Assert(Js::TaggedNumber::Is(num));
              return num;
  #if !FLOATVAR
          }
          Assert(obj);
          obj->vtbl = VirtualTableInfo<Js::JavascriptNumber>::Address;
          Assert(Js::JavascriptNumber::Is(obj));
          return (Js::JavascriptNumber*)obj;
  #endif
      }
  
      intptr_t GetInlineCache(uint index) const;
      intptr_t GetIsInstInlineCache(uint index) const;
      Js::TypeId GetConstantType(Js::RegSlot location) const;
      void * GetConstTable() const;
  
      intptr_t GetRootObject() const;
      intptr_t GetLoopHeaderAddr(uint loopNum) const;
      const JITLoopHeaderIDL * GetLoopHeaderData(uint loopNum) const;
  
      intptr_t GetScriptIdAddr() const;
      intptr_t GetProbeCountAddr() const;
      intptr_t GetFlagsAddr() const;
      intptr_t GetRegAllocLoadCountAddr() const;
      intptr_t GetRegAllocStoreCountAddr() const;
      intptr_t GetCallCountStatsAddr() const;
      intptr_t GetFormalsPropIdArrayAddr() const;
      intptr_t GetObjectLiteralTypeRef(uint index) const;
      intptr_t GetLiteralRegexAddr(uint index) const;
      uint GetNestedFuncIndexForSlotIdInCachedScope(uint index) const;
      const AsmJsJITInfo * GetAsmJsInfo() const;
      const JITTimeProfileInfo * GetReadOnlyProfileInfo() const;
      JITTimeProfileInfo * GetProfileInfo() const;
      bool HasProfileInfo() const;
      bool IsRegSlotFormal(Js::RegSlot reg) const;
      bool HasPropIdToFormalsMap() const;
      Js::ProfileId GetCallApplyCallSiteIdForCallSiteId(Js::ProfileId callSiteId) const;
  
      static bool LoopContains(const JITLoopHeaderIDL * loop1, const JITLoopHeaderIDL * loop2);
  
      char16* GetDisplayName() const;
  
      intptr_t GetAuxDataAddr(uint offset) const;
      const Js::PropertyIdArray * ReadPropertyIdArrayFromAuxData(uint offset) const;
      Js::PropertyIdArray * GetFormalsPropIdArray() const;
  
      Js::EnumeratorCache * GetForInCache(uint profileId) const;
      bool InitializeStatementMap(Js::SmallSpanSequence * statementMap, ArenaAllocator* alloc) const;
  private:
      Js::FunctionInfo::Attributes GetAttributes() const;
      Js::FunctionBody::FunctionBodyFlags GetFlags() const;
  
      FunctionBodyDataIDL m_bodyData;
  };
  