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 | Andrei Zmievski <andrei@php.net> |
18 | Dmitry Stogov <dmitry@php.net> |
19 +----------------------------------------------------------------------+
20 */
21
22 #ifndef ZEND_API_H
23 #define ZEND_API_H
24
25 #include "zend_modules.h"
26 #include "zend_list.h"
27 #include "zend_operators.h"
28 #include "zend_variables.h"
29 #include "zend_execute.h"
30
31
32 BEGIN_EXTERN_C()
33
34 typedef struct _zend_function_entry {
35 const char *fname;
36 zif_handler handler;
37 const struct _zend_internal_arg_info *arg_info;
38 uint32_t num_args;
39 uint32_t flags;
40 } zend_function_entry;
41
42 typedef struct _zend_fcall_info {
43 size_t size;
44 zval function_name;
45 zval *retval;
46 zval *params;
47 zend_object *object;
48 zend_bool no_separation;
49 uint32_t param_count;
50 } zend_fcall_info;
51
52 typedef struct _zend_fcall_info_cache {
53 zend_function *function_handler;
54 zend_class_entry *calling_scope;
55 zend_class_entry *called_scope;
56 zend_object *object;
57 } zend_fcall_info_cache;
58
59 #define ZEND_NS_NAME(ns, name) ns "\\" name
60
61 #define ZEND_FN(name) zif_##name
62 #define ZEND_MN(name) zim_##name
63 #define ZEND_NAMED_FUNCTION(name) void ZEND_FASTCALL name(INTERNAL_FUNCTION_PARAMETERS)
64 #define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
65 #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))
66
67 #define ZEND_FENTRY(zend_name, name, arg_info, flags) { #zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags },
68
69 #define ZEND_RAW_FENTRY(zend_name, name, arg_info, flags) { zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags },
70 #define ZEND_RAW_NAMED_FE(zend_name, name, arg_info) ZEND_RAW_FENTRY(#zend_name, name, arg_info, 0)
71
72 #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0)
73 #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
74 #define ZEND_DEP_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, ZEND_ACC_DEPRECATED)
75 #define ZEND_FALIAS(name, alias, arg_info) ZEND_FENTRY(name, ZEND_FN(alias), arg_info, 0)
76 #define ZEND_DEP_FALIAS(name, alias, arg_info) ZEND_FENTRY(name, ZEND_FN(alias), arg_info, ZEND_ACC_DEPRECATED)
77 #define ZEND_NAMED_ME(zend_name, name, arg_info, flags) ZEND_FENTRY(zend_name, name, arg_info, flags)
78 #define ZEND_ME(classname, name, arg_info, flags) ZEND_FENTRY(name, ZEND_MN(classname##_##name), arg_info, flags)
79 #define ZEND_DEP_ME(classname, name, arg_info, flags) ZEND_ME(classname, name, arg_info, flags | ZEND_ACC_DEPRECATED)
80 #define ZEND_ABSTRACT_ME(classname, name, arg_info) ZEND_FENTRY(name, NULL, arg_info, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT)
81 #define ZEND_MALIAS(classname, name, alias, arg_info, flags) \
82 ZEND_FENTRY(name, ZEND_MN(classname##_##alias), arg_info, flags)
83 #define ZEND_ME_MAPPING(name, func_name, arg_types, flags) ZEND_NAMED_ME(name, ZEND_FN(func_name), arg_types, flags)
84
85 #define ZEND_NS_FENTRY(ns, zend_name, name, arg_info, flags) ZEND_RAW_FENTRY(ZEND_NS_NAME(ns, #zend_name), name, arg_info, flags)
86
87 #define ZEND_NS_RAW_FENTRY(ns, zend_name, name, arg_info, flags) ZEND_RAW_FENTRY(ZEND_NS_NAME(ns, zend_name), name, arg_info, flags)
88 #define ZEND_NS_RAW_NAMED_FE(ns, zend_name, name, arg_info) ZEND_NS_RAW_FENTRY(ns, #zend_name, name, arg_info, 0)
89
90 #define ZEND_NS_NAMED_FE(ns, zend_name, name, arg_info) ZEND_NS_FENTRY(ns, zend_name, name, arg_info, 0)
91 #define ZEND_NS_FE(ns, name, arg_info) ZEND_NS_FENTRY(ns, name, ZEND_FN(name), arg_info, 0)
92 #define ZEND_NS_DEP_FE(ns, name, arg_info) ZEND_NS_FENTRY(ns, name, ZEND_FN(name), arg_info, ZEND_ACC_DEPRECATED)
93 #define ZEND_NS_FALIAS(ns, name, alias, arg_info) ZEND_NS_FENTRY(ns, name, ZEND_FN(alias), arg_info, 0)
94 #define ZEND_NS_DEP_FALIAS(ns, name, alias, arg_info) ZEND_NS_FENTRY(ns, name, ZEND_FN(alias), arg_info, ZEND_ACC_DEPRECATED)
95
96 #define ZEND_FE_END { NULL, NULL, NULL, 0, 0 }
97
98 #define ZEND_ARG_INFO(pass_by_ref, name) { #name, 0, pass_by_ref, 0},
99 #define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, pass_by_ref, 0},
100 #define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, ZEND_TYPE_ENCODE_CLASS_CONST(#classname, allow_null), pass_by_ref, 0 },
101 #define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, ZEND_TYPE_ENCODE(IS_ARRAY, allow_null), pass_by_ref, 0 },
102 #define ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null) { #name, ZEND_TYPE_ENCODE(IS_CALLABLE, allow_null), pass_by_ref, 0 },
103 #define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, ZEND_TYPE_ENCODE(type_hint, allow_null), pass_by_ref, 0 },
104 #define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name) { #name, 0, pass_by_ref, 1 },
105 #define ZEND_ARG_VARIADIC_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, ZEND_TYPE_ENCODE(type_hint, allow_null), pass_by_ref, 1 },
106 #define ZEND_ARG_VARIADIC_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, ZEND_TYPE_ENCODE_CLASS_CONST(#classname, allow_null), pass_by_ref, 1 },
107
108 #define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
109 static const zend_internal_arg_info name[] = { \
110 { (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_ENCODE_CLASS_CONST(#class_name, allow_null), return_reference, 0 },
111
112 #define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO(name, class_name, allow_null) \
113 ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, 0, -1, class_name, allow_null)
114
115 #define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \
116 static const zend_internal_arg_info name[] = { \
117 { (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_ENCODE(type, allow_null), return_reference, 0 },
118 #define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(name, type, allow_null) \
119 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, 0, -1, type, allow_null)
120
121 #define ZEND_BEGIN_ARG_INFO_EX(name, _unused, return_reference, required_num_args) \
122 static const zend_internal_arg_info name[] = { \
123 { (const char*)(zend_uintptr_t)(required_num_args), 0, return_reference, 0 },
124 #define ZEND_BEGIN_ARG_INFO(name, _unused) \
125 ZEND_BEGIN_ARG_INFO_EX(name, 0, ZEND_RETURN_VALUE, -1)
126 #define ZEND_END_ARG_INFO() };
127
128 /* Name macros */
129 #define ZEND_MODULE_STARTUP_N(module) zm_startup_##module
130 #define ZEND_MODULE_SHUTDOWN_N(module) zm_shutdown_##module
131 #define ZEND_MODULE_ACTIVATE_N(module) zm_activate_##module
132 #define ZEND_MODULE_DEACTIVATE_N(module) zm_deactivate_##module
133 #define ZEND_MODULE_POST_ZEND_DEACTIVATE_N(module) zm_post_zend_deactivate_##module
134 #define ZEND_MODULE_INFO_N(module) zm_info_##module
135 #define ZEND_MODULE_GLOBALS_CTOR_N(module) zm_globals_ctor_##module
136 #define ZEND_MODULE_GLOBALS_DTOR_N(module) zm_globals_dtor_##module
137
138 /* Declaration macros */
139 #define ZEND_MODULE_STARTUP_D(module) int ZEND_MODULE_STARTUP_N(module)(INIT_FUNC_ARGS)
140 #define ZEND_MODULE_SHUTDOWN_D(module) int ZEND_MODULE_SHUTDOWN_N(module)(SHUTDOWN_FUNC_ARGS)
141 #define ZEND_MODULE_ACTIVATE_D(module) int ZEND_MODULE_ACTIVATE_N(module)(INIT_FUNC_ARGS)
142 #define ZEND_MODULE_DEACTIVATE_D(module) int ZEND_MODULE_DEACTIVATE_N(module)(SHUTDOWN_FUNC_ARGS)
143 #define ZEND_MODULE_POST_ZEND_DEACTIVATE_D(module) int ZEND_MODULE_POST_ZEND_DEACTIVATE_N(module)(void)
144 #define ZEND_MODULE_INFO_D(module) ZEND_COLD void ZEND_MODULE_INFO_N(module)(ZEND_MODULE_INFO_FUNC_ARGS)
145 #define ZEND_MODULE_GLOBALS_CTOR_D(module) void ZEND_MODULE_GLOBALS_CTOR_N(module)(zend_##module##_globals *module##_globals)
146 #define ZEND_MODULE_GLOBALS_DTOR_D(module) void ZEND_MODULE_GLOBALS_DTOR_N(module)(zend_##module##_globals *module##_globals)
147
148 #define ZEND_GET_MODULE(name) \
149 BEGIN_EXTERN_C()\
150 ZEND_DLEXPORT zend_module_entry *get_module(void) { return &name##_module_entry; }\
151 END_EXTERN_C()
152
153 #define ZEND_BEGIN_MODULE_GLOBALS(module_name) \
154 typedef struct _zend_##module_name##_globals {
155 #define ZEND_END_MODULE_GLOBALS(module_name) \
156 } zend_##module_name##_globals;
157
158 #ifdef ZTS
159
160 #define ZEND_DECLARE_MODULE_GLOBALS(module_name) \
161 ts_rsrc_id module_name##_globals_id;
162 #define ZEND_EXTERN_MODULE_GLOBALS(module_name) \
163 extern ts_rsrc_id module_name##_globals_id;
164 #define ZEND_INIT_MODULE_GLOBALS(module_name, globals_ctor, globals_dtor) \
165 ts_allocate_id(&module_name##_globals_id, sizeof(zend_##module_name##_globals), (ts_allocate_ctor) globals_ctor, (ts_allocate_dtor) globals_dtor);
166 #define ZEND_MODULE_GLOBALS_ACCESSOR(module_name, v) ZEND_TSRMG(module_name##_globals_id, zend_##module_name##_globals *, v)
167 #if ZEND_ENABLE_STATIC_TSRMLS_CACHE
168 #define ZEND_MODULE_GLOBALS_BULK(module_name) TSRMG_BULK_STATIC(module_name##_globals_id, zend_##module_name##_globals *)
169 #else
170 #define ZEND_MODULE_GLOBALS_BULK(module_name) TSRMG_BULK(module_name##_globals_id, zend_##module_name##_globals *)
171 #endif
172
173 #else
174
175 #define ZEND_DECLARE_MODULE_GLOBALS(module_name) \
176 zend_##module_name##_globals module_name##_globals;
177 #define ZEND_EXTERN_MODULE_GLOBALS(module_name) \
178 extern zend_##module_name##_globals module_name##_globals;
179 #define ZEND_INIT_MODULE_GLOBALS(module_name, globals_ctor, globals_dtor) \
180 globals_ctor(&module_name##_globals);
181 #define ZEND_MODULE_GLOBALS_ACCESSOR(module_name, v) (module_name##_globals.v)
182 #define ZEND_MODULE_GLOBALS_BULK(module_name) (&module_name##_globals)
183
184 #endif
185
186 #define INIT_CLASS_ENTRY(class_container, class_name, functions) \
187 INIT_CLASS_ENTRY_EX(class_container, class_name, sizeof(class_name)-1, functions)
188
189 #define INIT_CLASS_ENTRY_EX(class_container, class_name, class_name_len, functions) \
190 { \
191 memset(&class_container, 0, sizeof(zend_class_entry)); \
192 class_container.name = zend_string_init_interned(class_name, class_name_len, 1); \
193 class_container.info.internal.builtin_functions = functions; \
194 }
195
196 #define INIT_CLASS_ENTRY_INIT_METHODS(class_container, functions) \
197 { \
198 class_container.constructor = NULL; \
199 class_container.destructor = NULL; \
200 class_container.clone = NULL; \
201 class_container.serialize = NULL; \
202 class_container.unserialize = NULL; \
203 class_container.create_object = NULL; \
204 class_container.get_static_method = NULL; \
205 class_container.__call = NULL; \
206 class_container.__callstatic = NULL; \
207 class_container.__tostring = NULL; \
208 class_container.__get = NULL; \
209 class_container.__set = NULL; \
210 class_container.__unset = NULL; \
211 class_container.__isset = NULL; \
212 class_container.__debugInfo = NULL; \
213 class_container.serialize_func = NULL; \
214 class_container.unserialize_func = NULL; \
215 class_container.parent = NULL; \
216 class_container.num_interfaces = 0; \
217 class_container.trait_names = NULL; \
218 class_container.num_traits = 0; \
219 class_container.trait_aliases = NULL; \
220 class_container.trait_precedences = NULL; \
221 class_container.interfaces = NULL; \
222 class_container.get_iterator = NULL; \
223 class_container.iterator_funcs_ptr = NULL; \
224 class_container.info.internal.module = NULL; \
225 class_container.info.internal.builtin_functions = functions; \
226 }
227
228
229 #define INIT_NS_CLASS_ENTRY(class_container, ns, class_name, functions) \
230 INIT_CLASS_ENTRY(class_container, ZEND_NS_NAME(ns, class_name), functions)
231
232 #define CE_STATIC_MEMBERS(ce) \
233 ((zval*)ZEND_MAP_PTR_GET((ce)->static_members_table))
234
235 #define ZEND_FCI_INITIALIZED(fci) ((fci).size != 0)
236
237 ZEND_API int zend_next_free_module(void);
238
239 BEGIN_EXTERN_C()
240 ZEND_API int _zend_get_parameters_array_ex(int param_count, zval *argument_array);
241
242 /* internal function to efficiently copy parameters when executing __call() */
243 ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array);
244
245 #define zend_get_parameters_array(ht, param_count, argument_array) \
246 _zend_get_parameters_array_ex(param_count, argument_array)
247 #define zend_get_parameters_array_ex(param_count, argument_array) \
248 _zend_get_parameters_array_ex(param_count, argument_array)
249 #define zend_parse_parameters_none() \
250 (EXPECTED(ZEND_NUM_ARGS() == 0) ? SUCCESS : (zend_wrong_parameters_none_error(), FAILURE))
251 #define zend_parse_parameters_none_throw() \
252 (EXPECTED(ZEND_NUM_ARGS() == 0) ? SUCCESS : (zend_wrong_parameters_none_exception(), FAILURE))
253
254 /* Parameter parsing API -- andrei */
255
256 #define ZEND_PARSE_PARAMS_QUIET (1<<1)
257 #define ZEND_PARSE_PARAMS_THROW (1<<2)
258 ZEND_API int zend_parse_parameters(int num_args, const char *type_spec, ...);
259 ZEND_API int zend_parse_parameters_ex(int flags, int num_args, const char *type_spec, ...);
260 ZEND_API int zend_parse_parameters_throw(int num_args, const char *type_spec, ...);
261 ZEND_API char *zend_zval_type_name(const zval *arg);
262 ZEND_API zend_string *zend_zval_get_type(const zval *arg);
263
264 ZEND_API int zend_parse_method_parameters(int num_args, zval *this_ptr, const char *type_spec, ...);
265 ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args, zval *this_ptr, const char *type_spec, ...);
266
267 ZEND_API int zend_parse_parameter(int flags, int arg_num, zval *arg, const char *spec, ...);
268
269 /* End of parameter parsing API -- andrei */
270
271 ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_function_entry *functions, HashTable *function_table, int type);
272 ZEND_API void zend_unregister_functions(const zend_function_entry *functions, int count, HashTable *function_table);
273 ZEND_API int zend_startup_module(zend_module_entry *module_entry);
274 ZEND_API zend_module_entry* zend_register_internal_module(zend_module_entry *module_entry);
275 ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module);
276 ZEND_API int zend_startup_module_ex(zend_module_entry *module);
277 ZEND_API int zend_startup_modules(void);
278 ZEND_API void zend_collect_module_handlers(void);
279 ZEND_API void zend_destroy_modules(void);
280 ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, int error_type);
281
282 ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *class_entry);
283 ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce);
284 ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry);
285 ZEND_API void zend_class_implements(zend_class_entry *class_entry, int num_interfaces, ...);
286
287 ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce, int persistent);
288
289 #define zend_register_class_alias(name, ce) \
290 zend_register_class_alias_ex(name, sizeof(name)-1, ce, 1)
291 #define zend_register_ns_class_alias(ns, name, ce) \
292 zend_register_class_alias_ex(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name))-1, ce, 1)
293
294 ZEND_API int zend_disable_function(char *function_name, size_t function_name_length);
295 ZEND_API int zend_disable_class(char *class_name, size_t class_name_length);
296
297 ZEND_API ZEND_COLD void zend_wrong_param_count(void);
298
299 #define IS_CALLABLE_CHECK_SYNTAX_ONLY (1<<0)
300 #define IS_CALLABLE_CHECK_NO_ACCESS (1<<1)
301 #define IS_CALLABLE_CHECK_IS_STATIC (1<<2)
302 #define IS_CALLABLE_CHECK_SILENT (1<<3)
303
304 #define IS_CALLABLE_STRICT (IS_CALLABLE_CHECK_IS_STATIC)
305
306 ZEND_API void zend_release_fcall_info_cache(zend_fcall_info_cache *fcc);
307 ZEND_API zend_string *zend_get_callable_name_ex(zval *callable, zend_object *object);
308 ZEND_API zend_string *zend_get_callable_name(zval *callable);
309 ZEND_API zend_bool zend_is_callable_ex(zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error);
310 ZEND_API zend_bool zend_is_callable(zval *callable, uint32_t check_flags, zend_string **callable_name);
311 ZEND_API zend_bool zend_make_callable(zval *callable, zend_string **callable_name);
312 ZEND_API const char *zend_get_module_version(const char *module_name);
313 ZEND_API int zend_get_module_started(const char *module_name);
314
315 ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, zend_type type);
316
317 ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment);
318 ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, size_t name_length, zval *property, int access_type);
319 ZEND_API int zend_declare_property_null(zend_class_entry *ce, const char *name, size_t name_length, int access_type);
320 ZEND_API int zend_declare_property_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type);
321 ZEND_API int zend_declare_property_long(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type);
322 ZEND_API int zend_declare_property_double(zend_class_entry *ce, const char *name, size_t name_length, double value, int access_type);
323 ZEND_API int zend_declare_property_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value, int access_type);
324 ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_len, int access_type);
325
326 ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *name, zval *value, int access_type, zend_string *doc_comment);
327 ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value);
328 ZEND_API int zend_declare_class_constant_null(zend_class_entry *ce, const char *name, size_t name_length);
329 ZEND_API int zend_declare_class_constant_long(zend_class_entry *ce, const char *name, size_t name_length, zend_long value);
330 ZEND_API int zend_declare_class_constant_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_bool value);
331 ZEND_API int zend_declare_class_constant_double(zend_class_entry *ce, const char *name, size_t name_length, double value);
332 ZEND_API int zend_declare_class_constant_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_length);
333 ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value);
334
335 ZEND_API int zend_update_class_constants(zend_class_entry *class_type);
336
337 ZEND_API void zend_update_property_ex(zend_class_entry *scope, zval *object, zend_string *name, zval *value);
338 ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zval *value);
339 ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, const char *name, size_t name_length);
340 ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value);
341 ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value);
342 ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, const char *name, size_t name_length, double value);
343 ZEND_API void zend_update_property_str(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_string *value);
344 ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, const char *name, size_t name_length, const char *value);
345 ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, const char *name, size_t name_length, const char *value, size_t value_length);
346 ZEND_API void zend_unset_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length);
347
348 ZEND_API int zend_update_static_property_ex(zend_class_entry *scope, zend_string *name, zval *value);
349 ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *name, size_t name_length, zval *value);
350 ZEND_API int zend_update_static_property_null(zend_class_entry *scope, const char *name, size_t name_length);
351 ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, const char *name, size_t name_length, zend_long value);
352 ZEND_API int zend_update_static_property_long(zend_class_entry *scope, const char *name, size_t name_length, zend_long value);
353 ZEND_API int zend_update_static_property_double(zend_class_entry *scope, const char *name, size_t name_length, double value);
354 ZEND_API int zend_update_static_property_string(zend_class_entry *scope, const char *name, size_t name_length, const char *value);
355 ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, const char *name, size_t name_length, const char *value, size_t value_length);
356
357 ZEND_API zval *zend_read_property_ex(zend_class_entry *scope, zval *object, zend_string *name, zend_bool silent, zval *rv);
358 ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent, zval *rv);
359
360 ZEND_API zval *zend_read_static_property_ex(zend_class_entry *scope, zend_string *name, zend_bool silent);
361 ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, size_t name_length, zend_bool silent);
362
363 ZEND_API char *zend_get_type_by_const(int type);
364
365 #define ZEND_THIS (&EX(This))
366
367 #define getThis() ((Z_TYPE_P(ZEND_THIS) == IS_OBJECT) ? ZEND_THIS : NULL)
368 #define ZEND_IS_METHOD_CALL() (EX(func)->common.scope != NULL)
369
370 #define WRONG_PARAM_COUNT ZEND_WRONG_PARAM_COUNT()
371 #define WRONG_PARAM_COUNT_WITH_RETVAL(ret) ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(ret)
372 #define ARG_COUNT(dummy) EX_NUM_ARGS()
373 #define ZEND_NUM_ARGS() EX_NUM_ARGS()
374 #define ZEND_WRONG_PARAM_COUNT() { zend_wrong_param_count(); return; }
375 #define ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(ret) { zend_wrong_param_count(); return ret; }
376
377 #ifndef ZEND_WIN32
378 #define DLEXPORT
379 #endif
380
381 #define array_init(arg) ZVAL_ARR((arg), zend_new_array(0))
382 #define array_init_size(arg, size) ZVAL_ARR((arg), zend_new_array(size))
383 ZEND_API int object_init(zval *arg);
384 ZEND_API int object_init_ex(zval *arg, zend_class_entry *ce);
385 ZEND_API int object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties);
386 ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type);
387 ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properties);
388 ZEND_API void object_properties_load(zend_object *object, HashTable *properties);
389
390 ZEND_API void zend_merge_properties(zval *obj, HashTable *properties);
391
392 ZEND_API int add_assoc_long_ex(zval *arg, const char *key, size_t key_len, zend_long n);
393 ZEND_API int add_assoc_null_ex(zval *arg, const char *key, size_t key_len);
394 ZEND_API int add_assoc_bool_ex(zval *arg, const char *key, size_t key_len, int b);
395 ZEND_API int add_assoc_resource_ex(zval *arg, const char *key, size_t key_len, zend_resource *r);
396 ZEND_API int add_assoc_double_ex(zval *arg, const char *key, size_t key_len, double d);
397 ZEND_API int add_assoc_str_ex(zval *arg, const char *key, size_t key_len, zend_string *str);
398 ZEND_API int add_assoc_string_ex(zval *arg, const char *key, size_t key_len, const char *str);
399 ZEND_API int add_assoc_stringl_ex(zval *arg, const char *key, size_t key_len, const char *str, size_t length);
400 ZEND_API int add_assoc_zval_ex(zval *arg, const char *key, size_t key_len, zval *value);
401
402 #define add_assoc_long(__arg, __key, __n) add_assoc_long_ex(__arg, __key, strlen(__key), __n)
403 #define add_assoc_null(__arg, __key) add_assoc_null_ex(__arg, __key, strlen(__key))
404 #define add_assoc_bool(__arg, __key, __b) add_assoc_bool_ex(__arg, __key, strlen(__key), __b)
405 #define add_assoc_resource(__arg, __key, __r) add_assoc_resource_ex(__arg, __key, strlen(__key), __r)
406 #define add_assoc_double(__arg, __key, __d) add_assoc_double_ex(__arg, __key, strlen(__key), __d)
407 #define add_assoc_str(__arg, __key, __str) add_assoc_str_ex(__arg, __key, strlen(__key), __str)
408 #define add_assoc_string(__arg, __key, __str) add_assoc_string_ex(__arg, __key, strlen(__key), __str)
409 #define add_assoc_stringl(__arg, __key, __str, __length) add_assoc_stringl_ex(__arg, __key, strlen(__key), __str, __length)
410 #define add_assoc_zval(__arg, __key, __value) add_assoc_zval_ex(__arg, __key, strlen(__key), __value)
411
412 ZEND_API int add_index_long(zval *arg, zend_ulong index, zend_long n);
413 ZEND_API int add_index_null(zval *arg, zend_ulong index);
414 ZEND_API int add_index_bool(zval *arg, zend_ulong index, int b);
415 ZEND_API int add_index_resource(zval *arg, zend_ulong index, zend_resource *r);
416 ZEND_API int add_index_double(zval *arg, zend_ulong index, double d);
417 ZEND_API int add_index_str(zval *arg, zend_ulong index, zend_string *str);
418 ZEND_API int add_index_string(zval *arg, zend_ulong index, const char *str);
419 ZEND_API int add_index_stringl(zval *arg, zend_ulong index, const char *str, size_t length);
420
add_index_zval(zval * arg,zend_ulong index,zval * value)421 static zend_always_inline int add_index_zval(zval *arg, zend_ulong index, zval *value)
422 {
423 return zend_hash_index_update(Z_ARRVAL_P(arg), index, value) ? SUCCESS : FAILURE;
424 }
425
426 ZEND_API int add_next_index_long(zval *arg, zend_long n);
427 ZEND_API int add_next_index_null(zval *arg);
428 ZEND_API int add_next_index_bool(zval *arg, int b);
429 ZEND_API int add_next_index_resource(zval *arg, zend_resource *r);
430 ZEND_API int add_next_index_double(zval *arg, double d);
431 ZEND_API int add_next_index_str(zval *arg, zend_string *str);
432 ZEND_API int add_next_index_string(zval *arg, const char *str);
433 ZEND_API int add_next_index_stringl(zval *arg, const char *str, size_t length);
434
add_next_index_zval(zval * arg,zval * value)435 static zend_always_inline int add_next_index_zval(zval *arg, zval *value)
436 {
437 return zend_hash_next_index_insert(Z_ARRVAL_P(arg), value) ? SUCCESS : FAILURE;
438 }
439
440 ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value);
441
442 ZEND_API int add_property_long_ex(zval *arg, const char *key, size_t key_len, zend_long l);
443 ZEND_API int add_property_null_ex(zval *arg, const char *key, size_t key_len);
444 ZEND_API int add_property_bool_ex(zval *arg, const char *key, size_t key_len, zend_long b);
445 ZEND_API int add_property_resource_ex(zval *arg, const char *key, size_t key_len, zend_resource *r);
446 ZEND_API int add_property_double_ex(zval *arg, const char *key, size_t key_len, double d);
447 ZEND_API int add_property_str_ex(zval *arg, const char *key, size_t key_len, zend_string *str);
448 ZEND_API int add_property_string_ex(zval *arg, const char *key, size_t key_len, const char *str);
449 ZEND_API int add_property_stringl_ex(zval *arg, const char *key, size_t key_len, const char *str, size_t length);
450 ZEND_API int add_property_zval_ex(zval *arg, const char *key, size_t key_len, zval *value);
451
452 #define add_property_long(__arg, __key, __n) add_property_long_ex(__arg, __key, strlen(__key), __n)
453 #define add_property_null(__arg, __key) add_property_null_ex(__arg, __key, strlen(__key))
454 #define add_property_bool(__arg, __key, __b) add_property_bool_ex(__arg, __key, strlen(__key), __b)
455 #define add_property_resource(__arg, __key, __r) add_property_resource_ex(__arg, __key, strlen(__key), __r)
456 #define add_property_double(__arg, __key, __d) add_property_double_ex(__arg, __key, strlen(__key), __d)
457 #define add_property_str(__arg, __key, __str) add_property_str_ex(__arg, __key, strlen(__key), __str)
458 #define add_property_string(__arg, __key, __str) add_property_string_ex(__arg, __key, strlen(__key), __str)
459 #define add_property_stringl(__arg, __key, __str, __length) add_property_stringl_ex(__arg, __key, strlen(__key), __str, __length)
460 #define add_property_zval(__arg, __key, __value) add_property_zval_ex(__arg, __key, strlen(__key), __value)
461
462
463 ZEND_API int _call_user_function_ex(zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[], int no_separation);
464
465 #define call_user_function(function_table, object, function_name, retval_ptr, param_count, params) \
466 _call_user_function_ex(object, function_name, retval_ptr, param_count, params, 1)
467 #define call_user_function_ex(function_table, object, function_name, retval_ptr, param_count, params, no_separation, symbol_table) \
468 _call_user_function_ex(object, function_name, retval_ptr, param_count, params, no_separation)
469
470 ZEND_API extern const zend_fcall_info empty_fcall_info;
471 ZEND_API extern const zend_fcall_info_cache empty_fcall_info_cache;
472
473 /** Build zend_call_info/cache from a zval*
474 *
475 * Caller is responsible to provide a return value (fci->retval), otherwise the we will crash.
476 * In order to pass parameters the following members need to be set:
477 * fci->param_count = 0;
478 * fci->params = NULL;
479 * The callable_name argument may be NULL.
480 * Set check_flags to IS_CALLABLE_STRICT for every new usage!
481 */
482 ZEND_API int zend_fcall_info_init(zval *callable, uint32_t check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error);
483
484 /** Clear arguments connected with zend_fcall_info *fci
485 * If free_mem is not zero then the params array gets free'd as well
486 */
487 ZEND_API void zend_fcall_info_args_clear(zend_fcall_info *fci, int free_mem);
488
489 /** Save current arguments from zend_fcall_info *fci
490 * params array will be set to NULL
491 */
492 ZEND_API void zend_fcall_info_args_save(zend_fcall_info *fci, int *param_count, zval **params);
493
494 /** Free arguments connected with zend_fcall_info *fci andset back saved ones.
495 */
496 ZEND_API void zend_fcall_info_args_restore(zend_fcall_info *fci, int param_count, zval *params);
497
498 /** Set or clear the arguments in the zend_call_info struct taking care of
499 * refcount. If args is NULL and arguments are set then those are cleared.
500 */
501 ZEND_API int zend_fcall_info_args(zend_fcall_info *fci, zval *args);
502 ZEND_API int zend_fcall_info_args_ex(zend_fcall_info *fci, zend_function *func, zval *args);
503
504 /** Set arguments in the zend_fcall_info struct taking care of refcount.
505 * If argc is 0 the arguments which are set will be cleared, else pass
506 * a variable amount of zval** arguments.
507 */
508 ZEND_API int zend_fcall_info_argp(zend_fcall_info *fci, int argc, zval *argv);
509
510 /** Set arguments in the zend_fcall_info struct taking care of refcount.
511 * If argc is 0 the arguments which are set will be cleared, else pass
512 * a variable amount of zval** arguments.
513 */
514 ZEND_API int zend_fcall_info_argv(zend_fcall_info *fci, int argc, va_list *argv);
515
516 /** Set arguments in the zend_fcall_info struct taking care of refcount.
517 * If argc is 0 the arguments which are set will be cleared, else pass
518 * a variable amount of zval** arguments.
519 */
520 ZEND_API int zend_fcall_info_argn(zend_fcall_info *fci, int argc, ...);
521
522 /** Call a function using information created by zend_fcall_info_init()/args().
523 * If args is given then those replace the argument info in fci is temporarily.
524 */
525 ZEND_API int zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval *retval, zval *args);
526
527 ZEND_API int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache);
528
529 ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_length, zend_bool is_ref, int num_symbol_tables, ...);
530
531 ZEND_API int zend_delete_global_variable(zend_string *name);
532
533 ZEND_API zend_array *zend_rebuild_symbol_table(void);
534 ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data);
535 ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data);
536 ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force);
537 ZEND_API int zend_set_local_var_str(const char *name, size_t len, zval *value, int force);
538
zend_forbid_dynamic_call(const char * func_name)539 static zend_always_inline int zend_forbid_dynamic_call(const char *func_name)
540 {
541 zend_execute_data *ex = EG(current_execute_data);
542 ZEND_ASSERT(ex != NULL && ex->func != NULL);
543
544 if (ZEND_CALL_INFO(ex) & ZEND_CALL_DYNAMIC) {
545 zend_error(E_WARNING, "Cannot call %s dynamically", func_name);
546 return FAILURE;
547 }
548
549 return SUCCESS;
550 }
551
552 ZEND_API zend_string *zend_find_alias_name(zend_class_entry *ce, zend_string *name);
553 ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_function *f);
554
555 ZEND_API ZEND_COLD const char *zend_get_object_type(const zend_class_entry *ce);
556
557 ZEND_API zend_bool zend_is_iterable(zval *iterable);
558
559 ZEND_API zend_bool zend_is_countable(zval *countable);
560
561 ZEND_API ZEND_FUNCTION(display_disabled_function);
562 END_EXTERN_C()
563
564 #if ZEND_DEBUG
565 #define CHECK_ZVAL_STRING(str) \
566 if (ZSTR_VAL(str)[ZSTR_LEN(str)] != '\0') { zend_error(E_WARNING, "String is not zero-terminated (%s)", ZSTR_VAL(str)); }
567 #define CHECK_ZVAL_STRING_REL(str) \
568 if (ZSTR_VAL(str)[ZSTR_LEN(str)] != '\0') { zend_error(E_WARNING, "String is not zero-terminated (%s) (source: %s:%d)", ZSTR_VAL(str) ZEND_FILE_LINE_RELAY_CC); }
569 #else
570 #define CHECK_ZVAL_STRING(z)
571 #define CHECK_ZVAL_STRING_REL(z)
572 #endif
573
574 #define CHECK_ZVAL_NULL_PATH(p) (Z_STRLEN_P(p) != strlen(Z_STRVAL_P(p)))
575 #define CHECK_NULL_PATH(p, l) (strlen(p) != (size_t)(l))
576
577 #define ZVAL_STRINGL(z, s, l) do { \
578 ZVAL_NEW_STR(z, zend_string_init(s, l, 0)); \
579 } while (0)
580
581 #define ZVAL_STRING(z, s) do { \
582 const char *_s = (s); \
583 ZVAL_STRINGL(z, _s, strlen(_s)); \
584 } while (0)
585
586 #define ZVAL_EMPTY_STRING(z) do { \
587 ZVAL_INTERNED_STR(z, ZSTR_EMPTY_ALLOC()); \
588 } while (0)
589
590 #define ZVAL_PSTRINGL(z, s, l) do { \
591 ZVAL_NEW_STR(z, zend_string_init(s, l, 1)); \
592 } while (0)
593
594 #define ZVAL_PSTRING(z, s) do { \
595 const char *_s = (s); \
596 ZVAL_PSTRINGL(z, _s, strlen(_s)); \
597 } while (0)
598
599 #define ZVAL_EMPTY_PSTRING(z) do { \
600 ZVAL_PSTRINGL(z, "", 0); \
601 } while (0)
602
603 #define ZVAL_ZVAL(z, zv, copy, dtor) do { \
604 zval *__z = (z); \
605 zval *__zv = (zv); \
606 if (EXPECTED(!Z_ISREF_P(__zv))) { \
607 if (copy && !dtor) { \
608 ZVAL_COPY(__z, __zv); \
609 } else { \
610 ZVAL_COPY_VALUE(__z, __zv); \
611 } \
612 } else { \
613 ZVAL_COPY(__z, Z_REFVAL_P(__zv)); \
614 if (dtor || !copy) { \
615 zval_ptr_dtor(__zv); \
616 } \
617 } \
618 } while (0)
619
620 #define RETVAL_BOOL(b) ZVAL_BOOL(return_value, b)
621 #define RETVAL_NULL() ZVAL_NULL(return_value)
622 #define RETVAL_LONG(l) ZVAL_LONG(return_value, l)
623 #define RETVAL_DOUBLE(d) ZVAL_DOUBLE(return_value, d)
624 #define RETVAL_STR(s) ZVAL_STR(return_value, s)
625 #define RETVAL_INTERNED_STR(s) ZVAL_INTERNED_STR(return_value, s)
626 #define RETVAL_NEW_STR(s) ZVAL_NEW_STR(return_value, s)
627 #define RETVAL_STR_COPY(s) ZVAL_STR_COPY(return_value, s)
628 #define RETVAL_STRING(s) ZVAL_STRING(return_value, s)
629 #define RETVAL_STRINGL(s, l) ZVAL_STRINGL(return_value, s, l)
630 #define RETVAL_EMPTY_STRING() ZVAL_EMPTY_STRING(return_value)
631 #define RETVAL_RES(r) ZVAL_RES(return_value, r)
632 #define RETVAL_ARR(r) ZVAL_ARR(return_value, r)
633 #define RETVAL_EMPTY_ARRAY() ZVAL_EMPTY_ARRAY(return_value)
634 #define RETVAL_OBJ(r) ZVAL_OBJ(return_value, r)
635 #define RETVAL_ZVAL(zv, copy, dtor) ZVAL_ZVAL(return_value, zv, copy, dtor)
636 #define RETVAL_FALSE ZVAL_FALSE(return_value)
637 #define RETVAL_TRUE ZVAL_TRUE(return_value)
638
639 #define RETURN_BOOL(b) { RETVAL_BOOL(b); return; }
640 #define RETURN_NULL() { RETVAL_NULL(); return;}
641 #define RETURN_LONG(l) { RETVAL_LONG(l); return; }
642 #define RETURN_DOUBLE(d) { RETVAL_DOUBLE(d); return; }
643 #define RETURN_STR(s) { RETVAL_STR(s); return; }
644 #define RETURN_INTERNED_STR(s) { RETVAL_INTERNED_STR(s); return; }
645 #define RETURN_NEW_STR(s) { RETVAL_NEW_STR(s); return; }
646 #define RETURN_STR_COPY(s) { RETVAL_STR_COPY(s); return; }
647 #define RETURN_STRING(s) { RETVAL_STRING(s); return; }
648 #define RETURN_STRINGL(s, l) { RETVAL_STRINGL(s, l); return; }
649 #define RETURN_EMPTY_STRING() { RETVAL_EMPTY_STRING(); return; }
650 #define RETURN_RES(r) { RETVAL_RES(r); return; }
651 #define RETURN_ARR(r) { RETVAL_ARR(r); return; }
652 #define RETURN_EMPTY_ARRAY() { RETVAL_EMPTY_ARRAY(); return; }
653 #define RETURN_OBJ(r) { RETVAL_OBJ(r); return; }
654 #define RETURN_ZVAL(zv, copy, dtor) { RETVAL_ZVAL(zv, copy, dtor); return; }
655 #define RETURN_FALSE { RETVAL_FALSE; return; }
656 #define RETURN_TRUE { RETVAL_TRUE; return; }
657
658 #define HASH_OF(p) (Z_TYPE_P(p)==IS_ARRAY ? Z_ARRVAL_P(p) : ((Z_TYPE_P(p)==IS_OBJECT ? Z_OBJ_HT_P(p)->get_properties((p)) : NULL)))
659 #define ZVAL_IS_NULL(z) (Z_TYPE_P(z) == IS_NULL)
660
661 /* For compatibility */
662 #define ZEND_MINIT ZEND_MODULE_STARTUP_N
663 #define ZEND_MSHUTDOWN ZEND_MODULE_SHUTDOWN_N
664 #define ZEND_RINIT ZEND_MODULE_ACTIVATE_N
665 #define ZEND_RSHUTDOWN ZEND_MODULE_DEACTIVATE_N
666 #define ZEND_MINFO ZEND_MODULE_INFO_N
667 #define ZEND_GINIT(module) ((void (*)(void*))(ZEND_MODULE_GLOBALS_CTOR_N(module)))
668 #define ZEND_GSHUTDOWN(module) ((void (*)(void*))(ZEND_MODULE_GLOBALS_DTOR_N(module)))
669
670 #define ZEND_MINIT_FUNCTION ZEND_MODULE_STARTUP_D
671 #define ZEND_MSHUTDOWN_FUNCTION ZEND_MODULE_SHUTDOWN_D
672 #define ZEND_RINIT_FUNCTION ZEND_MODULE_ACTIVATE_D
673 #define ZEND_RSHUTDOWN_FUNCTION ZEND_MODULE_DEACTIVATE_D
674 #define ZEND_MINFO_FUNCTION ZEND_MODULE_INFO_D
675 #define ZEND_GINIT_FUNCTION ZEND_MODULE_GLOBALS_CTOR_D
676 #define ZEND_GSHUTDOWN_FUNCTION ZEND_MODULE_GLOBALS_DTOR_D
677
678 /* May modify arg in-place. Will free arg in failure case (and take ownership in success case).
679 * Prefer using the ZEND_TRY_ASSIGN_* macros over these APIs. */
680 ZEND_API int zend_try_assign_typed_ref_ex(zend_reference *ref, zval *zv, zend_bool strict);
681 ZEND_API int zend_try_assign_typed_ref(zend_reference *ref, zval *zv);
682
683 ZEND_API int zend_try_assign_typed_ref_null(zend_reference *ref);
684 ZEND_API int zend_try_assign_typed_ref_bool(zend_reference *ref, zend_bool val);
685 ZEND_API int zend_try_assign_typed_ref_long(zend_reference *ref, zend_long lval);
686 ZEND_API int zend_try_assign_typed_ref_double(zend_reference *ref, double dval);
687 ZEND_API int zend_try_assign_typed_ref_empty_string(zend_reference *ref);
688 ZEND_API int zend_try_assign_typed_ref_str(zend_reference *ref, zend_string *str);
689 ZEND_API int zend_try_assign_typed_ref_string(zend_reference *ref, const char *string);
690 ZEND_API int zend_try_assign_typed_ref_stringl(zend_reference *ref, const char *string, size_t len);
691 ZEND_API int zend_try_assign_typed_ref_arr(zend_reference *ref, zend_array *arr);
692 ZEND_API int zend_try_assign_typed_ref_res(zend_reference *ref, zend_resource *res);
693 ZEND_API int zend_try_assign_typed_ref_zval(zend_reference *ref, zval *zv);
694 ZEND_API int zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval *zv, zend_bool strict);
695
696 #define _ZEND_TRY_ASSIGN_NULL(zv, is_ref) do { \
697 zval *_zv = zv; \
698 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
699 zend_reference *ref = Z_REF_P(_zv); \
700 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
701 zend_try_assign_typed_ref_null(ref); \
702 break; \
703 } \
704 _zv = &ref->val; \
705 } \
706 zval_ptr_dtor(_zv); \
707 ZVAL_NULL(_zv); \
708 } while (0)
709
710 #define ZEND_TRY_ASSIGN_NULL(zv) \
711 _ZEND_TRY_ASSIGN_NULL(zv, 0)
712
713 #define ZEND_TRY_ASSIGN_REF_NULL(zv) do { \
714 ZEND_ASSERT(Z_ISREF_P(zv)); \
715 _ZEND_TRY_ASSIGN_NULL(zv, 1); \
716 } while (0)
717
718 #define _ZEND_TRY_ASSIGN_FALSE(zv, is_ref) do { \
719 zval *_zv = zv; \
720 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
721 zend_reference *ref = Z_REF_P(_zv); \
722 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
723 zend_try_assign_typed_ref_bool(ref, 0); \
724 break; \
725 } \
726 _zv = &ref->val; \
727 } \
728 zval_ptr_dtor(_zv); \
729 ZVAL_FALSE(_zv); \
730 } while (0)
731
732 #define ZEND_TRY_ASSIGN_FALSE(zv) \
733 _ZEND_TRY_ASSIGN_FALSE(zv, 0)
734
735 #define ZEND_TRY_ASSIGN_REF_FALSE(zv) do { \
736 ZEND_ASSERT(Z_ISREF_P(zv)); \
737 _ZEND_TRY_ASSIGN_FALSE(zv, 1); \
738 } while (0)
739
740 #define _ZEND_TRY_ASSIGN_TRUE(zv, is_ref) do { \
741 zval *_zv = zv; \
742 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
743 zend_reference *ref = Z_REF_P(_zv); \
744 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
745 zend_try_assign_typed_ref_bool(ref, 1); \
746 break; \
747 } \
748 _zv = &ref->val; \
749 } \
750 zval_ptr_dtor(_zv); \
751 ZVAL_TRUE(_zv); \
752 } while (0)
753
754 #define ZEND_TRY_ASSIGN_TRUE(zv) \
755 _ZEND_TRY_ASSIGN_TRUE(zv, 0)
756
757 #define ZEND_TRY_ASSIGN_REF_TRUE(zv) do { \
758 ZEND_ASSERT(Z_ISREF_P(zv)); \
759 _ZEND_TRY_ASSIGN_TRUE(zv, 1); \
760 } while (0)
761
762 #define _ZEND_TRY_ASSIGN_BOOL(zv, bval, is_ref) do { \
763 zval *_zv = zv; \
764 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
765 zend_reference *ref = Z_REF_P(_zv); \
766 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
767 zend_try_assign_typed_ref_bool(ref, 1); \
768 break; \
769 } \
770 _zv = &ref->val; \
771 } \
772 zval_ptr_dtor(_zv); \
773 ZVAL_BOOL(_zv, bval); \
774 } while (0)
775
776 #define ZEND_TRY_ASSIGN_BOOL(zv, bval) \
777 _ZEND_TRY_ASSIGN_BOOL(zv, bval, 0)
778
779 #define ZEND_TRY_ASSIGN_REF_BOOL(zv, bval) do { \
780 ZEND_ASSERT(Z_ISREF_P(zv)); \
781 _ZEND_TRY_ASSIGN_BOOL(zv, bval, 1); \
782 } while (0)
783
784 #define _ZEND_TRY_ASSIGN_LONG(zv, lval, is_ref) do { \
785 zval *_zv = zv; \
786 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
787 zend_reference *ref = Z_REF_P(_zv); \
788 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
789 zend_try_assign_typed_ref_long(ref, lval); \
790 break; \
791 } \
792 _zv = &ref->val; \
793 } \
794 zval_ptr_dtor(_zv); \
795 ZVAL_LONG(_zv, lval); \
796 } while (0)
797
798 #define ZEND_TRY_ASSIGN_LONG(zv, lval) \
799 _ZEND_TRY_ASSIGN_LONG(zv, lval, 0)
800
801 #define ZEND_TRY_ASSIGN_REF_LONG(zv, lval) do { \
802 ZEND_ASSERT(Z_ISREF_P(zv)); \
803 _ZEND_TRY_ASSIGN_LONG(zv, lval, 1); \
804 } while (0)
805
806 #define _ZEND_TRY_ASSIGN_DOUBLE(zv, dval, is_ref) do { \
807 zval *_zv = zv; \
808 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
809 zend_reference *ref = Z_REF_P(_zv); \
810 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
811 zend_try_assign_typed_ref_double(ref, dval); \
812 break; \
813 } \
814 _zv = &ref->val; \
815 } \
816 zval_ptr_dtor(_zv); \
817 ZVAL_DOUBLE(_zv, dval); \
818 } while (0)
819
820 #define ZEND_TRY_ASSIGN_DOUBLE(zv, dval) \
821 _ZEND_TRY_ASSIGN_DOUBLE(zv, dval, 0)
822
823 #define ZEND_TRY_ASSIGN_REF_DOUBLE(zv, dval) do { \
824 ZEND_ASSERT(Z_ISREF_P(zv)); \
825 _ZEND_TRY_ASSIGN_DOUBLE(zv, dval, 1); \
826 } while (0)
827
828 #define _ZEND_TRY_ASSIGN_EMPTY_STRING(zv, is_ref) do { \
829 zval *_zv = zv; \
830 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
831 zend_reference *ref = Z_REF_P(_zv); \
832 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
833 zend_try_assign_typed_ref_empty_string(ref); \
834 break; \
835 } \
836 _zv = &ref->val; \
837 } \
838 zval_ptr_dtor(_zv); \
839 ZVAL_EMPTY_STRING(_zv); \
840 } while (0)
841
842 #define ZEND_TRY_ASSIGN_EMPTY_STRING(zv) \
843 _ZEND_TRY_ASSIGN_EMPTY_STRING(zv, 0)
844
845 #define ZEND_TRY_ASSIGN_REF_EMPTY_STRING(zv) do { \
846 ZEND_ASSERT(Z_ISREF_P(zv)); \
847 _ZEND_TRY_ASSIGN_EMPTY_STRING(zv, 1); \
848 } while (0)
849
850 #define _ZEND_TRY_ASSIGN_STR(zv, str, is_ref) do { \
851 zval *_zv = zv; \
852 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
853 zend_reference *ref = Z_REF_P(_zv); \
854 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
855 zend_try_assign_typed_ref_str(ref, str); \
856 break; \
857 } \
858 _zv = &ref->val; \
859 } \
860 zval_ptr_dtor(_zv); \
861 ZVAL_STR(_zv, str); \
862 } while (0)
863
864 #define ZEND_TRY_ASSIGN_STR(zv, str) \
865 _ZEND_TRY_ASSIGN_STR(zv, str, 0)
866
867 #define ZEND_TRY_ASSIGN_REF_STR(zv, str) do { \
868 ZEND_ASSERT(Z_ISREF_P(zv)); \
869 _ZEND_TRY_ASSIGN_STR(zv, str, 1); \
870 } while (0)
871
872 #define _ZEND_TRY_ASSIGN_NEW_STR(zv, str, is_str) do { \
873 zval *_zv = zv; \
874 if (is_str || UNEXPECTED(Z_ISREF_P(_zv))) { \
875 zend_reference *ref = Z_REF_P(_zv); \
876 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
877 zend_try_assign_typed_ref_str(ref, str); \
878 break; \
879 } \
880 _zv = &ref->val; \
881 } \
882 zval_ptr_dtor(_zv); \
883 ZVAL_NEW_STR(_zv, str); \
884 } while (0)
885
886 #define ZEND_TRY_ASSIGN_NEW_STR(zv, str) \
887 _ZEND_TRY_ASSIGN_NEW_STR(zv, str, 0)
888
889 #define ZEND_TRY_ASSIGN_REF_NEW_STR(zv, str) do { \
890 ZEND_ASSERT(Z_ISREF_P(zv)); \
891 _ZEND_TRY_ASSIGN_NEW_STR(zv, str, 1); \
892 } while (0)
893
894 #define _ZEND_TRY_ASSIGN_STRING(zv, string, is_ref) do { \
895 zval *_zv = zv; \
896 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
897 zend_reference *ref = Z_REF_P(_zv); \
898 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
899 zend_try_assign_typed_ref_string(ref, string); \
900 break; \
901 } \
902 _zv = &ref->val; \
903 } \
904 zval_ptr_dtor(_zv); \
905 ZVAL_STRING(_zv, string); \
906 } while (0)
907
908 #define ZEND_TRY_ASSIGN_STRING(zv, string) \
909 _ZEND_TRY_ASSIGN_STRING(zv, string, 0)
910
911 #define ZEND_TRY_ASSIGN_REF_STRING(zv, string) do { \
912 ZEND_ASSERT(Z_ISREF_P(zv)); \
913 _ZEND_TRY_ASSIGN_STRING(zv, string, 1); \
914 } while (0)
915
916 #define _ZEND_TRY_ASSIGN_STRINGL(zv, string, len, is_ref) do { \
917 zval *_zv = zv; \
918 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
919 zend_reference *ref = Z_REF_P(_zv); \
920 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
921 zend_try_assign_typed_ref_stringl(ref, string, len); \
922 break; \
923 } \
924 _zv = &ref->val; \
925 } \
926 zval_ptr_dtor(_zv); \
927 ZVAL_STRINGL(_zv, string, len); \
928 } while (0)
929
930 #define ZEND_TRY_ASSIGN_STRINGL(zv, string, len) \
931 _ZEND_TRY_ASSIGN_STRINGL(zv, string, len, 0)
932
933 #define ZEND_TRY_ASSIGN_REF_STRINGL(zv, string, len) do { \
934 ZEND_ASSERT(Z_ISREF_P(zv)); \
935 _ZEND_TRY_ASSIGN_STRINGL(zv, string, len, 1); \
936 } while (0)
937
938 #define _ZEND_TRY_ASSIGN_ARR(zv, arr, is_ref) do { \
939 zval *_zv = zv; \
940 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
941 zend_reference *ref = Z_REF_P(_zv); \
942 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
943 zend_try_assign_typed_ref_arr(ref, arr); \
944 break; \
945 } \
946 _zv = &ref->val; \
947 } \
948 zval_ptr_dtor(_zv); \
949 ZVAL_ARR(_zv, arr); \
950 } while (0)
951
952 #define ZEND_TRY_ASSIGN_ARR(zv, arr) \
953 _ZEND_TRY_ASSIGN_ARR(zv, arr, 0)
954
955 #define ZEND_TRY_ASSIGN_REF_ARR(zv, arr) do { \
956 ZEND_ASSERT(Z_ISREF_P(zv)); \
957 _ZEND_TRY_ASSIGN_ARR(zv, arr, 1); \
958 } while (0)
959
960 #define _ZEND_TRY_ASSIGN_RES(zv, res, is_ref) do { \
961 zval *_zv = zv; \
962 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
963 zend_reference *ref = Z_REF_P(_zv); \
964 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
965 zend_try_assign_typed_ref_res(ref, res); \
966 break; \
967 } \
968 _zv = &ref->val; \
969 } \
970 zval_ptr_dtor(_zv); \
971 ZVAL_RES(_zv, res); \
972 } while (0)
973
974 #define ZEND_TRY_ASSIGN_RES(zv, res) \
975 _ZEND_TRY_ASSIGN_RES(zv, res, 0)
976
977 #define ZEND_TRY_ASSIGN_REF_RES(zv, res) do { \
978 ZEND_ASSERT(Z_ISREF_P(zv)); \
979 _ZEND_TRY_ASSIGN_RES(zv, res, 1); \
980 } while (0)
981
982 #define _ZEND_TRY_ASSIGN_TMP(zv, other_zv, is_ref) do { \
983 zval *_zv = zv; \
984 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
985 zend_reference *ref = Z_REF_P(_zv); \
986 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
987 zend_try_assign_typed_ref(ref, other_zv); \
988 break; \
989 } \
990 _zv = &ref->val; \
991 } \
992 zval_ptr_dtor(_zv); \
993 ZVAL_COPY_VALUE(_zv, other_zv); \
994 } while (0)
995
996 #define ZEND_TRY_ASSIGN_TMP(zv, other_zv) \
997 _ZEND_TRY_ASSIGN_TMP(zv, other_zv, 0)
998
999 #define ZEND_TRY_ASSIGN_REF_TMP(zv, other_zv) do { \
1000 ZEND_ASSERT(Z_ISREF_P(zv)); \
1001 _ZEND_TRY_ASSIGN_TMP(zv, other_zv, 1); \
1002 } while (0)
1003
1004 #define _ZEND_TRY_ASSIGN_VALUE(zv, other_zv, is_ref) do { \
1005 zval *_zv = zv; \
1006 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
1007 zend_reference *ref = Z_REF_P(_zv); \
1008 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
1009 zend_try_assign_typed_ref_zval(ref, other_zv); \
1010 break; \
1011 } \
1012 _zv = &ref->val; \
1013 } \
1014 zval_ptr_dtor(_zv); \
1015 ZVAL_COPY_VALUE(_zv, other_zv); \
1016 } while (0)
1017
1018 #define ZEND_TRY_ASSIGN_VALUE(zv, other_zv) \
1019 _ZEND_TRY_ASSIGN_VALUE(zv, other_zv, 0)
1020
1021 #define ZEND_TRY_ASSIGN_REF_VALUE(zv, other_zv) do { \
1022 ZEND_ASSERT(Z_ISREF_P(zv)); \
1023 _ZEND_TRY_ASSIGN_VALUE(zv, other_zv, 1); \
1024 } while (0)
1025
1026 #define ZEND_TRY_ASSIGN_COPY(zv, other_zv) do { \
1027 Z_TRY_ADDREF_P(other_zv); \
1028 ZEND_TRY_ASSIGN_VALUE(zv, other_zv); \
1029 } while (0)
1030
1031 #define ZEND_TRY_ASSIGN_REF_COPY(zv, other_zv) do { \
1032 Z_TRY_ADDREF_P(other_zv); \
1033 ZEND_TRY_ASSIGN_REF_VALUE(zv, other_zv); \
1034 } while (0)
1035
1036 #define _ZEND_TRY_ASSIGN_VALUE_EX(zv, other_zv, strict, is_ref) do { \
1037 zval *_zv = zv; \
1038 if (is_ref || UNEXPECTED(Z_ISREF_P(_zv))) { \
1039 zend_reference *ref = Z_REF_P(_zv); \
1040 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { \
1041 zend_try_assign_typed_ref_zval_ex(ref, other_zv, strict); \
1042 break; \
1043 } \
1044 _zv = &ref->val; \
1045 } \
1046 zval_ptr_dtor(_zv); \
1047 ZVAL_COPY_VALUE(_zv, other_zv); \
1048 } while (0)
1049
1050 #define ZEND_TRY_ASSIGN_VALUE_EX(zv, other_zv, strict) \
1051 _ZEND_TRY_ASSIGN_VALUE_EX(zv, other_zv, strict, 0)
1052
1053 #define ZEND_TRY_ASSIGN_REF_VALUE_EX(zv, other_zv, strict) do { \
1054 ZEND_ASSERT(Z_ISREF_P(zv)); \
1055 _ZEND_TRY_ASSIGN_VALUE_EX(zv, other_zv, strict, 1); \
1056 } while (0)
1057
1058 #define ZEND_TRY_ASSIGN_COPY_EX(zv, other_zv, strict) do { \
1059 Z_TRY_ADDREF_P(other_zv); \
1060 ZEND_TRY_ASSIGN_VALUE_EX(zv, other_zv, strict); \
1061 } while (0)
1062
1063 #define ZEND_TRY_ASSIGN_REF_COPY_EX(zv, other_zv, strict) do { \
1064 Z_TRY_ADDREF_P(other_zv); \
1065 ZEND_TRY_ASSIGN_REF_VALUE_EX(zv, other_zv, strict); \
1066 } while (0)
1067
1068 /* Initializes a reference to an empty array and returns dereferenced zval,
1069 * or NULL if the initialization failed. */
zend_try_array_init_size(zval * zv,uint32_t size)1070 static zend_always_inline zval *zend_try_array_init_size(zval *zv, uint32_t size)
1071 {
1072 zend_array *arr = zend_new_array(size);
1073
1074 if (EXPECTED(Z_ISREF_P(zv))) {
1075 zend_reference *ref = Z_REF_P(zv);
1076 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
1077 if (zend_try_assign_typed_ref_arr(ref, arr) != SUCCESS) {
1078 return NULL;
1079 }
1080 return &ref->val;
1081 }
1082 zv = &ref->val;
1083 }
1084 zval_ptr_dtor(zv);
1085 ZVAL_ARR(zv, arr);
1086 return zv;
1087 }
1088
zend_try_array_init(zval * zv)1089 static zend_always_inline zval *zend_try_array_init(zval *zv)
1090 {
1091 return zend_try_array_init_size(zv, 0);
1092 }
1093
1094 /* Fast parameter parsing API */
1095
1096 /* Fast ZPP is always enabled now; this define is left in for compatibility
1097 * with any existing conditional compilation blocks.
1098 */
1099 #define FAST_ZPP 1
1100
1101 #define Z_EXPECTED_TYPES(_) \
1102 _(Z_EXPECTED_LONG, "int") \
1103 _(Z_EXPECTED_BOOL, "bool") \
1104 _(Z_EXPECTED_STRING, "string") \
1105 _(Z_EXPECTED_ARRAY, "array") \
1106 _(Z_EXPECTED_FUNC, "valid callback") \
1107 _(Z_EXPECTED_RESOURCE, "resource") \
1108 _(Z_EXPECTED_PATH, "a valid path") \
1109 _(Z_EXPECTED_OBJECT, "object") \
1110 _(Z_EXPECTED_DOUBLE, "float")
1111
1112 #define Z_EXPECTED_TYPE_ENUM(id, str) id,
1113 #define Z_EXPECTED_TYPE_STR(id, str) str,
1114
1115 typedef enum _zend_expected_type {
1116 Z_EXPECTED_TYPES(Z_EXPECTED_TYPE_ENUM)
1117 Z_EXPECTED_LAST
1118 } zend_expected_type;
1119
1120 ZEND_API ZEND_COLD int ZEND_FASTCALL zend_wrong_parameters_none_error(void);
1121 ZEND_API ZEND_COLD int ZEND_FASTCALL zend_wrong_parameters_none_exception(void);
1122 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(int min_num_args, int max_num_args);
1123 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_exception(int min_num_args, int max_num_args);
1124 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(int num, zend_expected_type expected_type, zval *arg);
1125 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_exception(int num, zend_expected_type expected_type, zval *arg);
1126 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(int num, char *name, zval *arg);
1127 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_exception(int num, char *name, zval *arg);
1128 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int num, char *error);
1129 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_deprecated(int num, char *error);
1130 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_exception(int num, char *error);
1131
1132 #define ZPP_ERROR_OK 0
1133 #define ZPP_ERROR_FAILURE 1
1134 #define ZPP_ERROR_WRONG_CALLBACK 2
1135 #define ZPP_ERROR_WRONG_CLASS 3
1136 #define ZPP_ERROR_WRONG_ARG 4
1137 #define ZPP_ERROR_WRONG_COUNT 5
1138
1139 #define ZEND_PARSE_PARAMETERS_START_EX(flags, min_num_args, max_num_args) do { \
1140 const int _flags = (flags); \
1141 int _min_num_args = (min_num_args); \
1142 int _max_num_args = (max_num_args); \
1143 int _num_args = EX_NUM_ARGS(); \
1144 int _i = 0; \
1145 zval *_real_arg, *_arg = NULL; \
1146 zend_expected_type _expected_type = Z_EXPECTED_LONG; \
1147 char *_error = NULL; \
1148 zend_bool _dummy; \
1149 zend_bool _optional = 0; \
1150 int _error_code = ZPP_ERROR_OK; \
1151 ((void)_i); \
1152 ((void)_real_arg); \
1153 ((void)_arg); \
1154 ((void)_expected_type); \
1155 ((void)_error); \
1156 ((void)_dummy); \
1157 ((void)_optional); \
1158 \
1159 do { \
1160 if (UNEXPECTED(_num_args < _min_num_args) || \
1161 (UNEXPECTED(_num_args > _max_num_args) && \
1162 EXPECTED(_max_num_args >= 0))) { \
1163 if (!(_flags & ZEND_PARSE_PARAMS_QUIET)) { \
1164 if (_flags & ZEND_PARSE_PARAMS_THROW) { \
1165 zend_wrong_parameters_count_exception(_min_num_args, _max_num_args); \
1166 } else { \
1167 zend_wrong_parameters_count_error(_min_num_args, _max_num_args); \
1168 } \
1169 } \
1170 _error_code = ZPP_ERROR_FAILURE; \
1171 break; \
1172 } \
1173 _real_arg = ZEND_CALL_ARG(execute_data, 0);
1174
1175 #define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args) \
1176 ZEND_PARSE_PARAMETERS_START_EX(0, min_num_args, max_num_args)
1177
1178 #define ZEND_PARSE_PARAMETERS_NONE() do { \
1179 if (UNEXPECTED(ZEND_NUM_ARGS() != 0)) { \
1180 zend_wrong_parameters_none_error(); \
1181 return; \
1182 } \
1183 } while (0)
1184
1185 #define ZEND_PARSE_PARAMETERS_END_EX(failure) \
1186 } while (0); \
1187 if (UNEXPECTED(_error_code != ZPP_ERROR_OK)) { \
1188 if (!(_flags & ZEND_PARSE_PARAMS_QUIET)) { \
1189 if (_error_code == ZPP_ERROR_WRONG_CALLBACK) { \
1190 if (_flags & ZEND_PARSE_PARAMS_THROW) { \
1191 zend_wrong_callback_exception(_i, _error); \
1192 } else { \
1193 zend_wrong_callback_error(_i, _error); \
1194 } \
1195 } else if (_error_code == ZPP_ERROR_WRONG_CLASS) { \
1196 if (_flags & ZEND_PARSE_PARAMS_THROW) { \
1197 zend_wrong_parameter_class_exception(_i, _error, _arg); \
1198 } else { \
1199 zend_wrong_parameter_class_error(_i, _error, _arg); \
1200 } \
1201 } else if (_error_code == ZPP_ERROR_WRONG_ARG) { \
1202 if (_flags & ZEND_PARSE_PARAMS_THROW) { \
1203 zend_wrong_parameter_type_exception(_i, _expected_type, _arg); \
1204 } else { \
1205 zend_wrong_parameter_type_error(_i, _expected_type, _arg); \
1206 } \
1207 } \
1208 } \
1209 failure; \
1210 } \
1211 } while (0)
1212
1213 #define ZEND_PARSE_PARAMETERS_END() \
1214 ZEND_PARSE_PARAMETERS_END_EX(return)
1215
1216 #define Z_PARAM_PROLOGUE(deref, separate) \
1217 ++_i; \
1218 ZEND_ASSERT(_i <= _min_num_args || _optional==1); \
1219 ZEND_ASSERT(_i > _min_num_args || _optional==0); \
1220 if (_optional) { \
1221 if (UNEXPECTED(_i >_num_args)) break; \
1222 } \
1223 _real_arg++; \
1224 _arg = _real_arg; \
1225 if (deref) { \
1226 if (EXPECTED(Z_ISREF_P(_arg))) { \
1227 _arg = Z_REFVAL_P(_arg); \
1228 } \
1229 } \
1230 if (separate) { \
1231 SEPARATE_ZVAL_NOREF(_arg); \
1232 }
1233
1234 /* old "|" */
1235 #define Z_PARAM_OPTIONAL \
1236 _optional = 1;
1237
1238 /* old "a" */
1239 #define Z_PARAM_ARRAY_EX2(dest, check_null, deref, separate) \
1240 Z_PARAM_PROLOGUE(deref, separate); \
1241 if (UNEXPECTED(!zend_parse_arg_array(_arg, &dest, check_null, 0))) { \
1242 _expected_type = Z_EXPECTED_ARRAY; \
1243 _error_code = ZPP_ERROR_WRONG_ARG; \
1244 break; \
1245 }
1246
1247 #define Z_PARAM_ARRAY_EX(dest, check_null, separate) \
1248 Z_PARAM_ARRAY_EX2(dest, check_null, separate, separate)
1249
1250 #define Z_PARAM_ARRAY(dest) \
1251 Z_PARAM_ARRAY_EX(dest, 0, 0)
1252
1253 /* old "A" */
1254 #define Z_PARAM_ARRAY_OR_OBJECT_EX2(dest, check_null, deref, separate) \
1255 Z_PARAM_PROLOGUE(deref, separate); \
1256 if (UNEXPECTED(!zend_parse_arg_array(_arg, &dest, check_null, 1))) { \
1257 _expected_type = Z_EXPECTED_ARRAY; \
1258 _error_code = ZPP_ERROR_WRONG_ARG; \
1259 break; \
1260 }
1261
1262 #define Z_PARAM_ARRAY_OR_OBJECT_EX(dest, check_null, separate) \
1263 Z_PARAM_ARRAY_OR_OBJECT_EX2(dest, check_null, separate, separate)
1264
1265 #define Z_PARAM_ARRAY_OR_OBJECT(dest) \
1266 Z_PARAM_ARRAY_OR_OBJECT_EX(dest, 0, 0)
1267
1268 /* old "b" */
1269 #define Z_PARAM_BOOL_EX2(dest, is_null, check_null, deref, separate) \
1270 Z_PARAM_PROLOGUE(deref, separate); \
1271 if (UNEXPECTED(!zend_parse_arg_bool(_arg, &dest, &is_null, check_null))) { \
1272 _expected_type = Z_EXPECTED_BOOL; \
1273 _error_code = ZPP_ERROR_WRONG_ARG; \
1274 break; \
1275 }
1276
1277 #define Z_PARAM_BOOL_EX(dest, is_null, check_null, separate) \
1278 Z_PARAM_BOOL_EX2(dest, is_null, check_null, separate, separate)
1279
1280 #define Z_PARAM_BOOL(dest) \
1281 Z_PARAM_BOOL_EX(dest, _dummy, 0, 0)
1282
1283 /* old "C" */
1284 #define Z_PARAM_CLASS_EX2(dest, check_null, deref, separate) \
1285 Z_PARAM_PROLOGUE(deref, separate); \
1286 if (UNEXPECTED(!zend_parse_arg_class(_arg, &dest, _i, check_null))) { \
1287 _error_code = ZPP_ERROR_FAILURE; \
1288 break; \
1289 }
1290
1291 #define Z_PARAM_CLASS_EX(dest, check_null, separate) \
1292 Z_PARAM_CLASS_EX2(dest, check_null, separate, separate)
1293
1294 #define Z_PARAM_CLASS(dest) \
1295 Z_PARAM_CLASS_EX(dest, 0, 0)
1296
1297 /* old "d" */
1298 #define Z_PARAM_DOUBLE_EX2(dest, is_null, check_null, deref, separate) \
1299 Z_PARAM_PROLOGUE(deref, separate); \
1300 if (UNEXPECTED(!zend_parse_arg_double(_arg, &dest, &is_null, check_null))) { \
1301 _expected_type = Z_EXPECTED_DOUBLE; \
1302 _error_code = ZPP_ERROR_WRONG_ARG; \
1303 break; \
1304 }
1305
1306 #define Z_PARAM_DOUBLE_EX(dest, is_null, check_null, separate) \
1307 Z_PARAM_DOUBLE_EX2(dest, is_null, check_null, separate, separate)
1308
1309 #define Z_PARAM_DOUBLE(dest) \
1310 Z_PARAM_DOUBLE_EX(dest, _dummy, 0, 0)
1311
1312 /* old "f" */
1313 #define Z_PARAM_FUNC_EX2(dest_fci, dest_fcc, check_null, deref, separate) \
1314 Z_PARAM_PROLOGUE(deref, separate); \
1315 if (UNEXPECTED(!zend_parse_arg_func(_arg, &dest_fci, &dest_fcc, check_null, &_error))) { \
1316 if (!_error) { \
1317 _expected_type = Z_EXPECTED_FUNC; \
1318 _error_code = ZPP_ERROR_WRONG_ARG; \
1319 break; \
1320 } else { \
1321 _error_code = ZPP_ERROR_WRONG_CALLBACK; \
1322 break; \
1323 } \
1324 } else if (UNEXPECTED(_error != NULL)) { \
1325 zend_wrong_callback_deprecated(_i, _error); \
1326 }
1327
1328 #define Z_PARAM_FUNC_EX(dest_fci, dest_fcc, check_null, separate) \
1329 Z_PARAM_FUNC_EX2(dest_fci, dest_fcc, check_null, separate, separate)
1330
1331 #define Z_PARAM_FUNC(dest_fci, dest_fcc) \
1332 Z_PARAM_FUNC_EX(dest_fci, dest_fcc, 0, 0)
1333
1334 /* old "h" */
1335 #define Z_PARAM_ARRAY_HT_EX2(dest, check_null, deref, separate) \
1336 Z_PARAM_PROLOGUE(deref, separate); \
1337 if (UNEXPECTED(!zend_parse_arg_array_ht(_arg, &dest, check_null, 0, separate))) { \
1338 _expected_type = Z_EXPECTED_ARRAY; \
1339 _error_code = ZPP_ERROR_WRONG_ARG; \
1340 break; \
1341 }
1342
1343 #define Z_PARAM_ARRAY_HT_EX(dest, check_null, separate) \
1344 Z_PARAM_ARRAY_HT_EX2(dest, check_null, separate, separate)
1345
1346 #define Z_PARAM_ARRAY_HT(dest) \
1347 Z_PARAM_ARRAY_HT_EX(dest, 0, 0)
1348
1349 /* old "H" */
1350 #define Z_PARAM_ARRAY_OR_OBJECT_HT_EX2(dest, check_null, deref, separate) \
1351 Z_PARAM_PROLOGUE(deref, separate); \
1352 if (UNEXPECTED(!zend_parse_arg_array_ht(_arg, &dest, check_null, 1, separate))) { \
1353 _expected_type = Z_EXPECTED_ARRAY; \
1354 _error_code = ZPP_ERROR_WRONG_ARG; \
1355 break; \
1356 }
1357
1358 #define Z_PARAM_ARRAY_OR_OBJECT_HT_EX(dest, check_null, separate) \
1359 Z_PARAM_ARRAY_OR_OBJECT_HT_EX2(dest, check_null, separate, separate)
1360
1361 #define Z_PARAM_ARRAY_OR_OBJECT_HT(dest) \
1362 Z_PARAM_ARRAY_OR_OBJECT_HT_EX(dest, 0, 0)
1363
1364 /* old "l" */
1365 #define Z_PARAM_LONG_EX2(dest, is_null, check_null, deref, separate) \
1366 Z_PARAM_PROLOGUE(deref, separate); \
1367 if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null, 0))) { \
1368 _expected_type = Z_EXPECTED_LONG; \
1369 _error_code = ZPP_ERROR_WRONG_ARG; \
1370 break; \
1371 }
1372
1373 #define Z_PARAM_LONG_EX(dest, is_null, check_null, separate) \
1374 Z_PARAM_LONG_EX2(dest, is_null, check_null, separate, separate)
1375
1376 #define Z_PARAM_LONG(dest) \
1377 Z_PARAM_LONG_EX(dest, _dummy, 0, 0)
1378
1379 /* old "L" */
1380 #define Z_PARAM_STRICT_LONG_EX2(dest, is_null, check_null, deref, separate) \
1381 Z_PARAM_PROLOGUE(deref, separate); \
1382 if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null, 1))) { \
1383 _expected_type = Z_EXPECTED_LONG; \
1384 _error_code = ZPP_ERROR_WRONG_ARG; \
1385 break; \
1386 }
1387
1388 #define Z_PARAM_STRICT_LONG_EX(dest, is_null, check_null, separate) \
1389 Z_PARAM_STRICT_LONG_EX2(dest, is_null, check_null, separate, separate)
1390
1391 #define Z_PARAM_STRICT_LONG(dest) \
1392 Z_PARAM_STRICT_LONG_EX(dest, _dummy, 0, 0)
1393
1394 /* old "o" */
1395 #define Z_PARAM_OBJECT_EX2(dest, check_null, deref, separate) \
1396 Z_PARAM_PROLOGUE(deref, separate); \
1397 if (UNEXPECTED(!zend_parse_arg_object(_arg, &dest, NULL, check_null))) { \
1398 _expected_type = Z_EXPECTED_OBJECT; \
1399 _error_code = ZPP_ERROR_WRONG_ARG; \
1400 break; \
1401 }
1402
1403 #define Z_PARAM_OBJECT_EX(dest, check_null, separate) \
1404 Z_PARAM_OBJECT_EX2(dest, check_null, separate, separate)
1405
1406 #define Z_PARAM_OBJECT(dest) \
1407 Z_PARAM_OBJECT_EX(dest, 0, 0)
1408
1409 /* old "O" */
1410 #define Z_PARAM_OBJECT_OF_CLASS_EX2(dest, _ce, check_null, deref, separate) \
1411 Z_PARAM_PROLOGUE(deref, separate); \
1412 if (UNEXPECTED(!zend_parse_arg_object(_arg, &dest, _ce, check_null))) { \
1413 if (_ce) { \
1414 _error = ZSTR_VAL((_ce)->name); \
1415 _error_code = ZPP_ERROR_WRONG_CLASS; \
1416 break; \
1417 } else { \
1418 _expected_type = Z_EXPECTED_OBJECT; \
1419 _error_code = ZPP_ERROR_WRONG_ARG; \
1420 break; \
1421 } \
1422 }
1423
1424 #define Z_PARAM_OBJECT_OF_CLASS_EX(dest, _ce, check_null, separate) \
1425 Z_PARAM_OBJECT_OF_CLASS_EX2(dest, _ce, check_null, separate, separate)
1426
1427 #define Z_PARAM_OBJECT_OF_CLASS(dest, _ce) \
1428 Z_PARAM_OBJECT_OF_CLASS_EX(dest, _ce, 0, 0)
1429
1430 /* old "p" */
1431 #define Z_PARAM_PATH_EX2(dest, dest_len, check_null, deref, separate) \
1432 Z_PARAM_PROLOGUE(deref, separate); \
1433 if (UNEXPECTED(!zend_parse_arg_path(_arg, &dest, &dest_len, check_null))) { \
1434 _expected_type = Z_EXPECTED_PATH; \
1435 _error_code = ZPP_ERROR_WRONG_ARG; \
1436 break; \
1437 }
1438
1439 #define Z_PARAM_PATH_EX(dest, dest_len, check_null, separate) \
1440 Z_PARAM_PATH_EX2(dest, dest_len, check_null, separate, separate)
1441
1442 #define Z_PARAM_PATH(dest, dest_len) \
1443 Z_PARAM_PATH_EX(dest, dest_len, 0, 0)
1444
1445 /* old "P" */
1446 #define Z_PARAM_PATH_STR_EX2(dest, check_null, deref, separate) \
1447 Z_PARAM_PROLOGUE(deref, separate); \
1448 if (UNEXPECTED(!zend_parse_arg_path_str(_arg, &dest, check_null))) { \
1449 _expected_type = Z_EXPECTED_PATH; \
1450 _error_code = ZPP_ERROR_WRONG_ARG; \
1451 break; \
1452 }
1453
1454 #define Z_PARAM_PATH_STR_EX(dest, check_null, separate) \
1455 Z_PARAM_PATH_STR_EX2(dest, check_null, separate, separate)
1456
1457 #define Z_PARAM_PATH_STR(dest) \
1458 Z_PARAM_PATH_STR_EX(dest, 0, 0)
1459
1460 /* old "r" */
1461 #define Z_PARAM_RESOURCE_EX2(dest, check_null, deref, separate) \
1462 Z_PARAM_PROLOGUE(deref, separate); \
1463 if (UNEXPECTED(!zend_parse_arg_resource(_arg, &dest, check_null))) { \
1464 _expected_type = Z_EXPECTED_RESOURCE; \
1465 _error_code = ZPP_ERROR_WRONG_ARG; \
1466 break; \
1467 }
1468
1469 #define Z_PARAM_RESOURCE_EX(dest, check_null, separate) \
1470 Z_PARAM_RESOURCE_EX2(dest, check_null, separate, separate)
1471
1472 #define Z_PARAM_RESOURCE(dest) \
1473 Z_PARAM_RESOURCE_EX(dest, 0, 0)
1474
1475 /* old "s" */
1476 #define Z_PARAM_STRING_EX2(dest, dest_len, check_null, deref, separate) \
1477 Z_PARAM_PROLOGUE(deref, separate); \
1478 if (UNEXPECTED(!zend_parse_arg_string(_arg, &dest, &dest_len, check_null))) { \
1479 _expected_type = Z_EXPECTED_STRING; \
1480 _error_code = ZPP_ERROR_WRONG_ARG; \
1481 break; \
1482 }
1483
1484 #define Z_PARAM_STRING_EX(dest, dest_len, check_null, separate) \
1485 Z_PARAM_STRING_EX2(dest, dest_len, check_null, separate, separate)
1486
1487 #define Z_PARAM_STRING(dest, dest_len) \
1488 Z_PARAM_STRING_EX(dest, dest_len, 0, 0)
1489
1490 /* old "S" */
1491 #define Z_PARAM_STR_EX2(dest, check_null, deref, separate) \
1492 Z_PARAM_PROLOGUE(deref, separate); \
1493 if (UNEXPECTED(!zend_parse_arg_str(_arg, &dest, check_null))) { \
1494 _expected_type = Z_EXPECTED_STRING; \
1495 _error_code = ZPP_ERROR_WRONG_ARG; \
1496 break; \
1497 }
1498
1499 #define Z_PARAM_STR_EX(dest, check_null, separate) \
1500 Z_PARAM_STR_EX2(dest, check_null, separate, separate)
1501
1502 #define Z_PARAM_STR(dest) \
1503 Z_PARAM_STR_EX(dest, 0, 0)
1504
1505 /* old "z" */
1506 #define Z_PARAM_ZVAL_EX2(dest, check_null, deref, separate) \
1507 Z_PARAM_PROLOGUE(deref, separate); \
1508 zend_parse_arg_zval_deref(_arg, &dest, check_null);
1509
1510 #define Z_PARAM_ZVAL_EX(dest, check_null, separate) \
1511 Z_PARAM_ZVAL_EX2(dest, check_null, separate, separate)
1512
1513 #define Z_PARAM_ZVAL(dest) \
1514 Z_PARAM_ZVAL_EX(dest, 0, 0)
1515
1516 /* old "z" (with dereference) */
1517 #define Z_PARAM_ZVAL_DEREF_EX(dest, check_null, separate) \
1518 Z_PARAM_PROLOGUE(1, separate); \
1519 zend_parse_arg_zval_deref(_arg, &dest, check_null);
1520
1521 #define Z_PARAM_ZVAL_DEREF(dest) \
1522 Z_PARAM_ZVAL_DEREF_EX(dest, 0, 0)
1523
1524 /* old "+" and "*" */
1525 #define Z_PARAM_VARIADIC_EX(spec, dest, dest_num, post_varargs) do { \
1526 int _num_varargs = _num_args - _i - (post_varargs); \
1527 if (EXPECTED(_num_varargs > 0)) { \
1528 dest = _real_arg + 1; \
1529 dest_num = _num_varargs; \
1530 _i += _num_varargs; \
1531 _real_arg += _num_varargs; \
1532 } else { \
1533 dest = NULL; \
1534 dest_num = 0; \
1535 } \
1536 } while (0);
1537
1538 #define Z_PARAM_VARIADIC(spec, dest, dest_num) \
1539 Z_PARAM_VARIADIC_EX(spec, dest, dest_num, 0)
1540
1541 /* End of new parameter parsing API */
1542
1543 /* Inlined implementations shared by new and old parameter parsing APIs */
1544
1545 ZEND_API int ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null);
1546 ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_slow(zval *arg, zend_bool *dest);
1547 ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_weak(zval *arg, zend_bool *dest);
1548 ZEND_API int ZEND_FASTCALL zend_parse_arg_long_slow(zval *arg, zend_long *dest);
1549 ZEND_API int ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest);
1550 ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_slow(zval *arg, zend_long *dest);
1551 ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_weak(zval *arg, zend_long *dest);
1552 ZEND_API int ZEND_FASTCALL zend_parse_arg_double_slow(zval *arg, double *dest);
1553 ZEND_API int ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest);
1554 ZEND_API int ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest);
1555 ZEND_API int ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest);
1556
zend_parse_arg_bool(zval * arg,zend_bool * dest,zend_bool * is_null,int check_null)1557 static zend_always_inline int zend_parse_arg_bool(zval *arg, zend_bool *dest, zend_bool *is_null, int check_null)
1558 {
1559 if (check_null) {
1560 *is_null = 0;
1561 }
1562 if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
1563 *dest = 1;
1564 } else if (EXPECTED(Z_TYPE_P(arg) == IS_FALSE)) {
1565 *dest = 0;
1566 } else if (check_null && Z_TYPE_P(arg) == IS_NULL) {
1567 *is_null = 1;
1568 *dest = 0;
1569 } else {
1570 return zend_parse_arg_bool_slow(arg, dest);
1571 }
1572 return 1;
1573 }
1574
zend_parse_arg_long(zval * arg,zend_long * dest,zend_bool * is_null,int check_null,int cap)1575 static zend_always_inline int zend_parse_arg_long(zval *arg, zend_long *dest, zend_bool *is_null, int check_null, int cap)
1576 {
1577 if (check_null) {
1578 *is_null = 0;
1579 }
1580 if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
1581 *dest = Z_LVAL_P(arg);
1582 } else if (check_null && Z_TYPE_P(arg) == IS_NULL) {
1583 *is_null = 1;
1584 *dest = 0;
1585 } else if (cap) {
1586 return zend_parse_arg_long_cap_slow(arg, dest);
1587 } else {
1588 return zend_parse_arg_long_slow(arg, dest);
1589 }
1590 return 1;
1591 }
1592
zend_parse_arg_double(zval * arg,double * dest,zend_bool * is_null,int check_null)1593 static zend_always_inline int zend_parse_arg_double(zval *arg, double *dest, zend_bool *is_null, int check_null)
1594 {
1595 if (check_null) {
1596 *is_null = 0;
1597 }
1598 if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
1599 *dest = Z_DVAL_P(arg);
1600 } else if (check_null && Z_TYPE_P(arg) == IS_NULL) {
1601 *is_null = 1;
1602 *dest = 0.0;
1603 } else {
1604 return zend_parse_arg_double_slow(arg, dest);
1605 }
1606 return 1;
1607 }
1608
zend_parse_arg_str(zval * arg,zend_string ** dest,int check_null)1609 static zend_always_inline int zend_parse_arg_str(zval *arg, zend_string **dest, int check_null)
1610 {
1611 if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
1612 *dest = Z_STR_P(arg);
1613 } else if (check_null && Z_TYPE_P(arg) == IS_NULL) {
1614 *dest = NULL;
1615 } else {
1616 return zend_parse_arg_str_slow(arg, dest);
1617 }
1618 return 1;
1619 }
1620
zend_parse_arg_string(zval * arg,char ** dest,size_t * dest_len,int check_null)1621 static zend_always_inline int zend_parse_arg_string(zval *arg, char **dest, size_t *dest_len, int check_null)
1622 {
1623 zend_string *str;
1624
1625 if (!zend_parse_arg_str(arg, &str, check_null)) {
1626 return 0;
1627 }
1628 if (check_null && UNEXPECTED(!str)) {
1629 *dest = NULL;
1630 *dest_len = 0;
1631 } else {
1632 *dest = ZSTR_VAL(str);
1633 *dest_len = ZSTR_LEN(str);
1634 }
1635 return 1;
1636 }
1637
zend_parse_arg_path_str(zval * arg,zend_string ** dest,int check_null)1638 static zend_always_inline int zend_parse_arg_path_str(zval *arg, zend_string **dest, int check_null)
1639 {
1640 if (!zend_parse_arg_str(arg, dest, check_null) ||
1641 (*dest && UNEXPECTED(CHECK_NULL_PATH(ZSTR_VAL(*dest), ZSTR_LEN(*dest))))) {
1642 return 0;
1643 }
1644 return 1;
1645 }
1646
zend_parse_arg_path(zval * arg,char ** dest,size_t * dest_len,int check_null)1647 static zend_always_inline int zend_parse_arg_path(zval *arg, char **dest, size_t *dest_len, int check_null)
1648 {
1649 zend_string *str;
1650
1651 if (!zend_parse_arg_path_str(arg, &str, check_null)) {
1652 return 0;
1653 }
1654 if (check_null && UNEXPECTED(!str)) {
1655 *dest = NULL;
1656 *dest_len = 0;
1657 } else {
1658 *dest = ZSTR_VAL(str);
1659 *dest_len = ZSTR_LEN(str);
1660 }
1661 return 1;
1662 }
1663
zend_parse_arg_array(zval * arg,zval ** dest,int check_null,int or_object)1664 static zend_always_inline int zend_parse_arg_array(zval *arg, zval **dest, int check_null, int or_object)
1665 {
1666 if (EXPECTED(Z_TYPE_P(arg) == IS_ARRAY) ||
1667 (or_object && EXPECTED(Z_TYPE_P(arg) == IS_OBJECT))) {
1668 *dest = arg;
1669 } else if (check_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
1670 *dest = NULL;
1671 } else {
1672 return 0;
1673 }
1674 return 1;
1675 }
1676
zend_parse_arg_array_ht(zval * arg,HashTable ** dest,int check_null,int or_object,int separate)1677 static zend_always_inline int zend_parse_arg_array_ht(zval *arg, HashTable **dest, int check_null, int or_object, int separate)
1678 {
1679 if (EXPECTED(Z_TYPE_P(arg) == IS_ARRAY)) {
1680 *dest = Z_ARRVAL_P(arg);
1681 } else if (or_object && EXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
1682 if (separate
1683 && Z_OBJ_P(arg)->properties
1684 && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(arg)->properties) > 1)) {
1685 if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(arg)->properties) & IS_ARRAY_IMMUTABLE))) {
1686 GC_DELREF(Z_OBJ_P(arg)->properties);
1687 }
1688 Z_OBJ_P(arg)->properties = zend_array_dup(Z_OBJ_P(arg)->properties);
1689 }
1690 *dest = Z_OBJ_HT_P(arg)->get_properties(arg);
1691 } else if (check_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
1692 *dest = NULL;
1693 } else {
1694 return 0;
1695 }
1696 return 1;
1697 }
1698
zend_parse_arg_object(zval * arg,zval ** dest,zend_class_entry * ce,int check_null)1699 static zend_always_inline int zend_parse_arg_object(zval *arg, zval **dest, zend_class_entry *ce, int check_null)
1700 {
1701 if (EXPECTED(Z_TYPE_P(arg) == IS_OBJECT) &&
1702 (!ce || EXPECTED(instanceof_function(Z_OBJCE_P(arg), ce) != 0))) {
1703 *dest = arg;
1704 } else if (check_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
1705 *dest = NULL;
1706 } else {
1707 return 0;
1708 }
1709 return 1;
1710 }
1711
zend_parse_arg_resource(zval * arg,zval ** dest,int check_null)1712 static zend_always_inline int zend_parse_arg_resource(zval *arg, zval **dest, int check_null)
1713 {
1714 if (EXPECTED(Z_TYPE_P(arg) == IS_RESOURCE)) {
1715 *dest = arg;
1716 } else if (check_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
1717 *dest = NULL;
1718 } else {
1719 return 0;
1720 }
1721 return 1;
1722 }
1723
zend_parse_arg_func(zval * arg,zend_fcall_info * dest_fci,zend_fcall_info_cache * dest_fcc,int check_null,char ** error)1724 static zend_always_inline int zend_parse_arg_func(zval *arg, zend_fcall_info *dest_fci, zend_fcall_info_cache *dest_fcc, int check_null, char **error)
1725 {
1726 if (check_null && UNEXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
1727 dest_fci->size = 0;
1728 dest_fcc->function_handler = NULL;
1729 *error = NULL;
1730 } else if (UNEXPECTED(zend_fcall_info_init(arg, 0, dest_fci, dest_fcc, NULL, error) != SUCCESS)) {
1731 return 0;
1732 }
1733 return 1;
1734 }
1735
zend_parse_arg_zval(zval * arg,zval ** dest,int check_null)1736 static zend_always_inline void zend_parse_arg_zval(zval *arg, zval **dest, int check_null)
1737 {
1738 *dest = (check_null &&
1739 (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) ||
1740 (UNEXPECTED(Z_ISREF_P(arg)) &&
1741 UNEXPECTED(Z_TYPE_P(Z_REFVAL_P(arg)) == IS_NULL)))) ? NULL : arg;
1742 }
1743
zend_parse_arg_zval_deref(zval * arg,zval ** dest,int check_null)1744 static zend_always_inline void zend_parse_arg_zval_deref(zval *arg, zval **dest, int check_null)
1745 {
1746 *dest = (check_null && UNEXPECTED(Z_TYPE_P(arg) == IS_NULL)) ? NULL : arg;
1747 }
1748
1749 END_EXTERN_C()
1750
1751 #endif /* ZEND_API_H */
1752