You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

port_def.inc 9.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * Copyright (c) 2009-2021, Google LLC
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of Google LLC nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  17. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. /*
  28. * This is where we define macros used across upb.
  29. *
  30. * All of these macros are undef'd in port_undef.inc to avoid leaking them to
  31. * users.
  32. *
  33. * The correct usage is:
  34. *
  35. * #include "upb/foobar.h"
  36. * #include "upb/baz.h"
  37. *
  38. * // MUST be last included header.
  39. * #include "upb/port_def.inc"
  40. *
  41. * // Code for this file.
  42. * // <...>
  43. *
  44. * // Can be omitted for .c files, required for .h.
  45. * #include "upb/port_undef.inc"
  46. *
  47. * This file is private and must not be included by users!
  48. */
  49. #if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
  50. (defined(__cplusplus) && __cplusplus >= 201103L) || \
  51. (defined(_MSC_VER) && _MSC_VER >= 1900))
  52. #error upb requires C99 or C++11 or MSVC >= 2015.
  53. #endif
  54. #include <stdint.h>
  55. #include <stddef.h>
  56. #if UINTPTR_MAX == 0xffffffff
  57. #define UPB_SIZE(size32, size64) size32
  58. #else
  59. #define UPB_SIZE(size32, size64) size64
  60. #endif
  61. /* If we always read/write as a consistent type to each address, this shouldn't
  62. * violate aliasing.
  63. */
  64. #define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs)))
  65. #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
  66. *UPB_PTR_AT(msg, case_offset, int) == case_val \
  67. ? *UPB_PTR_AT(msg, offset, fieldtype) \
  68. : default
  69. #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
  70. *UPB_PTR_AT(msg, case_offset, int) = case_val; \
  71. *UPB_PTR_AT(msg, offset, fieldtype) = value;
  72. #define UPB_MAPTYPE_STRING 0
  73. /* UPB_INLINE: inline if possible, emit standalone code if required. */
  74. #ifdef __cplusplus
  75. #define UPB_INLINE inline
  76. #elif defined (__GNUC__) || defined(__clang__)
  77. #define UPB_INLINE static __inline__
  78. #else
  79. #define UPB_INLINE static
  80. #endif
  81. #define UPB_MALLOC_ALIGN 8
  82. #define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align))
  83. #define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align))
  84. #define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, UPB_MALLOC_ALIGN)
  85. #define UPB_ALIGN_OF(type) offsetof (struct { char c; type member; }, member)
  86. /* Hints to the compiler about likely/unlikely branches. */
  87. #if defined (__GNUC__) || defined(__clang__)
  88. #define UPB_LIKELY(x) __builtin_expect((x),1)
  89. #define UPB_UNLIKELY(x) __builtin_expect((x),0)
  90. #else
  91. #define UPB_LIKELY(x) (x)
  92. #define UPB_UNLIKELY(x) (x)
  93. #endif
  94. /* Macros for function attributes on compilers that support them. */
  95. #ifdef __GNUC__
  96. #define UPB_FORCEINLINE __inline__ __attribute__((always_inline))
  97. #define UPB_NOINLINE __attribute__((noinline))
  98. #define UPB_NORETURN __attribute__((__noreturn__))
  99. #define UPB_PRINTF(str, first_vararg) __attribute__((format (printf, str, first_vararg)))
  100. #elif defined(_MSC_VER)
  101. #define UPB_NOINLINE
  102. #define UPB_FORCEINLINE
  103. #define UPB_NORETURN __declspec(noreturn)
  104. #define UPB_PRINTF(str, first_vararg)
  105. #else /* !defined(__GNUC__) */
  106. #define UPB_FORCEINLINE
  107. #define UPB_NOINLINE
  108. #define UPB_NORETURN
  109. #define UPB_PRINTF(str, first_vararg)
  110. #endif
  111. #define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
  112. #define UPB_MIN(x, y) ((x) < (y) ? (x) : (y))
  113. #define UPB_UNUSED(var) (void)var
  114. /* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true.
  115. */
  116. #ifdef NDEBUG
  117. #ifdef __GNUC__
  118. #define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable()
  119. #elif defined _MSC_VER
  120. #define UPB_ASSUME(expr) if (!(expr)) __assume(0)
  121. #else
  122. #define UPB_ASSUME(expr) do {} while (false && (expr))
  123. #endif
  124. #else
  125. #define UPB_ASSUME(expr) assert(expr)
  126. #endif
  127. /* UPB_ASSERT(): in release mode, we use the expression without letting it be
  128. * evaluated. This prevents "unused variable" warnings. */
  129. #ifdef NDEBUG
  130. #define UPB_ASSERT(expr) do {} while (false && (expr))
  131. #else
  132. #define UPB_ASSERT(expr) assert(expr)
  133. #endif
  134. #if defined(__GNUC__) || defined(__clang__)
  135. #define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0)
  136. #else
  137. #define UPB_UNREACHABLE() do { assert(0); } while(0)
  138. #endif
  139. /* UPB_SETJMP() / UPB_LONGJMP(): avoid setting/restoring signal mask. */
  140. #ifdef __APPLE__
  141. #define UPB_SETJMP(buf) _setjmp(buf)
  142. #define UPB_LONGJMP(buf, val) _longjmp(buf, val)
  143. #else
  144. #define UPB_SETJMP(buf) setjmp(buf)
  145. #define UPB_LONGJMP(buf, val) longjmp(buf, val)
  146. #endif
  147. /* UPB_PTRADD(ptr, ofs): add pointer while avoiding "NULL + 0" UB */
  148. #define UPB_PTRADD(ptr, ofs) ((ofs) ? (ptr) + (ofs) : (ptr))
  149. /* Configure whether fasttable is switched on or not. *************************/
  150. #ifdef __has_attribute
  151. #define UPB_HAS_ATTRIBUTE(x) __has_attribute(x)
  152. #else
  153. #define UPB_HAS_ATTRIBUTE(x) 0
  154. #endif
  155. #if UPB_HAS_ATTRIBUTE(musttail)
  156. #define UPB_MUSTTAIL __attribute__((musttail))
  157. #else
  158. #define UPB_MUSTTAIL
  159. #endif
  160. #undef UPB_HAS_ATTRIBUTE
  161. /* This check is not fully robust: it does not require that we have "musttail"
  162. * support available. We need tail calls to avoid consuming arbitrary amounts
  163. * of stack space.
  164. *
  165. * GCC/Clang can mostly be trusted to generate tail calls as long as
  166. * optimization is enabled, but, debug builds will not generate tail calls
  167. * unless "musttail" is available.
  168. *
  169. * We should probably either:
  170. * 1. require that the compiler supports musttail.
  171. * 2. add some fallback code for when musttail isn't available (ie. return
  172. * instead of tail calling). This is safe and portable, but this comes at
  173. * a CPU cost.
  174. */
  175. #if (defined(__x86_64__) || defined(__aarch64__)) && defined(__GNUC__)
  176. #define UPB_FASTTABLE_SUPPORTED 1
  177. #else
  178. #define UPB_FASTTABLE_SUPPORTED 0
  179. #endif
  180. /* define UPB_ENABLE_FASTTABLE to force fast table support.
  181. * This is useful when we want to ensure we are really getting fasttable,
  182. * for example for testing or benchmarking. */
  183. #if defined(UPB_ENABLE_FASTTABLE)
  184. #if !UPB_FASTTABLE_SUPPORTED
  185. #error fasttable is x86-64/ARM64 only and requires GCC or Clang.
  186. #endif
  187. #define UPB_FASTTABLE 1
  188. /* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible.
  189. * This is useful for releasing code that might be used on multiple platforms,
  190. * for example the PHP or Ruby C extensions. */
  191. #elif defined(UPB_TRY_ENABLE_FASTTABLE)
  192. #define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED
  193. #else
  194. #define UPB_FASTTABLE 0
  195. #endif
  196. /* UPB_FASTTABLE_INIT() allows protos compiled for fasttable to gracefully
  197. * degrade to non-fasttable if we are using UPB_TRY_ENABLE_FASTTABLE. */
  198. #if !UPB_FASTTABLE && defined(UPB_TRY_ENABLE_FASTTABLE)
  199. #define UPB_FASTTABLE_INIT(...)
  200. #else
  201. #define UPB_FASTTABLE_INIT(...) __VA_ARGS__
  202. #endif
  203. #undef UPB_FASTTABLE_SUPPORTED
  204. /* ASAN poisoning (for arena) *************************************************/
  205. #if defined(__SANITIZE_ADDRESS__)
  206. #define UPB_ASAN 1
  207. #ifdef __cplusplus
  208. extern "C" {
  209. #endif
  210. void __asan_poison_memory_region(void const volatile *addr, size_t size);
  211. void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
  212. #ifdef __cplusplus
  213. } /* extern "C" */
  214. #endif
  215. #define UPB_POISON_MEMORY_REGION(addr, size) \
  216. __asan_poison_memory_region((addr), (size))
  217. #define UPB_UNPOISON_MEMORY_REGION(addr, size) \
  218. __asan_unpoison_memory_region((addr), (size))
  219. #else
  220. #define UPB_ASAN 0
  221. #define UPB_POISON_MEMORY_REGION(addr, size) \
  222. ((void)(addr), (void)(size))
  223. #define UPB_UNPOISON_MEMORY_REGION(addr, size) \
  224. ((void)(addr), (void)(size))
  225. #endif
  226. /* Disable proto2 arena behavior (TEMPORARY) **********************************/
  227. #ifdef UPB_DISABLE_PROTO2_ENUM_CHECKING
  228. #define UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 1
  229. #else
  230. #define UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 0
  231. #endif