Imported Upstream version 1.41.0
[platform/upstream/grpc.git] / third_party / upb / upb / port_def.inc
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 /*
29  * This is where we define macros used across upb.
30  *
31  * All of these macros are undef'd in port_undef.inc to avoid leaking them to
32  * users.
33  *
34  * The correct usage is:
35  *
36  *   #include "upb/foobar.h"
37  *   #include "upb/baz.h"
38  *
39  *   // MUST be last included header.
40  *   #include "upb/port_def.inc"
41  *
42  *   // Code for this file.
43  *   // <...>
44  *
45  *   // Can be omitted for .c files, required for .h.
46  *   #include "upb/port_undef.inc"
47  *
48  * This file is private and must not be included by users!
49  */
50
51 #if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
52       (defined(__cplusplus) && __cplusplus >= 201103L) ||           \
53       (defined(_MSC_VER) && _MSC_VER >= 1900))
54 #error upb requires C99 or C++11 or MSVC >= 2015.
55 #endif
56
57 #include <stdint.h>
58 #include <stddef.h>
59
60 #if UINTPTR_MAX == 0xffffffff
61 #define UPB_SIZE(size32, size64) size32
62 #else
63 #define UPB_SIZE(size32, size64) size64
64 #endif
65
66 /* If we always read/write as a consistent type to each address, this shouldn't
67  * violate aliasing.
68  */
69 #define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs)))
70
71 #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
72   *UPB_PTR_AT(msg, case_offset, int) == case_val                              \
73       ? *UPB_PTR_AT(msg, offset, fieldtype)                                   \
74       : default
75
76 #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
77   *UPB_PTR_AT(msg, case_offset, int) = case_val;                             \
78   *UPB_PTR_AT(msg, offset, fieldtype) = value;
79
80 #define UPB_MAPTYPE_STRING 0
81
82 /* UPB_INLINE: inline if possible, emit standalone code if required. */
83 #ifdef __cplusplus
84 #define UPB_INLINE inline
85 #elif defined (__GNUC__) || defined(__clang__)
86 #define UPB_INLINE static __inline__
87 #else
88 #define UPB_INLINE static
89 #endif
90
91 #define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align))
92 #define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align))
93 #define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, 16)
94 #define UPB_ALIGN_OF(type) offsetof (struct { char c; type member; }, member)
95
96 /* Hints to the compiler about likely/unlikely branches. */
97 #if defined (__GNUC__) || defined(__clang__)
98 #define UPB_LIKELY(x) __builtin_expect((x),1)
99 #define UPB_UNLIKELY(x) __builtin_expect((x),0)
100 #else
101 #define UPB_LIKELY(x) (x)
102 #define UPB_UNLIKELY(x) (x)
103 #endif
104
105 /* Macros for function attributes on compilers that support them. */
106 #ifdef __GNUC__
107 #define UPB_FORCEINLINE __inline__ __attribute__((always_inline))
108 #define UPB_NOINLINE __attribute__((noinline))
109 #define UPB_NORETURN __attribute__((__noreturn__))
110 #define UPB_PRINTF(str, first_vararg) __attribute__((format (printf, str, first_vararg)))
111 #elif defined(_MSC_VER)
112 #define UPB_NOINLINE
113 #define UPB_FORCEINLINE
114 #define UPB_NORETURN __declspec(noreturn)
115 #define UPB_PRINTF(str, first_vararg)
116 #else  /* !defined(__GNUC__) */
117 #define UPB_FORCEINLINE
118 #define UPB_NOINLINE
119 #define UPB_NORETURN
120 #define UPB_PRINTF(str, first_vararg)
121 #endif
122
123 #define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
124 #define UPB_MIN(x, y) ((x) < (y) ? (x) : (y))
125
126 #define UPB_UNUSED(var) (void)var
127
128 /* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true.
129  */
130 #ifdef NDEBUG
131 #ifdef __GNUC__
132 #define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable()
133 #elif defined _MSC_VER
134 #define UPB_ASSUME(expr) if (!(expr)) __assume(0)
135 #else
136 #define UPB_ASSUME(expr) do {} while (false && (expr))
137 #endif
138 #else
139 #define UPB_ASSUME(expr) assert(expr)
140 #endif
141
142 /* UPB_ASSERT(): in release mode, we use the expression without letting it be
143  * evaluated.  This prevents "unused variable" warnings. */
144 #ifdef NDEBUG
145 #define UPB_ASSERT(expr) do {} while (false && (expr))
146 #else
147 #define UPB_ASSERT(expr) assert(expr)
148 #endif
149
150 #if defined(__GNUC__) || defined(__clang__)
151 #define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0)
152 #else
153 #define UPB_UNREACHABLE() do { assert(0); } while(0)
154 #endif
155
156 /* UPB_SETJMP() / UPB_LONGJMP(): avoid setting/restoring signal mask. */
157 #ifdef __APPLE__
158 #define UPB_SETJMP(buf) _setjmp(buf)
159 #define UPB_LONGJMP(buf, val) _longjmp(buf, val)
160 #else
161 #define UPB_SETJMP(buf) setjmp(buf)
162 #define UPB_LONGJMP(buf, val) longjmp(buf, val)
163 #endif
164
165 /* UPB_PTRADD(ptr, ofs): add pointer while avoiding "NULL + 0" UB */
166 #define UPB_PTRADD(ptr, ofs) ((ofs) ? (ptr) + (ofs) : (ptr))
167
168 /* Configure whether fasttable is switched on or not. *************************/
169
170 #ifdef __has_attribute
171 #define UPB_HAS_ATTRIBUTE(x) __has_attribute(x)
172 #else
173 #define UPB_HAS_ATTRIBUTE(x) 0
174 #endif
175
176 #if UPB_HAS_ATTRIBUTE(musttail)
177 #define UPB_MUSTTAIL __attribute__((musttail))
178 #else
179 #define UPB_MUSTTAIL
180 #endif
181
182 #undef UPB_HAS_ATTRIBUTE
183
184 /* This check is not fully robust: it does not require that we have "musttail"
185  * support available. We need tail calls to avoid consuming arbitrary amounts
186  * of stack space.
187  *
188  * GCC/Clang can mostly be trusted to generate tail calls as long as
189  * optimization is enabled, but, debug builds will not generate tail calls
190  * unless "musttail" is available.
191  *
192  * We should probably either:
193  *   1. require that the compiler supports musttail.
194  *   2. add some fallback code for when musttail isn't available (ie. return
195  *      instead of tail calling). This is safe and portable, but this comes at
196  *      a CPU cost.
197  */
198 #if (defined(__x86_64__) || defined(__aarch64__)) && defined(__GNUC__)
199 #define UPB_FASTTABLE_SUPPORTED 1
200 #else
201 #define UPB_FASTTABLE_SUPPORTED 0
202 #endif
203
204 /* define UPB_ENABLE_FASTTABLE to force fast table support.
205  * This is useful when we want to ensure we are really getting fasttable,
206  * for example for testing or benchmarking. */
207 #if defined(UPB_ENABLE_FASTTABLE)
208 #if !UPB_FASTTABLE_SUPPORTED
209 #error fasttable is x86-64/ARM64 only and requires GCC or Clang.
210 #endif
211 #define UPB_FASTTABLE 1
212 /* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible.
213  * This is useful for releasing code that might be used on multiple platforms,
214  * for example the PHP or Ruby C extensions. */
215 #elif defined(UPB_TRY_ENABLE_FASTTABLE)
216 #define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED
217 #else
218 #define UPB_FASTTABLE 0
219 #endif
220
221 /* UPB_FASTTABLE_INIT() allows protos compiled for fasttable to gracefully
222  * degrade to non-fasttable if we are using UPB_TRY_ENABLE_FASTTABLE. */
223 #if !UPB_FASTTABLE && defined(UPB_TRY_ENABLE_FASTTABLE)
224 #define UPB_FASTTABLE_INIT(...)
225 #else
226 #define UPB_FASTTABLE_INIT(...) __VA_ARGS__
227 #endif
228
229 #undef UPB_FASTTABLE_SUPPORTED
230
231 /* ASAN poisoning (for arena) *************************************************/
232
233 #if defined(__SANITIZE_ADDRESS__)
234 #define UPB_ASAN 1
235 #ifdef __cplusplus
236 extern "C" {
237 #endif
238 void __asan_poison_memory_region(void const volatile *addr, size_t size);
239 void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
240 #ifdef __cplusplus
241 }  /* extern "C" */
242 #endif
243 #define UPB_POISON_MEMORY_REGION(addr, size) \
244   __asan_poison_memory_region((addr), (size))
245 #define UPB_UNPOISON_MEMORY_REGION(addr, size) \
246   __asan_unpoison_memory_region((addr), (size))
247 #else
248 #define UPB_ASAN 0
249 #define UPB_POISON_MEMORY_REGION(addr, size) \
250   ((void)(addr), (void)(size))
251 #define UPB_UNPOISON_MEMORY_REGION(addr, size) \
252   ((void)(addr), (void)(size))
253 #endif