Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/upb/port/def.inc is written in an unsupported language. File is not indexed.

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2023 Google LLC.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 /*
0009  * This is where we define internal portability macros used across upb.
0010  *
0011  * All of these macros are undef'd in undef.inc to avoid leaking them to users.
0012  *
0013  * The correct usage is:
0014  *
0015  *   #include "upb/foobar.h"
0016  *   #include "upb/baz.h"
0017  *
0018  *   // MUST be last included header.
0019  *   #include "upb/port/def.inc"
0020  *
0021  *   // Code for this file.
0022  *   // <...>
0023  *
0024  *   // Can be omitted for .c files, required for .h.
0025  *   #include "upb/port/undef.inc"
0026  *
0027  * This file is private and must not be included by users!
0028  */
0029 
0030 #if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
0031       (defined(__cplusplus) && __cplusplus >= 201402L) ||           \
0032       (defined(_MSC_VER) && _MSC_VER >= 1900))
0033 #error upb requires C99 or C++14 or MSVC >= 2015.
0034 #endif
0035 
0036 // Portable check for GCC minimum version:
0037 // https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
0038 #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
0039 #define UPB_GNUC_MIN(x, y) \
0040   (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y))
0041 #else
0042 #define UPB_GNUC_MIN(x, y) 0
0043 #endif
0044 
0045 #include <assert.h>
0046 #include <setjmp.h>
0047 #include <stdbool.h>
0048 #include <stdint.h>
0049 #include <stdio.h>
0050 
0051 #ifndef UINTPTR_MAX
0052 Error, UINTPTR_MAX is undefined
0053 #endif
0054 
0055 #if UINTPTR_MAX == 0xffffffff
0056 #define UPB_SIZE(size32, size64) size32
0057 #else
0058 #define UPB_SIZE(size32, size64) size64
0059 #endif
0060 
0061 /* If we always read/write as a consistent type to each address, this shouldn't
0062  * violate aliasing.
0063  */
0064 #define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs)))
0065 
0066 #define UPB_MAPTYPE_STRING 0
0067 
0068 // UPB_EXPORT: always generate a public symbol.
0069 #if defined(__GNUC__) || defined(__clang__)
0070 #define UPB_EXPORT __attribute__((visibility("default"))) __attribute__((used))
0071 #else
0072 #define UPB_EXPORT
0073 #endif
0074 
0075 // UPB_INLINE: inline if possible, emit standalone code if required.
0076 #ifdef __cplusplus
0077 #define UPB_INLINE inline
0078 #elif defined (__GNUC__) || defined(__clang__)
0079 #define UPB_INLINE static __inline__
0080 #else
0081 #define UPB_INLINE static
0082 #endif
0083 
0084 #ifdef UPB_BUILD_API
0085 #define UPB_API UPB_EXPORT
0086 #define UPB_API_INLINE UPB_EXPORT
0087 #else
0088 #define UPB_API
0089 #define UPB_API_INLINE UPB_INLINE
0090 #endif
0091 
0092 #define UPB_MALLOC_ALIGN 8
0093 #define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align))
0094 #define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align))
0095 #define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, UPB_MALLOC_ALIGN)
0096 #ifdef __clang__
0097 #define UPB_ALIGN_OF(type) _Alignof(type)
0098 #else
0099 #define UPB_ALIGN_OF(type) offsetof (struct { char c; type member; }, member)
0100 #endif
0101 
0102 #ifdef _MSC_VER
0103 // Some versions of our Windows compiler don't support the C11 syntax.
0104 #define UPB_ALIGN_AS(x) __declspec(align(x))
0105 #else
0106 #define UPB_ALIGN_AS(x) _Alignas(x)
0107 #endif
0108 
0109 // Hints to the compiler about likely/unlikely branches.
0110 #if defined (__GNUC__) || defined(__clang__)
0111 #define UPB_LIKELY(x) __builtin_expect((bool)(x), 1)
0112 #define UPB_UNLIKELY(x) __builtin_expect((bool)(x), 0)
0113 #else
0114 #define UPB_LIKELY(x) (x)
0115 #define UPB_UNLIKELY(x) (x)
0116 #endif
0117 
0118 // Macros for function attributes on compilers that support them.
0119 #ifdef __GNUC__
0120 #define UPB_FORCEINLINE __inline__ __attribute__((always_inline)) static
0121 #define UPB_NOINLINE __attribute__((noinline))
0122 #define UPB_NORETURN __attribute__((__noreturn__))
0123 #define UPB_PRINTF(str, first_vararg) __attribute__((format (printf, str, first_vararg)))
0124 #elif defined(_MSC_VER)
0125 #define UPB_NOINLINE
0126 #define UPB_FORCEINLINE static
0127 #define UPB_NORETURN __declspec(noreturn)
0128 #define UPB_PRINTF(str, first_vararg)
0129 #else  /* !defined(__GNUC__) */
0130 #define UPB_FORCEINLINE static
0131 #define UPB_NOINLINE
0132 #define UPB_NORETURN
0133 #define UPB_PRINTF(str, first_vararg)
0134 #endif
0135 
0136 #define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
0137 #define UPB_MIN(x, y) ((x) < (y) ? (x) : (y))
0138 
0139 #define UPB_UNUSED(var) (void)var
0140 
0141 // UPB_ASSUME(): in release mode, we tell the compiler to assume this is true.
0142 #ifdef NDEBUG
0143 #ifdef __GNUC__
0144 #define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable()
0145 #elif defined _MSC_VER
0146 #define UPB_ASSUME(expr) if (!(expr)) __assume(0)
0147 #else
0148 #define UPB_ASSUME(expr) do {} while (false && (expr))
0149 #endif
0150 #else
0151 #define UPB_ASSUME(expr) assert(expr)
0152 #endif
0153 
0154 /* UPB_ASSERT(): in release mode, we use the expression without letting it be
0155  * evaluated.  This prevents "unused variable" warnings. */
0156 #ifdef NDEBUG
0157 #define UPB_ASSERT(expr) do {} while (false && (expr))
0158 #else
0159 #define UPB_ASSERT(expr) assert(expr)
0160 #endif
0161 
0162 #if defined(__GNUC__) || defined(__clang__)
0163 #define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0)
0164 #elif defined(_MSC_VER)
0165 #define UPB_UNREACHABLE() \
0166   do {                    \
0167     assert(0);            \
0168     __assume(0);          \
0169   } while (0)
0170 #else
0171 #define UPB_UNREACHABLE() do { assert(0); } while(0)
0172 #endif
0173 
0174 /* UPB_SETJMP() / UPB_LONGJMP(): avoid setting/restoring signal mask. */
0175 #ifdef __APPLE__
0176 #define UPB_SETJMP(buf) _setjmp(buf)
0177 #define UPB_LONGJMP(buf, val) _longjmp(buf, val)
0178 #else
0179 #define UPB_SETJMP(buf) setjmp(buf)
0180 #define UPB_LONGJMP(buf, val) longjmp(buf, val)
0181 #endif
0182 
0183 #ifdef __GNUC__
0184 #define UPB_USE_C11_ATOMICS
0185 #define UPB_ATOMIC(T) _Atomic(T)
0186 #else
0187 #define UPB_ATOMIC(T) T
0188 #endif
0189 
0190 /* UPB_PTRADD(ptr, ofs): add pointer while avoiding "NULL + 0" UB */
0191 #define UPB_PTRADD(ptr, ofs) ((ofs) ? (ptr) + (ofs) : (ptr))
0192 
0193 #define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only
0194 
0195 #ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY
0196 #define UPB_ONLYBITS(x) x
0197 #else
0198 #define UPB_ONLYBITS(x) UPB_PRIVATE(x)
0199 #endif
0200 
0201 /* Configure whether fasttable is switched on or not. *************************/
0202 
0203 #ifdef __has_attribute
0204 #define UPB_HAS_ATTRIBUTE(x) __has_attribute(x)
0205 #else
0206 #define UPB_HAS_ATTRIBUTE(x) 0
0207 #endif
0208 
0209 #if UPB_HAS_ATTRIBUTE(musttail)
0210 #define UPB_MUSTTAIL __attribute__((musttail))
0211 #else
0212 #define UPB_MUSTTAIL
0213 #endif
0214 
0215 #undef UPB_HAS_ATTRIBUTE
0216 
0217 /* This check is not fully robust: it does not require that we have "musttail"
0218  * support available. We need tail calls to avoid consuming arbitrary amounts
0219  * of stack space.
0220  *
0221  * GCC/Clang can mostly be trusted to generate tail calls as long as
0222  * optimization is enabled, but, debug builds will not generate tail calls
0223  * unless "musttail" is available.
0224  *
0225  * We should probably either:
0226  *   1. require that the compiler supports musttail.
0227  *   2. add some fallback code for when musttail isn't available (ie. return
0228  *      instead of tail calling). This is safe and portable, but this comes at
0229  *      a CPU cost.
0230  */
0231 #if (defined(__x86_64__) || defined(__aarch64__)) && defined(__GNUC__)
0232 #define UPB_FASTTABLE_SUPPORTED 1
0233 #else
0234 #define UPB_FASTTABLE_SUPPORTED 0
0235 #endif
0236 
0237 /* define UPB_ENABLE_FASTTABLE to force fast table support.
0238  * This is useful when we want to ensure we are really getting fasttable,
0239  * for example for testing or benchmarking. */
0240 #if defined(UPB_ENABLE_FASTTABLE)
0241 #if !UPB_FASTTABLE_SUPPORTED
0242 #error fasttable is x86-64/ARM64 only and requires GCC or Clang.
0243 #endif
0244 #define UPB_FASTTABLE 1
0245 /* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible.
0246  * This is useful for releasing code that might be used on multiple platforms,
0247  * for example the PHP or Ruby C extensions. */
0248 #elif defined(UPB_TRY_ENABLE_FASTTABLE)
0249 #define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED
0250 #else
0251 #define UPB_FASTTABLE 0
0252 #endif
0253 
0254 /* UPB_FASTTABLE_INIT() allows protos compiled for fasttable to gracefully
0255  * degrade to non-fasttable if the runtime or platform do not support it. */
0256 #if !UPB_FASTTABLE
0257 #define UPB_FASTTABLE_INIT(...)
0258 #define UPB_FASTTABLE_MASK(mask) -1
0259 #else
0260 #define UPB_FASTTABLE_INIT(...) __VA_ARGS__
0261 #define UPB_FASTTABLE_MASK(mask) mask
0262 #endif
0263 
0264 #undef UPB_FASTTABLE_SUPPORTED
0265 
0266 /* ASAN poisoning (for arena).
0267  * If using UPB from an interpreted language like Ruby, a build of the
0268  * interpreter compiled with ASAN enabled must be used in order to get sane and
0269  * expected behavior.
0270  */
0271 
0272 /* Due to preprocessor limitations, the conditional logic for setting
0273  * UPN_CLANG_ASAN below cannot be consolidated into a portable one-liner.
0274  * See https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html.
0275  */
0276 #if defined(__has_feature)
0277 #if __has_feature(address_sanitizer)
0278 #define UPB_CLANG_ASAN 1
0279 #else
0280 #define UPB_CLANG_ASAN 0
0281 #endif
0282 #else
0283 #define UPB_CLANG_ASAN 0
0284 #endif
0285 
0286 #if defined(__SANITIZE_ADDRESS__) || UPB_CLANG_ASAN
0287 #define UPB_ASAN 1
0288 #define UPB_ASAN_GUARD_SIZE 32
0289 #ifdef __cplusplus
0290     extern "C" {
0291 #endif
0292 void __asan_poison_memory_region(void const volatile *addr, size_t size);
0293 void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
0294 #ifdef __cplusplus
0295 }  /* extern "C" */
0296 #endif
0297 #define UPB_POISON_MEMORY_REGION(addr, size) \
0298   __asan_poison_memory_region((addr), (size))
0299 #define UPB_UNPOISON_MEMORY_REGION(addr, size) \
0300   __asan_unpoison_memory_region((addr), (size))
0301 #else
0302 #define UPB_ASAN 0
0303 #define UPB_ASAN_GUARD_SIZE 0
0304 #define UPB_POISON_MEMORY_REGION(addr, size) \
0305   ((void)(addr), (void)(size))
0306 #define UPB_UNPOISON_MEMORY_REGION(addr, size) \
0307   ((void)(addr), (void)(size))
0308 #endif
0309 
0310 /* Disable proto2 arena behavior (TEMPORARY) **********************************/
0311 
0312 #ifdef UPB_DISABLE_CLOSED_ENUM_CHECKING
0313 #define UPB_TREAT_CLOSED_ENUMS_LIKE_OPEN 1
0314 #else
0315 #define UPB_TREAT_CLOSED_ENUMS_LIKE_OPEN 0
0316 #endif
0317 
0318 #if defined(__cplusplus)
0319 #if defined(__clang__) || UPB_GNUC_MIN(6, 0)
0320 // https://gcc.gnu.org/gcc-6/changes.html
0321 #if __cplusplus >= 201402L
0322 #define UPB_DEPRECATED [[deprecated]]
0323 #else
0324 #define UPB_DEPRECATED __attribute__((deprecated))
0325 #endif
0326 #else
0327 #define UPB_DEPRECATED
0328 #endif
0329 #else
0330 #define UPB_DEPRECATED
0331 #endif
0332 
0333 // begin:google_only
0334 // #define UPB_IS_GOOGLE3
0335 // end:google_only
0336 
0337 #if defined(UPB_IS_GOOGLE3) && !defined(UPB_BOOTSTRAP_STAGE0)
0338 #define UPB_DESC(sym) proto2_##sym
0339 #define UPB_DESC_MINITABLE(sym) &proto2__##sym##_msg_init
0340 #elif defined(UPB_BOOTSTRAP_STAGE0)
0341 #define UPB_DESC(sym) google_protobuf_##sym
0342 #define UPB_DESC_MINITABLE(sym) google__protobuf__##sym##_msg_init()
0343 #else
0344 #define UPB_DESC(sym) google_protobuf_##sym
0345 #define UPB_DESC_MINITABLE(sym) &google__protobuf__##sym##_msg_init
0346 #endif
0347 
0348 
0349 // Linker arrays combine elements from multiple translation units into a single
0350 // array that can be iterated over at runtime.
0351 //
0352 // It is an alternative to pre-main "registration" functions.
0353 //
0354 // Usage:
0355 //
0356 //   // In N translation units.
0357 //   UPB_LINKARR_APPEND(foo_array) static int elems[3] = {1, 2, 3};
0358 //
0359 //   // At runtime:
0360 //   UPB_LINKARR_DECLARE(foo_array, int);
0361 //
0362 //   void f() {
0363 //     const int* start = UPB_LINKARR_START(foo_array);
0364 //     const int* stop = UPB_LINKARR_STOP(foo_array);
0365 //     for (const int* p = start; p < stop; p++) {
0366 //       // Windows can introduce zero padding, so we have to skip zeroes.
0367 //       if (*p != 0) {
0368 //         vec.push_back(*p);
0369 //       }
0370 //     }
0371 //   }
0372 
0373 #if defined(__ELF__) || defined(__wasm__)
0374 
0375 #define UPB_LINKARR_APPEND(name) \
0376   __attribute__((retain, used, section("linkarr_" #name)))
0377 #define UPB_LINKARR_DECLARE(name, type)     \
0378   extern type const __start_linkarr_##name; \
0379   extern type const __stop_linkarr_##name;  \
0380   UPB_LINKARR_APPEND(name) type UPB_linkarr_internal_empty_##name[1]
0381 #define UPB_LINKARR_START(name) (&__start_linkarr_##name)
0382 #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
0383 
0384 #elif defined(__MACH__)
0385 
0386 /* As described in: https://stackoverflow.com/a/22366882 */
0387 #define UPB_LINKARR_APPEND(name) \
0388   __attribute__((retain, used, section("__DATA,__la_" #name)))
0389 #define UPB_LINKARR_DECLARE(name, type)           \
0390   extern type const __start_linkarr_##name __asm( \
0391       "section$start$__DATA$__la_" #name);        \
0392   extern type const __stop_linkarr_##name __asm(  \
0393       "section$end$__DATA$"                       \
0394       "__la_" #name);                             \
0395   UPB_LINKARR_APPEND(name) type UPB_linkarr_internal_empty_##name[1]
0396 #define UPB_LINKARR_START(name) (&__start_linkarr_##name)
0397 #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
0398 
0399 #elif defined(_MSC_VER) && defined(__clang__)
0400 
0401 /* See:
0402  *   https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155
0403  *   https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165
0404  *   https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */
0405 
0406 // Usage of __attribute__ here probably means this is Clang-specific, and would
0407 // not work on MSVC.
0408 #define UPB_LINKARR_APPEND(name) \
0409   __declspec(allocate("la_" #name "$j")) __attribute__((retain, used))
0410 #define UPB_LINKARR_DECLARE(name, type)                               \
0411   __declspec(allocate("la_" #name "$a")) type __start_linkarr_##name; \
0412   __declspec(allocate("la_" #name "$z")) type __stop_linkarr_##name;  \
0413   UPB_LINKARR_APPEND(name) type UPB_linkarr_internal_empty_##name[1] = {0}
0414 #define UPB_LINKARR_START(name) (&__start_linkarr_##name)
0415 #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
0416 
0417 #else
0418 
0419 // Linker arrays are not supported on this platform.  Make appends a no-op but
0420 // don't define the other macros.
0421 #define UPB_LINKARR_APPEND(name)
0422 
0423 #endif