xref: /PHP-8.1/Zend/zend_portability.h (revision 55514a11)
1 /*
2    +----------------------------------------------------------------------+
3    | Zend Engine                                                          |
4    +----------------------------------------------------------------------+
5    | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 2.00 of the Zend license,     |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available through the world-wide-web at the following url:           |
10    | http://www.zend.com/license/2_00.txt.                                |
11    | If you did not receive a copy of the Zend license and are unable to  |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@zend.com so we can mail you a copy immediately.              |
14    +----------------------------------------------------------------------+
15    | Authors: Andi Gutmans <andi@php.net>                                 |
16    |          Zeev Suraski <zeev@php.net>                                 |
17    |          Dmitry Stogov <dmitry@php.net>                              |
18    +----------------------------------------------------------------------+
19 */
20 
21 #ifndef ZEND_PORTABILITY_H
22 #define ZEND_PORTABILITY_H
23 
24 #ifdef __cplusplus
25 #define BEGIN_EXTERN_C() extern "C" {
26 #define END_EXTERN_C() }
27 #else
28 #define BEGIN_EXTERN_C()
29 #define END_EXTERN_C()
30 #endif
31 
32 /*
33  * general definitions
34  */
35 
36 #ifdef ZEND_WIN32
37 # include "zend_config.w32.h"
38 # define ZEND_PATHS_SEPARATOR		';'
39 #elif defined(__riscos__)
40 # include <zend_config.h>
41 # define ZEND_PATHS_SEPARATOR		';'
42 #else
43 # include <zend_config.h>
44 # define ZEND_PATHS_SEPARATOR		':'
45 #endif
46 
47 #include "../TSRM/TSRM.h"
48 
49 #include <stdio.h>
50 #include <assert.h>
51 #include <math.h>
52 
53 #ifdef HAVE_UNIX_H
54 # include <unix.h>
55 #endif
56 
57 #include <stdarg.h>
58 #include <stddef.h>
59 
60 #ifdef HAVE_DLFCN_H
61 # include <dlfcn.h>
62 #endif
63 
64 #include <limits.h>
65 
66 #if HAVE_ALLOCA_H && !defined(_ALLOCA_H)
67 # include <alloca.h>
68 #endif
69 
70 #if defined(ZEND_WIN32) && !defined(__clang__)
71 #include <intrin.h>
72 #endif
73 
74 #include "zend_range_check.h"
75 
76 /* GCC x.y.z supplies __GNUC__ = x and __GNUC_MINOR__ = y */
77 #ifdef __GNUC__
78 # define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
79 #else
80 # define ZEND_GCC_VERSION 0
81 #endif
82 
83 /* Compatibility with non-clang compilers */
84 #ifndef __has_attribute
85 # define __has_attribute(x) 0
86 #endif
87 #ifndef __has_builtin
88 # define __has_builtin(x) 0
89 #endif
90 #ifndef __has_feature
91 # define __has_feature(x) 0
92 #endif
93 
94 #if defined(ZEND_WIN32) && !defined(__clang__)
95 # define ZEND_ASSUME(c)	__assume(c)
96 #elif ((defined(__GNUC__) && ZEND_GCC_VERSION >= 4005) || __has_builtin(__builtin_unreachable)) && PHP_HAVE_BUILTIN_EXPECT
97 # define ZEND_ASSUME(c)	do { \
98 		if (__builtin_expect(!(c), 0)) __builtin_unreachable(); \
99 	} while (0)
100 #else
101 # define ZEND_ASSUME(c)
102 #endif
103 
104 #if ZEND_DEBUG
105 # define ZEND_ASSERT(c)	assert(c)
106 #else
107 # define ZEND_ASSERT(c) ZEND_ASSUME(c)
108 #endif
109 
110 #if ZEND_DEBUG
111 # define ZEND_UNREACHABLE() do {ZEND_ASSERT(0); ZEND_ASSUME(0);} while (0)
112 #else
113 # define ZEND_UNREACHABLE() ZEND_ASSUME(0)
114 #endif
115 
116 /* pseudo fallthrough keyword; */
117 #if defined(__GNUC__) && __GNUC__ >= 7
118 # define ZEND_FALLTHROUGH __attribute__((__fallthrough__))
119 #else
120 # define ZEND_FALLTHROUGH ((void)0)
121 #endif
122 
123 /* Only use this macro if you know for sure that all of the switches values
124    are covered by its case statements */
125 #define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_UNREACHABLE(); break;
126 
127 #if defined(__GNUC__) && __GNUC__ >= 4
128 # define ZEND_IGNORE_VALUE(x) (({ __typeof__ (x) __x = (x); (void) __x; }))
129 #else
130 # define ZEND_IGNORE_VALUE(x) ((void) (x))
131 #endif
132 
133 #define zend_quiet_write(...) ZEND_IGNORE_VALUE(write(__VA_ARGS__))
134 
135 /* all HAVE_XXX test have to be after the include of zend_config above */
136 
137 #if defined(HAVE_LIBDL) && !defined(ZEND_WIN32)
138 
139 # if __has_feature(address_sanitizer)
140 #  define __SANITIZE_ADDRESS__
141 # endif
142 
143 # ifndef RTLD_LAZY
144 #  define RTLD_LAZY 1    /* Solaris 1, FreeBSD's (2.1.7.1 and older) */
145 # endif
146 
147 # ifndef RTLD_GLOBAL
148 #  define RTLD_GLOBAL 0
149 # endif
150 
151 # ifdef PHP_USE_RTLD_NOW
152 #  define PHP_RTLD_MODE  RTLD_NOW
153 # else
154 #  define PHP_RTLD_MODE  RTLD_LAZY
155 # endif
156 
157 # if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT)
158 #  define DL_LOAD(libname)			dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT)
159 # elif defined(RTLD_DEEPBIND) && !defined(__SANITIZE_ADDRESS__) && !__has_feature(memory_sanitizer)
160 #  define DL_LOAD(libname)			dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL | RTLD_DEEPBIND)
161 # else
162 #  define DL_LOAD(libname)			dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL)
163 # endif
164 # define DL_UNLOAD					dlclose
165 # if defined(DLSYM_NEEDS_UNDERSCORE)
166 #  define DL_FETCH_SYMBOL(h,s)		dlsym((h), "_" s)
167 # else
168 #  define DL_FETCH_SYMBOL			dlsym
169 # endif
170 # define DL_ERROR					dlerror
171 # define DL_HANDLE					void *
172 # define ZEND_EXTENSIONS_SUPPORT	1
173 #elif defined(ZEND_WIN32)
174 # define DL_LOAD(libname)			LoadLibrary(libname)
175 # define DL_FETCH_SYMBOL			GetProcAddress
176 # define DL_UNLOAD					FreeLibrary
177 # define DL_HANDLE					HMODULE
178 # define ZEND_EXTENSIONS_SUPPORT	1
179 #else
180 # define DL_HANDLE					void *
181 # define ZEND_EXTENSIONS_SUPPORT	0
182 #endif
183 
184 /* AIX requires this to be the first thing in the file.  */
185 #ifndef __GNUC__
186 # ifndef HAVE_ALLOCA_H
187 #  ifdef _AIX
188 #   pragma alloca
189 #  else
190 #   ifndef alloca /* predefined by HP cc +Olibcalls */
191 char *alloca();
192 #   endif
193 #  endif
194 # endif
195 #endif
196 
197 #if ZEND_GCC_VERSION >= 2096 || __has_attribute(__malloc__)
198 # define ZEND_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
199 #else
200 # define ZEND_ATTRIBUTE_MALLOC
201 #endif
202 
203 #if ZEND_GCC_VERSION >= 4003 || __has_attribute(alloc_size)
204 # define ZEND_ATTRIBUTE_ALLOC_SIZE(X) __attribute__ ((alloc_size(X)))
205 # define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y) __attribute__ ((alloc_size(X,Y)))
206 #else
207 # define ZEND_ATTRIBUTE_ALLOC_SIZE(X)
208 # define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y)
209 #endif
210 
211 #if ZEND_GCC_VERSION >= 2007 || __has_attribute(format)
212 # define ZEND_ATTRIBUTE_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first)))
213 #else
214 # define ZEND_ATTRIBUTE_FORMAT(type, idx, first)
215 #endif
216 
217 #if (ZEND_GCC_VERSION >= 3001 && !defined(__INTEL_COMPILER)) || __has_attribute(format)
218 # define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first)))
219 #else
220 # define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first)
221 #endif
222 
223 #if ZEND_GCC_VERSION >= 3001 || __has_attribute(deprecated)
224 # define ZEND_ATTRIBUTE_DEPRECATED  __attribute__((deprecated))
225 #elif defined(ZEND_WIN32)
226 # define ZEND_ATTRIBUTE_DEPRECATED  __declspec(deprecated)
227 #else
228 # define ZEND_ATTRIBUTE_DEPRECATED
229 #endif
230 
231 #if ZEND_GCC_VERSION >= 4003 || __has_attribute(unused)
232 # define ZEND_ATTRIBUTE_UNUSED __attribute__((unused))
233 #else
234 # define ZEND_ATTRIBUTE_UNUSED
235 #endif
236 
237 #if defined(__GNUC__) && ZEND_GCC_VERSION >= 4003
238 # define ZEND_COLD __attribute__((cold))
239 # define ZEND_HOT __attribute__((hot))
240 # ifdef __OPTIMIZE__
241 #  define ZEND_OPT_SIZE  __attribute__((optimize("Os")))
242 #  define ZEND_OPT_SPEED __attribute__((optimize("Ofast")))
243 # else
244 #  define ZEND_OPT_SIZE
245 #  define ZEND_OPT_SPEED
246 # endif
247 #else
248 # define ZEND_COLD
249 # define ZEND_HOT
250 # define ZEND_OPT_SIZE
251 # define ZEND_OPT_SPEED
252 #endif
253 
254 #if defined(__GNUC__) && ZEND_GCC_VERSION >= 5000
255 # define ZEND_ATTRIBUTE_UNUSED_LABEL __attribute__((unused));
256 # define ZEND_ATTRIBUTE_COLD_LABEL __attribute__((cold));
257 # define ZEND_ATTRIBUTE_HOT_LABEL __attribute__((hot));
258 #else
259 # define ZEND_ATTRIBUTE_UNUSED_LABEL
260 # define ZEND_ATTRIBUTE_COLD_LABEL
261 # define ZEND_ATTRIBUTE_HOT_LABEL
262 #endif
263 
264 #if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__)
265 # define ZEND_FASTCALL __attribute__((fastcall))
266 #elif defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER == 1700
267 # define ZEND_FASTCALL __fastcall
268 #elif defined(_MSC_VER) && _MSC_VER >= 1800 && !defined(__clang__)
269 # define ZEND_FASTCALL __vectorcall
270 #else
271 # define ZEND_FASTCALL
272 #endif
273 
274 #if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)) || __has_attribute(noreturn)
275 # define HAVE_NORETURN
276 # define ZEND_NORETURN __attribute__((noreturn))
277 #elif defined(ZEND_WIN32)
278 # define HAVE_NORETURN
279 # define ZEND_NORETURN __declspec(noreturn)
280 #else
281 # define ZEND_NORETURN
282 #endif
283 
284 #if __has_attribute(force_align_arg_pointer)
285 # define ZEND_STACK_ALIGNED __attribute__((force_align_arg_pointer))
286 #else
287 # define ZEND_STACK_ALIGNED
288 #endif
289 
290 #if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__))
291 # define HAVE_NORETURN_ALIAS
292 # define HAVE_ATTRIBUTE_WEAK
293 #endif
294 
295 #if ZEND_GCC_VERSION >= 3001 || __has_builtin(__builtin_constant_p)
296 # define HAVE_BUILTIN_CONSTANT_P
297 #endif
298 
299 #ifdef HAVE_BUILTIN_CONSTANT_P
300 # define ZEND_CONST_COND(_condition, _default) \
301 	(__builtin_constant_p(_condition) ? (_condition) : (_default))
302 #else
303 # define ZEND_CONST_COND(_condition, _default) \
304 	(_default)
305 #endif
306 
307 #if ZEND_DEBUG || defined(ZEND_WIN32_NEVER_INLINE)
308 # define zend_always_inline inline
309 # define zend_never_inline
310 #else
311 # if defined(__GNUC__)
312 #  if __GNUC__ >= 3
313 #   define zend_always_inline inline __attribute__((always_inline))
314 #   define zend_never_inline __attribute__((noinline))
315 #  else
316 #   define zend_always_inline inline
317 #   define zend_never_inline
318 #  endif
319 # elif defined(_MSC_VER)
320 #  define zend_always_inline __forceinline
321 #  define zend_never_inline __declspec(noinline)
322 # else
323 #  if __has_attribute(always_inline)
324 #   define zend_always_inline inline __attribute__((always_inline))
325 #  else
326 #   define zend_always_inline inline
327 #  endif
328 #  if __has_attribute(noinline)
329 #   define zend_never_inline __attribute__((noinline))
330 #  else
331 #   define zend_never_inline
332 #  endif
333 # endif
334 #endif /* ZEND_DEBUG */
335 
336 #ifdef PHP_HAVE_BUILTIN_EXPECT
337 # define EXPECTED(condition)   __builtin_expect(!!(condition), 1)
338 # define UNEXPECTED(condition) __builtin_expect(!!(condition), 0)
339 #else
340 # define EXPECTED(condition)   (condition)
341 # define UNEXPECTED(condition) (condition)
342 #endif
343 
344 #ifndef XtOffsetOf
345 # define XtOffsetOf(s_type, field) offsetof(s_type, field)
346 #endif
347 
348 #if (defined(HAVE_ALLOCA) || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN)
349 # define ZEND_ALLOCA_MAX_SIZE (32 * 1024)
350 # define ALLOCA_FLAG(name) \
351 	bool name;
352 # define SET_ALLOCA_FLAG(name) \
353 	name = 1
354 # define do_alloca_ex(size, limit, use_heap) \
355 	((use_heap = (UNEXPECTED((size) > (limit)))) ? emalloc(size) : alloca(size))
356 # define do_alloca(size, use_heap) \
357 	do_alloca_ex(size, ZEND_ALLOCA_MAX_SIZE, use_heap)
358 # define free_alloca(p, use_heap) \
359 	do { if (UNEXPECTED(use_heap)) efree(p); } while (0)
360 #else
361 # define ALLOCA_FLAG(name)
362 # define SET_ALLOCA_FLAG(name)
363 # define do_alloca(p, use_heap)		emalloc(p)
364 # define free_alloca(p, use_heap)	efree(p)
365 #endif
366 
367 #ifdef HAVE_SIGSETJMP
368 # define SETJMP(a) sigsetjmp(a, 0)
369 # define LONGJMP(a,b) siglongjmp(a, b)
370 # define JMP_BUF sigjmp_buf
371 #else
372 # define SETJMP(a) setjmp(a)
373 # define LONGJMP(a,b) longjmp(a, b)
374 # define JMP_BUF jmp_buf
375 #endif
376 
377 #if ZEND_DEBUG
378 # define ZEND_FILE_LINE_D				const char *__zend_filename, const uint32_t __zend_lineno
379 # define ZEND_FILE_LINE_DC				, ZEND_FILE_LINE_D
380 # define ZEND_FILE_LINE_ORIG_D			const char *__zend_orig_filename, const uint32_t __zend_orig_lineno
381 # define ZEND_FILE_LINE_ORIG_DC			, ZEND_FILE_LINE_ORIG_D
382 # define ZEND_FILE_LINE_RELAY_C			__zend_filename, __zend_lineno
383 # define ZEND_FILE_LINE_RELAY_CC		, ZEND_FILE_LINE_RELAY_C
384 # define ZEND_FILE_LINE_C				__FILE__, __LINE__
385 # define ZEND_FILE_LINE_CC				, ZEND_FILE_LINE_C
386 # define ZEND_FILE_LINE_EMPTY_C			NULL, 0
387 # define ZEND_FILE_LINE_EMPTY_CC		, ZEND_FILE_LINE_EMPTY_C
388 # define ZEND_FILE_LINE_ORIG_RELAY_C	__zend_orig_filename, __zend_orig_lineno
389 # define ZEND_FILE_LINE_ORIG_RELAY_CC	, ZEND_FILE_LINE_ORIG_RELAY_C
390 #else
391 # define ZEND_FILE_LINE_D				void
392 # define ZEND_FILE_LINE_DC
393 # define ZEND_FILE_LINE_ORIG_D			void
394 # define ZEND_FILE_LINE_ORIG_DC
395 # define ZEND_FILE_LINE_RELAY_C
396 # define ZEND_FILE_LINE_RELAY_CC
397 # define ZEND_FILE_LINE_C
398 # define ZEND_FILE_LINE_CC
399 # define ZEND_FILE_LINE_EMPTY_C
400 # define ZEND_FILE_LINE_EMPTY_CC
401 # define ZEND_FILE_LINE_ORIG_RELAY_C
402 # define ZEND_FILE_LINE_ORIG_RELAY_CC
403 #endif	/* ZEND_DEBUG */
404 
405 #if ZEND_DEBUG
406 # define Z_DBG(expr)		(expr)
407 #else
408 # define Z_DBG(expr)
409 #endif
410 
411 #ifdef ZTS
412 # define ZTS_V 1
413 #else
414 # define ZTS_V 0
415 #endif
416 
417 #ifndef LONG_MAX
418 # define LONG_MAX 2147483647L
419 #endif
420 
421 #ifndef LONG_MIN
422 # define LONG_MIN (- LONG_MAX - 1)
423 #endif
424 
425 #define MAX_LENGTH_OF_DOUBLE 32
426 
427 #undef MIN
428 #undef MAX
429 #define MAX(a, b)  (((a)>(b))?(a):(b))
430 #define MIN(a, b)  (((a)<(b))?(a):(b))
431 
432 #define ZEND_BIT_TEST(bits, bit) \
433 	(((bits)[(bit) / (sizeof((bits)[0])*8)] >> ((bit) & (sizeof((bits)[0])*8-1))) & 1)
434 
435 #define ZEND_INFINITY INFINITY
436 
437 #define ZEND_NAN NAN
438 
439 #if defined(__cplusplus) && __cplusplus >= 201103L
440 extern "C++" {
441 # include <cmath>
442 }
443 # define zend_isnan std::isnan
444 # define zend_isinf std::isinf
445 # define zend_finite std::isfinite
446 #else
447 # include <math.h>
448 # define zend_isnan(a) isnan(a)
449 # define zend_isinf(a) isinf(a)
450 # define zend_finite(a) isfinite(a)
451 #endif
452 
453 #define ZEND_STRL(str)		(str), (sizeof(str)-1)
454 #define ZEND_STRS(str)		(str), (sizeof(str))
455 #define ZEND_NORMALIZE_BOOL(n)			\
456 	((n) ? (((n)<0) ? -1 : 1) : 0)
457 #define ZEND_TRUTH(x)		((x) ? 1 : 0)
458 #define ZEND_LOG_XOR(a, b)		(ZEND_TRUTH(a) ^ ZEND_TRUTH(b))
459 
460 #define ZEND_MAX_RESERVED_RESOURCES	6
461 
462 /* excpt.h on Digital Unix 4.0 defines function_table */
463 #undef function_table
464 
465 #ifdef ZEND_WIN32
466 #define ZEND_SECURE_ZERO(var, size) RtlSecureZeroMemory((var), (size))
467 #else
468 #define ZEND_SECURE_ZERO(var, size) explicit_bzero((var), (size))
469 #endif
470 
471 /* This check should only be used on network socket, not file descriptors */
472 #ifdef ZEND_WIN32
473 #define ZEND_VALID_SOCKET(sock) (INVALID_SOCKET != (sock))
474 #else
475 #define ZEND_VALID_SOCKET(sock) ((sock) >= 0)
476 #endif
477 
478 /* Intrinsics macros start. */
479 
480 /* Memory sanitizer is incompatible with ifunc resolvers. Even if the resolver
481  * is marked as no_sanitize("memory") it will still be instrumented and crash. */
482 #if __has_feature(memory_sanitizer) || __has_feature(thread_sanitizer) || \
483 	__has_feature(dataflow_sanitizer)
484 # undef HAVE_FUNC_ATTRIBUTE_IFUNC
485 #endif
486 
487 /* Only use ifunc resolvers if we have __builtin_cpu_supports() and __builtin_cpu_init(),
488  * otherwise the use of zend_cpu_supports() may not be safe inside ifunc resolvers. */
489 #if defined(HAVE_FUNC_ATTRIBUTE_IFUNC) && defined(HAVE_FUNC_ATTRIBUTE_TARGET) && \
490 	defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && defined(PHP_HAVE_BUILTIN_CPU_INIT)
491 # define ZEND_INTRIN_HAVE_IFUNC_TARGET 1
492 #endif
493 
494 #if (defined(__i386__) || defined(__x86_64__))
495 # if defined(HAVE_TMMINTRIN_H)
496 #  define PHP_HAVE_SSSE3
497 # endif
498 
499 # if defined(HAVE_NMMINTRIN_H)
500 #  define PHP_HAVE_SSE4_2
501 # endif
502 
503 # if defined(HAVE_WMMINTRIN_H)
504 #  define PHP_HAVE_PCLMUL
505 # endif
506 
507 /*
508  * AVX2 support was added in gcc 4.7, but AVX2 intrinsics don't work in
509  * __attribute__((target("avx2"))) functions until gcc 4.9.
510  */
511 # if defined(HAVE_IMMINTRIN_H) && \
512   (defined(__llvm__) || defined(__clang__) || (defined(__GNUC__) && ZEND_GCC_VERSION >= 4009))
513 #  define PHP_HAVE_AVX2
514 # endif
515 #endif
516 
517 #ifdef __SSSE3__
518 /* Instructions compiled directly. */
519 # define ZEND_INTRIN_SSSE3_NATIVE 1
520 #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_SSSE3)) || defined(ZEND_WIN32)
521 /* Function resolved by ifunc or MINIT. */
522 # define ZEND_INTRIN_SSSE3_RESOLVER 1
523 #endif
524 
525 /* Do not use for conditional declaration of API functions! */
526 #if defined(ZEND_INTRIN_SSSE3_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET)
527 # define ZEND_INTRIN_SSSE3_FUNC_PROTO 1
528 #elif defined(ZEND_INTRIN_SSSE3_RESOLVER)
529 # define ZEND_INTRIN_SSSE3_FUNC_PTR 1
530 #endif
531 
532 #ifdef ZEND_INTRIN_SSSE3_RESOLVER
533 # ifdef HAVE_FUNC_ATTRIBUTE_TARGET
534 #  define ZEND_INTRIN_SSSE3_FUNC_DECL(func) ZEND_API func __attribute__((target("ssse3")))
535 # else
536 #  define ZEND_INTRIN_SSSE3_FUNC_DECL(func) func
537 # endif
538 #else
539 # define ZEND_INTRIN_SSSE3_FUNC_DECL(func)
540 #endif
541 
542 #ifdef __SSE4_2__
543 /* Instructions compiled directly. */
544 # define ZEND_INTRIN_SSE4_2_NATIVE 1
545 #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_SSE4_2)) || defined(ZEND_WIN32)
546 /* Function resolved by ifunc or MINIT. */
547 # define ZEND_INTRIN_SSE4_2_RESOLVER 1
548 #endif
549 
550 /* Do not use for conditional declaration of API functions! */
551 #if defined(ZEND_INTRIN_SSE4_2_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET)
552 # define ZEND_INTRIN_SSE4_2_FUNC_PROTO 1
553 #elif defined(ZEND_INTRIN_SSE4_2_RESOLVER)
554 # define ZEND_INTRIN_SSE4_2_FUNC_PTR 1
555 #endif
556 
557 #ifdef ZEND_INTRIN_SSE4_2_RESOLVER
558 # ifdef HAVE_FUNC_ATTRIBUTE_TARGET
559 #  define ZEND_INTRIN_SSE4_2_FUNC_DECL(func) ZEND_API func __attribute__((target("sse4.2")))
560 # else
561 #  define ZEND_INTRIN_SSE4_2_FUNC_DECL(func) func
562 # endif
563 #else
564 # define ZEND_INTRIN_SSE4_2_FUNC_DECL(func)
565 #endif
566 
567 #ifdef __PCLMUL__
568 /* Instructions compiled directly. */
569 # define ZEND_INTRIN_PCLMUL_NATIVE 1
570 #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_PCLMUL)) || defined(ZEND_WIN32)
571 /* Function resolved by ifunc or MINIT. */
572 # define ZEND_INTRIN_PCLMUL_RESOLVER 1
573 #endif
574 
575 /* Do not use for conditional declaration of API functions! */
576 #if defined(ZEND_INTRIN_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000))
577 /* __builtin_cpu_supports has pclmul from gcc9 */
578 # define ZEND_INTRIN_PCLMUL_FUNC_PROTO 1
579 #elif defined(ZEND_INTRIN_PCLMUL_RESOLVER)
580 # define ZEND_INTRIN_PCLMUL_FUNC_PTR 1
581 #endif
582 
583 #ifdef ZEND_INTRIN_PCLMUL_RESOLVER
584 # ifdef HAVE_FUNC_ATTRIBUTE_TARGET
585 #  define ZEND_INTRIN_PCLMUL_FUNC_DECL(func) ZEND_API func __attribute__((target("pclmul")))
586 # else
587 #  define ZEND_INTRIN_PCLMUL_FUNC_DECL(func) func
588 # endif
589 #else
590 # define ZEND_INTRIN_PCLMUL_FUNC_DECL(func)
591 #endif
592 
593 #if defined(ZEND_INTRIN_SSE4_2_NATIVE) && defined(ZEND_INTRIN_PCLMUL_NATIVE)
594 /* Instructions compiled directly. */
595 # define ZEND_INTRIN_SSE4_2_PCLMUL_NATIVE 1
596 #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_SSE4_2) && defined(PHP_HAVE_PCLMUL)) || defined(ZEND_WIN32)
597 /* Function resolved by ifunc or MINIT. */
598 # define ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER 1
599 #endif
600 
601 /* Do not use for conditional declaration of API functions! */
602 #if defined(ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000))
603 /* __builtin_cpu_supports has pclmul from gcc9 */
604 # define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PROTO 1
605 #elif defined(ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER)
606 # define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PTR 1
607 #endif
608 
609 #ifdef ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER
610 # ifdef HAVE_FUNC_ATTRIBUTE_TARGET
611 #  define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_DECL(func) ZEND_API func __attribute__((target("sse4.2,pclmul")))
612 # else
613 #  define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_DECL(func) func
614 # endif
615 #else
616 # define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_DECL(func)
617 #endif
618 
619 #ifdef __AVX2__
620 # define ZEND_INTRIN_AVX2_NATIVE 1
621 #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_AVX2)) || defined(ZEND_WIN32)
622 # define ZEND_INTRIN_AVX2_RESOLVER 1
623 #endif
624 
625 /* Do not use for conditional declaration of API functions! */
626 #if defined(ZEND_INTRIN_AVX2_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET)
627 # define ZEND_INTRIN_AVX2_FUNC_PROTO 1
628 #elif defined(ZEND_INTRIN_AVX2_RESOLVER)
629 # define ZEND_INTRIN_AVX2_FUNC_PTR 1
630 #endif
631 
632 #ifdef ZEND_INTRIN_AVX2_RESOLVER
633 # ifdef HAVE_FUNC_ATTRIBUTE_TARGET
634 #  define ZEND_INTRIN_AVX2_FUNC_DECL(func) ZEND_API func __attribute__((target("avx2")))
635 # else
636 #  define ZEND_INTRIN_AVX2_FUNC_DECL(func) func
637 # endif
638 #else
639 # define ZEND_INTRIN_AVX2_FUNC_DECL(func)
640 #endif
641 
642 /* Intrinsics macros end. */
643 
644 #ifdef ZEND_WIN32
645 # define ZEND_SET_ALIGNED(alignment, decl) __declspec(align(alignment)) decl
646 #elif defined(HAVE_ATTRIBUTE_ALIGNED)
647 # define ZEND_SET_ALIGNED(alignment, decl) decl __attribute__ ((__aligned__ (alignment)))
648 #else
649 # define ZEND_SET_ALIGNED(alignment, decl) decl
650 #endif
651 
652 #define ZEND_SLIDE_TO_ALIGNED(alignment, ptr) (((zend_uintptr_t)(ptr) + ((alignment)-1)) & ~((alignment)-1))
653 #define ZEND_SLIDE_TO_ALIGNED16(ptr) ZEND_SLIDE_TO_ALIGNED(Z_UL(16), ptr)
654 
655 #ifdef ZEND_WIN32
656 # define _ZEND_EXPAND_VA(a) a
657 # define ZEND_EXPAND_VA(code) _ZEND_EXPAND_VA(code)
658 #else
659 # define ZEND_EXPAND_VA(code) code
660 #endif
661 
662 /* On CPU with few registers, it's cheaper to reload value then use spill slot */
663 #if defined(__i386__) || (defined(_WIN32) && !defined(_WIN64))
664 # define ZEND_PREFER_RELOAD
665 #endif
666 
667 #if defined(ZEND_WIN32) && defined(_DEBUG)
668 # define ZEND_IGNORE_LEAKS_BEGIN() _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) & ~_CRTDBG_ALLOC_MEM_DF)
669 # define ZEND_IGNORE_LEAKS_END() _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_ALLOC_MEM_DF)
670 #else
671 # define ZEND_IGNORE_LEAKS_BEGIN()
672 # define ZEND_IGNORE_LEAKS_END()
673 #endif
674 
675 /* MSVC yields C4090 when a (const T **) is passed to a (void *); ZEND_VOIDP works around that */
676 #ifdef _MSC_VER
677 # define ZEND_VOIDP(ptr) ((void *) ptr)
678 #else
679 # define ZEND_VOIDP(ptr) (ptr)
680 #endif
681 
682 #if __has_attribute(__indirect_return__)
683 # define ZEND_INDIRECT_RETURN __attribute__((__indirect_return__))
684 #else
685 # define ZEND_INDIRECT_RETURN
686 #endif
687 
688 #endif /* ZEND_PORTABILITY_H */
689