zend_string.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  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: Dmitry Stogov <dmitry@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. #ifndef ZEND_STRING_H
  19. #define ZEND_STRING_H
  20. #include "zend.h"
  21. BEGIN_EXTERN_C()
  22. typedef void (*zend_string_copy_storage_func_t)(void);
  23. typedef zend_string *(ZEND_FASTCALL *zend_new_interned_string_func_t)(zend_string *str);
  24. typedef zend_string *(ZEND_FASTCALL *zend_string_init_interned_func_t)(const char *str, size_t size, bool permanent);
  25. typedef zend_string *(ZEND_FASTCALL *zend_string_init_existing_interned_func_t)(const char *str, size_t size, bool permanent);
  26. ZEND_API extern zend_new_interned_string_func_t zend_new_interned_string;
  27. ZEND_API extern zend_string_init_interned_func_t zend_string_init_interned;
  28. /* Init an interned string if it already exists, but do not create a new one if it does not. */
  29. ZEND_API extern zend_string_init_existing_interned_func_t zend_string_init_existing_interned;
  30. ZEND_API zend_ulong ZEND_FASTCALL zend_string_hash_func(zend_string *str);
  31. ZEND_API zend_ulong ZEND_FASTCALL zend_hash_func(const char *str, size_t len);
  32. ZEND_API zend_string* ZEND_FASTCALL zend_interned_string_find_permanent(zend_string *str);
  33. ZEND_API zend_string *zend_string_concat2(
  34. const char *str1, size_t str1_len,
  35. const char *str2, size_t str2_len);
  36. ZEND_API zend_string *zend_string_concat3(
  37. const char *str1, size_t str1_len,
  38. const char *str2, size_t str2_len,
  39. const char *str3, size_t str3_len);
  40. ZEND_API void zend_interned_strings_init(void);
  41. ZEND_API void zend_interned_strings_dtor(void);
  42. ZEND_API void zend_interned_strings_activate(void);
  43. ZEND_API void zend_interned_strings_deactivate(void);
  44. ZEND_API void zend_interned_strings_set_request_storage_handlers(
  45. zend_new_interned_string_func_t handler,
  46. zend_string_init_interned_func_t init_handler,
  47. zend_string_init_existing_interned_func_t init_existing_handler);
  48. ZEND_API void zend_interned_strings_switch_storage(bool request);
  49. ZEND_API extern zend_string *zend_empty_string;
  50. ZEND_API extern zend_string *zend_one_char_string[256];
  51. ZEND_API extern zend_string **zend_known_strings;
  52. END_EXTERN_C()
  53. /* Shortcuts */
  54. #define ZSTR_VAL(zstr) (zstr)->val
  55. #define ZSTR_LEN(zstr) (zstr)->len
  56. #define ZSTR_H(zstr) (zstr)->h
  57. #define ZSTR_HASH(zstr) zend_string_hash_val(zstr)
  58. /* Compatibility macros */
  59. #define IS_INTERNED(s) ZSTR_IS_INTERNED(s)
  60. #define STR_EMPTY_ALLOC() ZSTR_EMPTY_ALLOC()
  61. #define _STR_HEADER_SIZE _ZSTR_HEADER_SIZE
  62. #define STR_ALLOCA_ALLOC(str, _len, use_heap) ZSTR_ALLOCA_ALLOC(str, _len, use_heap)
  63. #define STR_ALLOCA_INIT(str, s, len, use_heap) ZSTR_ALLOCA_INIT(str, s, len, use_heap)
  64. #define STR_ALLOCA_FREE(str, use_heap) ZSTR_ALLOCA_FREE(str, use_heap)
  65. /*---*/
  66. #define ZSTR_IS_INTERNED(s) (GC_FLAGS(s) & IS_STR_INTERNED)
  67. #define ZSTR_EMPTY_ALLOC() zend_empty_string
  68. #define ZSTR_CHAR(c) zend_one_char_string[c]
  69. #define ZSTR_KNOWN(idx) zend_known_strings[idx]
  70. #define _ZSTR_HEADER_SIZE XtOffsetOf(zend_string, val)
  71. #define _ZSTR_STRUCT_SIZE(len) (_ZSTR_HEADER_SIZE + len + 1)
  72. #define ZSTR_MAX_OVERHEAD (ZEND_MM_ALIGNED_SIZE(_ZSTR_HEADER_SIZE + 1))
  73. #define ZSTR_MAX_LEN (SIZE_MAX - ZSTR_MAX_OVERHEAD)
  74. #define ZSTR_ALLOCA_ALLOC(str, _len, use_heap) do { \
  75. (str) = (zend_string *)do_alloca(ZEND_MM_ALIGNED_SIZE_EX(_ZSTR_STRUCT_SIZE(_len), 8), (use_heap)); \
  76. GC_SET_REFCOUNT(str, 1); \
  77. GC_TYPE_INFO(str) = GC_STRING; \
  78. ZSTR_H(str) = 0; \
  79. ZSTR_LEN(str) = _len; \
  80. } while (0)
  81. #define ZSTR_ALLOCA_INIT(str, s, len, use_heap) do { \
  82. ZSTR_ALLOCA_ALLOC(str, len, use_heap); \
  83. memcpy(ZSTR_VAL(str), (s), (len)); \
  84. ZSTR_VAL(str)[(len)] = '\0'; \
  85. } while (0)
  86. #define ZSTR_ALLOCA_FREE(str, use_heap) free_alloca(str, use_heap)
  87. /*---*/
  88. static zend_always_inline zend_ulong zend_string_hash_val(zend_string *s)
  89. {
  90. return ZSTR_H(s) ? ZSTR_H(s) : zend_string_hash_func(s);
  91. }
  92. static zend_always_inline void zend_string_forget_hash_val(zend_string *s)
  93. {
  94. ZSTR_H(s) = 0;
  95. GC_DEL_FLAGS(s, IS_STR_VALID_UTF8);
  96. }
  97. static zend_always_inline uint32_t zend_string_refcount(const zend_string *s)
  98. {
  99. if (!ZSTR_IS_INTERNED(s)) {
  100. return GC_REFCOUNT(s);
  101. }
  102. return 1;
  103. }
  104. static zend_always_inline uint32_t zend_string_addref(zend_string *s)
  105. {
  106. if (!ZSTR_IS_INTERNED(s)) {
  107. return GC_ADDREF(s);
  108. }
  109. return 1;
  110. }
  111. static zend_always_inline uint32_t zend_string_delref(zend_string *s)
  112. {
  113. if (!ZSTR_IS_INTERNED(s)) {
  114. return GC_DELREF(s);
  115. }
  116. return 1;
  117. }
  118. static zend_always_inline zend_string *zend_string_alloc(size_t len, bool persistent)
  119. {
  120. zend_string *ret = (zend_string *)pemalloc(ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(len)), persistent);
  121. GC_SET_REFCOUNT(ret, 1);
  122. GC_TYPE_INFO(ret) = GC_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << GC_FLAGS_SHIFT);
  123. ZSTR_H(ret) = 0;
  124. ZSTR_LEN(ret) = len;
  125. return ret;
  126. }
  127. static zend_always_inline zend_string *zend_string_safe_alloc(size_t n, size_t m, size_t l, bool persistent)
  128. {
  129. zend_string *ret = (zend_string *)safe_pemalloc(n, m, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(l)), persistent);
  130. GC_SET_REFCOUNT(ret, 1);
  131. GC_TYPE_INFO(ret) = GC_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << GC_FLAGS_SHIFT);
  132. ZSTR_H(ret) = 0;
  133. ZSTR_LEN(ret) = (n * m) + l;
  134. return ret;
  135. }
  136. static zend_always_inline zend_string *zend_string_init(const char *str, size_t len, bool persistent)
  137. {
  138. zend_string *ret = zend_string_alloc(len, persistent);
  139. memcpy(ZSTR_VAL(ret), str, len);
  140. ZSTR_VAL(ret)[len] = '\0';
  141. return ret;
  142. }
  143. static zend_always_inline zend_string *zend_string_init_fast(const char *str, size_t len)
  144. {
  145. if (len > 1) {
  146. return zend_string_init(str, len, 0);
  147. } else if (len == 0) {
  148. return zend_empty_string;
  149. } else /* if (len == 1) */ {
  150. return ZSTR_CHAR((zend_uchar) *str);
  151. }
  152. }
  153. static zend_always_inline zend_string *zend_string_copy(zend_string *s)
  154. {
  155. if (!ZSTR_IS_INTERNED(s)) {
  156. GC_ADDREF(s);
  157. }
  158. return s;
  159. }
  160. static zend_always_inline zend_string *zend_string_dup(zend_string *s, bool persistent)
  161. {
  162. if (ZSTR_IS_INTERNED(s)) {
  163. return s;
  164. } else {
  165. return zend_string_init(ZSTR_VAL(s), ZSTR_LEN(s), persistent);
  166. }
  167. }
  168. static zend_always_inline zend_string *zend_string_separate(zend_string *s, bool persistent)
  169. {
  170. if (ZSTR_IS_INTERNED(s) || GC_REFCOUNT(s) > 1) {
  171. if (!ZSTR_IS_INTERNED(s)) {
  172. GC_DELREF(s);
  173. }
  174. return zend_string_init(ZSTR_VAL(s), ZSTR_LEN(s), persistent);
  175. }
  176. zend_string_forget_hash_val(s);
  177. return s;
  178. }
  179. static zend_always_inline zend_string *zend_string_realloc(zend_string *s, size_t len, bool persistent)
  180. {
  181. zend_string *ret;
  182. if (!ZSTR_IS_INTERNED(s)) {
  183. if (EXPECTED(GC_REFCOUNT(s) == 1)) {
  184. ret = (zend_string *)perealloc(s, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(len)), persistent);
  185. ZSTR_LEN(ret) = len;
  186. zend_string_forget_hash_val(ret);
  187. return ret;
  188. }
  189. }
  190. ret = zend_string_alloc(len, persistent);
  191. memcpy(ZSTR_VAL(ret), ZSTR_VAL(s), MIN(len, ZSTR_LEN(s)) + 1);
  192. if (!ZSTR_IS_INTERNED(s)) {
  193. GC_DELREF(s);
  194. }
  195. return ret;
  196. }
  197. static zend_always_inline zend_string *zend_string_extend(zend_string *s, size_t len, bool persistent)
  198. {
  199. zend_string *ret;
  200. ZEND_ASSERT(len >= ZSTR_LEN(s));
  201. if (!ZSTR_IS_INTERNED(s)) {
  202. if (EXPECTED(GC_REFCOUNT(s) == 1)) {
  203. ret = (zend_string *)perealloc(s, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(len)), persistent);
  204. ZSTR_LEN(ret) = len;
  205. zend_string_forget_hash_val(ret);
  206. return ret;
  207. }
  208. }
  209. ret = zend_string_alloc(len, persistent);
  210. memcpy(ZSTR_VAL(ret), ZSTR_VAL(s), ZSTR_LEN(s) + 1);
  211. if (!ZSTR_IS_INTERNED(s)) {
  212. GC_DELREF(s);
  213. }
  214. return ret;
  215. }
  216. static zend_always_inline zend_string *zend_string_truncate(zend_string *s, size_t len, bool persistent)
  217. {
  218. zend_string *ret;
  219. ZEND_ASSERT(len <= ZSTR_LEN(s));
  220. if (!ZSTR_IS_INTERNED(s)) {
  221. if (EXPECTED(GC_REFCOUNT(s) == 1)) {
  222. ret = (zend_string *)perealloc(s, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(len)), persistent);
  223. ZSTR_LEN(ret) = len;
  224. zend_string_forget_hash_val(ret);
  225. return ret;
  226. }
  227. }
  228. ret = zend_string_alloc(len, persistent);
  229. memcpy(ZSTR_VAL(ret), ZSTR_VAL(s), len + 1);
  230. if (!ZSTR_IS_INTERNED(s)) {
  231. GC_DELREF(s);
  232. }
  233. return ret;
  234. }
  235. static zend_always_inline zend_string *zend_string_safe_realloc(zend_string *s, size_t n, size_t m, size_t l, bool persistent)
  236. {
  237. zend_string *ret;
  238. if (!ZSTR_IS_INTERNED(s)) {
  239. if (GC_REFCOUNT(s) == 1) {
  240. ret = (zend_string *)safe_perealloc(s, n, m, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(l)), persistent);
  241. ZSTR_LEN(ret) = (n * m) + l;
  242. zend_string_forget_hash_val(ret);
  243. return ret;
  244. }
  245. }
  246. ret = zend_string_safe_alloc(n, m, l, persistent);
  247. memcpy(ZSTR_VAL(ret), ZSTR_VAL(s), MIN((n * m) + l, ZSTR_LEN(s)) + 1);
  248. if (!ZSTR_IS_INTERNED(s)) {
  249. GC_DELREF(s);
  250. }
  251. return ret;
  252. }
  253. static zend_always_inline void zend_string_free(zend_string *s)
  254. {
  255. if (!ZSTR_IS_INTERNED(s)) {
  256. ZEND_ASSERT(GC_REFCOUNT(s) <= 1);
  257. pefree(s, GC_FLAGS(s) & IS_STR_PERSISTENT);
  258. }
  259. }
  260. static zend_always_inline void zend_string_efree(zend_string *s)
  261. {
  262. ZEND_ASSERT(!ZSTR_IS_INTERNED(s));
  263. ZEND_ASSERT(GC_REFCOUNT(s) <= 1);
  264. ZEND_ASSERT(!(GC_FLAGS(s) & IS_STR_PERSISTENT));
  265. efree(s);
  266. }
  267. static zend_always_inline void zend_string_release(zend_string *s)
  268. {
  269. if (!ZSTR_IS_INTERNED(s)) {
  270. if (GC_DELREF(s) == 0) {
  271. pefree(s, GC_FLAGS(s) & IS_STR_PERSISTENT);
  272. }
  273. }
  274. }
  275. static zend_always_inline void zend_string_release_ex(zend_string *s, bool persistent)
  276. {
  277. if (!ZSTR_IS_INTERNED(s)) {
  278. if (GC_DELREF(s) == 0) {
  279. if (persistent) {
  280. ZEND_ASSERT(GC_FLAGS(s) & IS_STR_PERSISTENT);
  281. free(s);
  282. } else {
  283. ZEND_ASSERT(!(GC_FLAGS(s) & IS_STR_PERSISTENT));
  284. efree(s);
  285. }
  286. }
  287. }
  288. }
  289. #if defined(__GNUC__) && (defined(__i386__) || (defined(__x86_64__) && !defined(__ILP32__)))
  290. BEGIN_EXTERN_C()
  291. ZEND_API bool ZEND_FASTCALL zend_string_equal_val(zend_string *s1, zend_string *s2);
  292. END_EXTERN_C()
  293. #else
  294. static zend_always_inline bool zend_string_equal_val(zend_string *s1, zend_string *s2)
  295. {
  296. return !memcmp(ZSTR_VAL(s1), ZSTR_VAL(s2), ZSTR_LEN(s1));
  297. }
  298. #endif
  299. static zend_always_inline bool zend_string_equal_content(zend_string *s1, zend_string *s2)
  300. {
  301. return ZSTR_LEN(s1) == ZSTR_LEN(s2) && zend_string_equal_val(s1, s2);
  302. }
  303. static zend_always_inline bool zend_string_equals(zend_string *s1, zend_string *s2)
  304. {
  305. return s1 == s2 || zend_string_equal_content(s1, s2);
  306. }
  307. #define zend_string_equals_ci(s1, s2) \
  308. (ZSTR_LEN(s1) == ZSTR_LEN(s2) && !zend_binary_strcasecmp(ZSTR_VAL(s1), ZSTR_LEN(s1), ZSTR_VAL(s2), ZSTR_LEN(s2)))
  309. #define zend_string_equals_literal_ci(str, c) \
  310. (ZSTR_LEN(str) == sizeof(c) - 1 && !zend_binary_strcasecmp(ZSTR_VAL(str), ZSTR_LEN(str), (c), sizeof(c) - 1))
  311. #define zend_string_equals_literal(str, literal) \
  312. (ZSTR_LEN(str) == sizeof(literal)-1 && !memcmp(ZSTR_VAL(str), literal, sizeof(literal) - 1))
  313. /*
  314. * DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
  315. *
  316. * This is Daniel J. Bernstein's popular `times 33' hash function as
  317. * posted by him years ago on comp.lang.c. It basically uses a function
  318. * like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best
  319. * known hash functions for strings. Because it is both computed very
  320. * fast and distributes very well.
  321. *
  322. * The magic of number 33, i.e. why it works better than many other
  323. * constants, prime or not, has never been adequately explained by
  324. * anyone. So I try an explanation: if one experimentally tests all
  325. * multipliers between 1 and 256 (as RSE did now) one detects that even
  326. * numbers are not usable at all. The remaining 128 odd numbers
  327. * (except for the number 1) work more or less all equally well. They
  328. * all distribute in an acceptable way and this way fill a hash table
  329. * with an average percent of approx. 86%.
  330. *
  331. * If one compares the Chi^2 values of the variants, the number 33 not
  332. * even has the best value. But the number 33 and a few other equally
  333. * good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
  334. * advantage to the remaining numbers in the large set of possible
  335. * multipliers: their multiply operation can be replaced by a faster
  336. * operation based on just one shift plus either a single addition
  337. * or subtraction operation. And because a hash function has to both
  338. * distribute good _and_ has to be very fast to compute, those few
  339. * numbers should be preferred and seems to be the reason why Daniel J.
  340. * Bernstein also preferred it.
  341. *
  342. *
  343. * -- Ralf S. Engelschall <rse@engelschall.com>
  344. */
  345. static zend_always_inline zend_ulong zend_inline_hash_func(const char *str, size_t len)
  346. {
  347. zend_ulong hash = Z_UL(5381);
  348. #if defined(_WIN32) || defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
  349. /* Version with multiplication works better on modern CPU */
  350. for (; len >= 8; len -= 8, str += 8) {
  351. # if defined(__aarch64__) && !defined(WORDS_BIGENDIAN)
  352. /* On some architectures it is beneficial to load 8 bytes at a
  353. time and extract each byte with a bit field extract instr. */
  354. uint64_t chunk;
  355. memcpy(&chunk, str, sizeof(chunk));
  356. hash =
  357. hash * 33 * 33 * 33 * 33 +
  358. ((chunk >> (8 * 0)) & 0xff) * 33 * 33 * 33 +
  359. ((chunk >> (8 * 1)) & 0xff) * 33 * 33 +
  360. ((chunk >> (8 * 2)) & 0xff) * 33 +
  361. ((chunk >> (8 * 3)) & 0xff);
  362. hash =
  363. hash * 33 * 33 * 33 * 33 +
  364. ((chunk >> (8 * 4)) & 0xff) * 33 * 33 * 33 +
  365. ((chunk >> (8 * 5)) & 0xff) * 33 * 33 +
  366. ((chunk >> (8 * 6)) & 0xff) * 33 +
  367. ((chunk >> (8 * 7)) & 0xff);
  368. # else
  369. hash =
  370. hash * 33 * 33 * 33 * 33 +
  371. str[0] * 33 * 33 * 33 +
  372. str[1] * 33 * 33 +
  373. str[2] * 33 +
  374. str[3];
  375. hash =
  376. hash * 33 * 33 * 33 * 33 +
  377. str[4] * 33 * 33 * 33 +
  378. str[5] * 33 * 33 +
  379. str[6] * 33 +
  380. str[7];
  381. # endif
  382. }
  383. if (len >= 4) {
  384. hash =
  385. hash * 33 * 33 * 33 * 33 +
  386. str[0] * 33 * 33 * 33 +
  387. str[1] * 33 * 33 +
  388. str[2] * 33 +
  389. str[3];
  390. len -= 4;
  391. str += 4;
  392. }
  393. if (len >= 2) {
  394. if (len > 2) {
  395. hash =
  396. hash * 33 * 33 * 33 +
  397. str[0] * 33 * 33 +
  398. str[1] * 33 +
  399. str[2];
  400. } else {
  401. hash =
  402. hash * 33 * 33 +
  403. str[0] * 33 +
  404. str[1];
  405. }
  406. } else if (len != 0) {
  407. hash = hash * 33 + *str;
  408. }
  409. #else
  410. /* variant with the hash unrolled eight times */
  411. for (; len >= 8; len -= 8) {
  412. hash = ((hash << 5) + hash) + *str++;
  413. hash = ((hash << 5) + hash) + *str++;
  414. hash = ((hash << 5) + hash) + *str++;
  415. hash = ((hash << 5) + hash) + *str++;
  416. hash = ((hash << 5) + hash) + *str++;
  417. hash = ((hash << 5) + hash) + *str++;
  418. hash = ((hash << 5) + hash) + *str++;
  419. hash = ((hash << 5) + hash) + *str++;
  420. }
  421. switch (len) {
  422. case 7: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
  423. case 6: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
  424. case 5: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
  425. case 4: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
  426. case 3: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
  427. case 2: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
  428. case 1: hash = ((hash << 5) + hash) + *str++; break;
  429. case 0: break;
  430. EMPTY_SWITCH_DEFAULT_CASE()
  431. }
  432. #endif
  433. /* Hash value can't be zero, so we always set the high bit */
  434. #if SIZEOF_ZEND_LONG == 8
  435. return hash | Z_UL(0x8000000000000000);
  436. #elif SIZEOF_ZEND_LONG == 4
  437. return hash | Z_UL(0x80000000);
  438. #else
  439. # error "Unknown SIZEOF_ZEND_LONG"
  440. #endif
  441. }
  442. #define ZEND_KNOWN_STRINGS(_) \
  443. _(ZEND_STR_FILE, "file") \
  444. _(ZEND_STR_LINE, "line") \
  445. _(ZEND_STR_FUNCTION, "function") \
  446. _(ZEND_STR_CLASS, "class") \
  447. _(ZEND_STR_OBJECT, "object") \
  448. _(ZEND_STR_TYPE, "type") \
  449. _(ZEND_STR_OBJECT_OPERATOR, "->") \
  450. _(ZEND_STR_PAAMAYIM_NEKUDOTAYIM, "::") \
  451. _(ZEND_STR_ARGS, "args") \
  452. _(ZEND_STR_UNKNOWN, "unknown") \
  453. _(ZEND_STR_UNKNOWN_CAPITALIZED, "Unknown") \
  454. _(ZEND_STR_EVAL, "eval") \
  455. _(ZEND_STR_INCLUDE, "include") \
  456. _(ZEND_STR_REQUIRE, "require") \
  457. _(ZEND_STR_INCLUDE_ONCE, "include_once") \
  458. _(ZEND_STR_REQUIRE_ONCE, "require_once") \
  459. _(ZEND_STR_SCALAR, "scalar") \
  460. _(ZEND_STR_ERROR_REPORTING, "error_reporting") \
  461. _(ZEND_STR_STATIC, "static") \
  462. _(ZEND_STR_THIS, "this") \
  463. _(ZEND_STR_VALUE, "value") \
  464. _(ZEND_STR_KEY, "key") \
  465. _(ZEND_STR_MAGIC_INVOKE, "__invoke") \
  466. _(ZEND_STR_PREVIOUS, "previous") \
  467. _(ZEND_STR_CODE, "code") \
  468. _(ZEND_STR_MESSAGE, "message") \
  469. _(ZEND_STR_SEVERITY, "severity") \
  470. _(ZEND_STR_STRING, "string") \
  471. _(ZEND_STR_TRACE, "trace") \
  472. _(ZEND_STR_SCHEME, "scheme") \
  473. _(ZEND_STR_HOST, "host") \
  474. _(ZEND_STR_PORT, "port") \
  475. _(ZEND_STR_USER, "user") \
  476. _(ZEND_STR_PASS, "pass") \
  477. _(ZEND_STR_PATH, "path") \
  478. _(ZEND_STR_QUERY, "query") \
  479. _(ZEND_STR_FRAGMENT, "fragment") \
  480. _(ZEND_STR_NULL, "NULL") \
  481. _(ZEND_STR_BOOLEAN, "boolean") \
  482. _(ZEND_STR_INTEGER, "integer") \
  483. _(ZEND_STR_DOUBLE, "double") \
  484. _(ZEND_STR_ARRAY, "array") \
  485. _(ZEND_STR_RESOURCE, "resource") \
  486. _(ZEND_STR_CLOSED_RESOURCE, "resource (closed)") \
  487. _(ZEND_STR_NAME, "name") \
  488. _(ZEND_STR_ARGV, "argv") \
  489. _(ZEND_STR_ARGC, "argc") \
  490. _(ZEND_STR_ARRAY_CAPITALIZED, "Array") \
  491. _(ZEND_STR_BOOL, "bool") \
  492. _(ZEND_STR_INT, "int") \
  493. _(ZEND_STR_FLOAT, "float") \
  494. _(ZEND_STR_CALLABLE, "callable") \
  495. _(ZEND_STR_ITERABLE, "iterable") \
  496. _(ZEND_STR_VOID, "void") \
  497. _(ZEND_STR_NEVER, "never") \
  498. _(ZEND_STR_FALSE, "false") \
  499. _(ZEND_STR_NULL_LOWERCASE, "null") \
  500. _(ZEND_STR_MIXED, "mixed") \
  501. _(ZEND_STR_SLEEP, "__sleep") \
  502. _(ZEND_STR_WAKEUP, "__wakeup") \
  503. _(ZEND_STR_CASES, "cases") \
  504. _(ZEND_STR_FROM, "from") \
  505. _(ZEND_STR_TRYFROM, "tryFrom") \
  506. _(ZEND_STR_TRYFROM_LOWERCASE, "tryfrom") \
  507. _(ZEND_STR_AUTOGLOBAL_SERVER, "_SERVER") \
  508. _(ZEND_STR_AUTOGLOBAL_ENV, "_ENV") \
  509. _(ZEND_STR_AUTOGLOBAL_REQUEST, "_REQUEST") \
  510. typedef enum _zend_known_string_id {
  511. #define _ZEND_STR_ID(id, str) id,
  512. ZEND_KNOWN_STRINGS(_ZEND_STR_ID)
  513. #undef _ZEND_STR_ID
  514. ZEND_STR_LAST_KNOWN
  515. } zend_known_string_id;
  516. #endif /* ZEND_STRING_H */