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
  
  #define __MAKE_WARNING__(X) "This compiler does not support '" ## X ## "'"
  // Define _ALWAYSINLINE for template that want to always inline, but doesn't allow inline linkage in clang
  #if defined(__GNUC__) || defined(__clang__)
      #if __has_attribute(always_inline)
          #define _ALWAYSINLINE __attribute__((always_inline))
          #define __forceinline inline _ALWAYSINLINE
      #else // No always_inline support
          #pragma message __MAKE_WARNING__("always_inline")
          #define _ALWAYSINLINE inline
          #define __forceinline _ALWAYSINLINE
      #endif
      #if __has_attribute(noinline)
          #ifdef CLANG_HAS_DISABLE_TAIL_CALLS
              #define _NOINLINE __attribute__((noinline, disable_tail_calls))
          #else
              #define _NOINLINE __attribute__((noinline))
          #endif
      #else // No noinline support
          #pragma message __MAKE_WARNING__("noinline")
          #define _NOINLINE
      #endif
  #else // Windows
      #define _ALWAYSINLINE __forceinline
      #define _NOINLINE __declspec(noinline)
  #endif
  
  // Only VC compiler support overflow guard
  #if defined(__GNUC__) || defined(__clang__)
  #define DECLSPEC_GUARD_OVERFLOW
  #else // Windows
  #define DECLSPEC_GUARD_OVERFLOW __declspec(guard(overflow))
  #endif
  
  #ifndef THREAD_LOCAL
  #ifndef __APPLE__
  #if defined(_MSC_VER) && _MSC_VER <= 1800 // VS2013?
  #define THREAD_LOCAL __declspec(thread)
  #else // VS2015+, linux Clang etc.
  #define THREAD_LOCAL thread_local
  #endif // VS2013?
  #else // __APPLE__
  #ifndef __IOS__
  #define THREAD_LOCAL _Thread_local
  #else
  #define THREAD_LOCAL
  #endif
  #endif // __APPLE__
  #endif // THREAD_LOCAL
  
  // VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known good version)
  #if !defined(_MSC_VER) || _MSC_FULL_VER >= 190024210
  #define HAS_CONSTEXPR 1
  #endif
  
  #ifdef HAS_CONSTEXPR
  #define OPT_CONSTEXPR constexpr
  #else
  #define OPT_CONSTEXPR
  #endif
  
  #ifdef __clang__
  #define CLANG_WNO_BEGIN_(x) \
      _Pragma("clang diagnostic push")\
      _Pragma(#x)
  
  #define CLANG_WNO_BEGIN(x) CLANG_WNO_BEGIN_(clang diagnostic ignored x)
  #define CLANG_WNO_END
      _Pragma("clang diagnostic pop")
  #else
  #define CLANG_WNO_BEGIN(x)
  #define CLANG_WNO_END
  #endif
  
  #ifndef __has_builtin
  #define __has_builtin(x) 0
  #endif
  
  #ifdef _WIN32
  #pragma warning(push)
  #pragma warning(disable: 4995) /* 'function': name was marked as #pragma deprecated */
  
  // === Windows Header Files ===
  #define WIN32_LEAN_AND_MEAN 1
  #define INC_OLE2                 /* for windows.h */
  #define CONST_VTABLE             /* for objbase.h */
  #include <windows.h>
  
  /* Don't want GetObject and GetClassName to be defined to GetObjectW and GetClassNameW */
  #undef GetObject
  #undef GetClassName
  #undef Yield /* winbase.h defines this but we want to use it for Js::OpCode::Yield; it is Win16 legacy, no harm undef'ing it */
  #pragma warning(pop)
  
  // xplat-todo: get a better name for this macro
  #define _u(s) L##s
  #define INIT_PRIORITY(x)
  
  #define get_cpuid __cpuid
  
  #else // !_WIN32
  
  #define USING_PAL_STDLIB 1
  #define STRSAFE_INLINE   1
  
  #ifdef PAL_STDCPP_COMPAT
  #include <wchar.h>
  #include <math.h>
  #include <time.h>
  #if defined(_AMD64_) || defined(__i686__)
  #include <smmintrin.h>
  #include <xmmintrin.h>
  #endif // defined(_AMD64_) || defined(__i686__)
  #endif
  
  #include "inc/pal.h"
  #include "inc/rt/palrt.h"
  #include "inc/rt/no_sal2.h"
  #include "inc/rt/oaidl.h"
  
  #define _u(s) u##s
  
  typedef GUID UUID;
  #define INIT_PRIORITY(x) __attribute__((init_priority(x)))
  
  #ifdef PAL_STDCPP_COMPAT
  #define __in
  #define __out
  #define FILE PAL_FILE
  #endif
  
  #if defined(_AMD64_) || defined(__i686__)
  // xplat-todo: verify below is correct
  #include <cpuid.h>
  inline int get_cpuid(int cpuInfo[4], int function_id)
  {
      return __get_cpuid(
              static_cast<unsigned int>(function_id),
              reinterpret_cast<unsigned int*>(&cpuInfo[0]),
              reinterpret_cast<unsigned int*>(&cpuInfo[1]),
              reinterpret_cast<unsigned int*>(&cpuInfo[2]),
              reinterpret_cast<unsigned int*>(&cpuInfo[3]));
  }
  #elif defined(_ARM_)
  inline int get_cpuid(int cpuInfo[4], int function_id)
  {
      int empty[4] = {0};
      memcpy(cpuInfo, empty, sizeof(int) * 4);
      // xplat-todo: implement me!!
  }
  #endif
  
  inline void DebugBreak()
  {
      __builtin_trap();
  }
  
  #define EXIT_FAILURE 1
  #define _BitScanForward BitScanForward
  #define _BitScanForward64 BitScanForward64
  #define _BitScanReverse BitScanReverse
  #define _BitScanReverse64 BitScanReverse64
  #define _bittest BitTest
  #define _bittestandset BitTestAndSet
  #define _interlockedbittestandset InterlockedBitTestAndSet
  
  #define DbgRaiseAssertionFailure() __builtin_trap()
  
  // These are not available in pal
  #define fwprintf_s      fwprintf
  
  // PAL LoadLibraryExW not supported
  #define LOAD_LIBRARY_SEARCH_SYSTEM32     0
  // winnt.h
  #define FAST_FAIL_INVALID_ARG            5
  // winerror.h
  #define FACILITY_JSCRIPT                 2306
  #define JSCRIPT_E_CANTEXECUTE            _HRESULT_TYPEDEF_(0x89020001L)
  #define DISP_E_UNKNOWNINTERFACE          _HRESULT_TYPEDEF_(0x80020001L)
  #define DISP_E_MEMBERNOTFOUND            _HRESULT_TYPEDEF_(0x80020003L)
  #define DISP_E_UNKNOWNNAME               _HRESULT_TYPEDEF_(0x80020006L)
  #define DISP_E_NONAMEDARGS               _HRESULT_TYPEDEF_(0x80020007L)
  #define DISP_E_EXCEPTION                 _HRESULT_TYPEDEF_(0x80020009L)
  #define DISP_E_BADINDEX                  _HRESULT_TYPEDEF_(0x8002000BL)
  #define DISP_E_UNKNOWNLCID               _HRESULT_TYPEDEF_(0x8002000CL)
  #define DISP_E_ARRAYISLOCKED             _HRESULT_TYPEDEF_(0x8002000DL)
  #define DISP_E_BADPARAMCOUNT             _HRESULT_TYPEDEF_(0x8002000EL)
  #define DISP_E_PARAMNOTOPTIONAL          _HRESULT_TYPEDEF_(0x8002000FL)
  #define DISP_E_NOTACOLLECTION            _HRESULT_TYPEDEF_(0x80020011L)
  #define TYPE_E_DLLFUNCTIONNOTFOUND       _HRESULT_TYPEDEF_(0x8002802FL)
  #define TYPE_E_TYPEMISMATCH              _HRESULT_TYPEDEF_(0x80028CA0L)
  #define TYPE_E_OUTOFBOUNDS               _HRESULT_TYPEDEF_(0x80028CA1L)
  #define TYPE_E_IOERROR                   _HRESULT_TYPEDEF_(0x80028CA2L)
  #define TYPE_E_CANTCREATETMPFILE         _HRESULT_TYPEDEF_(0x80028CA3L)
  #define TYPE_E_CANTLOADLIBRARY           _HRESULT_TYPEDEF_(0x80029C4AL)
  #define STG_E_TOOMANYOPENFILES           _HRESULT_TYPEDEF_(0x80030004L)
  #define STG_E_ACCESSDENIED               _HRESULT_TYPEDEF_(0x80030005L)
  #define STG_E_INSUFFICIENTMEMORY         _HRESULT_TYPEDEF_(0x80030008L)
  #define STG_E_NOMOREFILES                _HRESULT_TYPEDEF_(0x80030012L)
  #define STG_E_DISKISWRITEPROTECTED       _HRESULT_TYPEDEF_(0x80030013L)
  #define STG_E_READFAULT                  _HRESULT_TYPEDEF_(0x8003001EL)
  #define STG_E_SHAREVIOLATION             _HRESULT_TYPEDEF_(0x80030020L)
  #define STG_E_LOCKVIOLATION              _HRESULT_TYPEDEF_(0x80030021L)
  #define STG_E_MEDIUMFULL                 _HRESULT_TYPEDEF_(0x80030070L)
  #define STG_E_INVALIDNAME                _HRESULT_TYPEDEF_(0x800300FCL)
  #define STG_E_INUSE                      _HRESULT_TYPEDEF_(0x80030100L)
  #define STG_E_NOTCURRENT                 _HRESULT_TYPEDEF_(0x80030101L)
  #define STG_E_CANTSAVE                   _HRESULT_TYPEDEF_(0x80030103L)
  #define REGDB_E_CLASSNOTREG              _HRESULT_TYPEDEF_(0x80040154L)
  #define MK_E_UNAVAILABLE                 _HRESULT_TYPEDEF_(0x800401E3L)
  #define MK_E_INVALIDEXTENSION            _HRESULT_TYPEDEF_(0x800401E6L)
  #define MK_E_CANTOPENFILE                _HRESULT_TYPEDEF_(0x800401EAL)
  #define CO_E_APPNOTFOUND                 _HRESULT_TYPEDEF_(0x800401F5L)
  #define CO_E_APPDIDNTREG                 _HRESULT_TYPEDEF_(0x800401FEL)
  #define GetScode(hr) ((SCODE) (hr))
  // activscp.h
  #define SCRIPT_E_RECORDED                _HRESULT_TYPEDEF_(0x86664004L)
  
  #define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS        (0x00000004)
  
  typedef
  enum tagBREAKPOINT_STATE
      {
          BREAKPOINT_DELETED  = 0,
          BREAKPOINT_DISABLED = 1,
          BREAKPOINT_ENABLED  = 2
      }   BREAKPOINT_STATE;
  
  typedef
  enum tagBREAKRESUME_ACTION
      {
          BREAKRESUMEACTION_ABORT     = 0,
          BREAKRESUMEACTION_CONTINUE  = ( BREAKRESUMEACTION_ABORT + 1 ) ,
          BREAKRESUMEACTION_STEP_INTO = ( BREAKRESUMEACTION_CONTINUE + 1 ) ,
          BREAKRESUMEACTION_STEP_OVER = ( BREAKRESUMEACTION_STEP_INTO + 1 ) ,
          BREAKRESUMEACTION_STEP_OUT  = ( BREAKRESUMEACTION_STEP_OVER + 1 ) ,
          BREAKRESUMEACTION_IGNORE    = ( BREAKRESUMEACTION_STEP_OUT + 1 ) ,
          BREAKRESUMEACTION_STEP_DOCUMENT = ( BREAKRESUMEACTION_IGNORE + 1 )
      }   BREAKRESUMEACTION;
  
  enum tagDBGPROP_ATTRIB_FLAGS
  {
      DBGPROP_ATTRIB_NO_ATTRIB= 0,
      DBGPROP_ATTRIB_VALUE_IS_INVALID= 0x8,
      DBGPROP_ATTRIB_VALUE_IS_EXPANDABLE= 0x10,
      DBGPROP_ATTRIB_VALUE_IS_FAKE= 0x20,
      DBGPROP_ATTRIB_VALUE_IS_METHOD= 0x100,
      DBGPROP_ATTRIB_VALUE_IS_EVENT= 0x200,
      DBGPROP_ATTRIB_VALUE_IS_RAW_STRING= 0x400,
      DBGPROP_ATTRIB_VALUE_READONLY= 0x800,
      DBGPROP_ATTRIB_ACCESS_PUBLIC= 0x1000,
      DBGPROP_ATTRIB_ACCESS_PRIVATE= 0x2000,
      DBGPROP_ATTRIB_ACCESS_PROTECTED= 0x4000,
      DBGPROP_ATTRIB_ACCESS_FINAL= 0x8000,
      DBGPROP_ATTRIB_STORAGE_GLOBAL= 0x10000,
      DBGPROP_ATTRIB_STORAGE_STATIC= 0x20000,
      DBGPROP_ATTRIB_STORAGE_FIELD= 0x40000,
      DBGPROP_ATTRIB_STORAGE_VIRTUAL= 0x80000,
      DBGPROP_ATTRIB_TYPE_IS_CONSTANT= 0x100000,
      DBGPROP_ATTRIB_TYPE_IS_SYNCHRONIZED= 0x200000,
      DBGPROP_ATTRIB_TYPE_IS_VOLATILE= 0x400000,
      DBGPROP_ATTRIB_HAS_EXTENDED_ATTRIBS= 0x800000,
      DBGPROP_ATTRIB_FRAME_INTRYBLOCK= 0x1000000,
      DBGPROP_ATTRIB_FRAME_INCATCHBLOCK= 0x2000000,
      DBGPROP_ATTRIB_FRAME_INFINALLYBLOCK= 0x4000000,
      DBGPROP_ATTRIB_VALUE_IS_RETURN_VALUE= 0x8000000
  };
  typedef DWORD DBGPROP_ATTRIB_FLAGS;
  
  enum tagDBGPROP_INFO_FLAgS
  {
      DBGPROP_INFO_NAME= 0x1,
      DBGPROP_INFO_TYPE= 0x2,
      DBGPROP_INFO_VALUE= 0x4,
      DBGPROP_INFO_FULLNAME= 0x20,
      DBGPROP_INFO_ATTRIBUTES= 0x8,
      DBGPROP_INFO_DEBUGPROP= 0x10,
      DBGPROP_INFO_BEAUTIFY= 0x2000000,
      DBGPROP_INFO_CALLTOSTRING= 0x4000000,
      DBGPROP_INFO_AUTOEXPAND= 0x800000
  };
  
  typedef DWORD DBGPROP_INFO_FLAGS;
  
  #define DBGPROP_INFO_STANDARD ((((DBGPROP_INFO_NAME | DBGPROP_INFO_TYPE) | DBGPROP_INFO_VALUE) | DBGPROP_INFO_ATTRIBUTES))
  
  #define DBGPROP_INFO_ALL ((((((DBGPROP_INFO_NAME | DBGPROP_INFO_TYPE ) | DBGPROP_INFO_VALUE) | DBGPROP_INFO_FULLNAME) | DBGPROP_INFO_ATTRIBUTES) | DBGPROP_INFO_DEBUGPROP))
  
  // _countof
  #if defined _M_X64 || defined _M_ARM || defined _M_ARM64
  #define _UNALIGNED __unaligned
  #else
  #define _UNALIGNED
  #endif
  
  #ifdef __cplusplus
  extern "C++"
  {
    template <typename _CountofType, size_t _SizeOfArray>
    char(*__countof_helper(_UNALIGNED _CountofType(&_Array)[_SizeOfArray]))[_SizeOfArray];
  
  #define __crt_countof(_Array) (sizeof(*__countof_helper(_Array)) + 0)
  }
  #else
  #define __crt_countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
  #endif
  
  #ifndef _countof
  #define _countof __crt_countof
  #endif
  // _countof
  
  #define ARRAYSIZE(A) _countof(A)
  
  //
  //  Singly linked list structure. Can be used as either a list head, or
  //  as link words.
  //
  typedef struct _SINGLE_LIST_ENTRY {
    struct _SINGLE_LIST_ENTRY *Next;
  } SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
  
  #if defined(TARGET_64)
  
  //
  // The type SINGLE_LIST_ENTRY is not suitable for use with SLISTs.  For
  // TARGET_64, an entry on an SLIST is required to be 16-byte aligned, while a
  // SINGLE_LIST_ENTRY structure has only 8 byte alignment.
  //
  // Therefore, all SLIST code should use the SLIST_ENTRY type instead of the
  // SINGLE_LIST_ENTRY type.
  //
  
  #pragma warning(push)
  #pragma warning(disable:4324)   // structure padded due to align()
  
  typedef struct DECLSPEC_ALIGN(16) _SLIST_ENTRY {
    struct _SLIST_ENTRY *Next;
  } SLIST_ENTRY, *PSLIST_ENTRY;
  
  #pragma warning(pop)
  
  #else // defined(TARGET_64)
  
  typedef struct _SINGLE_LIST_ENTRY SLIST_ENTRY, *PSLIST_ENTRY;
  
  #endif // defined(TARGET_64)
  
  #if defined(_AMD64_)
  
  typedef union DECLSPEC_ALIGN(16) _SLIST_HEADER {
    struct {  // original struct
      ULONGLONG Alignment;
      ULONGLONG Region;
    } DUMMYSTRUCTNAME;
    struct {  // x64 16-byte header
      ULONGLONG Depth : 16;
      ULONGLONG Sequence : 48;
      ULONGLONG Reserved : 4;
      ULONGLONG NextEntry : 60; // last 4 bits are always 0's
    } HeaderX64;
  } SLIST_HEADER, *PSLIST_HEADER;
  
  #elif defined(_X86_)
  
  typedef union _SLIST_HEADER {
    ULONGLONG Alignment;
    struct {
      SLIST_ENTRY Next;
      WORD   Depth;
      WORD   CpuId;
    } DUMMYSTRUCTNAME;
  } SLIST_HEADER, *PSLIST_HEADER;
  
  #elif defined(_ARM_)
  
  typedef union _SLIST_HEADER {
    ULONGLONG Alignment;
    struct {
      SLIST_ENTRY Next;
      WORD   Depth;
      WORD   Reserved;
    } DUMMYSTRUCTNAME;
  } SLIST_HEADER, *PSLIST_HEADER;
  
  #endif
  
  PALIMPORT VOID PALAPI InitializeSListHead(IN OUT PSLIST_HEADER ListHead);
  PALIMPORT PSLIST_ENTRY PALAPI InterlockedPushEntrySList(IN OUT PSLIST_HEADER ListHead, IN OUT PSLIST_ENTRY  ListEntry);
  PALIMPORT PSLIST_ENTRY PALAPI InterlockedPopEntrySList(IN OUT PSLIST_HEADER ListHead);
  
  
  template <class T>
  inline T InterlockedExchangeAdd(
      IN OUT T volatile *Addend,
      IN T Value)
  {
      return __sync_fetch_and_add(Addend, Value);
  }
  
  template <class T>
  inline T InterlockedExchangeSubtract(
      IN OUT T volatile *Addend,
      IN T Value)
  {
      return __sync_fetch_and_sub(Addend, Value);
  }
  
  template <class T>
  inline T InterlockedIncrement(
      IN OUT T volatile *Addend)
  {
      return __sync_add_and_fetch(Addend, T(1));
  }
  
  template <class T>
  inline T InterlockedDecrement(
      IN OUT T volatile *Addend)
  {
      return __sync_sub_and_fetch(Addend, T(1));
  }
  
  inline __int64 _abs64(__int64 n)
  {
      return n < 0 ? -n : n;
  }
  
  int GetCurrentThreadStackLimits(ULONG_PTR* lowLimit, ULONG_PTR* highLimit);
  bool IsAddressOnStack(ULONG_PTR address);
  
  errno_t rand_s(unsigned int* randomValue);
  
  inline char16* wmemset(char16* wcs, char16 wc, size_t n)
  {
      while (n)
      {
          wcs[--n] = wc;
      }
      return wcs;
  }
  
  inline errno_t wmemcpy_s(char16* dest, size_t destSize, const char16* src, size_t count)
  {
      return memcpy_s(dest, sizeof(char16) * destSize, src, sizeof(char16) * count);
  }
  
  inline int _wunlink(const char16* filename)
  {
      // WARN: does not set errno when fail
      return DeleteFile(filename) ? 0 : -1;
  }
  
  template <size_t size>
  inline errno_t _wcserror_s(char16 (&buffer)[size], int errnum)
  {
      const char* str = strerror(errnum);
      // WARN: does not return detail errno when fail
      return MultiByteToWideChar(CP_ACP, 0, str, -1, buffer, size) ? 0 : -1;
  }
  
  #define midl_user_allocate(size) \
      HeapAlloc(GetProcessHeap(), 0, (size))
  #define midl_user_free(ptr) \
      if (ptr != NULL) { HeapFree(GetProcessHeap(), NULL, ptr); }
  
  DWORD __cdecl CharLowerBuffW(const char16* lpsz, DWORD  cchLength);
  DWORD __cdecl CharUpperBuffW(const char16* lpsz, DWORD  cchLength);
  
  #define MAXUINT32   ((uint32_t)~((uint32_t)0))
  #define MAXINT32    ((int32_t)(MAXUINT32 >> 1))
  #define BYTE_MAX    0xff
  #define USHORT_MAX  0xffff
  
  #ifdef UNICODE
  #define StringCchPrintf  StringCchPrintfW
  #endif
  
  #endif // _WIN32
  
  
  // Use intsafe.h for internal builds (currently missing some files with stdint.h)
  #if defined(_WIN32) && defined(NTBUILD)
  #define ENABLE_INTSAFE_SIGNED_FUNCTIONS 1
  #include <intsafe.h>
  #else
  #include <stdint.h>
  #endif
  
  // `typename QualifiedName` declarations outside of template code not supported before MSVC 2015 update 1
  #if defined(_MSC_VER) && _MSC_VER < 1910 && !defined(__clang__)
  #define _TYPENAME
  #else
  #define _TYPENAME typename
  #endif
  
  #if (defined(_MSC_VER) && _MSC_VER < 1900) || defined(NTBUILD)
  // "noexcept" not supported before VS 2015
  #define _NOEXCEPT_ throw()
  #else
  #define _NOEXCEPT_ noexcept
  #endif
  
  #ifdef _MSC_VER
  extern "C" PVOID _ReturnAddress(VOID);
  #pragma intrinsic(_ReturnAddress)
  extern "C" void * _AddressOfReturnAddress(void);
  #elif defined(__GNUC__) || defined(__clang__)
  #define _ReturnAddress() __builtin_return_address(0)
  #if !__has_builtin(_AddressOfReturnAddress)
  __forceinline void * _AddressOfReturnAddress()
  {
      return (void*)((char*) __builtin_frame_address(0) + sizeof(void*));
  }
  #endif
  #else
  #error _AddressOfReturnAddress and _ReturnAddress not defined for this platform
  #endif
  
  // Define strsafe related types and defines for non-VC++ compilers
  #ifndef _MSC_VER
  // xplat-todo: figure out why strsafe.h includes stdio etc
  // which prevents me from directly including PAL's strsafe.h
  #ifdef __cplusplus
  #define _STRSAFE_EXTERN_C    extern "C"
  #else
  #define _STRSAFE_EXTERN_C    extern
  #endif
  
  // If you do not want to use these functions inline (and instead want to link w/ strsafe.lib), then
  // #define STRSAFE_LIB before including this header file.
  #if defined(STRSAFE_LIB)
  #define STRSAFEAPI  _STRSAFE_EXTERN_C HRESULT __stdcall
  #pragma comment(lib, "strsafe.lib")
  #elif defined(STRSAFE_LIB_IMPL)
  #define STRSAFEAPI  _STRSAFE_EXTERN_C HRESULT __stdcall
  #else
  #define STRSAFEAPI  inline HRESULT __stdcall
  #define STRSAFE_INLINE
  #endif
  
  STRSAFEAPI StringCchPrintfW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszFormat, ...);
  STRSAFEAPI StringVPrintfWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszFormat, va_list argList);
  
  #define STRSAFE_MAX_CCH  2147483647 // max # of characters we support (same as INT_MAX)
  
  // STRSAFE error return codes
  //
  #define STRSAFE_E_INSUFFICIENT_BUFFER       ((HRESULT)0x8007007AL)  // 0x7A = 122L = ERROR_INSUFFICIENT_BUFFER
  #define STRSAFE_E_INVALID_PARAMETER         ((HRESULT)0x80070057L)  // 0x57 =  87L = ERROR_INVALID_PARAMETER
  #define STRSAFE_E_END_OF_FILE               ((HRESULT)0x80070026L)  // 0x26 =  38L = ERROR_HANDLE_EOF
  #endif
  
  // Provide the definitions for non-windows platforms
  #ifndef _MSC_VER
  STRSAFEAPI StringVPrintfWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszFormat, va_list argList)
  {
      HRESULT hr = S_OK;
  
      if (cchDest == 0)
      {
          // can not null terminate a zero-byte dest buffer
          hr = STRSAFE_E_INVALID_PARAMETER;
      }
      else
      {
          int iRet;
          size_t cchMax;
  
          // leave the last space for the null terminator
          cchMax = cchDest - 1;
  
          iRet = _vsnwprintf(pszDest, cchMax, pszFormat, argList);
          // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax));
  
          if ((iRet < 0) || (((size_t)iRet) > cchMax))
          {
              // need to null terminate the string
              pszDest += cchMax;
              *pszDest = _u('\0');
  
              // we have truncated pszDest
              hr = STRSAFE_E_INSUFFICIENT_BUFFER;
          }
          else if (((size_t)iRet) == cchMax)
          {
              // need to null terminate the string
              pszDest += cchMax;
              *pszDest = _u('\0');
          }
      }
  
      return hr;
  }
  
  STRSAFEAPI StringCchPrintfW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszFormat, ...)
  {
      HRESULT hr;
  
      if (cchDest > STRSAFE_MAX_CCH)
      {
          hr = STRSAFE_E_INVALID_PARAMETER;
      }
      else
      {
          va_list argList;
  
          va_start(argList, pszFormat);
  
          hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList);
  
          va_end(argList);
      }
  
      return hr;
  }
  #endif
  
  #ifndef _WIN32
  __inline
  HRESULT ULongMult(ULONG ulMultiplicand, ULONG ulMultiplier, ULONG* pulResult);
  #endif
  
  /* **** WARNING : finallyFunc is not allowed to raise exception *****
   * **** DO NOT ADD stack probe or memory allocations within the finallyFunc ****
   */
  template <class TryFunc, class FinallyFunc>
  void TryFinally(const TryFunc& tryFunc, const FinallyFunc& finallyFunc)
  {
      class FinallyObject
      {
      public:
          FinallyObject(const FinallyFunc& finallyFunc) : finallyFunc(finallyFunc), abnormalTermination(true) {}
          ~FinallyObject() { finallyFunc(abnormalTermination); }
  
          void SetHasNoAbnormalTermination() { abnormalTermination = false; }
      private:
          const FinallyFunc& finallyFunc;
          bool abnormalTermination;
      } finallyObject(finallyFunc);
  
      tryFunc();
      finallyObject.SetHasNoAbnormalTermination();
  }
  
  #ifdef DISABLE_SEH
  #define __TRY_FINALLY_BEGIN TryFinally([&]()
  #define __FINALLY           , [&](bool /* hasException */)
  #define __TRY_FINALLY_END   );
  #else
  #define __TRY_FINALLY_BEGIN __try
  #define __FINALLY   __finally
  #define __TRY_FINALLY_END
  #endif
  
  namespace PlatformAgnostic
  {
      __forceinline unsigned char _BitTestAndSet(LONG *_BitBase, int _BitPos)
      {
  #if defined(__clang__) && !defined(_ARM_)
          // Clang doesn't expand _bittestandset intrinic to bts, and it's implemention also doesn't work for _BitPos >= 32
          unsigned char retval = 0;
          asm(
              "bts %[_BitPos], %[_BitBase]\n\t"
              "setc %b[retval]\n\t"
              : [_BitBase] "+m" (*_BitBase), [retval] "+rm" (retval)
              : [_BitPos] "ri" (_BitPos)
              : "cc" // clobber condition code
          );
          return retval;
  #else
          return _bittestandset(_BitBase, _BitPos);
  #endif
      }
  
      __forceinline unsigned char _BitTest(LONG *_BitBase, int _BitPos)
      {
  #if defined(__clang__) && !defined(_ARM_)
          // Clang doesn't expand _bittest intrinic to bt, and it's implemention also doesn't work for _BitPos >= 32
          unsigned char retval;
          asm(
              "bt %[_BitPos], %[_BitBase]\n\t"
              "setc %b[retval]\n\t"
              : [retval] "+rm" (retval)
              : [_BitPos] "ri" (_BitPos), [_BitBase] "m" (*_BitBase)
              : "cc" // clobber condition code
          );
          return retval;
  #else
          return _bittest(_BitBase, _BitPos);
  #endif
      }
  
      __forceinline unsigned char _InterlockedBitTestAndSet(volatile LONG *_BitBase, int _BitPos)
      {
  #if defined(__clang__) && !defined(_ARM_)
          // Clang doesn't expand _interlockedbittestandset intrinic to lock bts, and it's implemention also doesn't work for _BitPos >= 32
          unsigned char retval;
          asm(
              "lock bts %[_BitPos], %[_BitBase]\n\t"
              "setc %b[retval]\n\t"
              : [_BitBase] "+m" (*_BitBase), [retval] "+rm" (retval)
              : [_BitPos] "ri" (_BitPos)
              : "cc" // clobber condition code
          );
          return retval;
  #else
          return _interlockedbittestandset(_BitBase, _BitPos);
  #endif
      }
  
      __forceinline unsigned char _InterlockedBitTestAndReset(volatile LONG *_BitBase, int _BitPos)
      {
  #if defined(__clang__) && !defined(_ARM_)
          // Clang doesn't expand _interlockedbittestandset intrinic to lock btr, and it's implemention also doesn't work for _BitPos >= 32
          unsigned char retval;
          asm(
              "lock btr %[_BitPos], %[_BitBase]\n\t"
              "setc %b[retval]\n\t"
              : [_BitBase] "+m" (*_BitBase), [retval] "+rm" (retval)
              : [_BitPos] "ri" (_BitPos)
              : "cc" // clobber condition code
          );
          return retval;
  #elif !defined(__ANDROID__)
          return _interlockedbittestandreset(_BitBase, (long)_BitPos);
  #else
          // xplat-todo: Implement _interlockedbittestandreset for Android
          abort();
  #endif
      }
  };
  
  #include "PlatformAgnostic/DateTime.h"
  #include "PlatformAgnostic/Numbers.h"
  #include "PlatformAgnostic/Arrays.h"
  #include "PlatformAgnostic/SystemInfo.h"
  #include "PlatformAgnostic/Thread.h"
  #include "PlatformAgnostic/AssemblyCommon.h"
  #include "PlatformAgnostic/Debugger.h"
  