1 | /* |
2 | +----------------------------------------------------------------------+ |
3 | | Zend Engine | |
4 | +----------------------------------------------------------------------+ |
5 | | Copyright (c) 1998-2015 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@zend.com> | |
16 | | Zeev Suraski <zeev@zend.com> | |
17 | +----------------------------------------------------------------------+ |
18 | */ |
19 | |
20 | /* $Id$ */ |
21 | |
22 | #ifndef ZEND_H |
23 | #define ZEND_H |
24 | |
25 | #define ZEND_VERSION "2.6.0" |
26 | |
27 | #define ZEND_ENGINE_2 |
28 | |
29 | #ifdef __cplusplus |
30 | #define BEGIN_EXTERN_C() extern "C" { |
31 | #define END_EXTERN_C() } |
32 | #else |
33 | #define BEGIN_EXTERN_C() |
34 | #define END_EXTERN_C() |
35 | #endif |
36 | |
37 | /* |
38 | * general definitions |
39 | */ |
40 | |
41 | #ifdef ZEND_WIN32 |
42 | # include "zend_config.w32.h" |
43 | # define ZEND_PATHS_SEPARATOR ';' |
44 | #elif defined(NETWARE) |
45 | # include <zend_config.h> |
46 | # define ZEND_PATHS_SEPARATOR ';' |
47 | #elif defined(__riscos__) |
48 | # include <zend_config.h> |
49 | # define ZEND_PATHS_SEPARATOR ';' |
50 | #else |
51 | # include <zend_config.h> |
52 | # define ZEND_PATHS_SEPARATOR ':' |
53 | #endif |
54 | |
55 | #ifdef ZEND_WIN32 |
56 | /* Only use this macro if you know for sure that all of the switches values |
57 | are covered by its case statements */ |
58 | #define EMPTY_SWITCH_DEFAULT_CASE() \ |
59 | default: \ |
60 | __assume(0); \ |
61 | break; |
62 | #else |
63 | #define EMPTY_SWITCH_DEFAULT_CASE() |
64 | #endif |
65 | |
66 | /* all HAVE_XXX test have to be after the include of zend_config above */ |
67 | |
68 | #include <stdio.h> |
69 | |
70 | #ifdef HAVE_UNIX_H |
71 | # include <unix.h> |
72 | #endif |
73 | |
74 | #ifdef HAVE_STDARG_H |
75 | # include <stdarg.h> |
76 | #endif |
77 | |
78 | #ifdef HAVE_DLFCN_H |
79 | # include <dlfcn.h> |
80 | #endif |
81 | |
82 | #if defined(HAVE_LIBDL) && !defined(ZEND_WIN32) |
83 | |
84 | # ifndef RTLD_LAZY |
85 | # define RTLD_LAZY 1 /* Solaris 1, FreeBSD's (2.1.7.1 and older) */ |
86 | # endif |
87 | |
88 | # ifndef RTLD_GLOBAL |
89 | # define RTLD_GLOBAL 0 |
90 | # endif |
91 | |
92 | # if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT) |
93 | # define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT) |
94 | # elif defined(RTLD_DEEPBIND) |
95 | # define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND) |
96 | # else |
97 | # define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL) |
98 | # endif |
99 | # define DL_UNLOAD dlclose |
100 | # if defined(DLSYM_NEEDS_UNDERSCORE) |
101 | # define DL_FETCH_SYMBOL(h,s) dlsym((h), "_" s) |
102 | # else |
103 | # define DL_FETCH_SYMBOL dlsym |
104 | # endif |
105 | # define DL_ERROR dlerror |
106 | # define DL_HANDLE void * |
107 | # define ZEND_EXTENSIONS_SUPPORT 1 |
108 | #elif defined(ZEND_WIN32) |
109 | # define DL_LOAD(libname) LoadLibrary(libname) |
110 | # define DL_FETCH_SYMBOL GetProcAddress |
111 | # define DL_UNLOAD FreeLibrary |
112 | # define DL_HANDLE HMODULE |
113 | # define ZEND_EXTENSIONS_SUPPORT 1 |
114 | #else |
115 | # define DL_HANDLE void * |
116 | # define ZEND_EXTENSIONS_SUPPORT 0 |
117 | #endif |
118 | |
119 | #if HAVE_ALLOCA_H && !defined(_ALLOCA_H) |
120 | # include <alloca.h> |
121 | #endif |
122 | |
123 | /* AIX requires this to be the first thing in the file. */ |
124 | #ifndef __GNUC__ |
125 | # ifndef HAVE_ALLOCA_H |
126 | # ifdef _AIX |
127 | #pragma alloca |
128 | # else |
129 | # ifndef alloca /* predefined by HP cc +Olibcalls */ |
130 | char *alloca (); |
131 | # endif |
132 | # endif |
133 | # endif |
134 | #endif |
135 | |
136 | /* Compatibility with non-clang compilers */ |
137 | #ifndef __has_attribute |
138 | # define __has_attribute(x) 0 |
139 | #endif |
140 | |
141 | /* GCC x.y.z supplies __GNUC__ = x and __GNUC_MINOR__ = y */ |
142 | #ifdef __GNUC__ |
143 | # define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) |
144 | #else |
145 | # define ZEND_GCC_VERSION 0 |
146 | #endif |
147 | |
148 | #if ZEND_GCC_VERSION >= 2096 |
149 | # define ZEND_ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) |
150 | #else |
151 | # define ZEND_ATTRIBUTE_MALLOC |
152 | #endif |
153 | |
154 | #if ZEND_GCC_VERSION >= 4003 || __has_attribute(alloc_size) |
155 | # define ZEND_ATTRIBUTE_ALLOC_SIZE(X) __attribute__ ((alloc_size(X))) |
156 | # define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y) __attribute__ ((alloc_size(X,Y))) |
157 | #else |
158 | # define ZEND_ATTRIBUTE_ALLOC_SIZE(X) |
159 | # define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y) |
160 | #endif |
161 | |
162 | #if ZEND_GCC_VERSION >= 2007 |
163 | # define ZEND_ATTRIBUTE_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first))) |
164 | #else |
165 | # define ZEND_ATTRIBUTE_FORMAT(type, idx, first) |
166 | #endif |
167 | |
168 | #if ZEND_GCC_VERSION >= 3001 && !defined(__INTEL_COMPILER) |
169 | # define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first))) |
170 | #else |
171 | # define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) |
172 | #endif |
173 | |
174 | #if ZEND_GCC_VERSION >= 3001 |
175 | # define ZEND_ATTRIBUTE_DEPRECATED __attribute__((deprecated)) |
176 | #elif defined(ZEND_WIN32) && defined(_MSC_VER) && _MSC_VER >= 1300 |
177 | # define ZEND_ATTRIBUTE_DEPRECATED __declspec(deprecated) |
178 | #else |
179 | # define ZEND_ATTRIBUTE_DEPRECATED |
180 | #endif |
181 | |
182 | #if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__) |
183 | # define ZEND_FASTCALL __attribute__((fastcall)) |
184 | #elif defined(_MSC_VER) && defined(_M_IX86) |
185 | # define ZEND_FASTCALL __fastcall |
186 | #else |
187 | # define ZEND_FASTCALL |
188 | #endif |
189 | |
190 | #if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 |
191 | #else |
192 | # define __restrict__ |
193 | #endif |
194 | #define restrict __restrict__ |
195 | |
196 | #if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(NETWARE)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN) |
197 | # define ZEND_ALLOCA_MAX_SIZE (32 * 1024) |
198 | # define ALLOCA_FLAG(name) \ |
199 | zend_bool name; |
200 | # define SET_ALLOCA_FLAG(name) \ |
201 | name = 1 |
202 | # define do_alloca_ex(size, limit, use_heap) \ |
203 | ((use_heap = (UNEXPECTED((size) > (limit)))) ? emalloc(size) : alloca(size)) |
204 | # define do_alloca(size, use_heap) \ |
205 | do_alloca_ex(size, ZEND_ALLOCA_MAX_SIZE, use_heap) |
206 | # define free_alloca(p, use_heap) \ |
207 | do { if (UNEXPECTED(use_heap)) efree(p); } while (0) |
208 | #else |
209 | # define ALLOCA_FLAG(name) |
210 | # define SET_ALLOCA_FLAG(name) |
211 | # define do_alloca(p, use_heap) emalloc(p) |
212 | # define free_alloca(p, use_heap) efree(p) |
213 | #endif |
214 | |
215 | #if ZEND_DEBUG |
216 | #define ZEND_FILE_LINE_D const char *__zend_filename, const uint __zend_lineno |
217 | #define ZEND_FILE_LINE_DC , ZEND_FILE_LINE_D |
218 | #define ZEND_FILE_LINE_ORIG_D const char *__zend_orig_filename, const uint __zend_orig_lineno |
219 | #define ZEND_FILE_LINE_ORIG_DC , ZEND_FILE_LINE_ORIG_D |
220 | #define ZEND_FILE_LINE_RELAY_C __zend_filename, __zend_lineno |
221 | #define ZEND_FILE_LINE_RELAY_CC , ZEND_FILE_LINE_RELAY_C |
222 | #define ZEND_FILE_LINE_C __FILE__, __LINE__ |
223 | #define ZEND_FILE_LINE_CC , ZEND_FILE_LINE_C |
224 | #define ZEND_FILE_LINE_EMPTY_C NULL, 0 |
225 | #define ZEND_FILE_LINE_EMPTY_CC , ZEND_FILE_LINE_EMPTY_C |
226 | #define ZEND_FILE_LINE_ORIG_RELAY_C __zend_orig_filename, __zend_orig_lineno |
227 | #define ZEND_FILE_LINE_ORIG_RELAY_CC , ZEND_FILE_LINE_ORIG_RELAY_C |
228 | #define ZEND_ASSERT(c) assert(c) |
229 | #else |
230 | #define ZEND_FILE_LINE_D |
231 | #define ZEND_FILE_LINE_DC |
232 | #define ZEND_FILE_LINE_ORIG_D |
233 | #define ZEND_FILE_LINE_ORIG_DC |
234 | #define ZEND_FILE_LINE_RELAY_C |
235 | #define ZEND_FILE_LINE_RELAY_CC |
236 | #define ZEND_FILE_LINE_C |
237 | #define ZEND_FILE_LINE_CC |
238 | #define ZEND_FILE_LINE_EMPTY_C |
239 | #define ZEND_FILE_LINE_EMPTY_CC |
240 | #define ZEND_FILE_LINE_ORIG_RELAY_C |
241 | #define ZEND_FILE_LINE_ORIG_RELAY_CC |
242 | #define ZEND_ASSERT(c) |
243 | #endif /* ZEND_DEBUG */ |
244 | |
245 | #ifdef ZTS |
246 | #define ZTS_V 1 |
247 | #else |
248 | #define ZTS_V 0 |
249 | #endif |
250 | |
251 | #include "zend_errors.h" |
252 | #include "zend_alloc.h" |
253 | |
254 | #include "zend_types.h" |
255 | #include "zend_string.h" |
256 | |
257 | #ifdef HAVE_LIMITS_H |
258 | # include <limits.h> |
259 | #endif |
260 | |
261 | #ifndef LONG_MAX |
262 | #define LONG_MAX 2147483647L |
263 | #endif |
264 | |
265 | #ifndef LONG_MIN |
266 | #define LONG_MIN (- LONG_MAX - 1) |
267 | #endif |
268 | |
269 | #if SIZEOF_LONG == 4 |
270 | #define MAX_LENGTH_OF_LONG 11 |
271 | static const char long_min_digits[] = "2147483648" ; |
272 | #elif SIZEOF_LONG == 8 |
273 | #define MAX_LENGTH_OF_LONG 20 |
274 | static const char long_min_digits[] = "9223372036854775808" ; |
275 | #else |
276 | #error "Unknown SIZEOF_LONG" |
277 | #endif |
278 | |
279 | #define MAX_LENGTH_OF_DOUBLE 32 |
280 | |
281 | typedef enum { |
282 | SUCCESS = 0, |
283 | FAILURE = -1, /* this MUST stay a negative number, or it may affect functions! */ |
284 | } ZEND_RESULT_CODE; |
285 | |
286 | #include "zend_hash.h" |
287 | #include "zend_ts_hash.h" |
288 | #include "zend_llist.h" |
289 | |
290 | #define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC |
291 | #define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, return_value_ptr, this_ptr, return_value_used TSRMLS_CC |
292 | |
293 | #if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__) |
294 | void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((noreturn)); |
295 | #else |
296 | # define zend_error_noreturn zend_error |
297 | #endif |
298 | |
299 | /* |
300 | * zval |
301 | */ |
302 | typedef struct _zend_class_entry zend_class_entry; |
303 | |
304 | typedef struct _zend_guard { |
305 | zend_bool in_get; |
306 | zend_bool in_set; |
307 | zend_bool in_unset; |
308 | zend_bool in_isset; |
309 | zend_bool dummy; /* sizeof(zend_guard) must not be equal to sizeof(void*) */ |
310 | } zend_guard; |
311 | |
312 | typedef struct _zend_object { |
313 | zend_class_entry *ce; |
314 | HashTable *properties; |
315 | zval **properties_table; |
316 | HashTable *guards; /* protects from __get/__set ... recursion */ |
317 | } zend_object; |
318 | |
319 | #include "zend_object_handlers.h" |
320 | #include "zend_ast.h" |
321 | |
322 | typedef union _zvalue_value { |
323 | long lval; /* long value */ |
324 | double dval; /* double value */ |
325 | struct { |
326 | char *val; |
327 | int len; |
328 | } str; |
329 | HashTable *ht; /* hash table value */ |
330 | zend_object_value obj; |
331 | zend_ast *ast; |
332 | } zvalue_value; |
333 | |
334 | struct _zval_struct { |
335 | /* Variable information */ |
336 | zvalue_value value; /* value */ |
337 | zend_uint refcount__gc; |
338 | zend_uchar type; /* active type */ |
339 | zend_uchar is_ref__gc; |
340 | }; |
341 | |
342 | #define Z_REFCOUNT_PP(ppz) Z_REFCOUNT_P(*(ppz)) |
343 | #define Z_SET_REFCOUNT_PP(ppz, rc) Z_SET_REFCOUNT_P(*(ppz), rc) |
344 | #define Z_ADDREF_PP(ppz) Z_ADDREF_P(*(ppz)) |
345 | #define Z_DELREF_PP(ppz) Z_DELREF_P(*(ppz)) |
346 | #define Z_ISREF_PP(ppz) Z_ISREF_P(*(ppz)) |
347 | #define Z_SET_ISREF_PP(ppz) Z_SET_ISREF_P(*(ppz)) |
348 | #define Z_UNSET_ISREF_PP(ppz) Z_UNSET_ISREF_P(*(ppz)) |
349 | #define Z_SET_ISREF_TO_PP(ppz, isref) Z_SET_ISREF_TO_P(*(ppz), isref) |
350 | |
351 | #define Z_REFCOUNT_P(pz) zval_refcount_p(pz) |
352 | #define Z_SET_REFCOUNT_P(pz, rc) zval_set_refcount_p(pz, rc) |
353 | #define Z_ADDREF_P(pz) zval_addref_p(pz) |
354 | #define Z_DELREF_P(pz) zval_delref_p(pz) |
355 | #define Z_ISREF_P(pz) zval_isref_p(pz) |
356 | #define Z_SET_ISREF_P(pz) zval_set_isref_p(pz) |
357 | #define Z_UNSET_ISREF_P(pz) zval_unset_isref_p(pz) |
358 | #define Z_SET_ISREF_TO_P(pz, isref) zval_set_isref_to_p(pz, isref) |
359 | |
360 | #define Z_REFCOUNT(z) Z_REFCOUNT_P(&(z)) |
361 | #define Z_SET_REFCOUNT(z, rc) Z_SET_REFCOUNT_P(&(z), rc) |
362 | #define Z_ADDREF(z) Z_ADDREF_P(&(z)) |
363 | #define Z_DELREF(z) Z_DELREF_P(&(z)) |
364 | #define Z_ISREF(z) Z_ISREF_P(&(z)) |
365 | #define Z_SET_ISREF(z) Z_SET_ISREF_P(&(z)) |
366 | #define Z_UNSET_ISREF(z) Z_UNSET_ISREF_P(&(z)) |
367 | #define Z_SET_ISREF_TO(z, isref) Z_SET_ISREF_TO_P(&(z), isref) |
368 | |
369 | #if ZEND_DEBUG |
370 | #define zend_always_inline inline |
371 | #define zend_never_inline |
372 | #else |
373 | #if defined(__GNUC__) |
374 | #if __GNUC__ >= 3 |
375 | #define zend_always_inline inline __attribute__((always_inline)) |
376 | #define zend_never_inline __attribute__((noinline)) |
377 | #else |
378 | #define zend_always_inline inline |
379 | #define zend_never_inline |
380 | #endif |
381 | #elif defined(_MSC_VER) |
382 | #define zend_always_inline __forceinline |
383 | #define zend_never_inline |
384 | #else |
385 | #define zend_always_inline inline |
386 | #define zend_never_inline |
387 | #endif |
388 | #endif /* ZEND_DEBUG */ |
389 | |
390 | #if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) |
391 | # define EXPECTED(condition) __builtin_expect(condition, 1) |
392 | # define UNEXPECTED(condition) __builtin_expect(condition, 0) |
393 | #else |
394 | # define EXPECTED(condition) (condition) |
395 | # define UNEXPECTED(condition) (condition) |
396 | #endif |
397 | |
398 | static zend_always_inline zend_uint zval_refcount_p(zval* pz) { |
399 | return pz->refcount__gc; |
400 | } |
401 | |
402 | static zend_always_inline zend_uint zval_set_refcount_p(zval* pz, zend_uint rc) { |
403 | return pz->refcount__gc = rc; |
404 | } |
405 | |
406 | static zend_always_inline zend_uint zval_addref_p(zval* pz) { |
407 | return ++pz->refcount__gc; |
408 | } |
409 | |
410 | static zend_always_inline zend_uint zval_delref_p(zval* pz) { |
411 | return --pz->refcount__gc; |
412 | } |
413 | |
414 | static zend_always_inline zend_bool zval_isref_p(zval* pz) { |
415 | return pz->is_ref__gc; |
416 | } |
417 | |
418 | static zend_always_inline zend_bool zval_set_isref_p(zval* pz) { |
419 | return pz->is_ref__gc = 1; |
420 | } |
421 | |
422 | static zend_always_inline zend_bool zval_unset_isref_p(zval* pz) { |
423 | return pz->is_ref__gc = 0; |
424 | } |
425 | |
426 | static zend_always_inline zend_bool zval_set_isref_to_p(zval* pz, zend_bool isref) { |
427 | return pz->is_ref__gc = isref; |
428 | } |
429 | |
430 | /* excpt.h on Digital Unix 4.0 defines function_table */ |
431 | #undef function_table |
432 | |
433 | /* A lot of stuff needs shifiting around in order to include zend_compile.h here */ |
434 | union _zend_function; |
435 | |
436 | #include "zend_iterators.h" |
437 | |
438 | struct _zend_serialize_data; |
439 | struct _zend_unserialize_data; |
440 | |
441 | typedef struct _zend_serialize_data zend_serialize_data; |
442 | typedef struct _zend_unserialize_data zend_unserialize_data; |
443 | |
444 | struct _zend_trait_method_reference { |
445 | const char* method_name; |
446 | unsigned int mname_len; |
447 | |
448 | zend_class_entry *ce; |
449 | |
450 | const char* class_name; |
451 | unsigned int cname_len; |
452 | }; |
453 | typedef struct _zend_trait_method_reference zend_trait_method_reference; |
454 | |
455 | struct _zend_trait_precedence { |
456 | zend_trait_method_reference *trait_method; |
457 | |
458 | zend_class_entry** exclude_from_classes; |
459 | }; |
460 | typedef struct _zend_trait_precedence zend_trait_precedence; |
461 | |
462 | struct _zend_trait_alias { |
463 | zend_trait_method_reference *trait_method; |
464 | |
465 | /** |
466 | * name for method to be added |
467 | */ |
468 | const char* alias; |
469 | unsigned int alias_len; |
470 | |
471 | /** |
472 | * modifiers to be set on trait method |
473 | */ |
474 | zend_uint modifiers; |
475 | }; |
476 | typedef struct _zend_trait_alias zend_trait_alias; |
477 | |
478 | struct _zend_class_entry { |
479 | char type; |
480 | const char *name; |
481 | zend_uint name_length; |
482 | struct _zend_class_entry *parent; |
483 | int refcount; |
484 | zend_uint ce_flags; |
485 | |
486 | HashTable function_table; |
487 | HashTable properties_info; |
488 | zval **default_properties_table; |
489 | zval **default_static_members_table; |
490 | zval **static_members_table; |
491 | HashTable constants_table; |
492 | int default_properties_count; |
493 | int default_static_members_count; |
494 | |
495 | union _zend_function *constructor; |
496 | union _zend_function *destructor; |
497 | union _zend_function *clone; |
498 | union _zend_function *__get; |
499 | union _zend_function *__set; |
500 | union _zend_function *__unset; |
501 | union _zend_function *__isset; |
502 | union _zend_function *__call; |
503 | union _zend_function *__callstatic; |
504 | union _zend_function *__tostring; |
505 | union _zend_function *__debugInfo; |
506 | union _zend_function *serialize_func; |
507 | union _zend_function *unserialize_func; |
508 | |
509 | zend_class_iterator_funcs iterator_funcs; |
510 | |
511 | /* handlers */ |
512 | zend_object_value (*create_object)(zend_class_entry *class_type TSRMLS_DC); |
513 | zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC); |
514 | int (*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type TSRMLS_DC); /* a class implements this interface */ |
515 | union _zend_function *(*get_static_method)(zend_class_entry *ce, char* method, int method_len TSRMLS_DC); |
516 | |
517 | /* serializer callbacks */ |
518 | int (*serialize)(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC); |
519 | int (*unserialize)(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC); |
520 | |
521 | zend_class_entry **interfaces; |
522 | zend_uint num_interfaces; |
523 | |
524 | zend_class_entry **traits; |
525 | zend_uint num_traits; |
526 | zend_trait_alias **trait_aliases; |
527 | zend_trait_precedence **trait_precedences; |
528 | |
529 | union { |
530 | struct { |
531 | const char *filename; |
532 | zend_uint line_start; |
533 | zend_uint line_end; |
534 | const char *; |
535 | zend_uint ; |
536 | } user; |
537 | struct { |
538 | const struct _zend_function_entry *builtin_functions; |
539 | struct _zend_module_entry *module; |
540 | } internal; |
541 | } info; |
542 | }; |
543 | |
544 | #include "zend_stream.h" |
545 | typedef struct _zend_utility_functions { |
546 | void (*error_function)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0); |
547 | int (*printf_function)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2); |
548 | int (*write_function)(const char *str, uint str_length); |
549 | FILE *(*fopen_function)(const char *filename, char **opened_path TSRMLS_DC); |
550 | void (*message_handler)(long message, const void *data TSRMLS_DC); |
551 | void (*block_interruptions)(void); |
552 | void (*unblock_interruptions)(void); |
553 | int (*get_configuration_directive)(const char *name, uint name_length, zval *contents); |
554 | void (*ticks_function)(int ticks); |
555 | void (*on_timeout)(int seconds TSRMLS_DC); |
556 | int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); |
557 | int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap); |
558 | char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC); |
559 | char *(*resolve_path_function)(const char *filename, int filename_len TSRMLS_DC); |
560 | } zend_utility_functions; |
561 | |
562 | typedef struct _zend_utility_values { |
563 | char *import_use_extension; |
564 | uint import_use_extension_length; |
565 | zend_bool html_errors; |
566 | } zend_utility_values; |
567 | |
568 | typedef int (*zend_write_func_t)(const char *str, uint str_length); |
569 | |
570 | #undef MIN |
571 | #undef MAX |
572 | #define MAX(a, b) (((a)>(b))?(a):(b)) |
573 | #define MIN(a, b) (((a)<(b))?(a):(b)) |
574 | #define ZEND_STRL(str) (str), (sizeof(str)-1) |
575 | #define ZEND_STRS(str) (str), (sizeof(str)) |
576 | #define ZEND_NORMALIZE_BOOL(n) \ |
577 | ((n) ? (((n)>0) ? 1 : -1) : 0) |
578 | #define ZEND_TRUTH(x) ((x) ? 1 : 0) |
579 | #define ZEND_LOG_XOR(a, b) (ZEND_TRUTH(a) ^ ZEND_TRUTH(b)) |
580 | |
581 | /* data types */ |
582 | /* All data types <= IS_BOOL have their constructor/destructors skipped */ |
583 | #define IS_NULL 0 |
584 | #define IS_LONG 1 |
585 | #define IS_DOUBLE 2 |
586 | #define IS_BOOL 3 |
587 | #define IS_ARRAY 4 |
588 | #define IS_OBJECT 5 |
589 | #define IS_STRING 6 |
590 | #define IS_RESOURCE 7 |
591 | #define IS_CONSTANT 8 |
592 | #define IS_CONSTANT_AST 9 |
593 | #define IS_CALLABLE 10 |
594 | |
595 | #define IS_CONSTANT_TYPE_MASK 0x00f |
596 | #define IS_CONSTANT_UNQUALIFIED 0x010 |
597 | #define IS_LEXICAL_VAR 0x020 |
598 | #define IS_LEXICAL_REF 0x040 |
599 | #define IS_CONSTANT_IN_NAMESPACE 0x100 |
600 | |
601 | #define IS_CONSTANT_TYPE(type) (((type) & IS_CONSTANT_TYPE_MASK) >= IS_CONSTANT && ((type) & IS_CONSTANT_TYPE_MASK) <= IS_CONSTANT_AST) |
602 | |
603 | /* overloaded elements data types */ |
604 | #define OE_IS_ARRAY (1<<0) |
605 | #define OE_IS_OBJECT (1<<1) |
606 | #define OE_IS_METHOD (1<<2) |
607 | |
608 | int zend_startup(zend_utility_functions *utility_functions, char **extensions TSRMLS_DC); |
609 | void zend_shutdown(TSRMLS_D); |
610 | void zend_register_standard_ini_entries(TSRMLS_D); |
611 | void zend_post_startup(TSRMLS_D); |
612 | void zend_set_utility_values(zend_utility_values *utility_values); |
613 | |
614 | BEGIN_EXTERN_C() |
615 | ZEND_API void _zend_bailout(char *filename, uint lineno); |
616 | END_EXTERN_C() |
617 | |
618 | #define zend_bailout() _zend_bailout(__FILE__, __LINE__) |
619 | |
620 | #ifdef HAVE_SIGSETJMP |
621 | # define SETJMP(a) sigsetjmp(a, 0) |
622 | # define LONGJMP(a,b) siglongjmp(a, b) |
623 | # define JMP_BUF sigjmp_buf |
624 | #else |
625 | # define SETJMP(a) setjmp(a) |
626 | # define LONGJMP(a,b) longjmp(a, b) |
627 | # define JMP_BUF jmp_buf |
628 | #endif |
629 | |
630 | #define zend_try \ |
631 | { \ |
632 | JMP_BUF *__orig_bailout = EG(bailout); \ |
633 | JMP_BUF __bailout; \ |
634 | \ |
635 | EG(bailout) = &__bailout; \ |
636 | if (SETJMP(__bailout)==0) { |
637 | #define zend_catch \ |
638 | } else { \ |
639 | EG(bailout) = __orig_bailout; |
640 | #define zend_end_try() \ |
641 | } \ |
642 | EG(bailout) = __orig_bailout; \ |
643 | } |
644 | #define zend_first_try EG(bailout)=NULL; zend_try |
645 | |
646 | BEGIN_EXTERN_C() |
647 | ZEND_API char *get_zend_version(void); |
648 | ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy); |
649 | ZEND_API int zend_print_zval(zval *expr, int indent); |
650 | ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent); |
651 | ZEND_API void zend_print_zval_r(zval *expr, int indent TSRMLS_DC); |
652 | ZEND_API void zend_print_flat_zval_r(zval *expr TSRMLS_DC); |
653 | ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC); |
654 | ZEND_API void zend_output_debug_string(zend_bool trigger_break, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); |
655 | END_EXTERN_C() |
656 | |
657 | BEGIN_EXTERN_C() |
658 | ZEND_API void zend_activate(TSRMLS_D); |
659 | ZEND_API void zend_deactivate(TSRMLS_D); |
660 | ZEND_API void zend_call_destructors(TSRMLS_D); |
661 | ZEND_API void zend_activate_modules(TSRMLS_D); |
662 | ZEND_API void zend_deactivate_modules(TSRMLS_D); |
663 | ZEND_API void zend_post_deactivate_modules(TSRMLS_D); |
664 | END_EXTERN_C() |
665 | |
666 | #if ZEND_DEBUG |
667 | #define Z_DBG(expr) (expr) |
668 | #else |
669 | #define Z_DBG(expr) |
670 | #endif |
671 | |
672 | BEGIN_EXTERN_C() |
673 | ZEND_API void free_estring(char **str_p); |
674 | END_EXTERN_C() |
675 | |
676 | /* FIXME: Check if we can save if (ptr) too */ |
677 | |
678 | #define STR_FREE(ptr) if (ptr) { str_efree(ptr); } |
679 | #define STR_FREE_REL(ptr) if (ptr) { str_efree_rel(ptr); } |
680 | |
681 | #ifndef ZTS |
682 | #define STR_EMPTY_ALLOC() CG(interned_empty_string)? CG(interned_empty_string) : estrndup("", sizeof("")-1) |
683 | #else |
684 | #define STR_EMPTY_ALLOC() estrndup("", sizeof("")-1) |
685 | #endif |
686 | |
687 | #define STR_REALLOC(ptr, size) \ |
688 | ptr = (char *) erealloc(ptr, size); |
689 | |
690 | /* output support */ |
691 | #define ZEND_WRITE(str, str_len) zend_write((str), (str_len)) |
692 | #define ZEND_WRITE_EX(str, str_len) write_func((str), (str_len)) |
693 | #define ZEND_PUTS(str) zend_write((str), strlen((str))) |
694 | #define ZEND_PUTS_EX(str) write_func((str), strlen((str))) |
695 | #define ZEND_PUTC(c) zend_write(&(c), 1) |
696 | |
697 | BEGIN_EXTERN_C() |
698 | extern ZEND_API int (*zend_printf)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2); |
699 | extern ZEND_API zend_write_func_t zend_write; |
700 | extern ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path TSRMLS_DC); |
701 | extern ZEND_API void (*zend_block_interruptions)(void); |
702 | extern ZEND_API void (*zend_unblock_interruptions)(void); |
703 | extern ZEND_API void (*zend_ticks_function)(int ticks); |
704 | extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0); |
705 | extern ZEND_API void (*zend_on_timeout)(int seconds TSRMLS_DC); |
706 | extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); |
707 | extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); |
708 | extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); |
709 | extern ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC); |
710 | |
711 | ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); |
712 | |
713 | void zenderror(const char *error); |
714 | |
715 | /* The following #define is used for code duality in PHP for Engine 1 & 2 */ |
716 | #define ZEND_STANDARD_CLASS_DEF_PTR zend_standard_class_def |
717 | extern ZEND_API zend_class_entry *zend_standard_class_def; |
718 | extern ZEND_API zend_utility_values zend_uv; |
719 | extern ZEND_API zval zval_used_for_init; |
720 | |
721 | END_EXTERN_C() |
722 | |
723 | #define ZEND_UV(name) (zend_uv.name) |
724 | |
725 | #ifndef ZEND_SIGNALS |
726 | #define HANDLE_BLOCK_INTERRUPTIONS() if (zend_block_interruptions) { zend_block_interruptions(); } |
727 | #define HANDLE_UNBLOCK_INTERRUPTIONS() if (zend_unblock_interruptions) { zend_unblock_interruptions(); } |
728 | #else |
729 | #include "zend_signal.h" |
730 | |
731 | #define HANDLE_BLOCK_INTERRUPTIONS() ZEND_SIGNAL_BLOCK_INTERRUPUTIONS() |
732 | #define HANDLE_UNBLOCK_INTERRUPTIONS() ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() |
733 | #endif |
734 | |
735 | BEGIN_EXTERN_C() |
736 | ZEND_API void zend_message_dispatcher(long message, const void *data TSRMLS_DC); |
737 | |
738 | ZEND_API int zend_get_configuration_directive(const char *name, uint name_length, zval *contents); |
739 | END_EXTERN_C() |
740 | |
741 | /* Messages for applications of Zend */ |
742 | #define ZMSG_FAILED_INCLUDE_FOPEN 1L |
743 | #define ZMSG_FAILED_REQUIRE_FOPEN 2L |
744 | #define ZMSG_FAILED_HIGHLIGHT_FOPEN 3L |
745 | #define ZMSG_MEMORY_LEAK_DETECTED 4L |
746 | #define ZMSG_MEMORY_LEAK_REPEATED 5L |
747 | #define ZMSG_LOG_SCRIPT_NAME 6L |
748 | #define ZMSG_MEMORY_LEAKS_GRAND_TOTAL 7L |
749 | |
750 | #define INIT_PZVAL(z) \ |
751 | (z)->refcount__gc = 1; \ |
752 | (z)->is_ref__gc = 0; |
753 | |
754 | #define INIT_ZVAL(z) z = zval_used_for_init; |
755 | |
756 | #define ALLOC_INIT_ZVAL(zp) \ |
757 | ALLOC_ZVAL(zp); \ |
758 | INIT_ZVAL(*zp); |
759 | |
760 | #define MAKE_STD_ZVAL(zv) \ |
761 | ALLOC_ZVAL(zv); \ |
762 | INIT_PZVAL(zv); |
763 | |
764 | #define PZVAL_IS_REF(z) Z_ISREF_P(z) |
765 | |
766 | #define ZVAL_COPY_VALUE(z, v) \ |
767 | do { \ |
768 | (z)->value = (v)->value; \ |
769 | Z_TYPE_P(z) = Z_TYPE_P(v); \ |
770 | } while (0) |
771 | |
772 | #define INIT_PZVAL_COPY(z, v) \ |
773 | do { \ |
774 | ZVAL_COPY_VALUE(z, v); \ |
775 | Z_SET_REFCOUNT_P(z, 1); \ |
776 | Z_UNSET_ISREF_P(z); \ |
777 | } while (0) |
778 | |
779 | #define SEPARATE_ZVAL(ppzv) \ |
780 | do { \ |
781 | if (Z_REFCOUNT_PP((ppzv)) > 1) { \ |
782 | zval *new_zv; \ |
783 | Z_DELREF_PP(ppzv); \ |
784 | ALLOC_ZVAL(new_zv); \ |
785 | INIT_PZVAL_COPY(new_zv, *(ppzv)); \ |
786 | *(ppzv) = new_zv; \ |
787 | zval_copy_ctor(new_zv); \ |
788 | } \ |
789 | } while (0) |
790 | |
791 | #define SEPARATE_ZVAL_IF_NOT_REF(ppzv) \ |
792 | if (!PZVAL_IS_REF(*ppzv)) { \ |
793 | SEPARATE_ZVAL(ppzv); \ |
794 | } |
795 | |
796 | #define SEPARATE_ZVAL_TO_MAKE_IS_REF(ppzv) \ |
797 | if (!PZVAL_IS_REF(*ppzv)) { \ |
798 | SEPARATE_ZVAL(ppzv); \ |
799 | Z_SET_ISREF_PP((ppzv)); \ |
800 | } |
801 | |
802 | #define COPY_PZVAL_TO_ZVAL(zv, pzv) \ |
803 | (zv) = *(pzv); \ |
804 | if (Z_REFCOUNT_P(pzv)>1) { \ |
805 | zval_copy_ctor(&(zv)); \ |
806 | Z_DELREF_P((pzv)); \ |
807 | } else { \ |
808 | FREE_ZVAL(pzv); \ |
809 | } \ |
810 | INIT_PZVAL(&(zv)); |
811 | |
812 | #define MAKE_COPY_ZVAL(ppzv, pzv) \ |
813 | INIT_PZVAL_COPY(pzv, *(ppzv)); \ |
814 | zval_copy_ctor((pzv)); |
815 | |
816 | #define REPLACE_ZVAL_VALUE(ppzv_dest, pzv_src, copy) { \ |
817 | int is_ref, refcount; \ |
818 | \ |
819 | SEPARATE_ZVAL_IF_NOT_REF(ppzv_dest); \ |
820 | is_ref = Z_ISREF_PP(ppzv_dest); \ |
821 | refcount = Z_REFCOUNT_PP(ppzv_dest); \ |
822 | zval_dtor(*ppzv_dest); \ |
823 | ZVAL_COPY_VALUE(*ppzv_dest, pzv_src); \ |
824 | if (copy) { \ |
825 | zval_copy_ctor(*ppzv_dest); \ |
826 | } \ |
827 | Z_SET_ISREF_TO_PP(ppzv_dest, is_ref); \ |
828 | Z_SET_REFCOUNT_PP(ppzv_dest, refcount); \ |
829 | } |
830 | |
831 | #define SEPARATE_ARG_IF_REF(varptr) \ |
832 | if (PZVAL_IS_REF(varptr)) { \ |
833 | zval *original_var = varptr; \ |
834 | ALLOC_ZVAL(varptr); \ |
835 | INIT_PZVAL_COPY(varptr, original_var); \ |
836 | zval_copy_ctor(varptr); \ |
837 | } else { \ |
838 | Z_ADDREF_P(varptr); \ |
839 | } |
840 | |
841 | #define READY_TO_DESTROY(zv) \ |
842 | (Z_REFCOUNT_P(zv) == 1 && \ |
843 | (Z_TYPE_P(zv) != IS_OBJECT || \ |
844 | zend_objects_store_get_refcount(zv TSRMLS_CC) == 1)) |
845 | |
846 | #define ZEND_MAX_RESERVED_RESOURCES 4 |
847 | |
848 | #include "zend_gc.h" |
849 | #include "zend_operators.h" |
850 | #include "zend_variables.h" |
851 | |
852 | typedef enum { |
853 | EH_NORMAL = 0, |
854 | EH_SUPPRESS, |
855 | EH_THROW |
856 | } zend_error_handling_t; |
857 | |
858 | typedef struct { |
859 | zend_error_handling_t handling; |
860 | zend_class_entry *exception; |
861 | zval *user_handler; |
862 | } zend_error_handling; |
863 | |
864 | ZEND_API void zend_save_error_handling(zend_error_handling *current TSRMLS_DC); |
865 | ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, zend_class_entry *exception_class, zend_error_handling *current TSRMLS_DC); |
866 | ZEND_API void zend_restore_error_handling(zend_error_handling *saved TSRMLS_DC); |
867 | |
868 | #define DEBUG_BACKTRACE_PROVIDE_OBJECT (1<<0) |
869 | #define DEBUG_BACKTRACE_IGNORE_ARGS (1<<1) |
870 | |
871 | #endif /* ZEND_H */ |
872 | |
873 | /* |
874 | * Local variables: |
875 | * tab-width: 4 |
876 | * c-basic-offset: 4 |
877 | * indent-tabs-mode: t |
878 | * End: |
879 | */ |
880 | |