/*** Copyright (c) Meta Platforms, Inc. and affiliates.** This source code is licensed under the MIT license found in the* LICENSE file in the root directory of this source tree.*/#ifndef incl_HPHP_PORTABILITY_H_
#define incl_HPHP_PORTABILITY_H_
// From folly/Likely.h#if defined(__GNUC__) && __GNUC__ >= 4
#define LIKELY(x) (__builtin_expect((x), 1))
#define UNLIKELY(x) (__builtin_expect((x), 0))
#else#define LIKELY(x) (x)
#define UNLIKELY(x) (x)
#endif///////////////////////////////////////////////////////////////////////** Various macros to make certain things conditional on either* compiler or architecture.** Currently we don't *really* compile on anything other than gcc or* sometimes clang, and there are some parts of the code using* __attribute__ stuff directly, but some things go through these* macros to make it maybe easier to change later.*///////////////////////////////////////////////////////////////////////// TODO: does clang define __GNUC__ ?#ifndef __GNUC__
# define __attribute__(x)
#endif//////////////////////////////////////////////////////////////////////#ifdef ATTRIBUTE_UNUSED
# undef ATTRIBUTE_UNUSED
#endif#ifdef ATTRIBUTE_NORETURN
# undef ATTRIBUTE_NORETURN
#endif#ifdef ATTRIBUTE_PRINTF
# undef ATTRIBUTE_PRINTF
#endif#ifdef ATTRIBUTE_PRINTF_STRING
# undef ATTRIBUTE_PRINTF_STRING
#endif#define ATTRIBUTE_PRINTF_STRING FOLLY_PRINTF_FORMAT
#ifdef _MSC_VER
#define ATTRIBUTE_NORETURN __declspec(noreturn)
#define ATTRIBUTE_PRINTF(a1, a2)
#ifndef __thread
# define __thread __declspec(thread)
#endif#define ATTRIBUTE_UNUSED
#define ALWAYS_INLINE __forceinline
#define EXTERNALLY_VISIBLE
#define FLATTEN
#define NEVER_INLINE __declspec(noinline)
#define UNUSED
#else#define ATTRIBUTE_NORETURN __attribute__((__noreturn__))
#define ATTRIBUTE_PRINTF(a1, a2) \
__attribute__((__format__ (__printf__, a1, a2)))
#define ATTRIBUTE_UNUSED __attribute__((__unused__))
#define ALWAYS_INLINE inline __attribute__((__always_inline__))
#define EXTERNALLY_VISIBLE __attribute__((__externally_visible__))
#define FLATTEN __attribute__((__flatten__))
#define NEVER_INLINE __attribute__((__noinline__))
#define UNUSED __attribute__((__unused__))
#endif#ifdef DEBUG
# define DEBUG_ONLY /* nop */
#else# define DEBUG_ONLY UNUSED
#endif/** We need to keep some unreferenced functions from being removed by* the linker. There is no compile time mechanism for doing this, but* by putting them in the same section as some other, referenced function* in the same file, we can keep them around.** So this macro should be used to mark at least one function that is* referenced, and other functions that are not referenced in the same* file.** Note: this may not work properly with LTO. We'll revisit when/if we* move to it.*/#ifndef __APPLE__
# define KEEP_SECTION \
__attribute__((__section__(".text.keep")))
#else# define KEEP_SECTION \
__attribute__((__section__(".text,.text.keep")))
#endif#if defined(__APPLE__)
// OS X has a macro "isset" defined in this header. Force the include so we can// make sure the macro gets undef'd. (I think this also applies to BSD, but we// can cross that road when we come to it.)# include <sys/param.h>
# ifdef isset
# undef isset
# endif#endif//////////////////////////////////////////////////////////////////////#if defined(__x86_64__)
# if defined(__clang__)
# define DECLARE_FRAME_POINTER(fp) \
ActRec* fp; \asm volatile("mov %%rbp, %0" : "=r" (fp) ::)
# else# define DECLARE_FRAME_POINTER(fp) register ActRec* fp asm("rbp");
# endif#elif defined(_M_X64)
// TODO: FIXME! Without this implemented properly, the JIT// will fail "pretty spectacularly".# define DECLARE_FRAME_POINTER(fp) \
always_assert(false); \
register ActRec* fp = nullptr;
#elif defined(__AARCH64EL__)
# if defined(__clang__)
# error Clang implementation not done for ARM
# endif# define DECLARE_FRAME_POINTER(fp) register ActRec* fp asm("x29");
#elif defined(__powerpc64__)
# if defined(__clang__)
# error Clang implementation not done for PPC64
# endif# define DECLARE_FRAME_POINTER(fp) register ActRec* fp = (ActRec*) __builtin_frame_address(0);
#else# error What are the stack and frame pointers called on your architecture?
#endif//////////////////////////////////////////////////////////////////////// We reserve the exit status 127 to signal a failure in the// interpreter. 127 is a valid exit code on all reasonable// architectures: POSIX requires at least 8 unsigned bits and// Windows 32 signed bits.#define HPHP_EXIT_FAILURE 127
//////////////////////////////////////////////////////////////////////#if FACEBOOK
// Linking in libbfd is a gigantic PITA. If you want this yourself in a non-FB// build, feel free to define HAVE_LIBBFD and specify the right options to link// in libbfd.a in the extra C++ options.#define HAVE_LIBBFD 1
#endif#ifndef PACKAGE
// The value doesn't matter, but it must be defined before you include// bfd.h#define PACKAGE "hhvm"
#endif//////////////////////////////////////////////////////////////////////#endif