zend_portability.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1998-2018 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 <zeev@php.net> |
  18. +----------------------------------------------------------------------+
  19. */
  20. #ifndef ZEND_PORTABILITY_H
  21. #define ZEND_PORTABILITY_H
  22. #ifdef __cplusplus
  23. #define BEGIN_EXTERN_C() extern "C" {
  24. #define END_EXTERN_C() }
  25. #else
  26. #define BEGIN_EXTERN_C()
  27. #define END_EXTERN_C()
  28. #endif
  29. /*
  30. * general definitions
  31. */
  32. #ifdef ZEND_WIN32
  33. # include "zend_config.w32.h"
  34. # define ZEND_PATHS_SEPARATOR ';'
  35. #elif defined(__riscos__)
  36. # include <zend_config.h>
  37. # define ZEND_PATHS_SEPARATOR ';'
  38. #else
  39. # include <zend_config.h>
  40. # define ZEND_PATHS_SEPARATOR ':'
  41. #endif
  42. #include "../TSRM/TSRM.h"
  43. #include <stdio.h>
  44. #include <assert.h>
  45. #include <math.h>
  46. #ifdef HAVE_UNIX_H
  47. # include <unix.h>
  48. #endif
  49. #ifdef HAVE_STDARG_H
  50. # include <stdarg.h>
  51. #endif
  52. #ifdef HAVE_DLFCN_H
  53. # include <dlfcn.h>
  54. #endif
  55. #ifdef HAVE_LIMITS_H
  56. # include <limits.h>
  57. #endif
  58. #if HAVE_ALLOCA_H && !defined(_ALLOCA_H)
  59. # include <alloca.h>
  60. #endif
  61. #if defined(ZEND_WIN32) && !defined(__clang__)
  62. #include <intrin.h>
  63. #endif
  64. #include "zend_range_check.h"
  65. /* GCC x.y.z supplies __GNUC__ = x and __GNUC_MINOR__ = y */
  66. #ifdef __GNUC__
  67. # define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
  68. #else
  69. # define ZEND_GCC_VERSION 0
  70. #endif
  71. /* Compatibility with non-clang compilers */
  72. #ifndef __has_attribute
  73. # define __has_attribute(x) 0
  74. #endif
  75. #ifndef __has_builtin
  76. # define __has_builtin(x) 0
  77. #endif
  78. #if defined(ZEND_WIN32) && !defined(__clang__)
  79. # define ZEND_ASSUME(c) __assume(c)
  80. #elif ((defined(__GNUC__) && ZEND_GCC_VERSION >= 4005) || __has_builtin(__builtin_unreachable)) && PHP_HAVE_BUILTIN_EXPECT
  81. # define ZEND_ASSUME(c) do { \
  82. if (__builtin_expect(!(c), 0)) __builtin_unreachable(); \
  83. } while (0)
  84. #else
  85. # define ZEND_ASSUME(c)
  86. #endif
  87. #if ZEND_DEBUG
  88. # define ZEND_ASSERT(c) assert(c)
  89. #else
  90. # define ZEND_ASSERT(c) ZEND_ASSUME(c)
  91. #endif
  92. /* Only use this macro if you know for sure that all of the switches values
  93. are covered by its case statements */
  94. #if ZEND_DEBUG
  95. # define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_ASSERT(0); break;
  96. #else
  97. # define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_ASSUME(0); break;
  98. #endif
  99. #if defined(__GNUC__) && __GNUC__ >= 4
  100. # define ZEND_IGNORE_VALUE(x) (({ __typeof__ (x) __x = (x); (void) __x; }))
  101. #else
  102. # define ZEND_IGNORE_VALUE(x) ((void) (x))
  103. #endif
  104. #define zend_quiet_write(...) ZEND_IGNORE_VALUE(write(__VA_ARGS__))
  105. /* all HAVE_XXX test have to be after the include of zend_config above */
  106. #if defined(HAVE_LIBDL) && !defined(ZEND_WIN32)
  107. # if defined(__has_feature)
  108. # if __has_feature(address_sanitizer)
  109. # define __SANITIZE_ADDRESS__
  110. # endif
  111. # endif
  112. # ifndef RTLD_LAZY
  113. # define RTLD_LAZY 1 /* Solaris 1, FreeBSD's (2.1.7.1 and older) */
  114. # endif
  115. # ifndef RTLD_GLOBAL
  116. # define RTLD_GLOBAL 0
  117. # endif
  118. # if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT)
  119. # define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT)
  120. # elif defined(RTLD_DEEPBIND) && !defined(__SANITIZE_ADDRESS__)
  121. # define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND)
  122. # else
  123. # define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL)
  124. # endif
  125. # define DL_UNLOAD dlclose
  126. # if defined(DLSYM_NEEDS_UNDERSCORE)
  127. # define DL_FETCH_SYMBOL(h,s) dlsym((h), "_" s)
  128. # else
  129. # define DL_FETCH_SYMBOL dlsym
  130. # endif
  131. # define DL_ERROR dlerror
  132. # define DL_HANDLE void *
  133. # define ZEND_EXTENSIONS_SUPPORT 1
  134. #elif defined(ZEND_WIN32)
  135. # define DL_LOAD(libname) LoadLibrary(libname)
  136. # define DL_FETCH_SYMBOL GetProcAddress
  137. # define DL_UNLOAD FreeLibrary
  138. # define DL_HANDLE HMODULE
  139. # define ZEND_EXTENSIONS_SUPPORT 1
  140. #else
  141. # define DL_HANDLE void *
  142. # define ZEND_EXTENSIONS_SUPPORT 0
  143. #endif
  144. /* AIX requires this to be the first thing in the file. */
  145. #ifndef __GNUC__
  146. # ifndef HAVE_ALLOCA_H
  147. # ifdef _AIX
  148. # pragma alloca
  149. # else
  150. # ifndef alloca /* predefined by HP cc +Olibcalls */
  151. char *alloca();
  152. # endif
  153. # endif
  154. # endif
  155. #endif
  156. #if ZEND_GCC_VERSION >= 2096 || __has_attribute(__malloc__)
  157. # define ZEND_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
  158. #else
  159. # define ZEND_ATTRIBUTE_MALLOC
  160. #endif
  161. #if ZEND_GCC_VERSION >= 4003 || __has_attribute(alloc_size)
  162. # define ZEND_ATTRIBUTE_ALLOC_SIZE(X) __attribute__ ((alloc_size(X)))
  163. # define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y) __attribute__ ((alloc_size(X,Y)))
  164. #else
  165. # define ZEND_ATTRIBUTE_ALLOC_SIZE(X)
  166. # define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y)
  167. #endif
  168. #if ZEND_GCC_VERSION >= 2007 || __has_attribute(format)
  169. # define ZEND_ATTRIBUTE_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first)))
  170. #else
  171. # define ZEND_ATTRIBUTE_FORMAT(type, idx, first)
  172. #endif
  173. #if (ZEND_GCC_VERSION >= 3001 && !defined(__INTEL_COMPILER)) || __has_attribute(format)
  174. # define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first)))
  175. #else
  176. # define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first)
  177. #endif
  178. #if ZEND_GCC_VERSION >= 3001 || __has_attribute(deprecated)
  179. # define ZEND_ATTRIBUTE_DEPRECATED __attribute__((deprecated))
  180. #elif defined(ZEND_WIN32)
  181. # define ZEND_ATTRIBUTE_DEPRECATED __declspec(deprecated)
  182. #else
  183. # define ZEND_ATTRIBUTE_DEPRECATED
  184. #endif
  185. #if defined(__GNUC__) && ZEND_GCC_VERSION >= 4003
  186. # define ZEND_ATTRIBUTE_UNUSED __attribute__((unused))
  187. # define ZEND_COLD __attribute__((cold))
  188. # define ZEND_HOT __attribute__((hot))
  189. # ifdef __OPTIMIZE__
  190. # define ZEND_OPT_SIZE __attribute__((optimize("Os")))
  191. # define ZEND_OPT_SPEED __attribute__((optimize("Ofast")))
  192. # else
  193. # define ZEND_OPT_SIZE
  194. # define ZEND_OPT_SPEED
  195. # endif
  196. #else
  197. # define ZEND_ATTRIBUTE_UNUSED
  198. # define ZEND_COLD
  199. # define ZEND_HOT
  200. # define ZEND_OPT_SIZE
  201. # define ZEND_OPT_SPEED
  202. #endif
  203. #if defined(__GNUC__) && ZEND_GCC_VERSION >= 5000
  204. # define ZEND_ATTRIBUTE_UNUSED_LABEL __attribute__((cold, unused));
  205. # define ZEND_ATTRIBUTE_COLD_LABEL __attribute__((cold));
  206. # define ZEND_ATTRIBUTE_HOT_LABEL __attribute__((hot));
  207. #else
  208. # define ZEND_ATTRIBUTE_UNUSED_LABEL
  209. # define ZEND_ATTRIBUTE_COLD_LABEL
  210. # define ZEND_ATTRIBUTE_HOT_LABEL
  211. #endif
  212. #if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__)
  213. # define ZEND_FASTCALL __attribute__((fastcall))
  214. #elif defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER == 1700
  215. # define ZEND_FASTCALL __fastcall
  216. #elif defined(_MSC_VER) && _MSC_VER >= 1800 && !defined(__clang__)
  217. # define ZEND_FASTCALL __vectorcall
  218. #else
  219. # define ZEND_FASTCALL
  220. #endif
  221. #ifndef restrict
  222. # if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004
  223. # else
  224. # define __restrict__
  225. # endif
  226. # define restrict __restrict__
  227. #endif
  228. #if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)) || __has_attribute(noreturn)
  229. # define HAVE_NORETURN
  230. # define ZEND_NORETURN __attribute__((noreturn))
  231. #elif defined(ZEND_WIN32)
  232. # define HAVE_NORETURN
  233. # define ZEND_NORETURN __declspec(noreturn)
  234. #else
  235. # define ZEND_NORETURN
  236. #endif
  237. #if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__))
  238. # define HAVE_NORETURN_ALIAS
  239. # define HAVE_ATTRIBUTE_WEAK
  240. #endif
  241. #if ZEND_GCC_VERSION >= 3001 || __has_builtin(__builtin_constant_p)
  242. # define HAVE_BUILTIN_CONSTANT_P
  243. #endif
  244. #ifdef HAVE_BUILTIN_CONSTANT_P
  245. # define ZEND_CONST_COND(_condition, _default) \
  246. (__builtin_constant_p(_condition) ? (_condition) : (_default))
  247. #else
  248. # define ZEND_CONST_COND(_condition, _default) \
  249. (_default)
  250. #endif
  251. #if ZEND_DEBUG
  252. # define zend_always_inline inline
  253. # define zend_never_inline
  254. #else
  255. # if defined(__GNUC__)
  256. # if __GNUC__ >= 3
  257. # define zend_always_inline inline __attribute__((always_inline))
  258. # define zend_never_inline __attribute__((noinline))
  259. # else
  260. # define zend_always_inline inline
  261. # define zend_never_inline
  262. # endif
  263. # elif defined(_MSC_VER)
  264. # define zend_always_inline __forceinline
  265. # define zend_never_inline __declspec(noinline)
  266. # else
  267. # if __has_attribute(always_inline)
  268. # define zend_always_inline inline __attribute__((always_inline))
  269. # else
  270. # define zend_always_inline inline
  271. # endif
  272. # if __has_attribute(noinline)
  273. # define zend_never_inline __attribute__((noinline))
  274. # else
  275. # define zend_never_inline
  276. # endif
  277. # endif
  278. #endif /* ZEND_DEBUG */
  279. #if PHP_HAVE_BUILTIN_EXPECT
  280. # define EXPECTED(condition) __builtin_expect(!!(condition), 1)
  281. # define UNEXPECTED(condition) __builtin_expect(!!(condition), 0)
  282. #else
  283. # define EXPECTED(condition) (condition)
  284. # define UNEXPECTED(condition) (condition)
  285. #endif
  286. #ifndef XtOffsetOf
  287. # if defined(CRAY) || (defined(__ARMCC_VERSION) && !defined(LINUX))
  288. # ifdef __STDC__
  289. # define XtOffset(p_type, field) _Offsetof(p_type, field)
  290. # else
  291. # ifdef CRAY2
  292. # define XtOffset(p_type, field) \
  293. (sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))
  294. # else /* !CRAY2 */
  295. # define XtOffset(p_type, field) ((unsigned int)&(((p_type)NULL)->field))
  296. # endif /* !CRAY2 */
  297. # endif /* __STDC__ */
  298. # else /* ! (CRAY || __arm) */
  299. # define XtOffset(p_type, field) \
  300. ((zend_long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))
  301. # endif /* !CRAY */
  302. # ifdef offsetof
  303. # define XtOffsetOf(s_type, field) offsetof(s_type, field)
  304. # else
  305. # define XtOffsetOf(s_type, field) XtOffset(s_type*, field)
  306. # endif
  307. #endif
  308. #if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN)
  309. # define ZEND_ALLOCA_MAX_SIZE (32 * 1024)
  310. # define ALLOCA_FLAG(name) \
  311. zend_bool name;
  312. # define SET_ALLOCA_FLAG(name) \
  313. name = 1
  314. # define do_alloca_ex(size, limit, use_heap) \
  315. ((use_heap = (UNEXPECTED((size) > (limit)))) ? emalloc(size) : alloca(size))
  316. # define do_alloca(size, use_heap) \
  317. do_alloca_ex(size, ZEND_ALLOCA_MAX_SIZE, use_heap)
  318. # define free_alloca(p, use_heap) \
  319. do { if (UNEXPECTED(use_heap)) efree(p); } while (0)
  320. #else
  321. # define ALLOCA_FLAG(name)
  322. # define SET_ALLOCA_FLAG(name)
  323. # define do_alloca(p, use_heap) emalloc(p)
  324. # define free_alloca(p, use_heap) efree(p)
  325. #endif
  326. #ifdef HAVE_SIGSETJMP
  327. # define SETJMP(a) sigsetjmp(a, 0)
  328. # define LONGJMP(a,b) siglongjmp(a, b)
  329. # define JMP_BUF sigjmp_buf
  330. #else
  331. # define SETJMP(a) setjmp(a)
  332. # define LONGJMP(a,b) longjmp(a, b)
  333. # define JMP_BUF jmp_buf
  334. #endif
  335. #if ZEND_DEBUG
  336. # define ZEND_FILE_LINE_D const char *__zend_filename, const uint32_t __zend_lineno
  337. # define ZEND_FILE_LINE_DC , ZEND_FILE_LINE_D
  338. # define ZEND_FILE_LINE_ORIG_D const char *__zend_orig_filename, const uint32_t __zend_orig_lineno
  339. # define ZEND_FILE_LINE_ORIG_DC , ZEND_FILE_LINE_ORIG_D
  340. # define ZEND_FILE_LINE_RELAY_C __zend_filename, __zend_lineno
  341. # define ZEND_FILE_LINE_RELAY_CC , ZEND_FILE_LINE_RELAY_C
  342. # define ZEND_FILE_LINE_C __FILE__, __LINE__
  343. # define ZEND_FILE_LINE_CC , ZEND_FILE_LINE_C
  344. # define ZEND_FILE_LINE_EMPTY_C NULL, 0
  345. # define ZEND_FILE_LINE_EMPTY_CC , ZEND_FILE_LINE_EMPTY_C
  346. # define ZEND_FILE_LINE_ORIG_RELAY_C __zend_orig_filename, __zend_orig_lineno
  347. # define ZEND_FILE_LINE_ORIG_RELAY_CC , ZEND_FILE_LINE_ORIG_RELAY_C
  348. #else
  349. # define ZEND_FILE_LINE_D void
  350. # define ZEND_FILE_LINE_DC
  351. # define ZEND_FILE_LINE_ORIG_D void
  352. # define ZEND_FILE_LINE_ORIG_DC
  353. # define ZEND_FILE_LINE_RELAY_C
  354. # define ZEND_FILE_LINE_RELAY_CC
  355. # define ZEND_FILE_LINE_C
  356. # define ZEND_FILE_LINE_CC
  357. # define ZEND_FILE_LINE_EMPTY_C
  358. # define ZEND_FILE_LINE_EMPTY_CC
  359. # define ZEND_FILE_LINE_ORIG_RELAY_C
  360. # define ZEND_FILE_LINE_ORIG_RELAY_CC
  361. #endif /* ZEND_DEBUG */
  362. #if ZEND_DEBUG
  363. # define Z_DBG(expr) (expr)
  364. #else
  365. # define Z_DBG(expr)
  366. #endif
  367. #ifdef ZTS
  368. # define ZTS_V 1
  369. #else
  370. # define ZTS_V 0
  371. #endif
  372. #ifndef LONG_MAX
  373. # define LONG_MAX 2147483647L
  374. #endif
  375. #ifndef LONG_MIN
  376. # define LONG_MIN (- LONG_MAX - 1)
  377. #endif
  378. #define MAX_LENGTH_OF_DOUBLE 32
  379. #undef MIN
  380. #undef MAX
  381. #define MAX(a, b) (((a)>(b))?(a):(b))
  382. #define MIN(a, b) (((a)<(b))?(a):(b))
  383. #define ZEND_BIT_TEST(bits, bit) \
  384. (((bits)[(bit) / (sizeof((bits)[0])*8)] >> ((bit) & (sizeof((bits)[0])*8-1))) & 1)
  385. /* We always define a function, even if there's a macro or expression we could
  386. * alias, so that using it in contexts where we can't make function calls
  387. * won't fail to compile on some machines and not others.
  388. */
  389. static zend_always_inline double _zend_get_inf(void) /* {{{ */
  390. {
  391. #ifdef INFINITY
  392. return INFINITY;
  393. #elif HAVE_HUGE_VAL_INF
  394. return HUGE_VAL;
  395. #elif defined(__i386__) || defined(_X86_) || defined(ALPHA) || defined(_ALPHA) || defined(__alpha)
  396. # define _zend_DOUBLE_INFINITY_HIGH 0x7ff00000
  397. double val = 0.0;
  398. ((uint32_t*)&val)[1] = _zend_DOUBLE_INFINITY_HIGH;
  399. ((uint32_t*)&val)[0] = 0;
  400. return val;
  401. #elif HAVE_ATOF_ACCEPTS_INF
  402. return atof("INF");
  403. #else
  404. return 1.0/0.0;
  405. #endif
  406. } /* }}} */
  407. #define ZEND_INFINITY (_zend_get_inf())
  408. static zend_always_inline double _zend_get_nan(void) /* {{{ */
  409. {
  410. #ifdef NAN
  411. return NAN;
  412. #elif HAVE_HUGE_VAL_NAN
  413. return HUGE_VAL + -HUGE_VAL;
  414. #elif defined(__i386__) || defined(_X86_) || defined(ALPHA) || defined(_ALPHA) || defined(__alpha)
  415. # define _zend_DOUBLE_QUIET_NAN_HIGH 0xfff80000
  416. double val = 0.0;
  417. ((uint32_t*)&val)[1] = _zend_DOUBLE_QUIET_NAN_HIGH;
  418. ((uint32_t*)&val)[0] = 0;
  419. return val;
  420. #elif HAVE_ATOF_ACCEPTS_NAN
  421. return atof("NAN");
  422. #else
  423. return 0.0/0.0;
  424. #endif
  425. } /* }}} */
  426. #define ZEND_NAN (_zend_get_nan())
  427. #define ZEND_STRL(str) (str), (sizeof(str)-1)
  428. #define ZEND_STRS(str) (str), (sizeof(str))
  429. #define ZEND_NORMALIZE_BOOL(n) \
  430. ((n) ? (((n)<0) ? -1 : 1) : 0)
  431. #define ZEND_TRUTH(x) ((x) ? 1 : 0)
  432. #define ZEND_LOG_XOR(a, b) (ZEND_TRUTH(a) ^ ZEND_TRUTH(b))
  433. #define ZEND_MAX_RESERVED_RESOURCES 6
  434. /* excpt.h on Digital Unix 4.0 defines function_table */
  435. #undef function_table
  436. #ifdef ZEND_WIN32
  437. #define ZEND_SECURE_ZERO(var, size) RtlSecureZeroMemory((var), (size))
  438. #else
  439. #define ZEND_SECURE_ZERO(var, size) explicit_bzero((var), (size))
  440. #endif
  441. /* This check should only be used on network socket, not file descriptors */
  442. #ifdef ZEND_WIN32
  443. #define ZEND_VALID_SOCKET(sock) (INVALID_SOCKET != (sock))
  444. #else
  445. #define ZEND_VALID_SOCKET(sock) ((sock) >= 0)
  446. #endif
  447. /* va_copy() is __va_copy() in old gcc versions.
  448. * According to the autoconf manual, using
  449. * memcpy(&dst, &src, sizeof(va_list))
  450. * gives maximum portability. */
  451. #ifndef va_copy
  452. # ifdef __va_copy
  453. # define va_copy(dest, src) __va_copy((dest), (src))
  454. # else
  455. # define va_copy(dest, src) memcpy(&(dest), &(src), sizeof(va_list))
  456. # endif
  457. #endif
  458. /* Intrinsics macros start. */
  459. #if defined(HAVE_FUNC_ATTRIBUTE_IFUNC) && defined(HAVE_FUNC_ATTRIBUTE_TARGET)
  460. # define ZEND_INTRIN_HAVE_IFUNC_TARGET 1
  461. #endif
  462. #if (defined(__i386__) || defined(__x86_64__))
  463. # if PHP_HAVE_SSSE3_INSTRUCTIONS && defined(HAVE_TMMINTRIN_H)
  464. # define PHP_HAVE_SSSE3
  465. # endif
  466. # if PHP_HAVE_SSE4_2_INSTRUCTIONS && defined(HAVE_NMMINTRIN_H)
  467. # define PHP_HAVE_SSE4_2
  468. # endif
  469. /*
  470. * AVX2 support was added in gcc 4.7, but AVX2 intrinsics don't work in
  471. * __attribute__((target("avx2"))) functions until gcc 4.9.
  472. */
  473. # if PHP_HAVE_AVX2_INSTRUCTIONS && defined(HAVE_IMMINTRIN_H) && \
  474. (defined(__llvm__) || defined(__clang__) || (defined(__GNUC__) && ZEND_GCC_VERSION >= 4009))
  475. # define PHP_HAVE_AVX2
  476. # endif
  477. #endif
  478. #ifdef __SSSE3__
  479. /* Instructions compiled directly. */
  480. # define ZEND_INTRIN_SSSE3_NATIVE 1
  481. #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_SSSE3)) || defined(ZEND_WIN32)
  482. /* Function resolved by ifunc or MINIT. */
  483. # define ZEND_INTRIN_SSSE3_RESOLVER 1
  484. #endif
  485. #if ZEND_INTRIN_SSSE3_RESOLVER && ZEND_INTRIN_HAVE_IFUNC_TARGET
  486. # define ZEND_INTRIN_SSSE3_FUNC_PROTO 1
  487. #elif ZEND_INTRIN_SSSE3_RESOLVER
  488. # define ZEND_INTRIN_SSSE3_FUNC_PTR 1
  489. #endif
  490. #if ZEND_INTRIN_SSSE3_RESOLVER
  491. # if defined(HAVE_FUNC_ATTRIBUTE_TARGET)
  492. # define ZEND_INTRIN_SSSE3_FUNC_DECL(func) ZEND_API func __attribute__((target("ssse3")))
  493. # else
  494. # define ZEND_INTRIN_SSSE3_FUNC_DECL(func) func
  495. # endif
  496. #else
  497. # define ZEND_INTRIN_SSSE3_FUNC_DECL(func)
  498. #endif
  499. #if defined(HAVE_SSE4_2_DEF) || (defined(ZEND_WIN32) && defined(__SSE4_2__))
  500. /* Instructions compiled directly. */
  501. # define ZEND_INTRIN_SSE4_2_NATIVE 1
  502. #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_SSE4_2)) || defined(ZEND_WIN32)
  503. /* Function resolved by ifunc or MINIT. */
  504. # define ZEND_INTRIN_SSE4_2_RESOLVER 1
  505. #endif
  506. #if ZEND_INTRIN_SSE4_2_RESOLVER && ZEND_INTRIN_HAVE_IFUNC_TARGET
  507. # define ZEND_INTRIN_SSE4_2_FUNC_PROTO 1
  508. #elif ZEND_INTRIN_SSE4_2_RESOLVER
  509. # define ZEND_INTRIN_SSE4_2_FUNC_PTR 1
  510. #endif
  511. #if ZEND_INTRIN_SSE4_2_RESOLVER
  512. # if defined(HAVE_FUNC_ATTRIBUTE_TARGET)
  513. # define ZEND_INTRIN_SSE4_2_FUNC_DECL(func) ZEND_API func __attribute__((target("sse4.2")))
  514. # else
  515. # define ZEND_INTRIN_SSE4_2_FUNC_DECL(func) func
  516. # endif
  517. #else
  518. # define ZEND_INTRIN_SSE4_2_FUNC_DECL(func)
  519. #endif
  520. #ifdef __AVX2__
  521. # define ZEND_INTRIN_AVX2_NATIVE 1
  522. #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_AVX2)) || defined(ZEND_WIN32)
  523. # define ZEND_INTRIN_AVX2_RESOLVER 1
  524. #endif
  525. #if ZEND_INTRIN_AVX2_RESOLVER && ZEND_INTRIN_HAVE_IFUNC_TARGET
  526. # define ZEND_INTRIN_AVX2_FUNC_PROTO 1
  527. #elif ZEND_INTRIN_AVX2_RESOLVER
  528. # define ZEND_INTRIN_AVX2_FUNC_PTR 1
  529. #endif
  530. #if ZEND_INTRIN_AVX2_RESOLVER
  531. # if defined(HAVE_FUNC_ATTRIBUTE_TARGET)
  532. # define ZEND_INTRIN_AVX2_FUNC_DECL(func) ZEND_API func __attribute__((target("avx2")))
  533. # else
  534. # define ZEND_INTRIN_AVX2_FUNC_DECL(func) func
  535. # endif
  536. #else
  537. # define ZEND_INTRIN_AVX2_FUNC_DECL(func)
  538. #endif
  539. /* Intrinsics macros end. */
  540. #ifdef ZEND_WIN32
  541. # define ZEND_SET_ALIGNED(alignment, decl) __declspec(align(alignment)) decl
  542. #elif HAVE_ATTRIBUTE_ALIGNED
  543. # define ZEND_SET_ALIGNED(alignment, decl) decl __attribute__ ((__aligned__ (alignment)))
  544. #else
  545. # define ZEND_SET_ALIGNED(alignment, decl) decl
  546. #endif
  547. #define ZEND_SLIDE_TO_ALIGNED(alignment, ptr) (((zend_uintptr_t)(ptr) + ((alignment)-1)) & ~((alignment)-1))
  548. #define ZEND_SLIDE_TO_ALIGNED16(ptr) ZEND_SLIDE_TO_ALIGNED(Z_UL(16), ptr)
  549. #ifdef ZEND_WIN32
  550. # define _ZEND_EXPAND_VA(a) a
  551. # define ZEND_EXPAND_VA(code) _ZEND_EXPAND_VA(code)
  552. #else
  553. # define ZEND_EXPAND_VA(code) code
  554. #endif
  555. #endif /* ZEND_PORTABILITY_H */
  556. /*
  557. * Local variables:
  558. * tab-width: 4
  559. * c-basic-offset: 4
  560. * indent-tabs-mode: t
  561. * End:
  562. * vim600: sw=4 ts=4 fdm=marker
  563. * vim<600: sw=4 ts=4
  564. */