/* * Copyright (c) 2009-2021, Google LLC * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Google LLC nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This is where we define macros used across upb. * * All of these macros are undef'd in port_undef.inc to avoid leaking them to * users. * * The correct usage is: * * #include "upb/foobar.h" * #include "upb/baz.h" * * // MUST be last included header. * #include "upb/port_def.inc" * * // Code for this file. * // <...> * * // Can be omitted for .c files, required for .h. * #include "upb/port_undef.inc" * * This file is private and must not be included by users! */ #if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ (defined(__cplusplus) && __cplusplus >= 201103L) || \ (defined(_MSC_VER) && _MSC_VER >= 1900)) #error upb requires C99 or C++11 or MSVC >= 2015. #endif #include <stdint.h> #include <stddef.h> #if UINTPTR_MAX == 0xffffffff #define UPB_SIZE … #else #define UPB_SIZE … #endif /* If we always read/write as a consistent type to each address, this shouldn't * violate aliasing. */ #define UPB_PTR_AT … #define UPB_READ_ONEOF … #define UPB_WRITE_ONEOF … #define UPB_MAPTYPE_STRING … /* UPB_INLINE: inline if possible, emit standalone code if required. */ #ifdef __cplusplus #define UPB_INLINE … #elif defined (__GNUC__) || defined(__clang__) #define UPB_INLINE … #else #define UPB_INLINE … #endif #define UPB_MALLOC_ALIGN … #define UPB_ALIGN_UP … #define UPB_ALIGN_DOWN … #define UPB_ALIGN_MALLOC … #define UPB_ALIGN_OF … /* Hints to the compiler about likely/unlikely branches. */ #if defined (__GNUC__) || defined(__clang__) #define UPB_LIKELY … #define UPB_UNLIKELY … #else #define UPB_LIKELY … #define UPB_UNLIKELY … #endif /* Macros for function attributes on compilers that support them. */ #ifdef __GNUC__ #define UPB_FORCEINLINE … #define UPB_NOINLINE … #define UPB_NORETURN … #define UPB_PRINTF … #elif defined(_MSC_VER) #define UPB_NOINLINE #define UPB_FORCEINLINE #define UPB_NORETURN … #define UPB_PRINTF … #else /* !defined(__GNUC__) */ #define UPB_FORCEINLINE #define UPB_NOINLINE #define UPB_NORETURN #define UPB_PRINTF … #endif #define UPB_MAX … #define UPB_MIN … #define UPB_UNUSED … /* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true. */ #ifdef NDEBUG #ifdef __GNUC__ #define UPB_ASSUME … #elif defined _MSC_VER #define UPB_ASSUME … #else #define UPB_ASSUME … #endif #else #define UPB_ASSUME … #endif /* UPB_ASSERT(): in release mode, we use the expression without letting it be * evaluated. This prevents "unused variable" warnings. */ #ifdef NDEBUG #define UPB_ASSERT … #else #define UPB_ASSERT … #endif #if defined(__GNUC__) || defined(__clang__) #define UPB_UNREACHABLE … #else #define UPB_UNREACHABLE … #endif /* UPB_SETJMP() / UPB_LONGJMP(): avoid setting/restoring signal mask. */ #ifdef __APPLE__ #define UPB_SETJMP … #define UPB_LONGJMP … #else #define UPB_SETJMP … #define UPB_LONGJMP … #endif /* UPB_PTRADD(ptr, ofs): add pointer while avoiding "NULL + 0" UB */ #define UPB_PTRADD … /* Configure whether fasttable is switched on or not. *************************/ #ifdef __has_attribute #define UPB_HAS_ATTRIBUTE … #else #define UPB_HAS_ATTRIBUTE … #endif #if UPB_HAS_ATTRIBUTE(musttail) #define UPB_MUSTTAIL … #else #define UPB_MUSTTAIL #endif #undef UPB_HAS_ATTRIBUTE /* This check is not fully robust: it does not require that we have "musttail" * support available. We need tail calls to avoid consuming arbitrary amounts * of stack space. * * GCC/Clang can mostly be trusted to generate tail calls as long as * optimization is enabled, but, debug builds will not generate tail calls * unless "musttail" is available. * * We should probably either: * 1. require that the compiler supports musttail. * 2. add some fallback code for when musttail isn't available (ie. return * instead of tail calling). This is safe and portable, but this comes at * a CPU cost. */ #if (defined(__x86_64__) || defined(__aarch64__)) && defined(__GNUC__) #define UPB_FASTTABLE_SUPPORTED … #else #define UPB_FASTTABLE_SUPPORTED … #endif /* define UPB_ENABLE_FASTTABLE to force fast table support. * This is useful when we want to ensure we are really getting fasttable, * for example for testing or benchmarking. */ #if defined(UPB_ENABLE_FASTTABLE) #if !UPB_FASTTABLE_SUPPORTED #error fasttable is x86-64/ARM64 only and requires GCC or Clang. #endif #define UPB_FASTTABLE … /* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible. * This is useful for releasing code that might be used on multiple platforms, * for example the PHP or Ruby C extensions. */ #elif defined(UPB_TRY_ENABLE_FASTTABLE) #define UPB_FASTTABLE … #else #define UPB_FASTTABLE … #endif /* UPB_FASTTABLE_INIT() allows protos compiled for fasttable to gracefully * degrade to non-fasttable if we are using UPB_TRY_ENABLE_FASTTABLE. */ #if !UPB_FASTTABLE && defined(UPB_TRY_ENABLE_FASTTABLE) #define UPB_FASTTABLE_INIT … #else #define UPB_FASTTABLE_INIT … #endif #undef UPB_FASTTABLE_SUPPORTED /* ASAN poisoning (for arena) *************************************************/ #if defined(__SANITIZE_ADDRESS__) #define UPB_ASAN … #ifdef __cplusplus extern "C" { #endif void __asan_poison_memory_region(void const volatile *addr, size_t size); void __asan_unpoison_memory_region(void const volatile *addr, size_t size); #ifdef __cplusplus } /* extern "C" */ #endif #define UPB_POISON_MEMORY_REGION … #define UPB_UNPOISON_MEMORY_REGION … #else #define UPB_ASAN … #define UPB_POISON_MEMORY_REGION … #define UPB_UNPOISON_MEMORY_REGION … #endif /* Disable proto2 arena behavior (TEMPORARY) **********************************/ #ifdef UPB_DISABLE_PROTO2_ENUM_CHECKING #define UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 … #else #define UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 … #endif