This source file includes following definitions.
- string_init
- string_printf
- string_write
- string_append
- string_free
- reflection_object_from_obj
- _default_load_entry
- _default_get_entry
- _default_lookup_entry
- _copy_function
- _free_function
- reflection_free_objects_storage
- reflection_objects_new
- reflection_instantiate
- _class_string
- _const_string
- _get_recv_op
- _parameter_string
- _function_parameter_string
- _function_closure_string
- _function_string
- _property_string
- _extension_ini_string
- _extension_class_string
- _extension_const_string
- _extension_string
- _zend_extension_string
- _function_check_flag
- zend_reflection_class_factory
- reflection_extension_factory
- reflection_parameter_factory
- reflection_type_factory
- reflection_function_factory
- reflection_method_factory
- reflection_property_factory
- _reflection_export
- _reflection_param_get_default_param
- _reflection_param_get_default_precv
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- reflection_class_object_ctor
- ZEND_METHOD
- add_class_vars
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- _addmethod
- _addmethod_va
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- _addproperty
- _adddynproperty
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- _class_check_flag
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- _property_check_flag
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- _addconstant
- ZEND_METHOD
- _addinientry
- ZEND_METHOD
- add_extension_class
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- ZEND_METHOD
- _reflection_write_property
- PHP_MINIT_FUNCTION
- PHP_MINFO_FUNCTION
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "php.h"
30 #include "php_ini.h"
31 #include "php_reflection.h"
32 #include "ext/standard/info.h"
33
34 #include "zend.h"
35 #include "zend_API.h"
36 #include "zend_exceptions.h"
37 #include "zend_operators.h"
38 #include "zend_constants.h"
39 #include "zend_ini.h"
40 #include "zend_interfaces.h"
41 #include "zend_closures.h"
42 #include "zend_generators.h"
43 #include "zend_extensions.h"
44 #include "zend_builtin_functions.h"
45
46 #define reflection_update_property(object, name, value) do { \
47 zval member; \
48 ZVAL_STRINGL(&member, name, sizeof(name)-1); \
49 zend_std_write_property(object, &member, value, NULL); \
50 if (Z_REFCOUNTED_P(value)) Z_DELREF_P(value); \
51 zval_ptr_dtor(&member); \
52 } while (0)
53
54
55 PHPAPI zend_class_entry *reflector_ptr;
56 PHPAPI zend_class_entry *reflection_exception_ptr;
57 PHPAPI zend_class_entry *reflection_ptr;
58 PHPAPI zend_class_entry *reflection_function_abstract_ptr;
59 PHPAPI zend_class_entry *reflection_function_ptr;
60 PHPAPI zend_class_entry *reflection_generator_ptr;
61 PHPAPI zend_class_entry *reflection_parameter_ptr;
62 PHPAPI zend_class_entry *reflection_type_ptr;
63 PHPAPI zend_class_entry *reflection_class_ptr;
64 PHPAPI zend_class_entry *reflection_object_ptr;
65 PHPAPI zend_class_entry *reflection_method_ptr;
66 PHPAPI zend_class_entry *reflection_property_ptr;
67 PHPAPI zend_class_entry *reflection_extension_ptr;
68 PHPAPI zend_class_entry *reflection_zend_extension_ptr;
69
70 #if MBO_0
71 ZEND_BEGIN_MODULE_GLOBALS(reflection)
72 int dummy;
73 ZEND_END_MODULE_GLOBALS(reflection)
74
75 #ifdef ZTS
76 # define REFLECTION_G(v) \
77 ZEND_TSRMG(reflection_globals_id, zend_reflection_globals*, v)
78 extern int reflection_globals_id;
79 #else
80 # define REFLECTION_G(v) (reflection_globals.v)
81 extern zend_reflection_globals reflectionglobals;
82 #endif
83
84 ZEND_DECLARE_MODULE_GLOBALS(reflection)
85 #endif
86
87
88
89 #define METHOD_NOTSTATIC(ce) \
90 if (!Z_OBJ(EX(This)) || !instanceof_function(Z_OBJCE(EX(This)), ce)) { \
91 php_error_docref(NULL, E_ERROR, "%s() cannot be called statically", get_active_function_name()); \
92 return; \
93 } \
94
95
96 #define _DO_THROW(msg) \
97 zend_throw_exception(reflection_exception_ptr, msg, 0); \
98 return; \
99
100 #define RETURN_ON_EXCEPTION \
101 if (EG(exception) && EG(exception)->ce == reflection_exception_ptr) { \
102 return; \
103 }
104
105 #define GET_REFLECTION_OBJECT() \
106 intern = Z_REFLECTION_P(getThis()); \
107 if (intern->ptr == NULL) { \
108 RETURN_ON_EXCEPTION \
109 php_error_docref(NULL, E_ERROR, "Internal error: Failed to retrieve the reflection object"); \
110 } \
111
112 #define GET_REFLECTION_OBJECT_PTR(target) \
113 GET_REFLECTION_OBJECT() \
114 target = intern->ptr; \
115
116
117 #define REGISTER_REFLECTION_CLASS_CONST_LONG(class_name, const_name, value) \
118 zend_declare_class_constant_long(reflection_ ## class_name ## _ptr, const_name, sizeof(const_name)-1, (zend_long)value);
119
120
121 typedef struct _string {
122 zend_string *buf;
123 size_t alloced;
124 } string;
125
126 static void string_init(string *str)
127 {
128 str->buf= zend_string_alloc(1024, 0);
129 str->alloced = 1024;
130 ZSTR_VAL(str->buf)[0] = '\0';
131 ZSTR_LEN(str->buf) = 0;
132 }
133
134 static string *string_printf(string *str, const char *format, ...)
135 {
136 size_t len;
137 va_list arg;
138 char *s_tmp;
139
140 va_start(arg, format);
141 len = zend_vspprintf(&s_tmp, 0, format, arg);
142 if (len) {
143 register size_t nlen = (ZSTR_LEN(str->buf) + 1 + len + (1024 - 1)) & ~(1024 - 1);
144 if (str->alloced < nlen) {
145 size_t old_len = ZSTR_LEN(str->buf);
146 str->alloced = nlen;
147 str->buf = zend_string_extend(str->buf, str->alloced, 0);
148 ZSTR_LEN(str->buf) = old_len;
149 }
150 memcpy(ZSTR_VAL(str->buf) + ZSTR_LEN(str->buf), s_tmp, len + 1);
151 ZSTR_LEN(str->buf) += len;
152 }
153 efree(s_tmp);
154 va_end(arg);
155 return str;
156 }
157
158 static string *string_write(string *str, char *buf, size_t len)
159 {
160 register size_t nlen = (ZSTR_LEN(str->buf) + 1 + len + (1024 - 1)) & ~(1024 - 1);
161 if (str->alloced < nlen) {
162 size_t old_len = ZSTR_LEN(str->buf);
163 str->alloced = nlen;
164 str->buf = zend_string_extend(str->buf, str->alloced, 0);
165 ZSTR_LEN(str->buf) = old_len;
166 }
167 memcpy(ZSTR_VAL(str->buf) + ZSTR_LEN(str->buf), buf, len);
168 ZSTR_LEN(str->buf) += len;
169 ZSTR_VAL(str->buf)[ZSTR_LEN(str->buf)] = '\0';
170 return str;
171 }
172
173 static string *string_append(string *str, string *append)
174 {
175 if (ZSTR_LEN(append->buf) > 0) {
176 string_write(str, ZSTR_VAL(append->buf), ZSTR_LEN(append->buf));
177 }
178 return str;
179 }
180
181 static void string_free(string *str)
182 {
183 zend_string_release(str->buf);
184 str->alloced = 0;
185 str->buf = NULL;
186 }
187
188
189
190
191
192 typedef struct _property_reference {
193 zend_class_entry *ce;
194 zend_property_info prop;
195 } property_reference;
196
197
198 typedef struct _parameter_reference {
199 uint32_t offset;
200 uint32_t required;
201 struct _zend_arg_info *arg_info;
202 zend_function *fptr;
203 } parameter_reference;
204
205
206 typedef struct _type_reference {
207 struct _zend_arg_info *arg_info;
208 zend_function *fptr;
209 } type_reference;
210
211 typedef enum {
212 REF_TYPE_OTHER,
213 REF_TYPE_FUNCTION,
214 REF_TYPE_GENERATOR,
215 REF_TYPE_PARAMETER,
216 REF_TYPE_TYPE,
217 REF_TYPE_PROPERTY,
218 REF_TYPE_DYNAMIC_PROPERTY
219 } reflection_type_t;
220
221
222 typedef struct {
223 zval dummy;
224 zval obj;
225 void *ptr;
226 zend_class_entry *ce;
227 reflection_type_t ref_type;
228 unsigned int ignore_visibility:1;
229 zend_object zo;
230 } reflection_object;
231
232 static inline reflection_object *reflection_object_from_obj(zend_object *obj) {
233 return (reflection_object*)((char*)(obj) - XtOffsetOf(reflection_object, zo));
234 }
235
236 #define Z_REFLECTION_P(zv) reflection_object_from_obj(Z_OBJ_P((zv)))
237
238
239 static zend_object_handlers reflection_object_handlers;
240
241 static zval *_default_load_entry(zval *object, char *name, size_t name_len)
242 {
243 zval *value;
244
245 if ((value = zend_hash_str_find_ind(Z_OBJPROP_P(object), name, name_len)) == NULL) {
246 return NULL;
247 }
248 return value;
249 }
250
251
252 static void _default_get_entry(zval *object, char *name, int name_len, zval *return_value)
253 {
254 zval *value;
255
256 if ((value = _default_load_entry(object, name, name_len)) == NULL) {
257 RETURN_FALSE;
258 }
259 ZVAL_DUP(return_value, value);
260 }
261
262
263 #ifdef ilia_0
264 static void _default_lookup_entry(zval *object, char *name, int name_len, zval **return_value)
265 {
266 zval **value;
267
268 if (zend_hash_find(Z_OBJPROP_P(object), name, name_len, (void **) &value) == FAILURE) {
269 *return_value = NULL;
270 } else {
271 *return_value = *value;
272 }
273 }
274
275 #endif
276
277 static zend_function *_copy_function(zend_function *fptr)
278 {
279 if (fptr
280 && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))
281 {
282 zend_function *copy_fptr;
283 copy_fptr = emalloc(sizeof(zend_function));
284 memcpy(copy_fptr, fptr, sizeof(zend_function));
285 copy_fptr->internal_function.function_name = zend_string_copy(fptr->internal_function.function_name);
286 return copy_fptr;
287 } else {
288
289 return fptr;
290 }
291 }
292
293
294 static void _free_function(zend_function *fptr)
295 {
296 if (fptr
297 && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))
298 {
299 zend_string_release(fptr->internal_function.function_name);
300 zend_free_trampoline(fptr);
301 }
302 }
303
304
305 static void reflection_free_objects_storage(zend_object *object)
306 {
307 reflection_object *intern = reflection_object_from_obj(object);
308 parameter_reference *reference;
309 property_reference *prop_reference;
310 type_reference *typ_reference;
311
312 if (intern->ptr) {
313 switch (intern->ref_type) {
314 case REF_TYPE_PARAMETER:
315 reference = (parameter_reference*)intern->ptr;
316 _free_function(reference->fptr);
317 efree(intern->ptr);
318 break;
319 case REF_TYPE_TYPE:
320 typ_reference = (type_reference*)intern->ptr;
321 _free_function(typ_reference->fptr);
322 efree(intern->ptr);
323 break;
324 case REF_TYPE_FUNCTION:
325 _free_function(intern->ptr);
326 break;
327 case REF_TYPE_PROPERTY:
328 efree(intern->ptr);
329 break;
330 case REF_TYPE_DYNAMIC_PROPERTY:
331 prop_reference = (property_reference*)intern->ptr;
332 zend_string_release(prop_reference->prop.name);
333 efree(intern->ptr);
334 break;
335 case REF_TYPE_GENERATOR:
336 break;
337 case REF_TYPE_OTHER:
338 break;
339 }
340 }
341 intern->ptr = NULL;
342 zval_ptr_dtor(&intern->obj);
343 zend_object_std_dtor(object);
344 }
345
346
347 static zend_object *reflection_objects_new(zend_class_entry *class_type)
348 {
349 reflection_object *intern;
350
351 intern = ecalloc(1, sizeof(reflection_object) + zend_object_properties_size(class_type));
352 intern->zo.ce = class_type;
353
354 zend_object_std_init(&intern->zo, class_type);
355 object_properties_init(&intern->zo, class_type);
356 intern->zo.handlers = &reflection_object_handlers;
357 return &intern->zo;
358 }
359
360
361 static zval *reflection_instantiate(zend_class_entry *pce, zval *object)
362 {
363 object_init_ex(object, pce);
364 return object;
365 }
366
367
368 static void _const_string(string *str, char *name, zval *value, char *indent);
369 static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent);
370 static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent);
371 static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent);
372 static void _extension_string(string *str, zend_module_entry *module, char *indent);
373 static void _zend_extension_string(string *str, zend_extension *extension, char *indent);
374
375
376 static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent)
377 {
378 int count, count_static_props = 0, count_static_funcs = 0, count_shadow_props = 0;
379 string sub_indent;
380
381 string_init(&sub_indent);
382 string_printf(&sub_indent, "%s ", indent);
383
384
385 if (ce->type == ZEND_USER_CLASS && ce->info.user.doc_comment) {
386 string_printf(str, "%s%s", indent, ZSTR_VAL(ce->info.user.doc_comment));
387 string_write(str, "\n", 1);
388 }
389
390 if (obj && Z_TYPE_P(obj) == IS_OBJECT) {
391 string_printf(str, "%sObject of class [ ", indent);
392 } else {
393 char *kind = "Class";
394 if (ce->ce_flags & ZEND_ACC_INTERFACE) {
395 kind = "Interface";
396 } else if (ce->ce_flags & ZEND_ACC_TRAIT) {
397 kind = "Trait";
398 }
399 string_printf(str, "%s%s [ ", indent, kind);
400 }
401 string_printf(str, (ce->type == ZEND_USER_CLASS) ? "<user" : "<internal");
402 if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module) {
403 string_printf(str, ":%s", ce->info.internal.module->name);
404 }
405 string_printf(str, "> ");
406 if (ce->get_iterator != NULL) {
407 string_printf(str, "<iterateable> ");
408 }
409 if (ce->ce_flags & ZEND_ACC_INTERFACE) {
410 string_printf(str, "interface ");
411 } else if (ce->ce_flags & ZEND_ACC_TRAIT) {
412 string_printf(str, "trait ");
413 } else {
414 if (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
415 string_printf(str, "abstract ");
416 }
417 if (ce->ce_flags & ZEND_ACC_FINAL) {
418 string_printf(str, "final ");
419 }
420 string_printf(str, "class ");
421 }
422 string_printf(str, "%s", ZSTR_VAL(ce->name));
423 if (ce->parent) {
424 string_printf(str, " extends %s", ZSTR_VAL(ce->parent->name));
425 }
426
427 if (ce->num_interfaces) {
428 uint32_t i;
429
430 if (ce->ce_flags & ZEND_ACC_INTERFACE) {
431 string_printf(str, " extends %s", ZSTR_VAL(ce->interfaces[0]->name));
432 } else {
433 string_printf(str, " implements %s", ZSTR_VAL(ce->interfaces[0]->name));
434 }
435 for (i = 1; i < ce->num_interfaces; ++i) {
436 string_printf(str, ", %s", ZSTR_VAL(ce->interfaces[i]->name));
437 }
438 }
439 string_printf(str, " ] {\n");
440
441
442 if (ce->type == ZEND_USER_CLASS) {
443 string_printf(str, "%s @@ %s %d-%d\n", indent, ZSTR_VAL(ce->info.user.filename),
444 ce->info.user.line_start, ce->info.user.line_end);
445 }
446
447
448 string_printf(str, "\n");
449 count = zend_hash_num_elements(&ce->constants_table);
450 string_printf(str, "%s - Constants [%d] {\n", indent, count);
451 if (count > 0) {
452 zend_string *key;
453 zval *value;
454
455 ZEND_HASH_FOREACH_STR_KEY_VAL(&ce->constants_table, key, value) {
456 zval_update_constant_ex(value, 1, NULL);
457 _const_string(str, ZSTR_VAL(key), value, indent);
458 } ZEND_HASH_FOREACH_END();
459 }
460 string_printf(str, "%s }\n", indent);
461
462
463
464 count = zend_hash_num_elements(&ce->properties_info);
465 if (count > 0) {
466 zend_property_info *prop;
467
468 ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
469 if(prop->flags & ZEND_ACC_SHADOW) {
470 count_shadow_props++;
471 } else if (prop->flags & ZEND_ACC_STATIC) {
472 count_static_props++;
473 }
474 } ZEND_HASH_FOREACH_END();
475 }
476
477
478 string_printf(str, "\n%s - Static properties [%d] {\n", indent, count_static_props);
479 if (count_static_props > 0) {
480 zend_property_info *prop;
481
482 ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
483 if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) {
484 _property_string(str, prop, NULL, ZSTR_VAL(sub_indent.buf));
485 }
486 } ZEND_HASH_FOREACH_END();
487 }
488 string_printf(str, "%s }\n", indent);
489
490
491
492 count = zend_hash_num_elements(&ce->function_table);
493 if (count > 0) {
494 zend_function *mptr;
495
496 ZEND_HASH_FOREACH_PTR(&ce->function_table, mptr) {
497 if (mptr->common.fn_flags & ZEND_ACC_STATIC
498 && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
499 {
500 count_static_funcs++;
501 }
502 } ZEND_HASH_FOREACH_END();
503 }
504
505
506 string_printf(str, "\n%s - Static methods [%d] {", indent, count_static_funcs);
507 if (count_static_funcs > 0) {
508 zend_function *mptr;
509
510 ZEND_HASH_FOREACH_PTR(&ce->function_table, mptr) {
511 if (mptr->common.fn_flags & ZEND_ACC_STATIC
512 && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
513 {
514 string_printf(str, "\n");
515 _function_string(str, mptr, ce, ZSTR_VAL(sub_indent.buf));
516 }
517 } ZEND_HASH_FOREACH_END();
518 } else {
519 string_printf(str, "\n");
520 }
521 string_printf(str, "%s }\n", indent);
522
523
524 count = zend_hash_num_elements(&ce->properties_info) - count_static_props - count_shadow_props;
525 string_printf(str, "\n%s - Properties [%d] {\n", indent, count);
526 if (count > 0) {
527 zend_property_info *prop;
528
529 ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
530 if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) {
531 _property_string(str, prop, NULL, ZSTR_VAL(sub_indent.buf));
532 }
533 } ZEND_HASH_FOREACH_END();
534 }
535 string_printf(str, "%s }\n", indent);
536
537 if (obj && Z_TYPE_P(obj) == IS_OBJECT && Z_OBJ_HT_P(obj)->get_properties) {
538 string dyn;
539 HashTable *properties = Z_OBJ_HT_P(obj)->get_properties(obj);
540 zend_string *prop_name;
541
542 string_init(&dyn);
543 count = 0;
544
545 if (properties && zend_hash_num_elements(properties)) {
546 ZEND_HASH_FOREACH_STR_KEY(properties, prop_name) {
547 if (prop_name && ZSTR_LEN(prop_name) && ZSTR_VAL(prop_name)[0]) {
548 if (!zend_hash_exists(&ce->properties_info, prop_name)) {
549 count++;
550 _property_string(&dyn, NULL, ZSTR_VAL(prop_name), ZSTR_VAL(sub_indent.buf));
551 }
552 }
553 } ZEND_HASH_FOREACH_END();
554 }
555
556 string_printf(str, "\n%s - Dynamic properties [%d] {\n", indent, count);
557 string_append(str, &dyn);
558 string_printf(str, "%s }\n", indent);
559 string_free(&dyn);
560 }
561
562
563 count = zend_hash_num_elements(&ce->function_table) - count_static_funcs;
564 if (count > 0) {
565 zend_function *mptr;
566 zend_string *key;
567 string dyn;
568
569 count = 0;
570 string_init(&dyn);
571
572 ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, key, mptr) {
573 if ((mptr->common.fn_flags & ZEND_ACC_STATIC) == 0
574 && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
575 {
576 size_t len = ZSTR_LEN(mptr->common.function_name);
577
578
579 if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0
580 || mptr->common.scope == ce
581 || !key
582 || zend_binary_strcasecmp(ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(mptr->common.function_name), len) == 0)
583 {
584 zend_function *closure;
585
586 if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
587 && memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
588 && (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL)
589 {
590 mptr = closure;
591 } else {
592 closure = NULL;
593 }
594 string_printf(&dyn, "\n");
595 _function_string(&dyn, mptr, ce, ZSTR_VAL(sub_indent.buf));
596 count++;
597 _free_function(closure);
598 }
599 }
600 } ZEND_HASH_FOREACH_END();
601 string_printf(str, "\n%s - Methods [%d] {", indent, count);
602 if (!count) {
603 string_printf(str, "\n");
604 }
605 string_append(str, &dyn);
606 string_free(&dyn);
607 } else {
608 string_printf(str, "\n%s - Methods [0] {\n", indent);
609 }
610 string_printf(str, "%s }\n", indent);
611
612 string_printf(str, "%s}\n", indent);
613 string_free(&sub_indent);
614 }
615
616
617
618 static void _const_string(string *str, char *name, zval *value, char *indent)
619 {
620 char *type = zend_zval_type_name(value);
621 zend_string *value_str = zval_get_string(value);
622
623 string_printf(str, "%s Constant [ %s %s ] { %s }\n",
624 indent, type, name, ZSTR_VAL(value_str));
625
626 zend_string_release(value_str);
627 }
628
629
630
631 static zend_op* _get_recv_op(zend_op_array *op_array, uint32_t offset)
632 {
633 zend_op *op = op_array->opcodes;
634 zend_op *end = op + op_array->last;
635
636 ++offset;
637 while (op < end) {
638 if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT
639 || op->opcode == ZEND_RECV_VARIADIC) && op->op1.num == (zend_long)offset)
640 {
641 return op;
642 }
643 ++op;
644 }
645 return NULL;
646 }
647
648
649
650 static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg_info *arg_info, uint32_t offset, uint32_t required, char* indent)
651 {
652 string_printf(str, "Parameter #%d [ ", offset);
653 if (offset >= required) {
654 string_printf(str, "<optional> ");
655 } else {
656 string_printf(str, "<required> ");
657 }
658 if (arg_info->class_name) {
659 string_printf(str, "%s ",
660 (fptr->type == ZEND_INTERNAL_FUNCTION &&
661 !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) ?
662 ((zend_internal_arg_info*)arg_info)->class_name :
663 ZSTR_VAL(arg_info->class_name));
664 if (arg_info->allow_null) {
665 string_printf(str, "or NULL ");
666 }
667 } else if (arg_info->type_hint) {
668 string_printf(str, "%s ", zend_get_type_by_const(arg_info->type_hint));
669 if (arg_info->allow_null) {
670 string_printf(str, "or NULL ");
671 }
672 }
673 if (arg_info->pass_by_reference) {
674 string_write(str, "&", sizeof("&")-1);
675 }
676 if (arg_info->is_variadic) {
677 string_write(str, "...", sizeof("...")-1);
678 }
679 if (arg_info->name) {
680 string_printf(str, "$%s",
681 (fptr->type == ZEND_INTERNAL_FUNCTION &&
682 !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) ?
683 ((zend_internal_arg_info*)arg_info)->name :
684 ZSTR_VAL(arg_info->name));
685 } else {
686 string_printf(str, "$param%d", offset);
687 }
688 if (fptr->type == ZEND_USER_FUNCTION && offset >= required) {
689 zend_op *precv = _get_recv_op((zend_op_array*)fptr, offset);
690 if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) {
691 zval zv;
692 zend_class_entry *old_scope;
693
694 string_write(str, " = ", sizeof(" = ")-1);
695 ZVAL_DUP(&zv, RT_CONSTANT(&fptr->op_array, precv->op2));
696 old_scope = EG(scope);
697 EG(scope) = fptr->common.scope;
698 zval_update_constant_ex(&zv, 1, NULL);
699 EG(scope) = old_scope;
700 if (Z_TYPE(zv) == IS_TRUE) {
701 string_write(str, "true", sizeof("true")-1);
702 } else if (Z_TYPE(zv) == IS_FALSE) {
703 string_write(str, "false", sizeof("false")-1);
704 } else if (Z_TYPE(zv) == IS_NULL) {
705 string_write(str, "NULL", sizeof("NULL")-1);
706 } else if (Z_TYPE(zv) == IS_STRING) {
707 string_write(str, "'", sizeof("'")-1);
708 string_write(str, Z_STRVAL(zv), MIN(Z_STRLEN(zv), 15));
709 if (Z_STRLEN(zv) > 15) {
710 string_write(str, "...", sizeof("...")-1);
711 }
712 string_write(str, "'", sizeof("'")-1);
713 } else if (Z_TYPE(zv) == IS_ARRAY) {
714 string_write(str, "Array", sizeof("Array")-1);
715 } else {
716 zend_string *zv_str = zval_get_string(&zv);
717 string_write(str, ZSTR_VAL(zv_str), ZSTR_LEN(zv_str));
718 zend_string_release(zv_str);
719 }
720 zval_ptr_dtor(&zv);
721 }
722 }
723 string_write(str, " ]", sizeof(" ]")-1);
724 }
725
726
727
728 static void _function_parameter_string(string *str, zend_function *fptr, char* indent)
729 {
730 struct _zend_arg_info *arg_info = fptr->common.arg_info;
731 uint32_t i, num_args, required = fptr->common.required_num_args;
732
733 if (!arg_info) {
734 return;
735 }
736
737 num_args = fptr->common.num_args;
738 if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) {
739 num_args++;
740 }
741 string_printf(str, "\n");
742 string_printf(str, "%s- Parameters [%d] {\n", indent, num_args);
743 for (i = 0; i < num_args; i++) {
744 string_printf(str, "%s ", indent);
745 _parameter_string(str, fptr, arg_info, i, required, indent);
746 string_write(str, "\n", sizeof("\n")-1);
747 arg_info++;
748 }
749 string_printf(str, "%s}\n", indent);
750 }
751
752
753
754 static void _function_closure_string(string *str, zend_function *fptr, char* indent)
755 {
756 uint32_t i, count;
757 zend_string *key;
758 HashTable *static_variables;
759
760 if (fptr->type != ZEND_USER_FUNCTION || !fptr->op_array.static_variables) {
761 return;
762 }
763
764 static_variables = fptr->op_array.static_variables;
765 count = zend_hash_num_elements(static_variables);
766
767 if (!count) {
768 return;
769 }
770
771 string_printf(str, "\n");
772 string_printf(str, "%s- Bound Variables [%d] {\n", indent, zend_hash_num_elements(static_variables));
773 i = 0;
774 ZEND_HASH_FOREACH_STR_KEY(static_variables, key) {
775 string_printf(str, "%s Variable #%d [ $%s ]\n", indent, i++, ZSTR_VAL(key));
776 } ZEND_HASH_FOREACH_END();
777 string_printf(str, "%s}\n", indent);
778 }
779
780
781
782 static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent)
783 {
784 string param_indent;
785 zend_function *overwrites;
786 zend_string *lc_name;
787 size_t lc_name_len;
788
789
790
791
792
793 if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
794 string_printf(str, "%s%s\n", indent, ZSTR_VAL(fptr->op_array.doc_comment));
795 }
796
797 string_write(str, indent, strlen(indent));
798 string_printf(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ "));
799 string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal");
800 if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) {
801 string_printf(str, ", deprecated");
802 }
803 if (fptr->type == ZEND_INTERNAL_FUNCTION && ((zend_internal_function*)fptr)->module) {
804 string_printf(str, ":%s", ((zend_internal_function*)fptr)->module->name);
805 }
806
807 if (scope && fptr->common.scope) {
808 if (fptr->common.scope != scope) {
809 string_printf(str, ", inherits %s", ZSTR_VAL(fptr->common.scope->name));
810 } else if (fptr->common.scope->parent) {
811 lc_name_len = ZSTR_LEN(fptr->common.function_name);
812 lc_name = zend_string_alloc(lc_name_len, 0);
813 zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(fptr->common.function_name), lc_name_len);
814 if ((overwrites = zend_hash_find_ptr(&fptr->common.scope->parent->function_table, lc_name)) != NULL) {
815 if (fptr->common.scope != overwrites->common.scope) {
816 string_printf(str, ", overwrites %s", ZSTR_VAL(overwrites->common.scope->name));
817 }
818 }
819 efree(lc_name);
820 }
821 }
822 if (fptr->common.prototype && fptr->common.prototype->common.scope) {
823 string_printf(str, ", prototype %s", ZSTR_VAL(fptr->common.prototype->common.scope->name));
824 }
825 if (fptr->common.fn_flags & ZEND_ACC_CTOR) {
826 string_printf(str, ", ctor");
827 }
828 if (fptr->common.fn_flags & ZEND_ACC_DTOR) {
829 string_printf(str, ", dtor");
830 }
831 string_printf(str, "> ");
832
833 if (fptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
834 string_printf(str, "abstract ");
835 }
836 if (fptr->common.fn_flags & ZEND_ACC_FINAL) {
837 string_printf(str, "final ");
838 }
839 if (fptr->common.fn_flags & ZEND_ACC_STATIC) {
840 string_printf(str, "static ");
841 }
842
843 if (fptr->common.scope) {
844
845 switch (fptr->common.fn_flags & ZEND_ACC_PPP_MASK) {
846 case ZEND_ACC_PUBLIC:
847 string_printf(str, "public ");
848 break;
849 case ZEND_ACC_PRIVATE:
850 string_printf(str, "private ");
851 break;
852 case ZEND_ACC_PROTECTED:
853 string_printf(str, "protected ");
854 break;
855 default:
856 string_printf(str, "<visibility error> ");
857 break;
858 }
859 string_printf(str, "method ");
860 } else {
861 string_printf(str, "function ");
862 }
863
864 if (fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
865 string_printf(str, "&");
866 }
867 string_printf(str, "%s ] {\n", ZSTR_VAL(fptr->common.function_name));
868
869 if (fptr->type == ZEND_USER_FUNCTION) {
870 string_printf(str, "%s @@ %s %d - %d\n", indent,
871 ZSTR_VAL(fptr->op_array.filename),
872 fptr->op_array.line_start,
873 fptr->op_array.line_end);
874 }
875 string_init(¶m_indent);
876 string_printf(¶m_indent, "%s ", indent);
877 if (fptr->common.fn_flags & ZEND_ACC_CLOSURE) {
878 _function_closure_string(str, fptr, ZSTR_VAL(param_indent.buf));
879 }
880 _function_parameter_string(str, fptr, ZSTR_VAL(param_indent.buf));
881 string_free(¶m_indent);
882 if (fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
883 string_printf(str, " %s- Return [ ", indent);
884 if (fptr->common.arg_info[-1].class_name) {
885 string_printf(str, "%s ",
886 (fptr->type == ZEND_INTERNAL_FUNCTION &&
887 !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) ?
888 ((zend_internal_arg_info*)(fptr->common.arg_info - 1))->class_name :
889 ZSTR_VAL(fptr->common.arg_info[-1].class_name));
890 if (fptr->common.arg_info[-1].allow_null) {
891 string_printf(str, "or NULL ");
892 }
893 } else if (fptr->common.arg_info[-1].type_hint) {
894 string_printf(str, "%s ", zend_get_type_by_const(fptr->common.arg_info[-1].type_hint));
895 if (fptr->common.arg_info[-1].allow_null) {
896 string_printf(str, "or NULL ");
897 }
898 }
899 string_printf(str, "]\n");
900 }
901 string_printf(str, "%s}\n", indent);
902 }
903
904
905
906 static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent)
907 {
908 const char *class_name;
909
910 string_printf(str, "%sProperty [ ", indent);
911 if (!prop) {
912 string_printf(str, "<dynamic> public $%s", prop_name);
913 } else {
914 if (!(prop->flags & ZEND_ACC_STATIC)) {
915 if (prop->flags & ZEND_ACC_IMPLICIT_PUBLIC) {
916 string_write(str, "<implicit> ", sizeof("<implicit> ") - 1);
917 } else {
918 string_write(str, "<default> ", sizeof("<default> ") - 1);
919 }
920 }
921
922
923 switch (prop->flags & ZEND_ACC_PPP_MASK) {
924 case ZEND_ACC_PUBLIC:
925 string_printf(str, "public ");
926 break;
927 case ZEND_ACC_PRIVATE:
928 string_printf(str, "private ");
929 break;
930 case ZEND_ACC_PROTECTED:
931 string_printf(str, "protected ");
932 break;
933 }
934 if(prop->flags & ZEND_ACC_STATIC) {
935 string_printf(str, "static ");
936 }
937
938 zend_unmangle_property_name(prop->name, &class_name, (const char**)&prop_name);
939 string_printf(str, "$%s", prop_name);
940 }
941
942 string_printf(str, " ]\n");
943 }
944
945
946 static int _extension_ini_string(zval *el, int num_args, va_list args, zend_hash_key *hash_key)
947 {
948 zend_ini_entry *ini_entry = (zend_ini_entry*)Z_PTR_P(el);
949 string *str = va_arg(args, string *);
950 char *indent = va_arg(args, char *);
951 int number = va_arg(args, int);
952 char *comma = "";
953
954 if (number == ini_entry->module_number) {
955 string_printf(str, " %sEntry [ %s <", indent, ZSTR_VAL(ini_entry->name));
956 if (ini_entry->modifiable == ZEND_INI_ALL) {
957 string_printf(str, "ALL");
958 } else {
959 if (ini_entry->modifiable & ZEND_INI_USER) {
960 string_printf(str, "USER");
961 comma = ",";
962 }
963 if (ini_entry->modifiable & ZEND_INI_PERDIR) {
964 string_printf(str, "%sPERDIR", comma);
965 comma = ",";
966 }
967 if (ini_entry->modifiable & ZEND_INI_SYSTEM) {
968 string_printf(str, "%sSYSTEM", comma);
969 }
970 }
971
972 string_printf(str, "> ]\n");
973 string_printf(str, " %s Current = '%s'\n", indent, ini_entry->value ? ZSTR_VAL(ini_entry->value) : "");
974 if (ini_entry->modified) {
975 string_printf(str, " %s Default = '%s'\n", indent, ini_entry->orig_value ? ZSTR_VAL(ini_entry->orig_value) : "");
976 }
977 string_printf(str, " %s}\n", indent);
978 }
979 return ZEND_HASH_APPLY_KEEP;
980 }
981
982
983 static int _extension_class_string(zval *el, int num_args, va_list args, zend_hash_key *hash_key)
984 {
985 zend_class_entry *ce = (zend_class_entry*)Z_PTR_P(el);
986 string *str = va_arg(args, string *);
987 char *indent = va_arg(args, char *);
988 struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
989 int *num_classes = va_arg(args, int*);
990
991 if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module && !strcasecmp(ce->info.internal.module->name, module->name)) {
992
993 if (!zend_binary_strcasecmp(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(hash_key->key), ZSTR_LEN(hash_key->key))) {
994 string_printf(str, "\n");
995 _class_string(str, ce, NULL, indent);
996 (*num_classes)++;
997 }
998 }
999 return ZEND_HASH_APPLY_KEEP;
1000 }
1001
1002
1003 static int _extension_const_string(zval *el, int num_args, va_list args, zend_hash_key *hash_key)
1004 {
1005 zend_constant *constant = (zend_constant*)Z_PTR_P(el);
1006 string *str = va_arg(args, string *);
1007 char *indent = va_arg(args, char *);
1008 struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
1009 int *num_classes = va_arg(args, int*);
1010
1011 if (constant->module_number == module->module_number) {
1012 _const_string(str, ZSTR_VAL(constant->name), &constant->value, indent);
1013 (*num_classes)++;
1014 }
1015 return ZEND_HASH_APPLY_KEEP;
1016 }
1017
1018
1019 static void _extension_string(string *str, zend_module_entry *module, char *indent)
1020 {
1021 string_printf(str, "%sExtension [ ", indent);
1022 if (module->type == MODULE_PERSISTENT) {
1023 string_printf(str, "<persistent>");
1024 }
1025 if (module->type == MODULE_TEMPORARY) {
1026 string_printf(str, "<temporary>" );
1027 }
1028 string_printf(str, " extension #%d %s version %s ] {\n",
1029 module->module_number, module->name,
1030 (module->version == NO_VERSION_YET) ? "<no_version>" : module->version);
1031
1032 if (module->deps) {
1033 const zend_module_dep* dep = module->deps;
1034
1035 string_printf(str, "\n - Dependencies {\n");
1036
1037 while(dep->name) {
1038 string_printf(str, "%s Dependency [ %s (", indent, dep->name);
1039
1040 switch(dep->type) {
1041 case MODULE_DEP_REQUIRED:
1042 string_write(str, "Required", sizeof("Required") - 1);
1043 break;
1044 case MODULE_DEP_CONFLICTS:
1045 string_write(str, "Conflicts", sizeof("Conflicts") - 1);
1046 break;
1047 case MODULE_DEP_OPTIONAL:
1048 string_write(str, "Optional", sizeof("Optional") - 1);
1049 break;
1050 default:
1051 string_write(str, "Error", sizeof("Error") - 1);
1052 break;
1053 }
1054
1055 if (dep->rel) {
1056 string_printf(str, " %s", dep->rel);
1057 }
1058 if (dep->version) {
1059 string_printf(str, " %s", dep->version);
1060 }
1061 string_write(str, ") ]\n", sizeof(") ]\n") - 1);
1062 dep++;
1063 }
1064 string_printf(str, "%s }\n", indent);
1065 }
1066
1067 {
1068 string str_ini;
1069 string_init(&str_ini);
1070 zend_hash_apply_with_arguments(EG(ini_directives), (apply_func_args_t) _extension_ini_string, 3, &str_ini, indent, module->module_number);
1071 if (ZSTR_LEN(str_ini.buf) > 0) {
1072 string_printf(str, "\n - INI {\n");
1073 string_append(str, &str_ini);
1074 string_printf(str, "%s }\n", indent);
1075 }
1076 string_free(&str_ini);
1077 }
1078
1079 {
1080 string str_constants;
1081 int num_constants = 0;
1082
1083 string_init(&str_constants);
1084 zend_hash_apply_with_arguments(EG(zend_constants), (apply_func_args_t) _extension_const_string, 4, &str_constants, indent, module, &num_constants);
1085 if (num_constants) {
1086 string_printf(str, "\n - Constants [%d] {\n", num_constants);
1087 string_append(str, &str_constants);
1088 string_printf(str, "%s }\n", indent);
1089 }
1090 string_free(&str_constants);
1091 }
1092
1093 {
1094 zend_function *fptr;
1095 int first = 1;
1096
1097 ZEND_HASH_FOREACH_PTR(CG(function_table), fptr) {
1098 if (fptr->common.type==ZEND_INTERNAL_FUNCTION
1099 && fptr->internal_function.module == module) {
1100 if (first) {
1101 string_printf(str, "\n - Functions {\n");
1102 first = 0;
1103 }
1104 _function_string(str, fptr, NULL, " ");
1105 }
1106 } ZEND_HASH_FOREACH_END();
1107 if (!first) {
1108 string_printf(str, "%s }\n", indent);
1109 }
1110 }
1111
1112 {
1113 string str_classes;
1114 string sub_indent;
1115 int num_classes = 0;
1116
1117 string_init(&sub_indent);
1118 string_printf(&sub_indent, "%s ", indent);
1119 string_init(&str_classes);
1120 zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) _extension_class_string, 4, &str_classes, ZSTR_VAL(sub_indent.buf), module, &num_classes);
1121 if (num_classes) {
1122 string_printf(str, "\n - Classes [%d] {", num_classes);
1123 string_append(str, &str_classes);
1124 string_printf(str, "%s }\n", indent);
1125 }
1126 string_free(&str_classes);
1127 string_free(&sub_indent);
1128 }
1129
1130 string_printf(str, "%s}\n", indent);
1131 }
1132
1133
1134 static void _zend_extension_string(string *str, zend_extension *extension, char *indent)
1135 {
1136 string_printf(str, "%sZend Extension [ %s ", indent, extension->name);
1137
1138 if (extension->version) {
1139 string_printf(str, "%s ", extension->version);
1140 }
1141 if (extension->copyright) {
1142 string_printf(str, "%s ", extension->copyright);
1143 }
1144 if (extension->author) {
1145 string_printf(str, "by %s ", extension->author);
1146 }
1147 if (extension->URL) {
1148 string_printf(str, "<%s> ", extension->URL);
1149 }
1150
1151 string_printf(str, "]\n");
1152 }
1153
1154
1155
1156 static void _function_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
1157 {
1158 reflection_object *intern;
1159 zend_function *mptr;
1160
1161 if (zend_parse_parameters_none() == FAILURE) {
1162 return;
1163 }
1164 GET_REFLECTION_OBJECT_PTR(mptr);
1165 RETURN_BOOL(mptr->common.fn_flags & mask);
1166 }
1167
1168
1169
1170 PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object)
1171 {
1172 reflection_object *intern;
1173 zval name;
1174
1175 ZVAL_STR_COPY(&name, ce->name);
1176 reflection_instantiate(reflection_class_ptr, object);
1177 intern = Z_REFLECTION_P(object);
1178 intern->ptr = ce;
1179 intern->ref_type = REF_TYPE_OTHER;
1180 intern->ce = ce;
1181 reflection_update_property(object, "name", &name);
1182 }
1183
1184
1185
1186 static void reflection_extension_factory(zval *object, const char *name_str)
1187 {
1188 reflection_object *intern;
1189 zval name;
1190 size_t name_len = strlen(name_str);
1191 zend_string *lcname;
1192 struct _zend_module_entry *module;
1193
1194 lcname = zend_string_alloc(name_len, 0);
1195 zend_str_tolower_copy(ZSTR_VAL(lcname), name_str, name_len);
1196 module = zend_hash_find_ptr(&module_registry, lcname);
1197 zend_string_free(lcname);
1198 if (!module) {
1199 return;
1200 }
1201
1202 reflection_instantiate(reflection_extension_ptr, object);
1203 intern = Z_REFLECTION_P(object);
1204 ZVAL_STRINGL(&name, module->name, name_len);
1205 intern->ptr = module;
1206 intern->ref_type = REF_TYPE_OTHER;
1207 intern->ce = NULL;
1208 reflection_update_property(object, "name", &name);
1209 }
1210
1211
1212
1213 static void reflection_parameter_factory(zend_function *fptr, zval *closure_object, struct _zend_arg_info *arg_info, uint32_t offset, uint32_t required, zval *object)
1214 {
1215 reflection_object *intern;
1216 parameter_reference *reference;
1217 zval name;
1218
1219 if (arg_info->name) {
1220 if (fptr->type == ZEND_INTERNAL_FUNCTION &&
1221 !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
1222 ZVAL_STRING(&name, ((zend_internal_arg_info*)arg_info)->name);
1223 } else {
1224 ZVAL_STR_COPY(&name, arg_info->name);
1225 }
1226 } else {
1227 ZVAL_NULL(&name);
1228 }
1229 reflection_instantiate(reflection_parameter_ptr, object);
1230 intern = Z_REFLECTION_P(object);
1231 reference = (parameter_reference*) emalloc(sizeof(parameter_reference));
1232 reference->arg_info = arg_info;
1233 reference->offset = offset;
1234 reference->required = required;
1235 reference->fptr = fptr;
1236 intern->ptr = reference;
1237 intern->ref_type = REF_TYPE_PARAMETER;
1238 intern->ce = fptr->common.scope;
1239 if (closure_object) {
1240 Z_ADDREF_P(closure_object);
1241 ZVAL_COPY_VALUE(&intern->obj, closure_object);
1242 }
1243 reflection_update_property(object, "name", &name);
1244 }
1245
1246
1247
1248 static void reflection_type_factory(zend_function *fptr, zval *closure_object, struct _zend_arg_info *arg_info, zval *object)
1249 {
1250 reflection_object *intern;
1251 type_reference *reference;
1252
1253 reflection_instantiate(reflection_type_ptr, object);
1254 intern = Z_REFLECTION_P(object);
1255 reference = (type_reference*) emalloc(sizeof(type_reference));
1256 reference->arg_info = arg_info;
1257 reference->fptr = fptr;
1258 intern->ptr = reference;
1259 intern->ref_type = REF_TYPE_TYPE;
1260 intern->ce = fptr->common.scope;
1261 if (closure_object) {
1262 Z_ADDREF_P(closure_object);
1263 ZVAL_COPY_VALUE(&intern->obj, closure_object);
1264 }
1265 }
1266
1267
1268
1269 static void reflection_function_factory(zend_function *function, zval *closure_object, zval *object)
1270 {
1271 reflection_object *intern;
1272 zval name;
1273
1274 ZVAL_STR_COPY(&name, function->common.function_name);
1275
1276 reflection_instantiate(reflection_function_ptr, object);
1277 intern = Z_REFLECTION_P(object);
1278 intern->ptr = function;
1279 intern->ref_type = REF_TYPE_FUNCTION;
1280 intern->ce = NULL;
1281 if (closure_object) {
1282 Z_ADDREF_P(closure_object);
1283 ZVAL_COPY_VALUE(&intern->obj, closure_object);
1284 }
1285 reflection_update_property(object, "name", &name);
1286 }
1287
1288
1289
1290 static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *closure_object, zval *object)
1291 {
1292 reflection_object *intern;
1293 zval name;
1294 zval classname;
1295
1296 ZVAL_STR_COPY(&name, (method->common.scope && method->common.scope->trait_aliases)?
1297 zend_resolve_method_name(ce, method) : method->common.function_name);
1298 ZVAL_STR_COPY(&classname, method->common.scope->name);
1299 reflection_instantiate(reflection_method_ptr, object);
1300 intern = Z_REFLECTION_P(object);
1301 intern->ptr = method;
1302 intern->ref_type = REF_TYPE_FUNCTION;
1303 intern->ce = ce;
1304 if (closure_object) {
1305 Z_ADDREF_P(closure_object);
1306 ZVAL_COPY_VALUE(&intern->obj, closure_object);
1307 }
1308 reflection_update_property(object, "name", &name);
1309 reflection_update_property(object, "class", &classname);
1310 }
1311
1312
1313
1314 static void reflection_property_factory(zend_class_entry *ce, zend_property_info *prop, zval *object)
1315 {
1316 reflection_object *intern;
1317 zval name;
1318 zval classname;
1319 property_reference *reference;
1320 const char *class_name, *prop_name;
1321 size_t prop_name_len;
1322
1323 zend_unmangle_property_name_ex(prop->name, &class_name, &prop_name, &prop_name_len);
1324
1325 if (!(prop->flags & ZEND_ACC_PRIVATE)) {
1326
1327 zend_class_entry *tmp_ce = ce, *store_ce = ce;
1328 zend_property_info *tmp_info = NULL;
1329
1330 while (tmp_ce && (tmp_info = zend_hash_str_find_ptr(&tmp_ce->properties_info, prop_name, prop_name_len)) == NULL) {
1331 ce = tmp_ce;
1332 tmp_ce = tmp_ce->parent;
1333 }
1334
1335 if (tmp_info && !(tmp_info->flags & ZEND_ACC_SHADOW)) {
1336 prop = tmp_info;
1337 } else {
1338 ce = store_ce;
1339 }
1340 }
1341
1342 ZVAL_STRINGL(&name, prop_name, prop_name_len);
1343 ZVAL_STR_COPY(&classname, prop->ce->name);
1344
1345 reflection_instantiate(reflection_property_ptr, object);
1346 intern = Z_REFLECTION_P(object);
1347 reference = (property_reference*) emalloc(sizeof(property_reference));
1348 reference->ce = ce;
1349 reference->prop = *prop;
1350 intern->ptr = reference;
1351 intern->ref_type = REF_TYPE_PROPERTY;
1352 intern->ce = ce;
1353 intern->ignore_visibility = 0;
1354 reflection_update_property(object, "name", &name);
1355 reflection_update_property(object, "class", &classname);
1356 }
1357
1358
1359
1360 static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_ptr, int ctor_argc)
1361 {
1362 zval reflector;
1363 zval output, *output_ptr = &output;
1364 zval *argument_ptr, *argument2_ptr;
1365 zval retval, params[2];
1366 int result;
1367 int return_output = 0;
1368 zend_fcall_info fci;
1369 zend_fcall_info_cache fcc;
1370
1371 if (ctor_argc == 1) {
1372 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &argument_ptr, &return_output) == FAILURE) {
1373 return;
1374 }
1375 ZVAL_COPY_VALUE(¶ms[0], argument_ptr);
1376 ZVAL_NULL(¶ms[1]);
1377 } else {
1378 if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz|b", &argument_ptr, &argument2_ptr, &return_output) == FAILURE) {
1379 return;
1380 }
1381 ZVAL_COPY_VALUE(¶ms[0], argument_ptr);
1382 ZVAL_COPY_VALUE(¶ms[1], argument2_ptr);
1383 }
1384
1385
1386 if (object_and_properties_init(&reflector, ce_ptr, NULL) == FAILURE) {
1387 _DO_THROW("Could not create reflector");
1388 }
1389
1390
1391
1392 fci.size = sizeof(fci);
1393 fci.function_table = NULL;
1394 ZVAL_UNDEF(&fci.function_name);
1395 fci.symbol_table = NULL;
1396 fci.object = Z_OBJ(reflector);
1397 fci.retval = &retval;
1398 fci.param_count = ctor_argc;
1399 fci.params = params;
1400 fci.no_separation = 1;
1401
1402 fcc.initialized = 1;
1403 fcc.function_handler = ce_ptr->constructor;
1404 fcc.calling_scope = ce_ptr;
1405 fcc.called_scope = Z_OBJCE(reflector);
1406 fcc.object = Z_OBJ(reflector);
1407
1408 result = zend_call_function(&fci, &fcc);
1409
1410 zval_ptr_dtor(&retval);
1411
1412 if (EG(exception)) {
1413 zval_ptr_dtor(&reflector);
1414 return;
1415 }
1416 if (result == FAILURE) {
1417 zval_ptr_dtor(&reflector);
1418 _DO_THROW("Could not create reflector");
1419 }
1420
1421
1422 ZVAL_BOOL(&output, return_output);
1423 ZVAL_COPY_VALUE(¶ms[0], &reflector);
1424 ZVAL_COPY_VALUE(¶ms[1], output_ptr);
1425
1426 ZVAL_STRINGL(&fci.function_name, "reflection::export", sizeof("reflection::export") - 1);
1427 fci.function_table = &reflection_ptr->function_table;
1428 fci.object = NULL;
1429 fci.retval = &retval;
1430 fci.param_count = 2;
1431 fci.params = params;
1432 fci.no_separation = 1;
1433
1434 result = zend_call_function(&fci, NULL);
1435
1436 zval_ptr_dtor(&fci.function_name);
1437
1438 if (result == FAILURE && EG(exception) == NULL) {
1439 zval_ptr_dtor(&reflector);
1440 zval_ptr_dtor(&retval);
1441 _DO_THROW("Could not execute reflection::export()");
1442 }
1443
1444 if (return_output) {
1445 ZVAL_COPY_VALUE(return_value, &retval);
1446 } else {
1447 zval_ptr_dtor(&retval);
1448 }
1449
1450
1451 zval_ptr_dtor(&reflector);
1452 }
1453
1454
1455
1456 static parameter_reference *_reflection_param_get_default_param(INTERNAL_FUNCTION_PARAMETERS)
1457 {
1458 reflection_object *intern;
1459 parameter_reference *param;
1460
1461 intern = Z_REFLECTION_P(getThis());
1462 if (intern->ptr == NULL) {
1463 if (EG(exception) && EG(exception)->ce == reflection_exception_ptr) {
1464 return NULL;
1465 }
1466 php_error_docref(NULL, E_ERROR, "Internal error: Failed to retrieve the reflection object");
1467 }
1468
1469 param = intern->ptr;
1470 if (param->fptr->type != ZEND_USER_FUNCTION) {
1471 zend_throw_exception_ex(reflection_exception_ptr, 0, "Cannot determine default value for internal functions");
1472 return NULL;
1473 }
1474
1475 return param;
1476 }
1477
1478
1479
1480 static zend_op *_reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAMETERS, parameter_reference *param)
1481 {
1482 zend_op *precv;
1483
1484 if (param == NULL) {
1485 return NULL;
1486 }
1487
1488 precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
1489 if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2_type == IS_UNUSED) {
1490 zend_throw_exception_ex(reflection_exception_ptr, 0, "Internal error: Failed to retrieve the default value");
1491 return NULL;
1492 }
1493
1494 return precv;
1495 }
1496
1497
1498
1499 ZEND_METHOD(reflection, __clone)
1500 {
1501
1502 _DO_THROW("Cannot clone object using __clone()");
1503 }
1504
1505
1506
1507
1508 ZEND_METHOD(reflection, export)
1509 {
1510 zval *object, fname, retval;
1511 int result;
1512 zend_bool return_output = 0;
1513
1514 #ifndef FAST_ZPP
1515 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|b", &object, reflector_ptr, &return_output) == FAILURE) {
1516 return;
1517 }
1518 #else
1519 ZEND_PARSE_PARAMETERS_START(1, 2)
1520 Z_PARAM_OBJECT_OF_CLASS(object, reflector_ptr)
1521 Z_PARAM_OPTIONAL
1522 Z_PARAM_BOOL(return_output)
1523 ZEND_PARSE_PARAMETERS_END();
1524 #endif
1525
1526
1527 ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring") - 1);
1528 result= call_user_function_ex(NULL, object, &fname, &retval, 0, NULL, 0, NULL);
1529 zval_dtor(&fname);
1530
1531 if (result == FAILURE) {
1532 _DO_THROW("Invocation of method __toString() failed");
1533
1534 }
1535
1536 if (Z_TYPE(retval) == IS_UNDEF) {
1537 php_error_docref(NULL, E_WARNING, "%s::__toString() did not return anything", ZSTR_VAL(Z_OBJCE_P(object)->name));
1538 RETURN_FALSE;
1539 }
1540
1541 if (return_output) {
1542 ZVAL_COPY_VALUE(return_value, &retval);
1543 } else {
1544
1545 zend_print_zval(&retval, 0);
1546 zend_printf("\n");
1547 zval_ptr_dtor(&retval);
1548 }
1549 }
1550
1551
1552
1553
1554 ZEND_METHOD(reflection, getModifierNames)
1555 {
1556 zend_long modifiers;
1557
1558 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &modifiers) == FAILURE) {
1559 return;
1560 }
1561
1562 array_init(return_value);
1563
1564 if (modifiers & (ZEND_ACC_ABSTRACT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
1565 add_next_index_stringl(return_value, "abstract", sizeof("abstract")-1);
1566 }
1567 if (modifiers & ZEND_ACC_FINAL) {
1568 add_next_index_stringl(return_value, "final", sizeof("final")-1);
1569 }
1570 if (modifiers & ZEND_ACC_IMPLICIT_PUBLIC) {
1571 add_next_index_stringl(return_value, "public", sizeof("public")-1);
1572 }
1573
1574
1575 switch (modifiers & ZEND_ACC_PPP_MASK) {
1576 case ZEND_ACC_PUBLIC:
1577 add_next_index_stringl(return_value, "public", sizeof("public")-1);
1578 break;
1579 case ZEND_ACC_PRIVATE:
1580 add_next_index_stringl(return_value, "private", sizeof("private")-1);
1581 break;
1582 case ZEND_ACC_PROTECTED:
1583 add_next_index_stringl(return_value, "protected", sizeof("protected")-1);
1584 break;
1585 }
1586
1587 if (modifiers & ZEND_ACC_STATIC) {
1588 add_next_index_stringl(return_value, "static", sizeof("static")-1);
1589 }
1590 }
1591
1592
1593
1594
1595 ZEND_METHOD(reflection_function, export)
1596 {
1597 _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_function_ptr, 1);
1598 }
1599
1600
1601
1602
1603 ZEND_METHOD(reflection_function, __construct)
1604 {
1605 zval name;
1606 zval *object;
1607 zval *closure = NULL;
1608 char *lcname, *nsname;
1609 reflection_object *intern;
1610 zend_function *fptr;
1611 char *name_str;
1612 size_t name_len;
1613
1614 object = getThis();
1615 intern = Z_REFLECTION_P(object);
1616
1617 if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "O", &closure, zend_ce_closure) == SUCCESS) {
1618 fptr = (zend_function*)zend_get_closure_method_def(closure);
1619 Z_ADDREF_P(closure);
1620 } else {
1621 if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s", &name_str, &name_len) == FAILURE) {
1622 return;
1623 }
1624
1625 lcname = zend_str_tolower_dup(name_str, name_len);
1626
1627
1628 nsname = lcname;
1629 if (lcname[0] == '\\') {
1630 nsname = &lcname[1];
1631 name_len--;
1632 }
1633
1634 if ((fptr = zend_hash_str_find_ptr(EG(function_table), nsname, name_len)) == NULL) {
1635 efree(lcname);
1636 zend_throw_exception_ex(reflection_exception_ptr, 0,
1637 "Function %s() does not exist", name_str);
1638 return;
1639 }
1640 efree(lcname);
1641 }
1642
1643 ZVAL_STR_COPY(&name, fptr->common.function_name);
1644 reflection_update_property(object, "name", &name);
1645 intern->ptr = fptr;
1646 intern->ref_type = REF_TYPE_FUNCTION;
1647 if (closure) {
1648 ZVAL_COPY_VALUE(&intern->obj, closure);
1649 } else {
1650 ZVAL_UNDEF(&intern->obj);
1651 }
1652 intern->ce = NULL;
1653 }
1654
1655
1656
1657
1658 ZEND_METHOD(reflection_function, __toString)
1659 {
1660 reflection_object *intern;
1661 zend_function *fptr;
1662 string str;
1663
1664 if (zend_parse_parameters_none() == FAILURE) {
1665 return;
1666 }
1667 GET_REFLECTION_OBJECT_PTR(fptr);
1668 string_init(&str);
1669 _function_string(&str, fptr, intern->ce, "");
1670 RETURN_NEW_STR(str.buf);
1671 }
1672
1673
1674
1675
1676 ZEND_METHOD(reflection_function, getName)
1677 {
1678 if (zend_parse_parameters_none() == FAILURE) {
1679 return;
1680 }
1681 _default_get_entry(getThis(), "name", sizeof("name")-1, return_value);
1682 }
1683
1684
1685
1686
1687 ZEND_METHOD(reflection_function, isClosure)
1688 {
1689 reflection_object *intern;
1690 zend_function *fptr;
1691
1692 if (zend_parse_parameters_none() == FAILURE) {
1693 return;
1694 }
1695 GET_REFLECTION_OBJECT_PTR(fptr);
1696 RETURN_BOOL(fptr->common.fn_flags & ZEND_ACC_CLOSURE);
1697 }
1698
1699
1700
1701
1702 ZEND_METHOD(reflection_function, getClosureThis)
1703 {
1704 reflection_object *intern;
1705 zval* closure_this;
1706
1707 if (zend_parse_parameters_none() == FAILURE) {
1708 return;
1709 }
1710 GET_REFLECTION_OBJECT();
1711 if (!Z_ISUNDEF(intern->obj)) {
1712 closure_this = zend_get_closure_this_ptr(&intern->obj);
1713 if (!Z_ISUNDEF_P(closure_this)) {
1714 ZVAL_COPY(return_value, closure_this);
1715 }
1716 }
1717 }
1718
1719
1720
1721
1722 ZEND_METHOD(reflection_function, getClosureScopeClass)
1723 {
1724 reflection_object *intern;
1725 const zend_function *closure_func;
1726
1727 if (zend_parse_parameters_none() == FAILURE) {
1728 return;
1729 }
1730 GET_REFLECTION_OBJECT();
1731 if (!Z_ISUNDEF(intern->obj)) {
1732 closure_func = zend_get_closure_method_def(&intern->obj);
1733 if (closure_func && closure_func->common.scope) {
1734 zend_reflection_class_factory(closure_func->common.scope, return_value);
1735 }
1736 }
1737 }
1738
1739
1740
1741
1742 ZEND_METHOD(reflection_function, getClosure)
1743 {
1744 reflection_object *intern;
1745 zend_function *fptr;
1746
1747 if (zend_parse_parameters_none() == FAILURE) {
1748 return;
1749 }
1750 GET_REFLECTION_OBJECT_PTR(fptr);
1751
1752 if (!Z_ISUNDEF(intern->obj)) {
1753
1754 ZVAL_COPY(return_value, &intern->obj);
1755 } else {
1756 zend_create_fake_closure(return_value, fptr, NULL, NULL, NULL);
1757 }
1758 }
1759
1760
1761
1762
1763 ZEND_METHOD(reflection_function, isInternal)
1764 {
1765 reflection_object *intern;
1766 zend_function *fptr;
1767
1768 if (zend_parse_parameters_none() == FAILURE) {
1769 return;
1770 }
1771 GET_REFLECTION_OBJECT_PTR(fptr);
1772 RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION);
1773 }
1774
1775
1776
1777
1778 ZEND_METHOD(reflection_function, isUserDefined)
1779 {
1780 reflection_object *intern;
1781 zend_function *fptr;
1782
1783 if (zend_parse_parameters_none() == FAILURE) {
1784 return;
1785 }
1786 GET_REFLECTION_OBJECT_PTR(fptr);
1787 RETURN_BOOL(fptr->type == ZEND_USER_FUNCTION);
1788 }
1789
1790
1791
1792
1793 ZEND_METHOD(reflection_function, isDisabled)
1794 {
1795 reflection_object *intern;
1796 zend_function *fptr;
1797
1798 METHOD_NOTSTATIC(reflection_function_ptr);
1799 GET_REFLECTION_OBJECT_PTR(fptr);
1800 RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION && fptr->internal_function.handler == zif_display_disabled_function);
1801 }
1802
1803
1804
1805
1806 ZEND_METHOD(reflection_function, getFileName)
1807 {
1808 reflection_object *intern;
1809 zend_function *fptr;
1810
1811 if (zend_parse_parameters_none() == FAILURE) {
1812 return;
1813 }
1814 GET_REFLECTION_OBJECT_PTR(fptr);
1815 if (fptr->type == ZEND_USER_FUNCTION) {
1816 RETURN_STR_COPY(fptr->op_array.filename);
1817 }
1818 RETURN_FALSE;
1819 }
1820
1821
1822
1823
1824 ZEND_METHOD(reflection_function, getStartLine)
1825 {
1826 reflection_object *intern;
1827 zend_function *fptr;
1828
1829 if (zend_parse_parameters_none() == FAILURE) {
1830 return;
1831 }
1832 GET_REFLECTION_OBJECT_PTR(fptr);
1833 if (fptr->type == ZEND_USER_FUNCTION) {
1834 RETURN_LONG(fptr->op_array.line_start);
1835 }
1836 RETURN_FALSE;
1837 }
1838
1839
1840
1841
1842 ZEND_METHOD(reflection_function, getEndLine)
1843 {
1844 reflection_object *intern;
1845 zend_function *fptr;
1846
1847 if (zend_parse_parameters_none() == FAILURE) {
1848 return;
1849 }
1850 GET_REFLECTION_OBJECT_PTR(fptr);
1851 if (fptr->type == ZEND_USER_FUNCTION) {
1852 RETURN_LONG(fptr->op_array.line_end);
1853 }
1854 RETURN_FALSE;
1855 }
1856
1857
1858
1859
1860 ZEND_METHOD(reflection_function, getDocComment)
1861 {
1862 reflection_object *intern;
1863 zend_function *fptr;
1864
1865 if (zend_parse_parameters_none() == FAILURE) {
1866 return;
1867 }
1868 GET_REFLECTION_OBJECT_PTR(fptr);
1869 if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
1870 RETURN_STR_COPY(fptr->op_array.doc_comment);
1871 }
1872 RETURN_FALSE;
1873 }
1874
1875
1876
1877
1878 ZEND_METHOD(reflection_function, getStaticVariables)
1879 {
1880 reflection_object *intern;
1881 zend_function *fptr;
1882 zval *val;
1883
1884 if (zend_parse_parameters_none() == FAILURE) {
1885 return;
1886 }
1887 GET_REFLECTION_OBJECT_PTR(fptr);
1888
1889
1890 array_init(return_value);
1891 if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.static_variables != NULL) {
1892 if (GC_REFCOUNT(fptr->op_array.static_variables) > 1) {
1893 if (!(GC_FLAGS(fptr->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
1894 GC_REFCOUNT(fptr->op_array.static_variables)--;
1895 }
1896 fptr->op_array.static_variables = zend_array_dup(fptr->op_array.static_variables);
1897 }
1898 ZEND_HASH_FOREACH_VAL(fptr->op_array.static_variables, val) {
1899 if (UNEXPECTED(zval_update_constant_ex(val, 1, fptr->common.scope) != SUCCESS)) {
1900 return;
1901 }
1902 } ZEND_HASH_FOREACH_END();
1903 zend_hash_copy(Z_ARRVAL_P(return_value), fptr->op_array.static_variables, zval_add_ref);
1904 }
1905 }
1906
1907
1908
1909
1910 ZEND_METHOD(reflection_function, invoke)
1911 {
1912 zval retval;
1913 zval *params = NULL;
1914 int result, num_args = 0;
1915 zend_fcall_info fci;
1916 zend_fcall_info_cache fcc;
1917 reflection_object *intern;
1918 zend_function *fptr;
1919
1920 METHOD_NOTSTATIC(reflection_function_ptr);
1921 GET_REFLECTION_OBJECT_PTR(fptr);
1922
1923 if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", ¶ms, &num_args) == FAILURE) {
1924 return;
1925 }
1926
1927 fci.size = sizeof(fci);
1928 fci.function_table = NULL;
1929 ZVAL_UNDEF(&fci.function_name);
1930 fci.symbol_table = NULL;
1931 fci.object = NULL;
1932 fci.retval = &retval;
1933 fci.param_count = num_args;
1934 fci.params = params;
1935 fci.no_separation = 1;
1936
1937 fcc.initialized = 1;
1938 fcc.function_handler = fptr;
1939 fcc.calling_scope = EG(scope);
1940 fcc.called_scope = NULL;
1941 fcc.object = NULL;
1942
1943 result = zend_call_function(&fci, &fcc);
1944
1945 if (result == FAILURE) {
1946 zend_throw_exception_ex(reflection_exception_ptr, 0,
1947 "Invocation of function %s() failed", ZSTR_VAL(fptr->common.function_name));
1948 return;
1949 }
1950
1951 if (Z_TYPE(retval) != IS_UNDEF) {
1952 ZVAL_COPY_VALUE(return_value, &retval);
1953 }
1954 }
1955
1956
1957
1958
1959 ZEND_METHOD(reflection_function, invokeArgs)
1960 {
1961 zval retval;
1962 zval *params, *val;
1963 int result;
1964 int i, argc;
1965 zend_fcall_info fci;
1966 zend_fcall_info_cache fcc;
1967 reflection_object *intern;
1968 zend_function *fptr;
1969 zval *param_array;
1970
1971 METHOD_NOTSTATIC(reflection_function_ptr);
1972 GET_REFLECTION_OBJECT_PTR(fptr);
1973
1974 if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", ¶m_array) == FAILURE) {
1975 return;
1976 }
1977
1978 argc = zend_hash_num_elements(Z_ARRVAL_P(param_array));
1979
1980 params = safe_emalloc(sizeof(zval), argc, 0);
1981 argc = 0;
1982 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(param_array), val) {
1983 ZVAL_COPY(¶ms[argc], val);
1984 argc++;
1985 } ZEND_HASH_FOREACH_END();
1986
1987 fci.size = sizeof(fci);
1988 fci.function_table = NULL;
1989 ZVAL_UNDEF(&fci.function_name);
1990 fci.symbol_table = NULL;
1991 fci.object = NULL;
1992 fci.retval = &retval;
1993 fci.param_count = argc;
1994 fci.params = params;
1995 fci.no_separation = 1;
1996
1997 fcc.initialized = 1;
1998 fcc.function_handler = fptr;
1999 fcc.calling_scope = EG(scope);
2000 fcc.called_scope = NULL;
2001 fcc.object = NULL;
2002
2003 result = zend_call_function(&fci, &fcc);
2004
2005 for (i = 0; i < argc; i++) {
2006 zval_ptr_dtor(¶ms[i]);
2007 }
2008 efree(params);
2009
2010 if (result == FAILURE) {
2011 zend_throw_exception_ex(reflection_exception_ptr, 0,
2012 "Invocation of function %s() failed", ZSTR_VAL(fptr->common.function_name));
2013 return;
2014 }
2015
2016 if (Z_TYPE(retval) != IS_UNDEF) {
2017 ZVAL_COPY_VALUE(return_value, &retval);
2018 }
2019 }
2020
2021
2022
2023
2024 ZEND_METHOD(reflection_function, returnsReference)
2025 {
2026 reflection_object *intern;
2027 zend_function *fptr;
2028
2029 METHOD_NOTSTATIC(reflection_function_abstract_ptr);
2030 GET_REFLECTION_OBJECT_PTR(fptr);
2031
2032 RETURN_BOOL((fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0);
2033 }
2034
2035
2036
2037
2038 ZEND_METHOD(reflection_function, getNumberOfParameters)
2039 {
2040 reflection_object *intern;
2041 zend_function *fptr;
2042 uint32_t num_args;
2043
2044 METHOD_NOTSTATIC(reflection_function_abstract_ptr);
2045 GET_REFLECTION_OBJECT_PTR(fptr);
2046
2047 num_args = fptr->common.num_args;
2048 if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) {
2049 num_args++;
2050 }
2051
2052 RETURN_LONG(num_args);
2053 }
2054
2055
2056
2057
2058 ZEND_METHOD(reflection_function, getNumberOfRequiredParameters)
2059 {
2060 reflection_object *intern;
2061 zend_function *fptr;
2062
2063 METHOD_NOTSTATIC(reflection_function_abstract_ptr);
2064 GET_REFLECTION_OBJECT_PTR(fptr);
2065
2066 RETURN_LONG(fptr->common.required_num_args);
2067 }
2068
2069
2070
2071
2072 ZEND_METHOD(reflection_function, getParameters)
2073 {
2074 reflection_object *intern;
2075 zend_function *fptr;
2076 uint32_t i, num_args;
2077 struct _zend_arg_info *arg_info;
2078
2079 METHOD_NOTSTATIC(reflection_function_abstract_ptr);
2080 GET_REFLECTION_OBJECT_PTR(fptr);
2081
2082 arg_info= fptr->common.arg_info;
2083 num_args = fptr->common.num_args;
2084 if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) {
2085 num_args++;
2086 }
2087
2088 array_init(return_value);
2089 for (i = 0; i < num_args; i++) {
2090 zval parameter;
2091
2092 reflection_parameter_factory(_copy_function(fptr), Z_ISUNDEF(intern->obj)? NULL : &intern->obj, arg_info, i, fptr->common.required_num_args, ¶meter);
2093 add_next_index_zval(return_value, ¶meter);
2094
2095 arg_info++;
2096 }
2097 }
2098
2099
2100
2101
2102 ZEND_METHOD(reflection_function, getExtension)
2103 {
2104 reflection_object *intern;
2105 zend_function *fptr;
2106 zend_internal_function *internal;
2107
2108 METHOD_NOTSTATIC(reflection_function_abstract_ptr);
2109 GET_REFLECTION_OBJECT_PTR(fptr);
2110
2111 if (fptr->type != ZEND_INTERNAL_FUNCTION) {
2112 RETURN_NULL();
2113 }
2114
2115 internal = (zend_internal_function *)fptr;
2116 if (internal->module) {
2117 reflection_extension_factory(return_value, internal->module->name);
2118 } else {
2119 RETURN_NULL();
2120 }
2121 }
2122
2123
2124
2125
2126 ZEND_METHOD(reflection_function, getExtensionName)
2127 {
2128 reflection_object *intern;
2129 zend_function *fptr;
2130 zend_internal_function *internal;
2131
2132 METHOD_NOTSTATIC(reflection_function_abstract_ptr);
2133 GET_REFLECTION_OBJECT_PTR(fptr);
2134
2135 if (fptr->type != ZEND_INTERNAL_FUNCTION) {
2136 RETURN_FALSE;
2137 }
2138
2139 internal = (zend_internal_function *)fptr;
2140 if (internal->module) {
2141 RETURN_STRING(internal->module->name);
2142 } else {
2143 RETURN_FALSE;
2144 }
2145 }
2146
2147
2148
2149 ZEND_METHOD(reflection_generator, __construct)
2150 {
2151 zval *generator, *object;
2152 reflection_object *intern;
2153 zend_execute_data *ex;
2154
2155 object = getThis();
2156 intern = Z_REFLECTION_P(object);
2157
2158 if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "O", &generator, zend_ce_generator) == FAILURE) {
2159 return;
2160 }
2161
2162 ex = ((zend_generator *) Z_OBJ_P(generator))->execute_data;
2163 if (!ex) {
2164 zend_throw_exception(NULL, "Cannot create ReflectionGenerator based on a terminated Generator", 0);
2165 return;
2166 }
2167
2168 intern->ref_type = REF_TYPE_GENERATOR;
2169 ZVAL_COPY(&intern->obj, generator);
2170 intern->ce = zend_ce_generator;
2171 }
2172
2173
2174 #define REFLECTION_CHECK_VALID_GENERATOR(ex) \
2175 if (!ex) { \
2176 zend_throw_exception(NULL, "Cannot fetch information from a terminated Generator", 0); \
2177 return; \
2178 }
2179
2180
2181 ZEND_METHOD(reflection_generator, getTrace)
2182 {
2183 zend_long options = DEBUG_BACKTRACE_PROVIDE_OBJECT;
2184 zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj);
2185 zend_generator *root_generator;
2186 zend_execute_data *ex_backup = EG(current_execute_data);
2187 zend_execute_data *ex = generator->execute_data;
2188 zend_execute_data *root_prev = NULL, *cur_prev;
2189
2190 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &options) == FAILURE) {
2191 return;
2192 }
2193
2194 REFLECTION_CHECK_VALID_GENERATOR(ex)
2195
2196 root_generator = zend_generator_get_current(generator);
2197
2198 cur_prev = generator->execute_data->prev_execute_data;
2199 if (generator == root_generator) {
2200 generator->execute_data->prev_execute_data = NULL;
2201 } else {
2202 root_prev = root_generator->execute_data->prev_execute_data;
2203 generator->execute_fake.prev_execute_data = NULL;
2204 root_generator->execute_data->prev_execute_data = &generator->execute_fake;
2205 }
2206
2207 EG(current_execute_data) = root_generator->execute_data;
2208 zend_fetch_debug_backtrace(return_value, 0, options, 0);
2209 EG(current_execute_data) = ex_backup;
2210
2211 root_generator->execute_data->prev_execute_data = root_prev;
2212 generator->execute_data->prev_execute_data = cur_prev;
2213 }
2214
2215
2216
2217 ZEND_METHOD(reflection_generator, getExecutingLine)
2218 {
2219 zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj);
2220 zend_execute_data *ex = generator->execute_data;
2221
2222 if (zend_parse_parameters_none() == FAILURE) {
2223 return;
2224 }
2225
2226 REFLECTION_CHECK_VALID_GENERATOR(ex)
2227
2228 ZVAL_LONG(return_value, ex->opline->lineno);
2229 }
2230
2231
2232
2233 ZEND_METHOD(reflection_generator, getExecutingFile)
2234 {
2235 zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj);
2236 zend_execute_data *ex = generator->execute_data;
2237
2238 if (zend_parse_parameters_none() == FAILURE) {
2239 return;
2240 }
2241
2242 REFLECTION_CHECK_VALID_GENERATOR(ex)
2243
2244 ZVAL_STR_COPY(return_value, ex->func->op_array.filename);
2245 }
2246
2247
2248
2249 ZEND_METHOD(reflection_generator, getFunction)
2250 {
2251 zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj);
2252 zend_execute_data *ex = generator->execute_data;
2253
2254 if (zend_parse_parameters_none() == FAILURE) {
2255 return;
2256 }
2257
2258 REFLECTION_CHECK_VALID_GENERATOR(ex)
2259
2260 if (ex->func->common.fn_flags & ZEND_ACC_CLOSURE) {
2261 zval closure;
2262 ZVAL_OBJ(&closure, (zend_object *) ex->func->common.prototype);
2263 reflection_function_factory(ex->func, &closure, return_value);
2264 } else if (ex->func->op_array.scope) {
2265 reflection_method_factory(ex->func->op_array.scope, ex->func, NULL, return_value);
2266 } else {
2267 reflection_function_factory(ex->func, NULL, return_value);
2268 }
2269 }
2270
2271
2272
2273 ZEND_METHOD(reflection_generator, getThis)
2274 {
2275 zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj);
2276 zend_execute_data *ex = generator->execute_data;
2277
2278 if (zend_parse_parameters_none() == FAILURE) {
2279 return;
2280 }
2281
2282 REFLECTION_CHECK_VALID_GENERATOR(ex)
2283
2284 if (Z_OBJ(ex->This)) {
2285 ZVAL_COPY(return_value, &ex->This);
2286 } else {
2287 ZVAL_NULL(return_value);
2288 }
2289 }
2290
2291
2292
2293 ZEND_METHOD(reflection_generator, getExecutingGenerator)
2294 {
2295 zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj);
2296 zend_execute_data *ex = generator->execute_data;
2297 zend_generator *current;
2298
2299 if (zend_parse_parameters_none() == FAILURE) {
2300 return;
2301 }
2302
2303 REFLECTION_CHECK_VALID_GENERATOR(ex)
2304
2305 current = zend_generator_get_current(generator);
2306 ++GC_REFCOUNT(¤t->std);
2307
2308 ZVAL_OBJ(return_value, (zend_object *) current);
2309 }
2310
2311
2312
2313
2314
2315 ZEND_METHOD(reflection_parameter, export)
2316 {
2317 _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_parameter_ptr, 2);
2318 }
2319
2320
2321
2322
2323 ZEND_METHOD(reflection_parameter, __construct)
2324 {
2325 parameter_reference *ref;
2326 zval *reference, *parameter;
2327 zval *object;
2328 zval name;
2329 reflection_object *intern;
2330 zend_function *fptr;
2331 struct _zend_arg_info *arg_info;
2332 int position;
2333 uint32_t num_args;
2334 zend_class_entry *ce = NULL;
2335 zend_bool is_closure = 0;
2336
2337 if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "zz", &reference, ¶meter) == FAILURE) {
2338 return;
2339 }
2340
2341 object = getThis();
2342 intern = Z_REFLECTION_P(object);
2343
2344
2345 switch (Z_TYPE_P(reference)) {
2346 case IS_STRING: {
2347 size_t lcname_len;
2348 char *lcname;
2349
2350 lcname_len = Z_STRLEN_P(reference);
2351 lcname = zend_str_tolower_dup(Z_STRVAL_P(reference), lcname_len);
2352 if ((fptr = zend_hash_str_find_ptr(EG(function_table), lcname, lcname_len)) == NULL) {
2353 efree(lcname);
2354 zend_throw_exception_ex(reflection_exception_ptr, 0,
2355 "Function %s() does not exist", Z_STRVAL_P(reference));
2356 return;
2357 }
2358 efree(lcname);
2359 }
2360 ce = fptr->common.scope;
2361 break;
2362
2363 case IS_ARRAY: {
2364 zval *classref;
2365 zval *method;
2366 size_t lcname_len;
2367 char *lcname;
2368
2369 if (((classref =zend_hash_index_find(Z_ARRVAL_P(reference), 0)) == NULL)
2370 || ((method = zend_hash_index_find(Z_ARRVAL_P(reference), 1)) == NULL))
2371 {
2372 _DO_THROW("Expected array($object, $method) or array($classname, $method)");
2373
2374 }
2375
2376 if (Z_TYPE_P(classref) == IS_OBJECT) {
2377 ce = Z_OBJCE_P(classref);
2378 } else {
2379 convert_to_string_ex(classref);
2380 if ((ce = zend_lookup_class(Z_STR_P(classref))) == NULL) {
2381 zend_throw_exception_ex(reflection_exception_ptr, 0,
2382 "Class %s does not exist", Z_STRVAL_P(classref));
2383 return;
2384 }
2385 }
2386
2387 convert_to_string_ex(method);
2388 lcname_len = Z_STRLEN_P(method);
2389 lcname = zend_str_tolower_dup(Z_STRVAL_P(method), lcname_len);
2390 if (ce == zend_ce_closure && Z_TYPE_P(classref) == IS_OBJECT
2391 && (lcname_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
2392 && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
2393 && (fptr = zend_get_closure_invoke_method(Z_OBJ_P(classref))) != NULL)
2394 {
2395
2396
2397 } else if ((fptr = zend_hash_str_find_ptr(&ce->function_table, lcname, lcname_len)) == NULL) {
2398 efree(lcname);
2399 zend_throw_exception_ex(reflection_exception_ptr, 0,
2400 "Method %s::%s() does not exist", ZSTR_VAL(ce->name), Z_STRVAL_P(method));
2401 return;
2402 }
2403 efree(lcname);
2404 }
2405 break;
2406
2407 case IS_OBJECT: {
2408 ce = Z_OBJCE_P(reference);
2409
2410 if (instanceof_function(ce, zend_ce_closure)) {
2411 fptr = (zend_function *)zend_get_closure_method_def(reference);
2412 Z_ADDREF_P(reference);
2413 is_closure = 1;
2414 } else if ((fptr = zend_hash_str_find_ptr(&ce->function_table, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME))) == NULL) {
2415 zend_throw_exception_ex(reflection_exception_ptr, 0,
2416 "Method %s::%s() does not exist", ZSTR_VAL(ce->name), ZEND_INVOKE_FUNC_NAME);
2417 return;
2418 }
2419 }
2420 break;
2421
2422 default:
2423 _DO_THROW("The parameter class is expected to be either a string, an array(class, method) or a callable object");
2424
2425 }
2426
2427
2428 arg_info = fptr->common.arg_info;
2429 num_args = fptr->common.num_args;
2430 if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) {
2431 num_args++;
2432 }
2433 if (Z_TYPE_P(parameter) == IS_LONG) {
2434 position= (int)Z_LVAL_P(parameter);
2435 if (position < 0 || (uint32_t)position >= num_args) {
2436 if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
2437 if (fptr->type != ZEND_OVERLOADED_FUNCTION) {
2438 zend_string_release(fptr->common.function_name);
2439 }
2440 zend_free_trampoline(fptr);
2441 }
2442 if (is_closure) {
2443 zval_ptr_dtor(reference);
2444 }
2445 _DO_THROW("The parameter specified by its offset could not be found");
2446
2447 }
2448 } else {
2449 uint32_t i;
2450
2451 position= -1;
2452 convert_to_string_ex(parameter);
2453 if (fptr->type == ZEND_INTERNAL_FUNCTION &&
2454 !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
2455 for (i = 0; i < num_args; i++) {
2456 if (arg_info[i].name) {
2457 if (strcmp(((zend_internal_arg_info*)arg_info)[i].name, Z_STRVAL_P(parameter)) == 0) {
2458 position= i;
2459 break;
2460 }
2461
2462 }
2463 }
2464 } else {
2465 for (i = 0; i < num_args; i++) {
2466 if (arg_info[i].name) {
2467 if (strcmp(ZSTR_VAL(arg_info[i].name), Z_STRVAL_P(parameter)) == 0) {
2468 position= i;
2469 break;
2470 }
2471 }
2472 }
2473 }
2474 if (position == -1) {
2475 if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
2476 if (fptr->type != ZEND_OVERLOADED_FUNCTION) {
2477 zend_string_release(fptr->common.function_name);
2478 }
2479 zend_free_trampoline(fptr);
2480 }
2481 if (is_closure) {
2482 zval_ptr_dtor(reference);
2483 }
2484 _DO_THROW("The parameter specified by its name could not be found");
2485
2486 }
2487 }
2488
2489 if (arg_info[position].name) {
2490 if (fptr->type == ZEND_INTERNAL_FUNCTION &&
2491 !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
2492 ZVAL_STRING(&name, ((zend_internal_arg_info*)arg_info)[position].name);
2493 } else {
2494 ZVAL_STR_COPY(&name, arg_info[position].name);
2495 }
2496 } else {
2497 ZVAL_NULL(&name);
2498 }
2499 reflection_update_property(object, "name", &name);
2500
2501 ref = (parameter_reference*) emalloc(sizeof(parameter_reference));
2502 ref->arg_info = &arg_info[position];
2503 ref->offset = (uint32_t)position;
2504 ref->required = fptr->common.required_num_args;
2505 ref->fptr = fptr;
2506
2507 intern->ptr = ref;
2508 intern->ref_type = REF_TYPE_PARAMETER;
2509 intern->ce = ce;
2510 if (reference && is_closure) {
2511 ZVAL_COPY_VALUE(&intern->obj, reference);
2512 }
2513 }
2514
2515
2516
2517
2518 ZEND_METHOD(reflection_parameter, __toString)
2519 {
2520 reflection_object *intern;
2521 parameter_reference *param;
2522 string str;
2523
2524 if (zend_parse_parameters_none() == FAILURE) {
2525 return;
2526 }
2527 GET_REFLECTION_OBJECT_PTR(param);
2528 string_init(&str);
2529 _parameter_string(&str, param->fptr, param->arg_info, param->offset, param->required, "");
2530 RETURN_NEW_STR(str.buf);
2531 }
2532
2533
2534
2535
2536
2537 ZEND_METHOD(reflection_parameter, getName)
2538 {
2539 if (zend_parse_parameters_none() == FAILURE) {
2540 return;
2541 }
2542 _default_get_entry(getThis(), "name", sizeof("name")-1, return_value);
2543 }
2544
2545
2546
2547
2548 ZEND_METHOD(reflection_parameter, getDeclaringFunction)
2549 {
2550 reflection_object *intern;
2551 parameter_reference *param;
2552
2553 if (zend_parse_parameters_none() == FAILURE) {
2554 return;
2555 }
2556 GET_REFLECTION_OBJECT_PTR(param);
2557
2558 if (!param->fptr->common.scope) {
2559 reflection_function_factory(_copy_function(param->fptr), Z_ISUNDEF(intern->obj)? NULL : &intern->obj, return_value);
2560 } else {
2561 reflection_method_factory(param->fptr->common.scope, _copy_function(param->fptr), Z_ISUNDEF(intern->obj)? NULL : &intern->obj, return_value);
2562 }
2563 }
2564
2565
2566
2567
2568 ZEND_METHOD(reflection_parameter, getDeclaringClass)
2569 {
2570 reflection_object *intern;
2571 parameter_reference *param;
2572
2573 if (zend_parse_parameters_none() == FAILURE) {
2574 return;
2575 }
2576 GET_REFLECTION_OBJECT_PTR(param);
2577
2578 if (param->fptr->common.scope) {
2579 zend_reflection_class_factory(param->fptr->common.scope, return_value);
2580 }
2581 }
2582
2583
2584
2585
2586 ZEND_METHOD(reflection_parameter, getClass)
2587 {
2588 reflection_object *intern;
2589 parameter_reference *param;
2590 zend_class_entry *ce;
2591
2592 if (zend_parse_parameters_none() == FAILURE) {
2593 return;
2594 }
2595 GET_REFLECTION_OBJECT_PTR(param);
2596
2597 if (param->arg_info->class_name) {
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610 const char *class_name;
2611 size_t class_name_len;
2612
2613 if (param->fptr->type == ZEND_INTERNAL_FUNCTION &&
2614 !(param->fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
2615 class_name = ((zend_internal_arg_info*)param->arg_info)->class_name;
2616 class_name_len = strlen(class_name);
2617 } else {
2618 class_name = ZSTR_VAL(param->arg_info->class_name);
2619 class_name_len = ZSTR_LEN(param->arg_info->class_name);
2620 }
2621 if (0 == zend_binary_strcasecmp(class_name, class_name_len, "self", sizeof("self")- 1)) {
2622 ce = param->fptr->common.scope;
2623 if (!ce) {
2624 zend_throw_exception_ex(reflection_exception_ptr, 0,
2625 "Parameter uses 'self' as type hint but function is not a class member!");
2626 return;
2627 }
2628 } else if (0 == zend_binary_strcasecmp(class_name, class_name_len, "parent", sizeof("parent")- 1)) {
2629 ce = param->fptr->common.scope;
2630 if (!ce) {
2631 zend_throw_exception_ex(reflection_exception_ptr, 0,
2632 "Parameter uses 'parent' as type hint but function is not a class member!");
2633 return;
2634 }
2635 if (!ce->parent) {
2636 zend_throw_exception_ex(reflection_exception_ptr, 0,
2637 "Parameter uses 'parent' as type hint although class does not have a parent!");
2638 return;
2639 }
2640 ce = ce->parent;
2641 } else {
2642 if (param->fptr->type == ZEND_INTERNAL_FUNCTION &&
2643 !(param->fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
2644 zend_string *name = zend_string_init(class_name, class_name_len, 0);
2645 ce = zend_lookup_class(name);
2646 zend_string_release(name);
2647 } else {
2648 ce = zend_lookup_class(param->arg_info->class_name);
2649 }
2650 if (!ce) {
2651 zend_throw_exception_ex(reflection_exception_ptr, 0,
2652 "Class %s does not exist", class_name);
2653 return;
2654 }
2655 }
2656 zend_reflection_class_factory(ce, return_value);
2657 }
2658 }
2659
2660
2661
2662
2663 ZEND_METHOD(reflection_parameter, hasType)
2664 {
2665 reflection_object *intern;
2666 parameter_reference *param;
2667
2668 if (zend_parse_parameters_none() == FAILURE) {
2669 return;
2670 }
2671 GET_REFLECTION_OBJECT_PTR(param);
2672
2673 RETVAL_BOOL(param->arg_info->type_hint != 0);
2674 }
2675
2676
2677
2678
2679 ZEND_METHOD(reflection_parameter, getType)
2680 {
2681 reflection_object *intern;
2682 parameter_reference *param;
2683
2684 if (zend_parse_parameters_none() == FAILURE) {
2685 return;
2686 }
2687 GET_REFLECTION_OBJECT_PTR(param);
2688
2689 if (((param->fptr->type == ZEND_INTERNAL_FUNCTION &&
2690 !(param->fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) ?
2691 ((zend_internal_arg_info*)param->arg_info)->type_hint :
2692 param->arg_info->type_hint) == 0)
2693 {
2694 RETURN_NULL();
2695 }
2696 reflection_type_factory(_copy_function(param->fptr), Z_ISUNDEF(intern->obj)? NULL : &intern->obj, param->arg_info, return_value);
2697 }
2698
2699
2700
2701
2702 ZEND_METHOD(reflection_parameter, isArray)
2703 {
2704 reflection_object *intern;
2705 parameter_reference *param;
2706
2707 if (zend_parse_parameters_none() == FAILURE) {
2708 return;
2709 }
2710 GET_REFLECTION_OBJECT_PTR(param);
2711
2712 RETVAL_BOOL(param->arg_info->type_hint == IS_ARRAY);
2713 }
2714
2715
2716
2717
2718 ZEND_METHOD(reflection_parameter, isCallable)
2719 {
2720 reflection_object *intern;
2721 parameter_reference *param;
2722
2723 if (zend_parse_parameters_none() == FAILURE) {
2724 return;
2725 }
2726 GET_REFLECTION_OBJECT_PTR(param);
2727
2728 RETVAL_BOOL(param->arg_info->type_hint == IS_CALLABLE);
2729 }
2730
2731
2732
2733
2734 ZEND_METHOD(reflection_parameter, allowsNull)
2735 {
2736 reflection_object *intern;
2737 parameter_reference *param;
2738
2739 if (zend_parse_parameters_none() == FAILURE) {
2740 return;
2741 }
2742 GET_REFLECTION_OBJECT_PTR(param);
2743
2744 RETVAL_BOOL(param->arg_info->allow_null);
2745 }
2746
2747
2748
2749
2750 ZEND_METHOD(reflection_parameter, isPassedByReference)
2751 {
2752 reflection_object *intern;
2753 parameter_reference *param;
2754
2755 if (zend_parse_parameters_none() == FAILURE) {
2756 return;
2757 }
2758 GET_REFLECTION_OBJECT_PTR(param);
2759
2760 RETVAL_BOOL(param->arg_info->pass_by_reference);
2761 }
2762
2763
2764
2765
2766 ZEND_METHOD(reflection_parameter, canBePassedByValue)
2767 {
2768 reflection_object *intern;
2769 parameter_reference *param;
2770
2771 if (zend_parse_parameters_none() == FAILURE) {
2772 return;
2773 }
2774 GET_REFLECTION_OBJECT_PTR(param);
2775
2776
2777 RETVAL_BOOL(param->arg_info->pass_by_reference != ZEND_SEND_BY_REF);
2778 }
2779
2780
2781
2782
2783 ZEND_METHOD(reflection_parameter, getPosition)
2784 {
2785 reflection_object *intern;
2786 parameter_reference *param;
2787
2788 if (zend_parse_parameters_none() == FAILURE) {
2789 return;
2790 }
2791 GET_REFLECTION_OBJECT_PTR(param);
2792
2793 RETVAL_LONG(param->offset);
2794 }
2795
2796
2797
2798
2799 ZEND_METHOD(reflection_parameter, isOptional)
2800 {
2801 reflection_object *intern;
2802 parameter_reference *param;
2803
2804 if (zend_parse_parameters_none() == FAILURE) {
2805 return;
2806 }
2807 GET_REFLECTION_OBJECT_PTR(param);
2808
2809 RETVAL_BOOL(param->offset >= param->required);
2810 }
2811
2812
2813
2814
2815 ZEND_METHOD(reflection_parameter, isDefaultValueAvailable)
2816 {
2817 reflection_object *intern;
2818 parameter_reference *param;
2819 zend_op *precv;
2820
2821 if (zend_parse_parameters_none() == FAILURE) {
2822 return;
2823 }
2824 GET_REFLECTION_OBJECT_PTR(param);
2825
2826 if (param->fptr->type != ZEND_USER_FUNCTION)
2827 {
2828 RETURN_FALSE;
2829 }
2830
2831 precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
2832 if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2_type == IS_UNUSED) {
2833 RETURN_FALSE;
2834 }
2835 RETURN_TRUE;
2836 }
2837
2838
2839
2840
2841 ZEND_METHOD(reflection_parameter, getDefaultValue)
2842 {
2843 parameter_reference *param;
2844 zend_op *precv;
2845
2846 if (zend_parse_parameters_none() == FAILURE) {
2847 return;
2848 }
2849
2850 param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
2851 if (!param) {
2852 return;
2853 }
2854
2855 precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
2856 if (!precv) {
2857 return;
2858 }
2859
2860 ZVAL_COPY_VALUE(return_value, RT_CONSTANT(¶m->fptr->op_array, precv->op2));
2861 if (Z_CONSTANT_P(return_value)) {
2862 zend_class_entry *old_scope = EG(scope);
2863
2864 EG(scope) = param->fptr->common.scope;
2865 zval_update_constant_ex(return_value, 0, NULL);
2866 EG(scope) = old_scope;
2867 } else {
2868 zval_copy_ctor(return_value);
2869 }
2870 }
2871
2872
2873
2874
2875 ZEND_METHOD(reflection_parameter, isDefaultValueConstant)
2876 {
2877 zend_op *precv;
2878 parameter_reference *param;
2879
2880 if (zend_parse_parameters_none() == FAILURE) {
2881 return;
2882 }
2883
2884 param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
2885 if (!param) {
2886 RETURN_FALSE;
2887 }
2888
2889 precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
2890 if (precv && Z_TYPE_P(RT_CONSTANT(¶m->fptr->op_array, precv->op2)) == IS_CONSTANT) {
2891 RETURN_TRUE;
2892 }
2893
2894 RETURN_FALSE;
2895 }
2896
2897
2898
2899
2900 ZEND_METHOD(reflection_parameter, getDefaultValueConstantName)
2901 {
2902 zend_op *precv;
2903 parameter_reference *param;
2904
2905 if (zend_parse_parameters_none() == FAILURE) {
2906 return;
2907 }
2908
2909 param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
2910 if (!param) {
2911 return;
2912 }
2913
2914 precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
2915 if (precv && Z_TYPE_P(RT_CONSTANT(¶m->fptr->op_array, precv->op2)) == IS_CONSTANT) {
2916 RETURN_STR_COPY(Z_STR_P(RT_CONSTANT(¶m->fptr->op_array, precv->op2)));
2917 }
2918 }
2919
2920
2921
2922
2923 ZEND_METHOD(reflection_parameter, isVariadic)
2924 {
2925 reflection_object *intern;
2926 parameter_reference *param;
2927
2928 if (zend_parse_parameters_none() == FAILURE) {
2929 return;
2930 }
2931 GET_REFLECTION_OBJECT_PTR(param);
2932
2933 RETVAL_BOOL(param->arg_info->is_variadic);
2934 }
2935
2936
2937
2938
2939 ZEND_METHOD(reflection_type, allowsNull)
2940 {
2941 reflection_object *intern;
2942 type_reference *param;
2943
2944 if (zend_parse_parameters_none() == FAILURE) {
2945 return;
2946 }
2947 GET_REFLECTION_OBJECT_PTR(param);
2948
2949 RETVAL_BOOL(param->arg_info->allow_null);
2950 }
2951
2952
2953
2954
2955 ZEND_METHOD(reflection_type, isBuiltin)
2956 {
2957 reflection_object *intern;
2958 type_reference *param;
2959
2960 if (zend_parse_parameters_none() == FAILURE) {
2961 return;
2962 }
2963 GET_REFLECTION_OBJECT_PTR(param);
2964
2965 RETVAL_BOOL(param->arg_info->type_hint != IS_OBJECT);
2966 }
2967
2968
2969
2970
2971 ZEND_METHOD(reflection_type, __toString)
2972 {
2973 reflection_object *intern;
2974 type_reference *param;
2975
2976 if (zend_parse_parameters_none() == FAILURE) {
2977 return;
2978 }
2979 GET_REFLECTION_OBJECT_PTR(param);
2980
2981 switch (param->arg_info->type_hint) {
2982 case IS_ARRAY: RETURN_STRINGL("array", sizeof("array") - 1);
2983 case IS_CALLABLE: RETURN_STRINGL("callable", sizeof("callable") - 1);
2984 case IS_OBJECT:
2985 if (param->fptr->type == ZEND_INTERNAL_FUNCTION &&
2986 !(param->fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
2987 RETURN_STRING(((zend_internal_arg_info*)param->arg_info)->class_name);
2988 }
2989 RETURN_STR_COPY(param->arg_info->class_name);
2990 case IS_STRING: RETURN_STRINGL("string", sizeof("string") - 1);
2991 case _IS_BOOL: RETURN_STRINGL("bool", sizeof("bool") - 1);
2992 case IS_LONG: RETURN_STRINGL("int", sizeof("int") - 1);
2993 case IS_DOUBLE: RETURN_STRINGL("float", sizeof("float") - 1);
2994 EMPTY_SWITCH_DEFAULT_CASE()
2995 }
2996 }
2997
2998
2999
3000
3001 ZEND_METHOD(reflection_method, export)
3002 {
3003 _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_method_ptr, 2);
3004 }
3005
3006
3007
3008
3009 ZEND_METHOD(reflection_method, __construct)
3010 {
3011 zval name, *classname;
3012 zval *object, *orig_obj;
3013 reflection_object *intern;
3014 char *lcname;
3015 zend_class_entry *ce;
3016 zend_function *mptr;
3017 char *name_str, *tmp;
3018 size_t name_len, tmp_len;
3019 zval ztmp;
3020
3021 if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "zs", &classname, &name_str, &name_len) == FAILURE) {
3022 if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s", &name_str, &name_len) == FAILURE) {
3023 return;
3024 }
3025
3026 if ((tmp = strstr(name_str, "::")) == NULL) {
3027 zend_throw_exception_ex(reflection_exception_ptr, 0,
3028 "Invalid method name %s", name_str);
3029 return;
3030 }
3031 classname = &ztmp;
3032 tmp_len = tmp - name_str;
3033 ZVAL_STRINGL(classname, name_str, tmp_len);
3034 name_len = name_len - (tmp_len + 2);
3035 name_str = tmp + 2;
3036 orig_obj = NULL;
3037 } else if (Z_TYPE_P(classname) == IS_OBJECT) {
3038 orig_obj = classname;
3039 } else {
3040 orig_obj = NULL;
3041 }
3042
3043 object = getThis();
3044 intern = Z_REFLECTION_P(object);
3045
3046
3047 switch (Z_TYPE_P(classname)) {
3048 case IS_STRING:
3049 if ((ce = zend_lookup_class(Z_STR_P(classname))) == NULL) {
3050 zend_throw_exception_ex(reflection_exception_ptr, 0,
3051 "Class %s does not exist", Z_STRVAL_P(classname));
3052 if (classname == &ztmp) {
3053 zval_dtor(&ztmp);
3054 }
3055 return;
3056 }
3057 break;
3058
3059 case IS_OBJECT:
3060 ce = Z_OBJCE_P(classname);
3061 break;
3062
3063 default:
3064 if (classname == &ztmp) {
3065 zval_dtor(&ztmp);
3066 }
3067 _DO_THROW("The parameter class is expected to be either a string or an object");
3068
3069 }
3070
3071 if (classname == &ztmp) {
3072 zval_dtor(&ztmp);
3073 }
3074
3075 lcname = zend_str_tolower_dup(name_str, name_len);
3076
3077 if (ce == zend_ce_closure && orig_obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
3078 && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
3079 && (mptr = zend_get_closure_invoke_method(Z_OBJ_P(orig_obj))) != NULL)
3080 {
3081
3082 } else if ((mptr = zend_hash_str_find_ptr(&ce->function_table, lcname, name_len)) == NULL) {
3083 efree(lcname);
3084 zend_throw_exception_ex(reflection_exception_ptr, 0,
3085 "Method %s::%s() does not exist", ZSTR_VAL(ce->name), name_str);
3086 return;
3087 }
3088 efree(lcname);
3089
3090 ZVAL_STR_COPY(&name, mptr->common.scope->name);
3091 reflection_update_property(object, "class", &name);
3092 ZVAL_STR_COPY(&name, mptr->common.function_name);
3093 reflection_update_property(object, "name", &name);
3094 intern->ptr = mptr;
3095 intern->ref_type = REF_TYPE_FUNCTION;
3096 intern->ce = ce;
3097 }
3098
3099
3100
3101
3102 ZEND_METHOD(reflection_method, __toString)
3103 {
3104 reflection_object *intern;
3105 zend_function *mptr;
3106 string str;
3107
3108 if (zend_parse_parameters_none() == FAILURE) {
3109 return;
3110 }
3111 GET_REFLECTION_OBJECT_PTR(mptr);
3112 string_init(&str);
3113 _function_string(&str, mptr, intern->ce, "");
3114 RETURN_NEW_STR(str.buf);
3115 }
3116
3117
3118
3119
3120 ZEND_METHOD(reflection_method, getClosure)
3121 {
3122 reflection_object *intern;
3123 zval *obj;
3124 zend_function *mptr;
3125
3126 METHOD_NOTSTATIC(reflection_method_ptr);
3127 GET_REFLECTION_OBJECT_PTR(mptr);
3128
3129 if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
3130 zend_create_fake_closure(return_value, mptr, mptr->common.scope, mptr->common.scope, NULL);
3131 } else {
3132 if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &obj) == FAILURE) {
3133 return;
3134 }
3135
3136 if (!instanceof_function(Z_OBJCE_P(obj), mptr->common.scope)) {
3137 _DO_THROW("Given object is not an instance of the class this method was declared in");
3138
3139 }
3140
3141
3142 if (Z_OBJCE_P(obj) == zend_ce_closure &&
3143 (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))
3144 {
3145 ZVAL_COPY(return_value, obj);
3146 } else {
3147 zend_create_fake_closure(return_value, mptr, mptr->common.scope, Z_OBJCE_P(obj), obj);
3148 }
3149 }
3150 }
3151
3152
3153
3154
3155 ZEND_METHOD(reflection_method, invoke)
3156 {
3157 zval retval;
3158 zval *params = NULL;
3159 zend_object *object;
3160 reflection_object *intern;
3161 zend_function *mptr;
3162 int result, num_args = 0;
3163 zend_fcall_info fci;
3164 zend_fcall_info_cache fcc;
3165 zend_class_entry *obj_ce;
3166
3167 METHOD_NOTSTATIC(reflection_method_ptr);
3168
3169 GET_REFLECTION_OBJECT_PTR(mptr);
3170
3171 if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)
3172 || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT))
3173 && intern->ignore_visibility == 0)
3174 {
3175 if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
3176 zend_throw_exception_ex(reflection_exception_ptr, 0,
3177 "Trying to invoke abstract method %s::%s()",
3178 ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name));
3179 } else {
3180 zend_throw_exception_ex(reflection_exception_ptr, 0,
3181 "Trying to invoke %s method %s::%s() from scope %s",
3182 mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
3183 ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name),
3184 ZSTR_VAL(Z_OBJCE_P(getThis())->name));
3185 }
3186 return;
3187 }
3188
3189 if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", ¶ms, &num_args) == FAILURE) {
3190 return;
3191 }
3192
3193
3194
3195
3196
3197
3198
3199 if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
3200 object = NULL;
3201 obj_ce = mptr->common.scope;
3202 } else {
3203 if (Z_TYPE(params[0]) != IS_OBJECT) {
3204 _DO_THROW("Non-object passed to Invoke()");
3205
3206 }
3207
3208 obj_ce = Z_OBJCE(params[0]);
3209
3210 if (!instanceof_function(obj_ce, mptr->common.scope)) {
3211 _DO_THROW("Given object is not an instance of the class this method was declared in");
3212
3213 }
3214
3215 object = Z_OBJ(params[0]);
3216 }
3217
3218 fci.size = sizeof(fci);
3219 fci.function_table = NULL;
3220 ZVAL_UNDEF(&fci.function_name);
3221 fci.symbol_table = NULL;
3222 fci.object = object;
3223 fci.retval = &retval;
3224 fci.param_count = num_args - 1;
3225 fci.params = params + 1;
3226 fci.no_separation = 1;
3227
3228 fcc.initialized = 1;
3229 fcc.function_handler = mptr;
3230 fcc.calling_scope = obj_ce;
3231 fcc.called_scope = intern->ce;
3232 fcc.object = object;
3233
3234 result = zend_call_function(&fci, &fcc);
3235
3236 if (result == FAILURE) {
3237 zend_throw_exception_ex(reflection_exception_ptr, 0,
3238 "Invocation of method %s::%s() failed", ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name));
3239 return;
3240 }
3241
3242 if (Z_TYPE(retval) != IS_UNDEF) {
3243 ZVAL_COPY_VALUE(return_value, &retval);
3244 }
3245 }
3246
3247
3248
3249
3250 ZEND_METHOD(reflection_method, invokeArgs)
3251 {
3252 zval retval;
3253 zval *params, *val, *object;
3254 reflection_object *intern;
3255 zend_function *mptr;
3256 int i, argc;
3257 int result;
3258 zend_fcall_info fci;
3259 zend_fcall_info_cache fcc;
3260 zend_class_entry *obj_ce;
3261 zval *param_array;
3262
3263 METHOD_NOTSTATIC(reflection_method_ptr);
3264
3265 GET_REFLECTION_OBJECT_PTR(mptr);
3266
3267 if (zend_parse_parameters(ZEND_NUM_ARGS(), "o!a", &object, ¶m_array) == FAILURE) {
3268 return;
3269 }
3270
3271 if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)
3272 || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT))
3273 && intern->ignore_visibility == 0)
3274 {
3275 if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
3276 zend_throw_exception_ex(reflection_exception_ptr, 0,
3277 "Trying to invoke abstract method %s::%s()",
3278 ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name));
3279 } else {
3280 zend_throw_exception_ex(reflection_exception_ptr, 0,
3281 "Trying to invoke %s method %s::%s() from scope %s",
3282 mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
3283 ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name),
3284 ZSTR_VAL(Z_OBJCE_P(getThis())->name));
3285 }
3286 return;
3287 }
3288
3289 argc = zend_hash_num_elements(Z_ARRVAL_P(param_array));
3290
3291 params = safe_emalloc(sizeof(zval), argc, 0);
3292 argc = 0;
3293 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(param_array), val) {
3294 ZVAL_COPY(¶ms[argc], val);
3295 argc++;
3296 } ZEND_HASH_FOREACH_END();
3297
3298
3299
3300
3301
3302
3303
3304 if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
3305 object = NULL;
3306 obj_ce = mptr->common.scope;
3307 } else {
3308 if (!object) {
3309 efree(params);
3310 zend_throw_exception_ex(reflection_exception_ptr, 0,
3311 "Trying to invoke non static method %s::%s() without an object",
3312 ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name));
3313 return;
3314 }
3315
3316 obj_ce = Z_OBJCE_P(object);
3317
3318 if (!instanceof_function(obj_ce, mptr->common.scope)) {
3319 efree(params);
3320 _DO_THROW("Given object is not an instance of the class this method was declared in");
3321
3322 }
3323 }
3324
3325 fci.size = sizeof(fci);
3326 fci.function_table = NULL;
3327 ZVAL_UNDEF(&fci.function_name);
3328 fci.symbol_table = NULL;
3329 fci.object = object ? Z_OBJ_P(object) : NULL;
3330 fci.retval = &retval;
3331 fci.param_count = argc;
3332 fci.params = params;
3333 fci.no_separation = 1;
3334
3335 fcc.initialized = 1;
3336 fcc.function_handler = mptr;
3337 fcc.calling_scope = obj_ce;
3338 fcc.called_scope = intern->ce;
3339 fcc.object = (object) ? Z_OBJ_P(object) : NULL;
3340
3341
3342
3343
3344 if ((mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
3345 fcc.function_handler = _copy_function(mptr);
3346 }
3347
3348 result = zend_call_function(&fci, &fcc);
3349
3350 for (i = 0; i < argc; i++) {
3351 zval_ptr_dtor(¶ms[i]);
3352 }
3353 efree(params);
3354
3355 if (result == FAILURE) {
3356 zend_throw_exception_ex(reflection_exception_ptr, 0,
3357 "Invocation of method %s::%s() failed", ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name));
3358 return;
3359 }
3360
3361 if (Z_TYPE(retval) != IS_UNDEF) {
3362 ZVAL_COPY_VALUE(return_value, &retval);
3363 }
3364 }
3365
3366
3367
3368
3369 ZEND_METHOD(reflection_method, isFinal)
3370 {
3371 _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL);
3372 }
3373
3374
3375
3376
3377 ZEND_METHOD(reflection_method, isAbstract)
3378 {
3379 _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_ABSTRACT);
3380 }
3381
3382
3383
3384
3385 ZEND_METHOD(reflection_method, isPublic)
3386 {
3387 _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC);
3388 }
3389
3390
3391
3392
3393 ZEND_METHOD(reflection_method, isPrivate)
3394 {
3395 _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
3396 }
3397
3398
3399
3400
3401 ZEND_METHOD(reflection_method, isProtected)
3402 {
3403 _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
3404 }
3405
3406
3407
3408
3409 ZEND_METHOD(reflection_method, isStatic)
3410 {
3411 _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC);
3412 }
3413
3414
3415
3416
3417 ZEND_METHOD(reflection_function, isDeprecated)
3418 {
3419 _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_DEPRECATED);
3420 }
3421
3422
3423
3424
3425 ZEND_METHOD(reflection_function, isGenerator)
3426 {
3427 _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_GENERATOR);
3428 }
3429
3430
3431
3432
3433 ZEND_METHOD(reflection_function, isVariadic)
3434 {
3435 _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_VARIADIC);
3436 }
3437
3438
3439
3440
3441 ZEND_METHOD(reflection_function, inNamespace)
3442 {
3443 zval *name;
3444 const char *backslash;
3445
3446 if (zend_parse_parameters_none() == FAILURE) {
3447 return;
3448 }
3449 if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1)) == NULL) {
3450 RETURN_FALSE;
3451 }
3452 if (Z_TYPE_P(name) == IS_STRING
3453 && (backslash = zend_memrchr(Z_STRVAL_P(name), '\\', Z_STRLEN_P(name)))
3454 && backslash > Z_STRVAL_P(name))
3455 {
3456 RETURN_TRUE;
3457 }
3458 RETURN_FALSE;
3459 }
3460
3461
3462
3463
3464 ZEND_METHOD(reflection_function, getNamespaceName)
3465 {
3466 zval *name;
3467 const char *backslash;
3468
3469 if (zend_parse_parameters_none() == FAILURE) {
3470 return;
3471 }
3472 if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1)) == NULL) {
3473 RETURN_FALSE;
3474 }
3475 if (Z_TYPE_P(name) == IS_STRING
3476 && (backslash = zend_memrchr(Z_STRVAL_P(name), '\\', Z_STRLEN_P(name)))
3477 && backslash > Z_STRVAL_P(name))
3478 {
3479 RETURN_STRINGL(Z_STRVAL_P(name), backslash - Z_STRVAL_P(name));
3480 }
3481 RETURN_EMPTY_STRING();
3482 }
3483
3484
3485
3486
3487 ZEND_METHOD(reflection_function, getShortName)
3488 {
3489 zval *name;
3490 const char *backslash;
3491
3492 if (zend_parse_parameters_none() == FAILURE) {
3493 return;
3494 }
3495 if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1)) == NULL) {
3496 RETURN_FALSE;
3497 }
3498 if (Z_TYPE_P(name) == IS_STRING
3499 && (backslash = zend_memrchr(Z_STRVAL_P(name), '\\', Z_STRLEN_P(name)))
3500 && backslash > Z_STRVAL_P(name))
3501 {
3502 RETURN_STRINGL(backslash + 1, Z_STRLEN_P(name) - (backslash - Z_STRVAL_P(name) + 1));
3503 }
3504 ZVAL_DEREF(name);
3505 ZVAL_COPY(return_value, name);
3506 }
3507
3508
3509
3510
3511 ZEND_METHOD(reflection_function, hasReturnType)
3512 {
3513 reflection_object *intern;
3514 zend_function *fptr;
3515
3516 if (zend_parse_parameters_none() == FAILURE) {
3517 return;
3518 }
3519
3520 GET_REFLECTION_OBJECT_PTR(fptr);
3521
3522 RETVAL_BOOL(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE);
3523 }
3524
3525
3526
3527
3528 ZEND_METHOD(reflection_function, getReturnType)
3529 {
3530 reflection_object *intern;
3531 zend_function *fptr;
3532
3533 if (zend_parse_parameters_none() == FAILURE) {
3534 return;
3535 }
3536
3537 GET_REFLECTION_OBJECT_PTR(fptr);
3538
3539 if (!(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) {
3540 RETURN_NULL();
3541 }
3542
3543 reflection_type_factory(_copy_function(fptr), Z_ISUNDEF(intern->obj)? NULL : &intern->obj, &fptr->common.arg_info[-1], return_value);
3544 }
3545
3546
3547
3548
3549 ZEND_METHOD(reflection_method, isConstructor)
3550 {
3551 reflection_object *intern;
3552 zend_function *mptr;
3553
3554 if (zend_parse_parameters_none() == FAILURE) {
3555 return;
3556 }
3557 GET_REFLECTION_OBJECT_PTR(mptr);
3558
3559
3560
3561 RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_CTOR && intern->ce->constructor && intern->ce->constructor->common.scope == mptr->common.scope);
3562 }
3563
3564
3565
3566
3567 ZEND_METHOD(reflection_method, isDestructor)
3568 {
3569 reflection_object *intern;
3570 zend_function *mptr;
3571
3572 if (zend_parse_parameters_none() == FAILURE) {
3573 return;
3574 }
3575 GET_REFLECTION_OBJECT_PTR(mptr);
3576 RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_DTOR);
3577 }
3578
3579
3580
3581
3582 ZEND_METHOD(reflection_method, getModifiers)
3583 {
3584 reflection_object *intern;
3585 zend_function *mptr;
3586
3587 if (zend_parse_parameters_none() == FAILURE) {
3588 return;
3589 }
3590 GET_REFLECTION_OBJECT_PTR(mptr);
3591
3592 RETURN_LONG(mptr->common.fn_flags);
3593 }
3594
3595
3596
3597
3598 ZEND_METHOD(reflection_method, getDeclaringClass)
3599 {
3600 reflection_object *intern;
3601 zend_function *mptr;
3602
3603 METHOD_NOTSTATIC(reflection_method_ptr);
3604 GET_REFLECTION_OBJECT_PTR(mptr);
3605
3606 if (zend_parse_parameters_none() == FAILURE) {
3607 return;
3608 }
3609
3610 zend_reflection_class_factory(mptr->common.scope, return_value);
3611 }
3612
3613
3614
3615
3616 ZEND_METHOD(reflection_method, getPrototype)
3617 {
3618 reflection_object *intern;
3619 zend_function *mptr;
3620
3621 METHOD_NOTSTATIC(reflection_method_ptr);
3622 GET_REFLECTION_OBJECT_PTR(mptr);
3623
3624 if (zend_parse_parameters_none() == FAILURE) {
3625 return;
3626 }
3627
3628 if (!mptr->common.prototype) {
3629 zend_throw_exception_ex(reflection_exception_ptr, 0,
3630 "Method %s::%s does not have a prototype", ZSTR_VAL(intern->ce->name), ZSTR_VAL(mptr->common.function_name));
3631 return;
3632 }
3633
3634 reflection_method_factory(mptr->common.prototype->common.scope, mptr->common.prototype, NULL, return_value);
3635 }
3636
3637
3638
3639
3640 ZEND_METHOD(reflection_method, setAccessible)
3641 {
3642 reflection_object *intern;
3643 zend_bool visible;
3644
3645 if (zend_parse_parameters(ZEND_NUM_ARGS(), "b", &visible) == FAILURE) {
3646 return;
3647 }
3648
3649 intern = Z_REFLECTION_P(getThis());
3650
3651 intern->ignore_visibility = visible;
3652 }
3653
3654
3655
3656
3657 ZEND_METHOD(reflection_class, export)
3658 {
3659 _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_class_ptr, 1);
3660 }
3661
3662
3663
3664 static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_object)
3665 {
3666 zval *argument;
3667 zval *object;
3668 zval classname;
3669 reflection_object *intern;
3670 zend_class_entry *ce;
3671
3672 if (is_object) {
3673 if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &argument) == FAILURE) {
3674 return;
3675 }
3676 } else {
3677 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z/", &argument) == FAILURE) {
3678 return;
3679 }
3680 }
3681
3682 object = getThis();
3683 intern = Z_REFLECTION_P(object);
3684
3685 if (Z_TYPE_P(argument) == IS_OBJECT) {
3686 ZVAL_STR_COPY(&classname, Z_OBJCE_P(argument)->name);
3687 reflection_update_property(object, "name", &classname);
3688 intern->ptr = Z_OBJCE_P(argument);
3689 if (is_object) {
3690 ZVAL_COPY_VALUE(&intern->obj, argument);
3691 zval_add_ref(argument);
3692 }
3693 } else {
3694 convert_to_string_ex(argument);
3695 if ((ce = zend_lookup_class(Z_STR_P(argument))) == NULL) {
3696 if (!EG(exception)) {
3697 zend_throw_exception_ex(reflection_exception_ptr, -1, "Class %s does not exist", Z_STRVAL_P(argument));
3698 }
3699 return;
3700 }
3701
3702 ZVAL_STR_COPY(&classname, ce->name);
3703 reflection_update_property(object, "name", &classname);
3704
3705 intern->ptr = ce;
3706 }
3707 intern->ref_type = REF_TYPE_OTHER;
3708 }
3709
3710
3711
3712
3713 ZEND_METHOD(reflection_class, __construct)
3714 {
3715 reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
3716 }
3717
3718
3719
3720 static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value)
3721 {
3722 zend_property_info *prop_info;
3723 zval *prop, prop_copy;
3724 zend_string *key;
3725
3726 ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
3727 if (((prop_info->flags & ZEND_ACC_SHADOW) &&
3728 prop_info->ce != ce) ||
3729 ((prop_info->flags & ZEND_ACC_PROTECTED) &&
3730 !zend_check_protected(prop_info->ce, ce)) ||
3731 ((prop_info->flags & ZEND_ACC_PRIVATE) &&
3732 prop_info->ce != ce)) {
3733 continue;
3734 }
3735 prop = NULL;
3736 if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) {
3737 prop = &ce->default_static_members_table[prop_info->offset];
3738 } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) {
3739 prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
3740 }
3741 if (!prop) {
3742 continue;
3743 }
3744
3745
3746 ZVAL_DEREF(prop);
3747 ZVAL_DUP(&prop_copy, prop);
3748
3749
3750
3751 if (Z_CONSTANT(prop_copy)) {
3752 if (UNEXPECTED(zval_update_constant_ex(&prop_copy, 1, NULL) != SUCCESS)) {
3753 return;
3754 }
3755 }
3756
3757 zend_hash_update(Z_ARRVAL_P(return_value), key, &prop_copy);
3758 } ZEND_HASH_FOREACH_END();
3759 }
3760
3761
3762
3763
3764 ZEND_METHOD(reflection_class, getStaticProperties)
3765 {
3766 reflection_object *intern;
3767 zend_class_entry *ce;
3768
3769 if (zend_parse_parameters_none() == FAILURE) {
3770 return;
3771 }
3772
3773 GET_REFLECTION_OBJECT_PTR(ce);
3774
3775 if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
3776 return;
3777 }
3778
3779 array_init(return_value);
3780 add_class_vars(ce, 1, return_value);
3781 }
3782
3783
3784
3785
3786 ZEND_METHOD(reflection_class, getStaticPropertyValue)
3787 {
3788 reflection_object *intern;
3789 zend_class_entry *ce;
3790 zend_string *name;
3791 zval *prop, *def_value = NULL;
3792
3793 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|z", &name, &def_value) == FAILURE) {
3794 return;
3795 }
3796
3797 GET_REFLECTION_OBJECT_PTR(ce);
3798
3799 if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
3800 return;
3801 }
3802 prop = zend_std_get_static_property(ce, name, 1);
3803 if (!prop) {
3804 if (def_value) {
3805 ZVAL_COPY(return_value, def_value);
3806 } else {
3807 zend_throw_exception_ex(reflection_exception_ptr, 0,
3808 "Class %s does not have a property named %s", ZSTR_VAL(ce->name), ZSTR_VAL(name));
3809 }
3810 return;
3811 } else {
3812 ZVAL_DEREF(prop);
3813 ZVAL_COPY(return_value, prop);
3814 }
3815 }
3816
3817
3818
3819
3820 ZEND_METHOD(reflection_class, setStaticPropertyValue)
3821 {
3822 reflection_object *intern;
3823 zend_class_entry *ce;
3824 zend_string *name;
3825 zval *variable_ptr, *value;
3826
3827 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sz", &name, &value) == FAILURE) {
3828 return;
3829 }
3830
3831 GET_REFLECTION_OBJECT_PTR(ce);
3832
3833 if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
3834 return;
3835 }
3836 variable_ptr = zend_std_get_static_property(ce, name, 1);
3837 if (!variable_ptr) {
3838 zend_throw_exception_ex(reflection_exception_ptr, 0,
3839 "Class %s does not have a property named %s", ZSTR_VAL(ce->name), ZSTR_VAL(name));
3840 return;
3841 }
3842 ZVAL_DEREF(variable_ptr);
3843 zval_ptr_dtor(variable_ptr);
3844 ZVAL_COPY(variable_ptr, value);
3845 }
3846
3847
3848
3849
3850 ZEND_METHOD(reflection_class, getDefaultProperties)
3851 {
3852 reflection_object *intern;
3853 zend_class_entry *ce;
3854
3855 if (zend_parse_parameters_none() == FAILURE) {
3856 return;
3857 }
3858 GET_REFLECTION_OBJECT_PTR(ce);
3859 array_init(return_value);
3860 if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
3861 return;
3862 }
3863 add_class_vars(ce, 1, return_value);
3864 add_class_vars(ce, 0, return_value);
3865 }
3866
3867
3868
3869
3870 ZEND_METHOD(reflection_class, __toString)
3871 {
3872 reflection_object *intern;
3873 zend_class_entry *ce;
3874 string str;
3875
3876 if (zend_parse_parameters_none() == FAILURE) {
3877 return;
3878 }
3879 GET_REFLECTION_OBJECT_PTR(ce);
3880 string_init(&str);
3881 _class_string(&str, ce, &intern->obj, "");
3882 RETURN_NEW_STR(str.buf);
3883 }
3884
3885
3886
3887
3888 ZEND_METHOD(reflection_class, getName)
3889 {
3890 if (zend_parse_parameters_none() == FAILURE) {
3891 return;
3892 }
3893 _default_get_entry(getThis(), "name", sizeof("name")-1, return_value);
3894 }
3895
3896
3897
3898
3899 ZEND_METHOD(reflection_class, isInternal)
3900 {
3901 reflection_object *intern;
3902 zend_class_entry *ce;
3903
3904 if (zend_parse_parameters_none() == FAILURE) {
3905 return;
3906 }
3907 GET_REFLECTION_OBJECT_PTR(ce);
3908 RETURN_BOOL(ce->type == ZEND_INTERNAL_CLASS);
3909 }
3910
3911
3912
3913
3914 ZEND_METHOD(reflection_class, isUserDefined)
3915 {
3916 reflection_object *intern;
3917 zend_class_entry *ce;
3918
3919 if (zend_parse_parameters_none() == FAILURE) {
3920 return;
3921 }
3922 GET_REFLECTION_OBJECT_PTR(ce);
3923 RETURN_BOOL(ce->type == ZEND_USER_CLASS);
3924 }
3925
3926
3927
3928
3929 ZEND_METHOD(reflection_class, isAnonymous)
3930 {
3931 reflection_object *intern;
3932 zend_class_entry *ce;
3933
3934 if (zend_parse_parameters_none() == FAILURE) {
3935 return;
3936 }
3937 GET_REFLECTION_OBJECT_PTR(ce);
3938 RETURN_BOOL(ce->ce_flags & ZEND_ACC_ANON_CLASS);
3939 }
3940
3941
3942
3943
3944 ZEND_METHOD(reflection_class, getFileName)
3945 {
3946 reflection_object *intern;
3947 zend_class_entry *ce;
3948
3949 if (zend_parse_parameters_none() == FAILURE) {
3950 return;
3951 }
3952 GET_REFLECTION_OBJECT_PTR(ce);
3953 if (ce->type == ZEND_USER_CLASS) {
3954 RETURN_STR_COPY(ce->info.user.filename);
3955 }
3956 RETURN_FALSE;
3957 }
3958
3959
3960
3961
3962 ZEND_METHOD(reflection_class, getStartLine)
3963 {
3964 reflection_object *intern;
3965 zend_class_entry *ce;
3966
3967 if (zend_parse_parameters_none() == FAILURE) {
3968 return;
3969 }
3970 GET_REFLECTION_OBJECT_PTR(ce);
3971 if (ce->type == ZEND_USER_FUNCTION) {
3972 RETURN_LONG(ce->info.user.line_start);
3973 }
3974 RETURN_FALSE;
3975 }
3976
3977
3978
3979
3980 ZEND_METHOD(reflection_class, getEndLine)
3981 {
3982 reflection_object *intern;
3983 zend_class_entry *ce;
3984
3985 if (zend_parse_parameters_none() == FAILURE) {
3986 return;
3987 }
3988 GET_REFLECTION_OBJECT_PTR(ce);
3989 if (ce->type == ZEND_USER_CLASS) {
3990 RETURN_LONG(ce->info.user.line_end);
3991 }
3992 RETURN_FALSE;
3993 }
3994
3995
3996
3997
3998 ZEND_METHOD(reflection_class, getDocComment)
3999 {
4000 reflection_object *intern;
4001 zend_class_entry *ce;
4002
4003 if (zend_parse_parameters_none() == FAILURE) {
4004 return;
4005 }
4006 GET_REFLECTION_OBJECT_PTR(ce);
4007 if (ce->type == ZEND_USER_CLASS && ce->info.user.doc_comment) {
4008 RETURN_STR_COPY(ce->info.user.doc_comment);
4009 }
4010 RETURN_FALSE;
4011 }
4012
4013
4014
4015
4016 ZEND_METHOD(reflection_class, getConstructor)
4017 {
4018 reflection_object *intern;
4019 zend_class_entry *ce;
4020
4021 if (zend_parse_parameters_none() == FAILURE) {
4022 return;
4023 }
4024 GET_REFLECTION_OBJECT_PTR(ce);
4025
4026 if (ce->constructor) {
4027 reflection_method_factory(ce, ce->constructor, NULL, return_value);
4028 } else {
4029 RETURN_NULL();
4030 }
4031 }
4032
4033
4034
4035
4036 ZEND_METHOD(reflection_class, hasMethod)
4037 {
4038 reflection_object *intern;
4039 zend_class_entry *ce;
4040 char *name, *lc_name;
4041 size_t name_len;
4042
4043 METHOD_NOTSTATIC(reflection_class_ptr);
4044 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
4045 return;
4046 }
4047
4048 GET_REFLECTION_OBJECT_PTR(ce);
4049 lc_name = zend_str_tolower_dup(name, name_len);
4050 if ((ce == zend_ce_closure && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
4051 && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0)
4052 || zend_hash_str_exists(&ce->function_table, lc_name, name_len)) {
4053 efree(lc_name);
4054 RETURN_TRUE;
4055 } else {
4056 efree(lc_name);
4057 RETURN_FALSE;
4058 }
4059 }
4060
4061
4062
4063
4064 ZEND_METHOD(reflection_class, getMethod)
4065 {
4066 reflection_object *intern;
4067 zend_class_entry *ce;
4068 zend_function *mptr;
4069 zval obj_tmp;
4070 char *name, *lc_name;
4071 size_t name_len;
4072
4073 METHOD_NOTSTATIC(reflection_class_ptr);
4074 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
4075 return;
4076 }
4077
4078 GET_REFLECTION_OBJECT_PTR(ce);
4079 lc_name = zend_str_tolower_dup(name, name_len);
4080 if (ce == zend_ce_closure && !Z_ISUNDEF(intern->obj) && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
4081 && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
4082 && (mptr = zend_get_closure_invoke_method(Z_OBJ(intern->obj))) != NULL)
4083 {
4084
4085
4086 reflection_method_factory(ce, mptr, NULL, return_value);
4087 efree(lc_name);
4088 } else if (ce == zend_ce_closure && Z_ISUNDEF(intern->obj) && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
4089 && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
4090 && object_init_ex(&obj_tmp, ce) == SUCCESS && (mptr = zend_get_closure_invoke_method(Z_OBJ(obj_tmp))) != NULL) {
4091
4092
4093 reflection_method_factory(ce, mptr, NULL, return_value);
4094 zval_dtor(&obj_tmp);
4095 efree(lc_name);
4096 } else if ((mptr = zend_hash_str_find_ptr(&ce->function_table, lc_name, name_len)) != NULL) {
4097 reflection_method_factory(ce, mptr, NULL, return_value);
4098 efree(lc_name);
4099 } else {
4100 efree(lc_name);
4101 zend_throw_exception_ex(reflection_exception_ptr, 0,
4102 "Method %s does not exist", name);
4103 return;
4104 }
4105 }
4106
4107
4108
4109 static void _addmethod(zend_function *mptr, zend_class_entry *ce, zval *retval, zend_long filter, zval *obj)
4110 {
4111 zval method;
4112 size_t len = ZSTR_LEN(mptr->common.function_name);
4113 zend_function *closure;
4114 if (mptr->common.fn_flags & filter) {
4115 if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
4116 && memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
4117 && (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL)
4118 {
4119 mptr = closure;
4120 }
4121
4122
4123
4124 reflection_method_factory(ce, mptr, NULL, &method);
4125 add_next_index_zval(retval, &method);
4126 }
4127 }
4128
4129
4130
4131 static int _addmethod_va(zval *el, int num_args, va_list args, zend_hash_key *hash_key)
4132 {
4133 zend_function *mptr = (zend_function*)Z_PTR_P(el);
4134 zend_class_entry *ce = *va_arg(args, zend_class_entry**);
4135 zval *retval = va_arg(args, zval*);
4136 long filter = va_arg(args, long);
4137 zval *obj = va_arg(args, zval *);
4138
4139 _addmethod(mptr, ce, retval, filter, obj);
4140 return ZEND_HASH_APPLY_KEEP;
4141 }
4142
4143
4144
4145
4146 ZEND_METHOD(reflection_class, getMethods)
4147 {
4148 reflection_object *intern;
4149 zend_class_entry *ce;
4150 zend_long filter = 0;
4151 int argc = ZEND_NUM_ARGS();
4152
4153 METHOD_NOTSTATIC(reflection_class_ptr);
4154 if (argc) {
4155 if (zend_parse_parameters(argc, "|l", &filter) == FAILURE) {
4156 return;
4157 }
4158 } else {
4159
4160 filter = ZEND_ACC_PPP_MASK | ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL | ZEND_ACC_STATIC;
4161 }
4162
4163 GET_REFLECTION_OBJECT_PTR(ce);
4164
4165 array_init(return_value);
4166 zend_hash_apply_with_arguments(&ce->function_table, (apply_func_args_t) _addmethod_va, 4, &ce, return_value, filter, intern->obj);
4167 if (Z_TYPE(intern->obj) != IS_UNDEF && instanceof_function(ce, zend_ce_closure)) {
4168 zend_function *closure = zend_get_closure_invoke_method(Z_OBJ(intern->obj));
4169 if (closure) {
4170 _addmethod(closure, ce, return_value, filter, &intern->obj);
4171 _free_function(closure);
4172 }
4173 }
4174 }
4175
4176
4177
4178
4179 ZEND_METHOD(reflection_class, hasProperty)
4180 {
4181 reflection_object *intern;
4182 zend_property_info *property_info;
4183 zend_class_entry *ce;
4184 zend_string *name;
4185 zval property;
4186
4187 METHOD_NOTSTATIC(reflection_class_ptr);
4188 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
4189 return;
4190 }
4191
4192 GET_REFLECTION_OBJECT_PTR(ce);
4193 if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) {
4194 if (property_info->flags & ZEND_ACC_SHADOW) {
4195 RETURN_FALSE;
4196 }
4197 RETURN_TRUE;
4198 } else {
4199 if (Z_TYPE(intern->obj) != IS_UNDEF && Z_OBJ_HANDLER(intern->obj, has_property)) {
4200 ZVAL_STR_COPY(&property, name);
4201 if (Z_OBJ_HANDLER(intern->obj, has_property)(&intern->obj, &property, 2, NULL)) {
4202 zval_ptr_dtor(&property);
4203 RETURN_TRUE;
4204 }
4205 zval_ptr_dtor(&property);
4206 }
4207 RETURN_FALSE;
4208 }
4209 }
4210
4211
4212
4213
4214 ZEND_METHOD(reflection_class, getProperty)
4215 {
4216 reflection_object *intern;
4217 zend_class_entry *ce, *ce2;
4218 zend_property_info *property_info;
4219 zend_string *name, *classname;
4220 char *tmp, *str_name;
4221 size_t classname_len, str_name_len;
4222
4223 METHOD_NOTSTATIC(reflection_class_ptr);
4224 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
4225 return;
4226 }
4227
4228 GET_REFLECTION_OBJECT_PTR(ce);
4229 if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) {
4230 if ((property_info->flags & ZEND_ACC_SHADOW) == 0) {
4231 reflection_property_factory(ce, property_info, return_value);
4232 return;
4233 }
4234 } else if (Z_TYPE(intern->obj) != IS_UNDEF) {
4235
4236 if (zend_hash_exists(Z_OBJ_HT(intern->obj)->get_properties(&intern->obj), name)) {
4237 zend_property_info property_info_tmp;
4238 property_info_tmp.flags = ZEND_ACC_IMPLICIT_PUBLIC;
4239 property_info_tmp.name = zend_string_copy(name);
4240 property_info_tmp.doc_comment = NULL;
4241 property_info_tmp.ce = ce;
4242
4243 reflection_property_factory(ce, &property_info_tmp, return_value);
4244 intern = Z_REFLECTION_P(return_value);
4245 intern->ref_type = REF_TYPE_DYNAMIC_PROPERTY;
4246 return;
4247 }
4248 }
4249 str_name = ZSTR_VAL(name);
4250 str_name_len = ZSTR_LEN(name);
4251 if ((tmp = strstr(ZSTR_VAL(name), "::")) != NULL) {
4252 classname_len = tmp - ZSTR_VAL(name);
4253 classname = zend_string_alloc(classname_len, 0);
4254 zend_str_tolower_copy(ZSTR_VAL(classname), ZSTR_VAL(name), classname_len);
4255 ZSTR_VAL(classname)[classname_len] = '\0';
4256 str_name_len = ZSTR_LEN(name) - (classname_len + 2);
4257 str_name = tmp + 2;
4258
4259 ce2 = zend_lookup_class(classname);
4260 if (!ce2) {
4261 if (!EG(exception)) {
4262 zend_throw_exception_ex(reflection_exception_ptr, -1, "Class %s does not exist", ZSTR_VAL(classname));
4263 }
4264 zend_string_release(classname);
4265 return;
4266 }
4267 zend_string_release(classname);
4268
4269 if (!instanceof_function(ce, ce2)) {
4270 zend_throw_exception_ex(reflection_exception_ptr, -1, "Fully qualified property name %s::%s does not specify a base class of %s", ZSTR_VAL(ce2->name), str_name, ZSTR_VAL(ce->name));
4271 return;
4272 }
4273 ce = ce2;
4274
4275 if ((property_info = zend_hash_str_find_ptr(&ce->properties_info, str_name, str_name_len)) != NULL && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
4276 reflection_property_factory(ce, property_info, return_value);
4277 return;
4278 }
4279 }
4280 zend_throw_exception_ex(reflection_exception_ptr, 0,
4281 "Property %s does not exist", str_name);
4282 }
4283
4284
4285
4286 static int _addproperty(zval *el, int num_args, va_list args, zend_hash_key *hash_key)
4287 {
4288 zval property;
4289 zend_property_info *pptr = (zend_property_info*)Z_PTR_P(el);
4290 zend_class_entry *ce = *va_arg(args, zend_class_entry**);
4291 zval *retval = va_arg(args, zval*);
4292 long filter = va_arg(args, long);
4293
4294 if (pptr->flags & ZEND_ACC_SHADOW) {
4295 return 0;
4296 }
4297
4298 if (pptr->flags & filter) {
4299 reflection_property_factory(ce, pptr, &property);
4300 add_next_index_zval(retval, &property);
4301 }
4302 return 0;
4303 }
4304
4305
4306
4307 static int _adddynproperty(zval *ptr, int num_args, va_list args, zend_hash_key *hash_key)
4308 {
4309 zval property;
4310 zend_class_entry *ce = *va_arg(args, zend_class_entry**);
4311 zval *retval = va_arg(args, zval*);
4312
4313
4314
4315
4316 if (hash_key->key == NULL) {
4317 return 0;
4318 }
4319
4320 if (ZSTR_VAL(hash_key->key)[0] == '\0') {
4321 return 0;
4322 }
4323
4324 if (zend_get_property_info(ce, hash_key->key, 1) == NULL) {
4325 zend_property_info property_info;
4326
4327 property_info.doc_comment = NULL;
4328 property_info.flags = ZEND_ACC_IMPLICIT_PUBLIC;
4329 property_info.name = hash_key->key;
4330 property_info.ce = ce;
4331 property_info.offset = -1;
4332 reflection_property_factory(ce, &property_info, &property);
4333 add_next_index_zval(retval, &property);
4334 }
4335 return 0;
4336 }
4337
4338
4339
4340
4341 ZEND_METHOD(reflection_class, getProperties)
4342 {
4343 reflection_object *intern;
4344 zend_class_entry *ce;
4345 zend_long filter = 0;
4346 int argc = ZEND_NUM_ARGS();
4347
4348 METHOD_NOTSTATIC(reflection_class_ptr);
4349 if (argc) {
4350 if (zend_parse_parameters(argc, "|l", &filter) == FAILURE) {
4351 return;
4352 }
4353 } else {
4354
4355 filter = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC;
4356 }
4357
4358 GET_REFLECTION_OBJECT_PTR(ce);
4359
4360 array_init(return_value);
4361 zend_hash_apply_with_arguments(&ce->properties_info, (apply_func_args_t) _addproperty, 3, &ce, return_value, filter);
4362
4363 if (Z_TYPE(intern->obj) != IS_UNDEF && (filter & ZEND_ACC_PUBLIC) != 0 && Z_OBJ_HT(intern->obj)->get_properties) {
4364 HashTable *properties = Z_OBJ_HT(intern->obj)->get_properties(&intern->obj);
4365 zend_hash_apply_with_arguments(properties, (apply_func_args_t) _adddynproperty, 2, &ce, return_value);
4366 }
4367 }
4368
4369
4370
4371
4372 ZEND_METHOD(reflection_class, hasConstant)
4373 {
4374 reflection_object *intern;
4375 zend_class_entry *ce;
4376 zend_string *name;
4377
4378 METHOD_NOTSTATIC(reflection_class_ptr);
4379 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
4380 return;
4381 }
4382
4383 GET_REFLECTION_OBJECT_PTR(ce);
4384 if (zend_hash_exists(&ce->constants_table, name)) {
4385 RETURN_TRUE;
4386 } else {
4387 RETURN_FALSE;
4388 }
4389 }
4390
4391
4392
4393
4394 ZEND_METHOD(reflection_class, getConstants)
4395 {
4396 reflection_object *intern;
4397 zend_class_entry *ce;
4398 zval *val;
4399
4400 if (zend_parse_parameters_none() == FAILURE) {
4401 return;
4402 }
4403 GET_REFLECTION_OBJECT_PTR(ce);
4404 array_init(return_value);
4405 ZEND_HASH_FOREACH_VAL(&ce->constants_table, val) {
4406 if (UNEXPECTED(zval_update_constant_ex(val, 1, ce) != SUCCESS)) {
4407 return;
4408 }
4409 } ZEND_HASH_FOREACH_END();
4410 zend_hash_copy(Z_ARRVAL_P(return_value), &ce->constants_table, zval_add_ref_unref);
4411 }
4412
4413
4414
4415
4416 ZEND_METHOD(reflection_class, getConstant)
4417 {
4418 reflection_object *intern;
4419 zend_class_entry *ce;
4420 zval *value;
4421 zend_string *name;
4422
4423 METHOD_NOTSTATIC(reflection_class_ptr);
4424 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
4425 return;
4426 }
4427
4428 GET_REFLECTION_OBJECT_PTR(ce);
4429 ZEND_HASH_FOREACH_VAL(&ce->constants_table, value) {
4430 if (UNEXPECTED(zval_update_constant_ex(value, 1, ce) != SUCCESS)) {
4431 return;
4432 }
4433 } ZEND_HASH_FOREACH_END();
4434 if ((value = zend_hash_find(&ce->constants_table, name)) == NULL) {
4435 RETURN_FALSE;
4436 }
4437 ZVAL_DUP(return_value, value);
4438 }
4439
4440
4441
4442 static void _class_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
4443 {
4444 reflection_object *intern;
4445 zend_class_entry *ce;
4446
4447 if (zend_parse_parameters_none() == FAILURE) {
4448 return;
4449 }
4450 GET_REFLECTION_OBJECT_PTR(ce);
4451 RETVAL_BOOL(ce->ce_flags & mask);
4452 }
4453
4454
4455
4456
4457 ZEND_METHOD(reflection_class, isInstantiable)
4458 {
4459 reflection_object *intern;
4460 zend_class_entry *ce;
4461
4462 if (zend_parse_parameters_none() == FAILURE) {
4463 return;
4464 }
4465 GET_REFLECTION_OBJECT_PTR(ce);
4466 if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS)) {
4467 RETURN_FALSE;
4468 }
4469
4470
4471
4472 if (!ce->constructor) {
4473 RETURN_TRUE;
4474 }
4475
4476 RETURN_BOOL(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC);
4477 }
4478
4479
4480
4481
4482 ZEND_METHOD(reflection_class, isCloneable)
4483 {
4484 reflection_object *intern;
4485 zend_class_entry *ce;
4486 zval obj;
4487
4488 if (zend_parse_parameters_none() == FAILURE) {
4489 return;
4490 }
4491 GET_REFLECTION_OBJECT_PTR(ce);
4492 if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS)) {
4493 RETURN_FALSE;
4494 }
4495 if (!Z_ISUNDEF(intern->obj)) {
4496 if (ce->clone) {
4497 RETURN_BOOL(ce->clone->common.fn_flags & ZEND_ACC_PUBLIC);
4498 } else {
4499 RETURN_BOOL(Z_OBJ_HANDLER(intern->obj, clone_obj) != NULL);
4500 }
4501 } else {
4502 if (ce->clone) {
4503 RETURN_BOOL(ce->clone->common.fn_flags & ZEND_ACC_PUBLIC);
4504 } else {
4505 if (UNEXPECTED(object_init_ex(&obj, ce) != SUCCESS)) {
4506 return;
4507 }
4508 RETVAL_BOOL(Z_OBJ_HANDLER(obj, clone_obj) != NULL);
4509 zval_dtor(&obj);
4510 }
4511 }
4512 }
4513
4514
4515
4516
4517 ZEND_METHOD(reflection_class, isInterface)
4518 {
4519 _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_INTERFACE);
4520 }
4521
4522
4523
4524
4525 ZEND_METHOD(reflection_class, isTrait)
4526 {
4527 _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_TRAIT);
4528 }
4529
4530
4531
4532
4533 ZEND_METHOD(reflection_class, isFinal)
4534 {
4535 _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL);
4536 }
4537
4538
4539
4540
4541 ZEND_METHOD(reflection_class, isAbstract)
4542 {
4543 _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
4544 }
4545
4546
4547
4548
4549 ZEND_METHOD(reflection_class, getModifiers)
4550 {
4551 reflection_object *intern;
4552 zend_class_entry *ce;
4553
4554 if (zend_parse_parameters_none() == FAILURE) {
4555 return;
4556 }
4557 GET_REFLECTION_OBJECT_PTR(ce);
4558
4559 RETURN_LONG(ce->ce_flags & ~(ZEND_ACC_CONSTANTS_UPDATED|ZEND_ACC_USE_GUARDS));
4560 }
4561
4562
4563
4564
4565 ZEND_METHOD(reflection_class, isInstance)
4566 {
4567 reflection_object *intern;
4568 zend_class_entry *ce;
4569 zval *object;
4570
4571 METHOD_NOTSTATIC(reflection_class_ptr);
4572 if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &object) == FAILURE) {
4573 return;
4574 }
4575 GET_REFLECTION_OBJECT_PTR(ce);
4576 RETURN_BOOL(instanceof_function(Z_OBJCE_P(object), ce));
4577 }
4578
4579
4580
4581
4582 ZEND_METHOD(reflection_class, newInstance)
4583 {
4584 zval retval;
4585 reflection_object *intern;
4586 zend_class_entry *ce, *old_scope;
4587 zend_function *constructor;
4588
4589 METHOD_NOTSTATIC(reflection_class_ptr);
4590 GET_REFLECTION_OBJECT_PTR(ce);
4591
4592 if (UNEXPECTED(object_init_ex(return_value, ce) != SUCCESS)) {
4593 return;
4594 }
4595
4596 old_scope = EG(scope);
4597 EG(scope) = ce;
4598 constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value));
4599 EG(scope) = old_scope;
4600
4601
4602 if (constructor) {
4603 zval *params = NULL;
4604 int ret, i, num_args = 0;
4605 zend_fcall_info fci;
4606 zend_fcall_info_cache fcc;
4607
4608 if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
4609 zend_throw_exception_ex(reflection_exception_ptr, 0, "Access to non-public constructor of class %s", ZSTR_VAL(ce->name));
4610 zval_dtor(return_value);
4611 RETURN_NULL();
4612 }
4613
4614 if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", ¶ms, &num_args) == FAILURE) {
4615 zval_dtor(return_value);
4616 RETURN_FALSE;
4617 }
4618
4619 for (i = 0; i < num_args; i++) {
4620 if (Z_REFCOUNTED(params[i])) Z_ADDREF(params[i]);
4621 }
4622
4623 fci.size = sizeof(fci);
4624 fci.function_table = EG(function_table);
4625 ZVAL_UNDEF(&fci.function_name);
4626 fci.symbol_table = NULL;
4627 fci.object = Z_OBJ_P(return_value);
4628 fci.retval = &retval;
4629 fci.param_count = num_args;
4630 fci.params = params;
4631 fci.no_separation = 1;
4632
4633 fcc.initialized = 1;
4634 fcc.function_handler = constructor;
4635 fcc.calling_scope = EG(scope);
4636 fcc.called_scope = Z_OBJCE_P(return_value);
4637 fcc.object = Z_OBJ_P(return_value);
4638
4639 ret = zend_call_function(&fci, &fcc);
4640 zval_ptr_dtor(&retval);
4641 for (i = 0; i < num_args; i++) {
4642 zval_ptr_dtor(¶ms[i]);
4643 }
4644 if (ret == FAILURE) {
4645 php_error_docref(NULL, E_WARNING, "Invocation of %s's constructor failed", ZSTR_VAL(ce->name));
4646 zval_dtor(return_value);
4647 RETURN_NULL();
4648 }
4649 } else if (ZEND_NUM_ARGS()) {
4650 zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ZSTR_VAL(ce->name));
4651 }
4652 }
4653
4654
4655
4656
4657 ZEND_METHOD(reflection_class, newInstanceWithoutConstructor)
4658 {
4659 reflection_object *intern;
4660 zend_class_entry *ce;
4661
4662 METHOD_NOTSTATIC(reflection_class_ptr);
4663 GET_REFLECTION_OBJECT_PTR(ce);
4664
4665 if (ce->create_object != NULL && ce->ce_flags & ZEND_ACC_FINAL) {
4666 zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s is an internal class marked as final that cannot be instantiated without invoking its constructor", ZSTR_VAL(ce->name));
4667 return;
4668 }
4669
4670 object_init_ex(return_value, ce);
4671 }
4672
4673
4674
4675
4676 ZEND_METHOD(reflection_class, newInstanceArgs)
4677 {
4678 zval retval, *val;
4679 reflection_object *intern;
4680 zend_class_entry *ce, *old_scope;
4681 int ret, i, argc = 0;
4682 HashTable *args;
4683 zend_function *constructor;
4684
4685
4686 METHOD_NOTSTATIC(reflection_class_ptr);
4687 GET_REFLECTION_OBJECT_PTR(ce);
4688
4689 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|h", &args) == FAILURE) {
4690 return;
4691 }
4692
4693 if (ZEND_NUM_ARGS() > 0) {
4694 argc = args->nNumOfElements;
4695 }
4696
4697 if (UNEXPECTED(object_init_ex(return_value, ce) != SUCCESS)) {
4698 return;
4699 }
4700
4701 old_scope = EG(scope);
4702 EG(scope) = ce;
4703 constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value));
4704 EG(scope) = old_scope;
4705
4706
4707 if (constructor) {
4708 zval *params = NULL;
4709 zend_fcall_info fci;
4710 zend_fcall_info_cache fcc;
4711
4712 if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
4713 zend_throw_exception_ex(reflection_exception_ptr, 0, "Access to non-public constructor of class %s", ZSTR_VAL(ce->name));
4714 zval_dtor(return_value);
4715 RETURN_NULL();
4716 }
4717
4718 if (argc) {
4719 params = safe_emalloc(sizeof(zval), argc, 0);
4720 argc = 0;
4721 ZEND_HASH_FOREACH_VAL(args, val) {
4722 ZVAL_COPY(¶ms[argc], val);
4723 argc++;
4724 } ZEND_HASH_FOREACH_END();
4725 }
4726
4727 fci.size = sizeof(fci);
4728 fci.function_table = EG(function_table);
4729 ZVAL_UNDEF(&fci.function_name);
4730 fci.symbol_table = NULL;
4731 fci.object = Z_OBJ_P(return_value);
4732 fci.retval = &retval;
4733 fci.param_count = argc;
4734 fci.params = params;
4735 fci.no_separation = 1;
4736
4737 fcc.initialized = 1;
4738 fcc.function_handler = constructor;
4739 fcc.calling_scope = EG(scope);
4740 fcc.called_scope = Z_OBJCE_P(return_value);
4741 fcc.object = Z_OBJ_P(return_value);
4742
4743 ret = zend_call_function(&fci, &fcc);
4744 zval_ptr_dtor(&retval);
4745 if (params) {
4746 for (i = 0; i < argc; i++) {
4747 zval_ptr_dtor(¶ms[i]);
4748 }
4749 efree(params);
4750 }
4751 if (ret == FAILURE) {
4752 zval_ptr_dtor(&retval);
4753 php_error_docref(NULL, E_WARNING, "Invocation of %s's constructor failed", ZSTR_VAL(ce->name));
4754 zval_dtor(return_value);
4755 RETURN_NULL();
4756 }
4757 } else if (argc) {
4758 zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ZSTR_VAL(ce->name));
4759 }
4760 }
4761
4762
4763
4764
4765 ZEND_METHOD(reflection_class, getInterfaces)
4766 {
4767 reflection_object *intern;
4768 zend_class_entry *ce;
4769
4770 if (zend_parse_parameters_none() == FAILURE) {
4771 return;
4772 }
4773 GET_REFLECTION_OBJECT_PTR(ce);
4774
4775
4776 array_init(return_value);
4777
4778 if (ce->num_interfaces) {
4779 uint32_t i;
4780
4781 for (i=0; i < ce->num_interfaces; i++) {
4782 zval interface;
4783 zend_reflection_class_factory(ce->interfaces[i], &interface);
4784 zend_hash_update(Z_ARRVAL_P(return_value), ce->interfaces[i]->name, &interface);
4785 }
4786 }
4787 }
4788
4789
4790
4791
4792 ZEND_METHOD(reflection_class, getInterfaceNames)
4793 {
4794 reflection_object *intern;
4795 zend_class_entry *ce;
4796 uint32_t i;
4797
4798 if (zend_parse_parameters_none() == FAILURE) {
4799 return;
4800 }
4801 GET_REFLECTION_OBJECT_PTR(ce);
4802
4803
4804 array_init(return_value);
4805
4806 for (i=0; i < ce->num_interfaces; i++) {
4807 add_next_index_str(return_value, zend_string_copy(ce->interfaces[i]->name));
4808 }
4809 }
4810
4811
4812
4813
4814 ZEND_METHOD(reflection_class, getTraits)
4815 {
4816 reflection_object *intern;
4817 zend_class_entry *ce;
4818 uint32_t i;
4819
4820 if (zend_parse_parameters_none() == FAILURE) {
4821 return;
4822 }
4823 GET_REFLECTION_OBJECT_PTR(ce);
4824
4825 array_init(return_value);
4826
4827 for (i=0; i < ce->num_traits; i++) {
4828 zval trait;
4829 zend_reflection_class_factory(ce->traits[i], &trait);
4830 zend_hash_update(Z_ARRVAL_P(return_value), ce->traits[i]->name, &trait);
4831 }
4832 }
4833
4834
4835
4836
4837 ZEND_METHOD(reflection_class, getTraitNames)
4838 {
4839 reflection_object *intern;
4840 zend_class_entry *ce;
4841 uint32_t i;
4842
4843 if (zend_parse_parameters_none() == FAILURE) {
4844 return;
4845 }
4846 GET_REFLECTION_OBJECT_PTR(ce);
4847
4848 array_init(return_value);
4849
4850 for (i=0; i < ce->num_traits; i++) {
4851 add_next_index_str(return_value, zend_string_copy(ce->traits[i]->name));
4852 }
4853 }
4854
4855
4856
4857
4858 ZEND_METHOD(reflection_class, getTraitAliases)
4859 {
4860 reflection_object *intern;
4861 zend_class_entry *ce;
4862
4863 if (zend_parse_parameters_none() == FAILURE) {
4864 return;
4865 }
4866 GET_REFLECTION_OBJECT_PTR(ce);
4867
4868 array_init(return_value);
4869
4870 if (ce->trait_aliases) {
4871 uint32_t i = 0;
4872 while (ce->trait_aliases[i]) {
4873 zend_string *mname;
4874 zend_trait_method_reference *cur_ref = ce->trait_aliases[i]->trait_method;
4875
4876 if (ce->trait_aliases[i]->alias) {
4877
4878 mname = zend_string_alloc(ZSTR_LEN(cur_ref->ce->name) + ZSTR_LEN(cur_ref->method_name) + 2, 0);
4879 snprintf(ZSTR_VAL(mname), ZSTR_LEN(mname) + 1, "%s::%s", ZSTR_VAL(cur_ref->ce->name), ZSTR_VAL(cur_ref->method_name));
4880 add_assoc_str_ex(return_value, ZSTR_VAL(ce->trait_aliases[i]->alias), ZSTR_LEN(ce->trait_aliases[i]->alias), mname);
4881 }
4882 i++;
4883 }
4884 }
4885 }
4886
4887
4888
4889
4890 ZEND_METHOD(reflection_class, getParentClass)
4891 {
4892 reflection_object *intern;
4893 zend_class_entry *ce;
4894
4895 if (zend_parse_parameters_none() == FAILURE) {
4896 return;
4897 }
4898 GET_REFLECTION_OBJECT_PTR(ce);
4899
4900 if (ce->parent) {
4901 zend_reflection_class_factory(ce->parent, return_value);
4902 } else {
4903 RETURN_FALSE;
4904 }
4905 }
4906
4907
4908
4909
4910 ZEND_METHOD(reflection_class, isSubclassOf)
4911 {
4912 reflection_object *intern, *argument;
4913 zend_class_entry *ce, *class_ce;
4914 zval *class_name;
4915
4916 METHOD_NOTSTATIC(reflection_class_ptr);
4917 GET_REFLECTION_OBJECT_PTR(ce);
4918
4919 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &class_name) == FAILURE) {
4920 return;
4921 }
4922
4923 switch (Z_TYPE_P(class_name)) {
4924 case IS_STRING:
4925 if ((class_ce = zend_lookup_class(Z_STR_P(class_name))) == NULL) {
4926 zend_throw_exception_ex(reflection_exception_ptr, 0,
4927 "Class %s does not exist", Z_STRVAL_P(class_name));
4928 return;
4929 }
4930 break;
4931 case IS_OBJECT:
4932 if (instanceof_function(Z_OBJCE_P(class_name), reflection_class_ptr)) {
4933 argument = Z_REFLECTION_P(class_name);
4934 if (argument == NULL || argument->ptr == NULL) {
4935 php_error_docref(NULL, E_ERROR, "Internal error: Failed to retrieve the argument's reflection object");
4936
4937 }
4938 class_ce = argument->ptr;
4939 break;
4940 }
4941
4942 default:
4943 zend_throw_exception_ex(reflection_exception_ptr, 0,
4944 "Parameter one must either be a string or a ReflectionClass object");
4945 return;
4946 }
4947
4948 RETURN_BOOL((ce != class_ce && instanceof_function(ce, class_ce)));
4949 }
4950
4951
4952
4953
4954 ZEND_METHOD(reflection_class, implementsInterface)
4955 {
4956 reflection_object *intern, *argument;
4957 zend_class_entry *ce, *interface_ce;
4958 zval *interface;
4959
4960 METHOD_NOTSTATIC(reflection_class_ptr);
4961 GET_REFLECTION_OBJECT_PTR(ce);
4962
4963 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &interface) == FAILURE) {
4964 return;
4965 }
4966
4967 switch (Z_TYPE_P(interface)) {
4968 case IS_STRING:
4969 if ((interface_ce = zend_lookup_class(Z_STR_P(interface))) == NULL) {
4970 zend_throw_exception_ex(reflection_exception_ptr, 0,
4971 "Interface %s does not exist", Z_STRVAL_P(interface));
4972 return;
4973 }
4974 break;
4975 case IS_OBJECT:
4976 if (instanceof_function(Z_OBJCE_P(interface), reflection_class_ptr)) {
4977 argument = Z_REFLECTION_P(interface);
4978 if (argument == NULL || argument->ptr == NULL) {
4979 php_error_docref(NULL, E_ERROR, "Internal error: Failed to retrieve the argument's reflection object");
4980
4981 }
4982 interface_ce = argument->ptr;
4983 break;
4984 }
4985
4986 default:
4987 zend_throw_exception_ex(reflection_exception_ptr, 0,
4988 "Parameter one must either be a string or a ReflectionClass object");
4989 return;
4990 }
4991
4992 if (!(interface_ce->ce_flags & ZEND_ACC_INTERFACE)) {
4993 zend_throw_exception_ex(reflection_exception_ptr, 0,
4994 "Interface %s is a Class", ZSTR_VAL(interface_ce->name));
4995 return;
4996 }
4997 RETURN_BOOL(instanceof_function(ce, interface_ce));
4998 }
4999
5000
5001
5002
5003 ZEND_METHOD(reflection_class, isIterateable)
5004 {
5005 reflection_object *intern;
5006 zend_class_entry *ce;
5007
5008 if (zend_parse_parameters_none() == FAILURE) {
5009 return;
5010 }
5011
5012 METHOD_NOTSTATIC(reflection_class_ptr);
5013 GET_REFLECTION_OBJECT_PTR(ce);
5014
5015 RETURN_BOOL(ce->get_iterator != NULL);
5016 }
5017
5018
5019
5020
5021 ZEND_METHOD(reflection_class, getExtension)
5022 {
5023 reflection_object *intern;
5024 zend_class_entry *ce;
5025
5026 if (zend_parse_parameters_none() == FAILURE) {
5027 return;
5028 }
5029
5030 METHOD_NOTSTATIC(reflection_class_ptr);
5031 GET_REFLECTION_OBJECT_PTR(ce);
5032
5033 if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module) {
5034 reflection_extension_factory(return_value, ce->info.internal.module->name);
5035 }
5036 }
5037
5038
5039
5040
5041 ZEND_METHOD(reflection_class, getExtensionName)
5042 {
5043 reflection_object *intern;
5044 zend_class_entry *ce;
5045
5046 if (zend_parse_parameters_none() == FAILURE) {
5047 return;
5048 }
5049
5050 METHOD_NOTSTATIC(reflection_class_ptr);
5051 GET_REFLECTION_OBJECT_PTR(ce);
5052
5053 if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module) {
5054 RETURN_STRING(ce->info.internal.module->name);
5055 } else {
5056 RETURN_FALSE;
5057 }
5058 }
5059
5060
5061
5062
5063 ZEND_METHOD(reflection_class, inNamespace)
5064 {
5065 zval *name;
5066 const char *backslash;
5067
5068 if (zend_parse_parameters_none() == FAILURE) {
5069 return;
5070 }
5071 if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1)) == NULL) {
5072 RETURN_FALSE;
5073 }
5074 if (Z_TYPE_P(name) == IS_STRING
5075 && (backslash = zend_memrchr(Z_STRVAL_P(name), '\\', Z_STRLEN_P(name)))
5076 && backslash > Z_STRVAL_P(name))
5077 {
5078 RETURN_TRUE;
5079 }
5080 RETURN_FALSE;
5081 }
5082
5083
5084
5085
5086 ZEND_METHOD(reflection_class, getNamespaceName)
5087 {
5088 zval *name;
5089 const char *backslash;
5090
5091 if (zend_parse_parameters_none() == FAILURE) {
5092 return;
5093 }
5094 if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1)) == NULL) {
5095 RETURN_FALSE;
5096 }
5097 if (Z_TYPE_P(name) == IS_STRING
5098 && (backslash = zend_memrchr(Z_STRVAL_P(name), '\\', Z_STRLEN_P(name)))
5099 && backslash > Z_STRVAL_P(name))
5100 {
5101 RETURN_STRINGL(Z_STRVAL_P(name), backslash - Z_STRVAL_P(name));
5102 }
5103 RETURN_EMPTY_STRING();
5104 }
5105
5106
5107
5108
5109 ZEND_METHOD(reflection_class, getShortName)
5110 {
5111 zval *name;
5112 const char *backslash;
5113
5114 if (zend_parse_parameters_none() == FAILURE) {
5115 return;
5116 }
5117 if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1)) == NULL) {
5118 RETURN_FALSE;
5119 }
5120 if (Z_TYPE_P(name) == IS_STRING
5121 && (backslash = zend_memrchr(Z_STRVAL_P(name), '\\', Z_STRLEN_P(name)))
5122 && backslash > Z_STRVAL_P(name))
5123 {
5124 RETURN_STRINGL(backslash + 1, Z_STRLEN_P(name) - (backslash - Z_STRVAL_P(name) + 1));
5125 }
5126 ZVAL_DEREF(name);
5127 ZVAL_COPY(return_value, name);
5128 }
5129
5130
5131
5132
5133 ZEND_METHOD(reflection_object, export)
5134 {
5135 _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_object_ptr, 1);
5136 }
5137
5138
5139
5140
5141 ZEND_METHOD(reflection_object, __construct)
5142 {
5143 reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
5144 }
5145
5146
5147
5148
5149 ZEND_METHOD(reflection_property, export)
5150 {
5151 _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_property_ptr, 2);
5152 }
5153
5154
5155
5156
5157 ZEND_METHOD(reflection_property, __construct)
5158 {
5159 zval propname, cname, *classname;
5160 char *name_str;
5161 size_t name_len;
5162 int dynam_prop = 0;
5163 zval *object;
5164 reflection_object *intern;
5165 zend_class_entry *ce;
5166 zend_property_info *property_info = NULL;
5167 property_reference *reference;
5168
5169 if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "zs", &classname, &name_str, &name_len) == FAILURE) {
5170 return;
5171 }
5172
5173 object = getThis();
5174 intern = Z_REFLECTION_P(object);
5175
5176
5177 switch (Z_TYPE_P(classname)) {
5178 case IS_STRING:
5179 if ((ce = zend_lookup_class(Z_STR_P(classname))) == NULL) {
5180 zend_throw_exception_ex(reflection_exception_ptr, 0,
5181 "Class %s does not exist", Z_STRVAL_P(classname));
5182 return;
5183 }
5184 break;
5185
5186 case IS_OBJECT:
5187 ce = Z_OBJCE_P(classname);
5188 break;
5189
5190 default:
5191 _DO_THROW("The parameter class is expected to be either a string or an object");
5192
5193 }
5194
5195 if ((property_info = zend_hash_str_find_ptr(&ce->properties_info, name_str, name_len)) == NULL || (property_info->flags & ZEND_ACC_SHADOW)) {
5196
5197 if (property_info == NULL && Z_TYPE_P(classname) == IS_OBJECT && Z_OBJ_HT_P(classname)->get_properties) {
5198 if (zend_hash_str_exists(Z_OBJ_HT_P(classname)->get_properties(classname), name_str, name_len)) {
5199 dynam_prop = 1;
5200 }
5201 }
5202 if (dynam_prop == 0) {
5203 zend_throw_exception_ex(reflection_exception_ptr, 0, "Property %s::$%s does not exist", ZSTR_VAL(ce->name), name_str);
5204 return;
5205 }
5206 }
5207
5208 if (dynam_prop == 0 && (property_info->flags & ZEND_ACC_PRIVATE) == 0) {
5209
5210 zend_class_entry *tmp_ce = ce;
5211 zend_property_info *tmp_info;
5212
5213 while (tmp_ce && (tmp_info = zend_hash_str_find_ptr(&tmp_ce->properties_info, name_str, name_len)) == NULL) {
5214 ce = tmp_ce;
5215 property_info = tmp_info;
5216 tmp_ce = tmp_ce->parent;
5217 }
5218 }
5219
5220 if (dynam_prop == 0) {
5221 const char *class_name, *prop_name;
5222 size_t prop_name_len;
5223 zend_unmangle_property_name_ex(property_info->name, &class_name, &prop_name, &prop_name_len);
5224 ZVAL_STR_COPY(&cname, property_info->ce->name);
5225 ZVAL_STRINGL(&propname, prop_name, prop_name_len);
5226 } else {
5227 ZVAL_STR_COPY(&cname, ce->name);
5228 ZVAL_STRINGL(&propname, name_str, name_len);
5229 }
5230 reflection_update_property(object, "class", &cname);
5231 reflection_update_property(object, "name", &propname);
5232
5233 reference = (property_reference*) emalloc(sizeof(property_reference));
5234 if (dynam_prop) {
5235 reference->prop.flags = ZEND_ACC_IMPLICIT_PUBLIC;
5236 reference->prop.name = Z_STR(propname);
5237 reference->prop.doc_comment = NULL;
5238 reference->prop.ce = ce;
5239 } else {
5240 reference->prop = *property_info;
5241 }
5242 reference->ce = ce;
5243 intern->ptr = reference;
5244 intern->ref_type = REF_TYPE_PROPERTY;
5245 intern->ce = ce;
5246 intern->ignore_visibility = 0;
5247 }
5248
5249
5250
5251
5252 ZEND_METHOD(reflection_property, __toString)
5253 {
5254 reflection_object *intern;
5255 property_reference *ref;
5256 string str;
5257
5258 if (zend_parse_parameters_none() == FAILURE) {
5259 return;
5260 }
5261 GET_REFLECTION_OBJECT_PTR(ref);
5262 string_init(&str);
5263 _property_string(&str, &ref->prop, NULL, "");
5264 RETURN_NEW_STR(str.buf);
5265 }
5266
5267
5268
5269
5270 ZEND_METHOD(reflection_property, getName)
5271 {
5272 if (zend_parse_parameters_none() == FAILURE) {
5273 return;
5274 }
5275 _default_get_entry(getThis(), "name", sizeof("name")-1, return_value);
5276 }
5277
5278
5279 static void _property_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
5280 {
5281 reflection_object *intern;
5282 property_reference *ref;
5283
5284 if (zend_parse_parameters_none() == FAILURE) {
5285 return;
5286 }
5287 GET_REFLECTION_OBJECT_PTR(ref);
5288 RETURN_BOOL(ref->prop.flags & mask);
5289 }
5290
5291
5292
5293
5294 ZEND_METHOD(reflection_property, isPublic)
5295 {
5296 _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC);
5297 }
5298
5299
5300
5301
5302 ZEND_METHOD(reflection_property, isPrivate)
5303 {
5304 _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
5305 }
5306
5307
5308
5309
5310 ZEND_METHOD(reflection_property, isProtected)
5311 {
5312 _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
5313 }
5314
5315
5316
5317
5318 ZEND_METHOD(reflection_property, isStatic)
5319 {
5320 _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC);
5321 }
5322
5323
5324
5325
5326 ZEND_METHOD(reflection_property, isDefault)
5327 {
5328 _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ~ZEND_ACC_IMPLICIT_PUBLIC);
5329 }
5330
5331
5332
5333
5334 ZEND_METHOD(reflection_property, getModifiers)
5335 {
5336 reflection_object *intern;
5337 property_reference *ref;
5338
5339 if (zend_parse_parameters_none() == FAILURE) {
5340 return;
5341 }
5342 GET_REFLECTION_OBJECT_PTR(ref);
5343
5344 RETURN_LONG(ref->prop.flags);
5345 }
5346
5347
5348
5349
5350 ZEND_METHOD(reflection_property, getValue)
5351 {
5352 reflection_object *intern;
5353 property_reference *ref;
5354 zval *object, *name;
5355 zval *member_p = NULL;
5356
5357 METHOD_NOTSTATIC(reflection_property_ptr);
5358 GET_REFLECTION_OBJECT_PTR(ref);
5359
5360 if (!(ref->prop.flags & (ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC)) && intern->ignore_visibility == 0) {
5361 name = _default_load_entry(getThis(), "name", sizeof("name")-1);
5362 zend_throw_exception_ex(reflection_exception_ptr, 0,
5363 "Cannot access non-public member %s::%s", ZSTR_VAL(intern->ce->name), Z_STRVAL_P(name));
5364 return;
5365 }
5366
5367 if ((ref->prop.flags & ZEND_ACC_STATIC)) {
5368 if (UNEXPECTED(zend_update_class_constants(intern->ce) != SUCCESS)) {
5369 return;
5370 }
5371 if (Z_TYPE(CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]) == IS_UNDEF) {
5372 php_error_docref(NULL, E_ERROR, "Internal error: Could not find the property %s::%s", ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->prop.name));
5373
5374 }
5375 ZVAL_DUP(return_value, &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]);
5376 } else {
5377 const char *class_name, *prop_name;
5378 size_t prop_name_len;
5379 zval rv;
5380
5381 if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &object) == FAILURE) {
5382 return;
5383 }
5384
5385 zend_unmangle_property_name_ex(ref->prop.name, &class_name, &prop_name, &prop_name_len);
5386 member_p = zend_read_property(ref->ce, object, prop_name, prop_name_len, 1, &rv);
5387 ZVAL_DUP(return_value, member_p);
5388 }
5389 }
5390
5391
5392
5393
5394 ZEND_METHOD(reflection_property, setValue)
5395 {
5396 reflection_object *intern;
5397 property_reference *ref;
5398 zval *variable_ptr;
5399 zval *object, *name;
5400 zval *value;
5401 zval *tmp;
5402
5403 METHOD_NOTSTATIC(reflection_property_ptr);
5404 GET_REFLECTION_OBJECT_PTR(ref);
5405
5406 if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
5407 name = _default_load_entry(getThis(), "name", sizeof("name")-1);
5408 zend_throw_exception_ex(reflection_exception_ptr, 0,
5409 "Cannot access non-public member %s::%s", ZSTR_VAL(intern->ce->name), Z_STRVAL_P(name));
5410 return;
5411 }
5412
5413 if ((ref->prop.flags & ZEND_ACC_STATIC)) {
5414 if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z", &value) == FAILURE) {
5415 if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &tmp, &value) == FAILURE) {
5416 return;
5417 }
5418 }
5419 if (UNEXPECTED(zend_update_class_constants(intern->ce) != SUCCESS)) {
5420 return;
5421 }
5422
5423 if (Z_TYPE(CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]) == IS_UNDEF) {
5424 php_error_docref(NULL, E_ERROR, "Internal error: Could not find the property %s::%s", ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->prop.name));
5425
5426 }
5427 variable_ptr = &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset];
5428 if (variable_ptr != value) {
5429 zval garbage;
5430
5431 ZVAL_DEREF(variable_ptr);
5432 ZVAL_DEREF(value);
5433
5434 ZVAL_COPY_VALUE(&garbage, variable_ptr);
5435
5436 ZVAL_COPY(variable_ptr, value);
5437
5438 zval_ptr_dtor(&garbage);
5439 }
5440 } else {
5441 const char *class_name, *prop_name;
5442 size_t prop_name_len;
5443
5444 if (zend_parse_parameters(ZEND_NUM_ARGS(), "oz", &object, &value) == FAILURE) {
5445 return;
5446 }
5447
5448 zend_unmangle_property_name_ex(ref->prop.name, &class_name, &prop_name, &prop_name_len);
5449 zend_update_property(ref->ce, object, prop_name, prop_name_len, value);
5450 }
5451 }
5452
5453
5454
5455
5456 ZEND_METHOD(reflection_property, getDeclaringClass)
5457 {
5458 reflection_object *intern;
5459 property_reference *ref;
5460 zend_class_entry *tmp_ce, *ce;
5461 zend_property_info *tmp_info;
5462 const char *prop_name, *class_name;
5463 size_t prop_name_len;
5464
5465 if (zend_parse_parameters_none() == FAILURE) {
5466 return;
5467 }
5468 GET_REFLECTION_OBJECT_PTR(ref);
5469
5470 if (zend_unmangle_property_name_ex(ref->prop.name, &class_name, &prop_name, &prop_name_len) != SUCCESS) {
5471 RETURN_FALSE;
5472 }
5473
5474 ce = tmp_ce = ref->ce;
5475 while (tmp_ce && (tmp_info = zend_hash_str_find_ptr(&tmp_ce->properties_info, prop_name, prop_name_len)) != NULL) {
5476 if (tmp_info->flags & ZEND_ACC_PRIVATE || tmp_info->flags & ZEND_ACC_SHADOW) {
5477
5478 break;
5479 }
5480 ce = tmp_ce;
5481 if (tmp_ce == tmp_info->ce) {
5482
5483 break;
5484 }
5485 tmp_ce = tmp_ce->parent;
5486 }
5487
5488 zend_reflection_class_factory(ce, return_value);
5489 }
5490
5491
5492
5493
5494 ZEND_METHOD(reflection_property, getDocComment)
5495 {
5496 reflection_object *intern;
5497 property_reference *ref;
5498
5499 if (zend_parse_parameters_none() == FAILURE) {
5500 return;
5501 }
5502 GET_REFLECTION_OBJECT_PTR(ref);
5503 if (ref->prop.doc_comment) {
5504 RETURN_STR_COPY(ref->prop.doc_comment);
5505 }
5506 RETURN_FALSE;
5507 }
5508
5509
5510
5511
5512 ZEND_METHOD(reflection_property, setAccessible)
5513 {
5514 reflection_object *intern;
5515 zend_bool visible;
5516
5517 if (zend_parse_parameters(ZEND_NUM_ARGS(), "b", &visible) == FAILURE) {
5518 return;
5519 }
5520
5521 intern = Z_REFLECTION_P(getThis());
5522
5523 intern->ignore_visibility = visible;
5524 }
5525
5526
5527
5528
5529 ZEND_METHOD(reflection_extension, export)
5530 {
5531 _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_extension_ptr, 1);
5532 }
5533
5534
5535
5536
5537 ZEND_METHOD(reflection_extension, __construct)
5538 {
5539 zval name;
5540 zval *object;
5541 char *lcname;
5542 reflection_object *intern;
5543 zend_module_entry *module;
5544 char *name_str;
5545 size_t name_len;
5546 ALLOCA_FLAG(use_heap)
5547
5548 if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s", &name_str, &name_len) == FAILURE) {
5549 return;
5550 }
5551
5552 object = getThis();
5553 intern = Z_REFLECTION_P(object);
5554
5555 lcname = do_alloca(name_len + 1, use_heap);
5556 zend_str_tolower_copy(lcname, name_str, name_len);
5557 if ((module = zend_hash_str_find_ptr(&module_registry, lcname, name_len)) == NULL) {
5558 free_alloca(lcname, use_heap);
5559 zend_throw_exception_ex(reflection_exception_ptr, 0,
5560 "Extension %s does not exist", name_str);
5561 return;
5562 }
5563 free_alloca(lcname, use_heap);
5564 ZVAL_STRING(&name, module->name);
5565 reflection_update_property(object, "name", &name);
5566 intern->ptr = module;
5567 intern->ref_type = REF_TYPE_OTHER;
5568 intern->ce = NULL;
5569 }
5570
5571
5572
5573
5574 ZEND_METHOD(reflection_extension, __toString)
5575 {
5576 reflection_object *intern;
5577 zend_module_entry *module;
5578 string str;
5579
5580 if (zend_parse_parameters_none() == FAILURE) {
5581 return;
5582 }
5583 GET_REFLECTION_OBJECT_PTR(module);
5584 string_init(&str);
5585 _extension_string(&str, module, "");
5586 RETURN_NEW_STR(str.buf);
5587 }
5588
5589
5590
5591
5592 ZEND_METHOD(reflection_extension, getName)
5593 {
5594 if (zend_parse_parameters_none() == FAILURE) {
5595 return;
5596 }
5597 _default_get_entry(getThis(), "name", sizeof("name")-1, return_value);
5598 }
5599
5600
5601
5602
5603 ZEND_METHOD(reflection_extension, getVersion)
5604 {
5605 reflection_object *intern;
5606 zend_module_entry *module;
5607
5608 if (zend_parse_parameters_none() == FAILURE) {
5609 return;
5610 }
5611 GET_REFLECTION_OBJECT_PTR(module);
5612
5613
5614 if (module->version == NO_VERSION_YET) {
5615 RETURN_NULL();
5616 } else {
5617 RETURN_STRING(module->version);
5618 }
5619 }
5620
5621
5622
5623
5624 ZEND_METHOD(reflection_extension, getFunctions)
5625 {
5626 reflection_object *intern;
5627 zend_module_entry *module;
5628 zval function;
5629 zend_function *fptr;
5630
5631 if (zend_parse_parameters_none() == FAILURE) {
5632 return;
5633 }
5634 GET_REFLECTION_OBJECT_PTR(module);
5635
5636 array_init(return_value);
5637 ZEND_HASH_FOREACH_PTR(CG(function_table), fptr) {
5638 if (fptr->common.type==ZEND_INTERNAL_FUNCTION
5639 && fptr->internal_function.module == module) {
5640 reflection_function_factory(fptr, NULL, &function);
5641 zend_hash_update(Z_ARRVAL_P(return_value), fptr->common.function_name, &function);
5642 }
5643 } ZEND_HASH_FOREACH_END();
5644 }
5645
5646
5647 static int _addconstant(zval *el, int num_args, va_list args, zend_hash_key *hash_key)
5648 {
5649 zval const_val;
5650 zend_constant *constant = (zend_constant*)Z_PTR_P(el);
5651 zval *retval = va_arg(args, zval*);
5652 int number = va_arg(args, int);
5653
5654 if (number == constant->module_number) {
5655 ZVAL_DUP(&const_val, &constant->value);
5656 zend_hash_update(Z_ARRVAL_P(retval), constant->name, &const_val);
5657 }
5658 return 0;
5659 }
5660
5661
5662
5663
5664 ZEND_METHOD(reflection_extension, getConstants)
5665 {
5666 reflection_object *intern;
5667 zend_module_entry *module;
5668
5669 if (zend_parse_parameters_none() == FAILURE) {
5670 return;
5671 }
5672 GET_REFLECTION_OBJECT_PTR(module);
5673
5674 array_init(return_value);
5675 zend_hash_apply_with_arguments(EG(zend_constants), (apply_func_args_t) _addconstant, 2, return_value, module->module_number);
5676 }
5677
5678
5679
5680 static int _addinientry(zval *el, int num_args, va_list args, zend_hash_key *hash_key)
5681 {
5682 zend_ini_entry *ini_entry = (zend_ini_entry*)Z_PTR_P(el);
5683 zval *retval = va_arg(args, zval*);
5684 int number = va_arg(args, int);
5685
5686 if (number == ini_entry->module_number) {
5687 if (ini_entry->value) {
5688 zval zv;
5689
5690 ZVAL_STR_COPY(&zv, ini_entry->value);
5691 zend_symtable_update(Z_ARRVAL_P(retval), ini_entry->name, &zv);
5692 } else {
5693 zend_symtable_update(Z_ARRVAL_P(retval), ini_entry->name, &EG(uninitialized_zval));
5694 }
5695 }
5696 return ZEND_HASH_APPLY_KEEP;
5697 }
5698
5699
5700
5701
5702 ZEND_METHOD(reflection_extension, getINIEntries)
5703 {
5704 reflection_object *intern;
5705 zend_module_entry *module;
5706
5707 if (zend_parse_parameters_none() == FAILURE) {
5708 return;
5709 }
5710 GET_REFLECTION_OBJECT_PTR(module);
5711
5712 array_init(return_value);
5713 zend_hash_apply_with_arguments(EG(ini_directives), (apply_func_args_t) _addinientry, 2, return_value, module->module_number);
5714 }
5715
5716
5717
5718 static int add_extension_class(zval *zv, int num_args, va_list args, zend_hash_key *hash_key)
5719 {
5720 zend_class_entry *ce = Z_PTR_P(zv);
5721 zval *class_array = va_arg(args, zval*), zclass;
5722 struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
5723 int add_reflection_class = va_arg(args, int);
5724
5725 if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module && !strcasecmp(ce->info.internal.module->name, module->name)) {
5726 zend_string *name;
5727
5728 if (zend_binary_strcasecmp(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(hash_key->key), ZSTR_LEN(hash_key->key))) {
5729
5730 name = hash_key->key;
5731 } else {
5732
5733 name = ce->name;
5734 }
5735 if (add_reflection_class) {
5736 zend_reflection_class_factory(ce, &zclass);
5737 zend_hash_update(Z_ARRVAL_P(class_array), name, &zclass);
5738 } else {
5739 add_next_index_str(class_array, zend_string_copy(name));
5740 }
5741 }
5742 return ZEND_HASH_APPLY_KEEP;
5743 }
5744
5745
5746
5747
5748 ZEND_METHOD(reflection_extension, getClasses)
5749 {
5750 reflection_object *intern;
5751 zend_module_entry *module;
5752
5753 if (zend_parse_parameters_none() == FAILURE) {
5754 return;
5755 }
5756 GET_REFLECTION_OBJECT_PTR(module);
5757
5758 array_init(return_value);
5759 zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) add_extension_class, 3, return_value, module, 1);
5760 }
5761
5762
5763
5764
5765 ZEND_METHOD(reflection_extension, getClassNames)
5766 {
5767 reflection_object *intern;
5768 zend_module_entry *module;
5769
5770 if (zend_parse_parameters_none() == FAILURE) {
5771 return;
5772 }
5773 GET_REFLECTION_OBJECT_PTR(module);
5774
5775 array_init(return_value);
5776 zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) add_extension_class, 3, return_value, module, 0);
5777 }
5778
5779
5780
5781
5782 ZEND_METHOD(reflection_extension, getDependencies)
5783 {
5784 reflection_object *intern;
5785 zend_module_entry *module;
5786 const zend_module_dep *dep;
5787
5788 if (zend_parse_parameters_none() == FAILURE) {
5789 return;
5790 }
5791 GET_REFLECTION_OBJECT_PTR(module);
5792
5793 array_init(return_value);
5794
5795 dep = module->deps;
5796
5797 if (!dep)
5798 {
5799 return;
5800 }
5801
5802 while(dep->name) {
5803 zend_string *relation;
5804 char *rel_type;
5805 size_t len = 0;
5806
5807 switch(dep->type) {
5808 case MODULE_DEP_REQUIRED:
5809 rel_type = "Required";
5810 len += sizeof("Required") - 1;
5811 break;
5812 case MODULE_DEP_CONFLICTS:
5813 rel_type = "Conflicts";
5814 len += sizeof("Conflicts") - 1;
5815 break;
5816 case MODULE_DEP_OPTIONAL:
5817 rel_type = "Optional";
5818 len += sizeof("Optional") - 1;
5819 break;
5820 default:
5821 rel_type = "Error";
5822 len += sizeof("Error") - 1;
5823 break;
5824 }
5825
5826 if (dep->rel) {
5827 len += strlen(dep->rel) + 1;
5828 }
5829
5830 if (dep->version) {
5831 len += strlen(dep->version) + 1;
5832 }
5833
5834 relation = zend_string_alloc(len, 0);
5835 snprintf(ZSTR_VAL(relation), ZSTR_LEN(relation) + 1, "%s%s%s%s%s",
5836 rel_type,
5837 dep->rel ? " " : "",
5838 dep->rel ? dep->rel : "",
5839 dep->version ? " " : "",
5840 dep->version ? dep->version : "");
5841 add_assoc_str(return_value, dep->name, relation);
5842 dep++;
5843 }
5844 }
5845
5846
5847
5848
5849 ZEND_METHOD(reflection_extension, info)
5850 {
5851 reflection_object *intern;
5852 zend_module_entry *module;
5853
5854 if (zend_parse_parameters_none() == FAILURE) {
5855 return;
5856 }
5857 GET_REFLECTION_OBJECT_PTR(module);
5858
5859 php_info_print_module(module);
5860 }
5861
5862
5863
5864
5865 ZEND_METHOD(reflection_extension, isPersistent)
5866 {
5867 reflection_object *intern;
5868 zend_module_entry *module;
5869
5870 if (zend_parse_parameters_none() == FAILURE) {
5871 return;
5872 }
5873 GET_REFLECTION_OBJECT_PTR(module);
5874
5875 RETURN_BOOL(module->type == MODULE_PERSISTENT);
5876 }
5877
5878
5879
5880
5881 ZEND_METHOD(reflection_extension, isTemporary)
5882 {
5883 reflection_object *intern;
5884 zend_module_entry *module;
5885
5886 if (zend_parse_parameters_none() == FAILURE) {
5887 return;
5888 }
5889 GET_REFLECTION_OBJECT_PTR(module);
5890
5891 RETURN_BOOL(module->type == MODULE_TEMPORARY);
5892 }
5893
5894
5895
5896
5897 ZEND_METHOD(reflection_zend_extension, export)
5898 {
5899 _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_zend_extension_ptr, 1);
5900 }
5901
5902
5903
5904
5905 ZEND_METHOD(reflection_zend_extension, __construct)
5906 {
5907 zval name;
5908 zval *object;
5909 reflection_object *intern;
5910 zend_extension *extension;
5911 char *name_str;
5912 size_t name_len;
5913
5914 if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s", &name_str, &name_len) == FAILURE) {
5915 return;
5916 }
5917
5918 object = getThis();
5919 intern = Z_REFLECTION_P(object);
5920
5921 extension = zend_get_extension(name_str);
5922 if (!extension) {
5923 zend_throw_exception_ex(reflection_exception_ptr, 0,
5924 "Zend Extension %s does not exist", name_str);
5925 return;
5926 }
5927 ZVAL_STRING(&name, extension->name);
5928 reflection_update_property(object, "name", &name);
5929 intern->ptr = extension;
5930 intern->ref_type = REF_TYPE_OTHER;
5931 intern->ce = NULL;
5932 }
5933
5934
5935
5936
5937 ZEND_METHOD(reflection_zend_extension, __toString)
5938 {
5939 reflection_object *intern;
5940 zend_extension *extension;
5941 string str;
5942
5943 if (zend_parse_parameters_none() == FAILURE) {
5944 return;
5945 }
5946 GET_REFLECTION_OBJECT_PTR(extension);
5947 string_init(&str);
5948 _zend_extension_string(&str, extension, "");
5949 RETURN_NEW_STR(str.buf);
5950 }
5951
5952
5953
5954
5955 ZEND_METHOD(reflection_zend_extension, getName)
5956 {
5957 reflection_object *intern;
5958 zend_extension *extension;
5959
5960 if (zend_parse_parameters_none() == FAILURE) {
5961 return;
5962 }
5963 GET_REFLECTION_OBJECT_PTR(extension);
5964
5965 RETURN_STRING(extension->name);
5966 }
5967
5968
5969
5970
5971 ZEND_METHOD(reflection_zend_extension, getVersion)
5972 {
5973 reflection_object *intern;
5974 zend_extension *extension;
5975
5976 if (zend_parse_parameters_none() == FAILURE) {
5977 return;
5978 }
5979 GET_REFLECTION_OBJECT_PTR(extension);
5980
5981 if (extension->version) {
5982 RETURN_STRING(extension->version);
5983 } else {
5984 RETURN_EMPTY_STRING();
5985 }
5986 }
5987
5988
5989
5990
5991 ZEND_METHOD(reflection_zend_extension, getAuthor)
5992 {
5993 reflection_object *intern;
5994 zend_extension *extension;
5995
5996 if (zend_parse_parameters_none() == FAILURE) {
5997 return;
5998 }
5999 GET_REFLECTION_OBJECT_PTR(extension);
6000
6001 if (extension->author) {
6002 RETURN_STRING(extension->author);
6003 } else {
6004 RETURN_EMPTY_STRING();
6005 }
6006 }
6007
6008
6009
6010
6011 ZEND_METHOD(reflection_zend_extension, getURL)
6012 {
6013 reflection_object *intern;
6014 zend_extension *extension;
6015
6016 if (zend_parse_parameters_none() == FAILURE) {
6017 return;
6018 }
6019 GET_REFLECTION_OBJECT_PTR(extension);
6020
6021 if (extension->URL) {
6022 RETURN_STRING(extension->URL);
6023 } else {
6024 RETURN_EMPTY_STRING();
6025 }
6026 }
6027
6028
6029
6030
6031 ZEND_METHOD(reflection_zend_extension, getCopyright)
6032 {
6033 reflection_object *intern;
6034 zend_extension *extension;
6035
6036 if (zend_parse_parameters_none() == FAILURE) {
6037 return;
6038 }
6039 GET_REFLECTION_OBJECT_PTR(extension);
6040
6041 if (extension->copyright) {
6042 RETURN_STRING(extension->copyright);
6043 } else {
6044 RETURN_EMPTY_STRING();
6045 }
6046 }
6047
6048
6049
6050 static const zend_function_entry reflection_exception_functions[] = {
6051 PHP_FE_END
6052 };
6053
6054 ZEND_BEGIN_ARG_INFO(arginfo_reflection__void, 0)
6055 ZEND_END_ARG_INFO()
6056
6057
6058 ZEND_BEGIN_ARG_INFO(arginfo_reflection_getModifierNames, 0)
6059 ZEND_ARG_INFO(0, modifiers)
6060 ZEND_END_ARG_INFO()
6061
6062 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_export, 0, 0, 1)
6063 ZEND_ARG_OBJ_INFO(0, reflector, Reflector, 0)
6064 ZEND_ARG_INFO(0, return)
6065 ZEND_END_ARG_INFO()
6066
6067 static const zend_function_entry reflection_functions[] = {
6068 ZEND_ME(reflection, getModifierNames, arginfo_reflection_getModifierNames, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
6069 ZEND_ME(reflection, export, arginfo_reflection_export, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
6070 PHP_FE_END
6071 };
6072
6073 static const zend_function_entry reflector_functions[] = {
6074 ZEND_FENTRY(export, NULL, NULL, ZEND_ACC_STATIC|ZEND_ACC_ABSTRACT|ZEND_ACC_PUBLIC)
6075 ZEND_ABSTRACT_ME(reflector, __toString, arginfo_reflection__void)
6076 PHP_FE_END
6077 };
6078
6079 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_export, 0, 0, 1)
6080 ZEND_ARG_INFO(0, name)
6081 ZEND_ARG_INFO(0, return)
6082 ZEND_END_ARG_INFO()
6083
6084 ZEND_BEGIN_ARG_INFO(arginfo_reflection_function___construct, 0)
6085 ZEND_ARG_INFO(0, name)
6086 ZEND_END_ARG_INFO()
6087
6088 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_invoke, 0, 0, 0)
6089 ZEND_ARG_INFO(0, args)
6090 ZEND_END_ARG_INFO()
6091
6092 ZEND_BEGIN_ARG_INFO(arginfo_reflection_function_invokeArgs, 0)
6093 ZEND_ARG_ARRAY_INFO(0, args, 0)
6094 ZEND_END_ARG_INFO()
6095
6096 static const zend_function_entry reflection_function_abstract_functions[] = {
6097 ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
6098 ZEND_ME(reflection_function, inNamespace, arginfo_reflection__void, 0)
6099 ZEND_ME(reflection_function, isClosure, arginfo_reflection__void, 0)
6100 ZEND_ME(reflection_function, isDeprecated, arginfo_reflection__void, 0)
6101 ZEND_ME(reflection_function, isInternal, arginfo_reflection__void, 0)
6102 ZEND_ME(reflection_function, isUserDefined, arginfo_reflection__void, 0)
6103 ZEND_ME(reflection_function, isGenerator, arginfo_reflection__void, 0)
6104 ZEND_ME(reflection_function, isVariadic, arginfo_reflection__void, 0)
6105 ZEND_ME(reflection_function, getClosureThis, arginfo_reflection__void, 0)
6106 ZEND_ME(reflection_function, getClosureScopeClass, arginfo_reflection__void, 0)
6107 ZEND_ME(reflection_function, getDocComment, arginfo_reflection__void, 0)
6108 ZEND_ME(reflection_function, getEndLine, arginfo_reflection__void, 0)
6109 ZEND_ME(reflection_function, getExtension, arginfo_reflection__void, 0)
6110 ZEND_ME(reflection_function, getExtensionName, arginfo_reflection__void, 0)
6111 ZEND_ME(reflection_function, getFileName, arginfo_reflection__void, 0)
6112 ZEND_ME(reflection_function, getName, arginfo_reflection__void, 0)
6113 ZEND_ME(reflection_function, getNamespaceName, arginfo_reflection__void, 0)
6114 ZEND_ME(reflection_function, getNumberOfParameters, arginfo_reflection__void, 0)
6115 ZEND_ME(reflection_function, getNumberOfRequiredParameters, arginfo_reflection__void, 0)
6116 ZEND_ME(reflection_function, getParameters, arginfo_reflection__void, 0)
6117 ZEND_ME(reflection_function, getShortName, arginfo_reflection__void, 0)
6118 ZEND_ME(reflection_function, getStartLine, arginfo_reflection__void, 0)
6119 ZEND_ME(reflection_function, getStaticVariables, arginfo_reflection__void, 0)
6120 ZEND_ME(reflection_function, returnsReference, arginfo_reflection__void, 0)
6121 ZEND_ME(reflection_function, hasReturnType, arginfo_reflection__void, 0)
6122 ZEND_ME(reflection_function, getReturnType, arginfo_reflection__void, 0)
6123 PHP_FE_END
6124 };
6125
6126 static const zend_function_entry reflection_function_functions[] = {
6127 ZEND_ME(reflection_function, __construct, arginfo_reflection_function___construct, 0)
6128 ZEND_ME(reflection_function, __toString, arginfo_reflection__void, 0)
6129 ZEND_ME(reflection_function, export, arginfo_reflection_function_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
6130 ZEND_ME(reflection_function, isDisabled, arginfo_reflection__void, 0)
6131 ZEND_ME(reflection_function, invoke, arginfo_reflection_function_invoke, 0)
6132 ZEND_ME(reflection_function, invokeArgs, arginfo_reflection_function_invokeArgs, 0)
6133 ZEND_ME(reflection_function, getClosure, arginfo_reflection__void, 0)
6134 PHP_FE_END
6135 };
6136
6137 ZEND_BEGIN_ARG_INFO(arginfo_reflection_generator___construct, 0)
6138 ZEND_ARG_INFO(0, generator)
6139 ZEND_END_ARG_INFO()
6140
6141 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_generator_trace, 0, 0, 0)
6142 ZEND_ARG_INFO(0, options)
6143 ZEND_END_ARG_INFO()
6144
6145 static const zend_function_entry reflection_generator_functions[] = {
6146 ZEND_ME(reflection_generator, __construct, arginfo_reflection_generator___construct, 0)
6147 ZEND_ME(reflection_generator, getExecutingLine, arginfo_reflection__void, 0)
6148 ZEND_ME(reflection_generator, getExecutingFile, arginfo_reflection__void, 0)
6149 ZEND_ME(reflection_generator, getTrace, arginfo_reflection_generator_trace, 0)
6150 ZEND_ME(reflection_generator, getFunction, arginfo_reflection__void, 0)
6151 ZEND_ME(reflection_generator, getThis, arginfo_reflection__void, 0)
6152 ZEND_ME(reflection_generator, getExecutingGenerator, arginfo_reflection__void, 0)
6153 PHP_FE_END
6154 };
6155
6156 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method_export, 0, 0, 2)
6157 ZEND_ARG_INFO(0, class)
6158 ZEND_ARG_INFO(0, name)
6159 ZEND_ARG_INFO(0, return)
6160 ZEND_END_ARG_INFO()
6161
6162 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method___construct, 0, 0, 1)
6163 ZEND_ARG_INFO(0, class_or_method)
6164 ZEND_ARG_INFO(0, name)
6165 ZEND_END_ARG_INFO()
6166
6167 ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invoke, 0)
6168 ZEND_ARG_INFO(0, object)
6169 ZEND_ARG_INFO(0, args)
6170 ZEND_END_ARG_INFO()
6171
6172 ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invokeArgs, 0)
6173 ZEND_ARG_INFO(0, object)
6174 ZEND_ARG_ARRAY_INFO(0, args, 0)
6175 ZEND_END_ARG_INFO()
6176
6177 ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_setAccessible, 0)
6178 ZEND_ARG_INFO(0, value)
6179 ZEND_END_ARG_INFO()
6180
6181 ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_getClosure, 0)
6182 ZEND_ARG_INFO(0, object)
6183 ZEND_END_ARG_INFO()
6184
6185 static const zend_function_entry reflection_method_functions[] = {
6186 ZEND_ME(reflection_method, export, arginfo_reflection_method_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
6187 ZEND_ME(reflection_method, __construct, arginfo_reflection_method___construct, 0)
6188 ZEND_ME(reflection_method, __toString, arginfo_reflection__void, 0)
6189 ZEND_ME(reflection_method, isPublic, arginfo_reflection__void, 0)
6190 ZEND_ME(reflection_method, isPrivate, arginfo_reflection__void, 0)
6191 ZEND_ME(reflection_method, isProtected, arginfo_reflection__void, 0)
6192 ZEND_ME(reflection_method, isAbstract, arginfo_reflection__void, 0)
6193 ZEND_ME(reflection_method, isFinal, arginfo_reflection__void, 0)
6194 ZEND_ME(reflection_method, isStatic, arginfo_reflection__void, 0)
6195 ZEND_ME(reflection_method, isConstructor, arginfo_reflection__void, 0)
6196 ZEND_ME(reflection_method, isDestructor, arginfo_reflection__void, 0)
6197 ZEND_ME(reflection_method, getClosure, arginfo_reflection_method_getClosure, 0)
6198 ZEND_ME(reflection_method, getModifiers, arginfo_reflection__void, 0)
6199 ZEND_ME(reflection_method, invoke, arginfo_reflection_method_invoke, 0)
6200 ZEND_ME(reflection_method, invokeArgs, arginfo_reflection_method_invokeArgs, 0)
6201 ZEND_ME(reflection_method, getDeclaringClass, arginfo_reflection__void, 0)
6202 ZEND_ME(reflection_method, getPrototype, arginfo_reflection__void, 0)
6203 ZEND_ME(reflection_method, setAccessible, arginfo_reflection_method_setAccessible, 0)
6204 PHP_FE_END
6205 };
6206
6207
6208 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_export, 0, 0, 1)
6209 ZEND_ARG_INFO(0, argument)
6210 ZEND_ARG_INFO(0, return)
6211 ZEND_END_ARG_INFO()
6212
6213 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class___construct, 0)
6214 ZEND_ARG_INFO(0, argument)
6215 ZEND_END_ARG_INFO()
6216
6217 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getStaticPropertyValue, 0, 0, 1)
6218 ZEND_ARG_INFO(0, name)
6219 ZEND_ARG_INFO(0, default)
6220 ZEND_END_ARG_INFO()
6221
6222 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_setStaticPropertyValue, 0)
6223 ZEND_ARG_INFO(0, name)
6224 ZEND_ARG_INFO(0, value)
6225 ZEND_END_ARG_INFO()
6226
6227 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasMethod, 0)
6228 ZEND_ARG_INFO(0, name)
6229 ZEND_END_ARG_INFO()
6230
6231 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getMethod, 0)
6232 ZEND_ARG_INFO(0, name)
6233 ZEND_END_ARG_INFO()
6234
6235 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getMethods, 0, 0, 0)
6236 ZEND_ARG_INFO(0, filter)
6237 ZEND_END_ARG_INFO()
6238
6239 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasProperty, 0)
6240 ZEND_ARG_INFO(0, name)
6241 ZEND_END_ARG_INFO()
6242
6243 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getProperty, 0)
6244 ZEND_ARG_INFO(0, name)
6245 ZEND_END_ARG_INFO()
6246
6247 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getProperties, 0, 0, 0)
6248 ZEND_ARG_INFO(0, filter)
6249 ZEND_END_ARG_INFO()
6250
6251 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasConstant, 0)
6252 ZEND_ARG_INFO(0, name)
6253 ZEND_END_ARG_INFO()
6254
6255 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getConstant, 0)
6256 ZEND_ARG_INFO(0, name)
6257 ZEND_END_ARG_INFO()
6258
6259 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isInstance, 0)
6260 ZEND_ARG_INFO(0, object)
6261 ZEND_END_ARG_INFO()
6262
6263 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_newInstance, 0)
6264 ZEND_ARG_INFO(0, args)
6265 ZEND_END_ARG_INFO()
6266
6267 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_newInstanceWithoutConstructor, 0)
6268 ZEND_END_ARG_INFO()
6269
6270 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_newInstanceArgs, 0, 0, 0)
6271 ZEND_ARG_ARRAY_INFO(0, args, 0)
6272 ZEND_END_ARG_INFO()
6273
6274 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isSubclassOf, 0)
6275 ZEND_ARG_INFO(0, class)
6276 ZEND_END_ARG_INFO()
6277
6278 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_implementsInterface, 0)
6279 ZEND_ARG_INFO(0, interface)
6280 ZEND_END_ARG_INFO()
6281
6282 static const zend_function_entry reflection_class_functions[] = {
6283 ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
6284 ZEND_ME(reflection_class, export, arginfo_reflection_class_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
6285 ZEND_ME(reflection_class, __construct, arginfo_reflection_class___construct, 0)
6286 ZEND_ME(reflection_class, __toString, arginfo_reflection__void, 0)
6287 ZEND_ME(reflection_class, getName, arginfo_reflection__void, 0)
6288 ZEND_ME(reflection_class, isInternal, arginfo_reflection__void, 0)
6289 ZEND_ME(reflection_class, isUserDefined, arginfo_reflection__void, 0)
6290 ZEND_ME(reflection_class, isAnonymous, arginfo_reflection__void, 0)
6291 ZEND_ME(reflection_class, isInstantiable, arginfo_reflection__void, 0)
6292 ZEND_ME(reflection_class, isCloneable, arginfo_reflection__void, 0)
6293 ZEND_ME(reflection_class, getFileName, arginfo_reflection__void, 0)
6294 ZEND_ME(reflection_class, getStartLine, arginfo_reflection__void, 0)
6295 ZEND_ME(reflection_class, getEndLine, arginfo_reflection__void, 0)
6296 ZEND_ME(reflection_class, getDocComment, arginfo_reflection__void, 0)
6297 ZEND_ME(reflection_class, getConstructor, arginfo_reflection__void, 0)
6298 ZEND_ME(reflection_class, hasMethod, arginfo_reflection_class_hasMethod, 0)
6299 ZEND_ME(reflection_class, getMethod, arginfo_reflection_class_getMethod, 0)
6300 ZEND_ME(reflection_class, getMethods, arginfo_reflection_class_getMethods, 0)
6301 ZEND_ME(reflection_class, hasProperty, arginfo_reflection_class_hasProperty, 0)
6302 ZEND_ME(reflection_class, getProperty, arginfo_reflection_class_getProperty, 0)
6303 ZEND_ME(reflection_class, getProperties, arginfo_reflection_class_getProperties, 0)
6304 ZEND_ME(reflection_class, hasConstant, arginfo_reflection_class_hasConstant, 0)
6305 ZEND_ME(reflection_class, getConstants, arginfo_reflection__void, 0)
6306 ZEND_ME(reflection_class, getConstant, arginfo_reflection_class_getConstant, 0)
6307 ZEND_ME(reflection_class, getInterfaces, arginfo_reflection__void, 0)
6308 ZEND_ME(reflection_class, getInterfaceNames, arginfo_reflection__void, 0)
6309 ZEND_ME(reflection_class, isInterface, arginfo_reflection__void, 0)
6310 ZEND_ME(reflection_class, getTraits, arginfo_reflection__void, 0)
6311 ZEND_ME(reflection_class, getTraitNames, arginfo_reflection__void, 0)
6312 ZEND_ME(reflection_class, getTraitAliases, arginfo_reflection__void, 0)
6313 ZEND_ME(reflection_class, isTrait, arginfo_reflection__void, 0)
6314 ZEND_ME(reflection_class, isAbstract, arginfo_reflection__void, 0)
6315 ZEND_ME(reflection_class, isFinal, arginfo_reflection__void, 0)
6316 ZEND_ME(reflection_class, getModifiers, arginfo_reflection__void, 0)
6317 ZEND_ME(reflection_class, isInstance, arginfo_reflection_class_isInstance, 0)
6318 ZEND_ME(reflection_class, newInstance, arginfo_reflection_class_newInstance, 0)
6319 ZEND_ME(reflection_class, newInstanceWithoutConstructor, arginfo_reflection_class_newInstanceWithoutConstructor, 0)
6320 ZEND_ME(reflection_class, newInstanceArgs, arginfo_reflection_class_newInstanceArgs, 0)
6321 ZEND_ME(reflection_class, getParentClass, arginfo_reflection__void, 0)
6322 ZEND_ME(reflection_class, isSubclassOf, arginfo_reflection_class_isSubclassOf, 0)
6323 ZEND_ME(reflection_class, getStaticProperties, arginfo_reflection__void, 0)
6324 ZEND_ME(reflection_class, getStaticPropertyValue, arginfo_reflection_class_getStaticPropertyValue, 0)
6325 ZEND_ME(reflection_class, setStaticPropertyValue, arginfo_reflection_class_setStaticPropertyValue, 0)
6326 ZEND_ME(reflection_class, getDefaultProperties, arginfo_reflection__void, 0)
6327 ZEND_ME(reflection_class, isIterateable, arginfo_reflection__void, 0)
6328 ZEND_ME(reflection_class, implementsInterface, arginfo_reflection_class_implementsInterface, 0)
6329 ZEND_ME(reflection_class, getExtension, arginfo_reflection__void, 0)
6330 ZEND_ME(reflection_class, getExtensionName, arginfo_reflection__void, 0)
6331 ZEND_ME(reflection_class, inNamespace, arginfo_reflection__void, 0)
6332 ZEND_ME(reflection_class, getNamespaceName, arginfo_reflection__void, 0)
6333 ZEND_ME(reflection_class, getShortName, arginfo_reflection__void, 0)
6334 PHP_FE_END
6335 };
6336
6337
6338 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_object_export, 0, 0, 1)
6339 ZEND_ARG_INFO(0, argument)
6340 ZEND_ARG_INFO(0, return)
6341 ZEND_END_ARG_INFO()
6342
6343 ZEND_BEGIN_ARG_INFO(arginfo_reflection_object___construct, 0)
6344 ZEND_ARG_INFO(0, argument)
6345 ZEND_END_ARG_INFO()
6346
6347 static const zend_function_entry reflection_object_functions[] = {
6348 ZEND_ME(reflection_object, export, arginfo_reflection_object_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
6349 ZEND_ME(reflection_object, __construct, arginfo_reflection_object___construct, 0)
6350 PHP_FE_END
6351 };
6352
6353
6354 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_export, 0, 0, 2)
6355 ZEND_ARG_INFO(0, class)
6356 ZEND_ARG_INFO(0, name)
6357 ZEND_ARG_INFO(0, return)
6358 ZEND_END_ARG_INFO()
6359
6360 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property___construct, 0, 0, 2)
6361 ZEND_ARG_INFO(0, class)
6362 ZEND_ARG_INFO(0, name)
6363 ZEND_END_ARG_INFO()
6364
6365 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_getValue, 0, 0, 0)
6366 ZEND_ARG_INFO(0, object)
6367 ZEND_END_ARG_INFO()
6368
6369 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_setValue, 0, 0, 1)
6370 ZEND_ARG_INFO(0, object)
6371 ZEND_ARG_INFO(0, value)
6372 ZEND_END_ARG_INFO()
6373
6374 ZEND_BEGIN_ARG_INFO(arginfo_reflection_property_setAccessible, 0)
6375 ZEND_ARG_INFO(0, visible)
6376 ZEND_END_ARG_INFO()
6377
6378 static const zend_function_entry reflection_property_functions[] = {
6379 ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
6380 ZEND_ME(reflection_property, export, arginfo_reflection_property_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
6381 ZEND_ME(reflection_property, __construct, arginfo_reflection_property___construct, 0)
6382 ZEND_ME(reflection_property, __toString, arginfo_reflection__void, 0)
6383 ZEND_ME(reflection_property, getName, arginfo_reflection__void, 0)
6384 ZEND_ME(reflection_property, getValue, arginfo_reflection_property_getValue, 0)
6385 ZEND_ME(reflection_property, setValue, arginfo_reflection_property_setValue, 0)
6386 ZEND_ME(reflection_property, isPublic, arginfo_reflection__void, 0)
6387 ZEND_ME(reflection_property, isPrivate, arginfo_reflection__void, 0)
6388 ZEND_ME(reflection_property, isProtected, arginfo_reflection__void, 0)
6389 ZEND_ME(reflection_property, isStatic, arginfo_reflection__void, 0)
6390 ZEND_ME(reflection_property, isDefault, arginfo_reflection__void, 0)
6391 ZEND_ME(reflection_property, getModifiers, arginfo_reflection__void, 0)
6392 ZEND_ME(reflection_property, getDeclaringClass, arginfo_reflection__void, 0)
6393 ZEND_ME(reflection_property, getDocComment, arginfo_reflection__void, 0)
6394 ZEND_ME(reflection_property, setAccessible, arginfo_reflection_property_setAccessible, 0)
6395 PHP_FE_END
6396 };
6397
6398 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_parameter_export, 0, 0, 2)
6399 ZEND_ARG_INFO(0, function)
6400 ZEND_ARG_INFO(0, parameter)
6401 ZEND_ARG_INFO(0, return)
6402 ZEND_END_ARG_INFO()
6403
6404 ZEND_BEGIN_ARG_INFO(arginfo_reflection_parameter___construct, 0)
6405 ZEND_ARG_INFO(0, function)
6406 ZEND_ARG_INFO(0, parameter)
6407 ZEND_END_ARG_INFO()
6408
6409 static const zend_function_entry reflection_parameter_functions[] = {
6410 ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
6411 ZEND_ME(reflection_parameter, export, arginfo_reflection_parameter_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
6412 ZEND_ME(reflection_parameter, __construct, arginfo_reflection_parameter___construct, 0)
6413 ZEND_ME(reflection_parameter, __toString, arginfo_reflection__void, 0)
6414 ZEND_ME(reflection_parameter, getName, arginfo_reflection__void, 0)
6415 ZEND_ME(reflection_parameter, isPassedByReference, arginfo_reflection__void, 0)
6416 ZEND_ME(reflection_parameter, canBePassedByValue, arginfo_reflection__void, 0)
6417 ZEND_ME(reflection_parameter, getDeclaringFunction, arginfo_reflection__void, 0)
6418 ZEND_ME(reflection_parameter, getDeclaringClass, arginfo_reflection__void, 0)
6419 ZEND_ME(reflection_parameter, getClass, arginfo_reflection__void, 0)
6420 ZEND_ME(reflection_parameter, hasType, arginfo_reflection__void, 0)
6421 ZEND_ME(reflection_parameter, getType, arginfo_reflection__void, 0)
6422 ZEND_ME(reflection_parameter, isArray, arginfo_reflection__void, 0)
6423 ZEND_ME(reflection_parameter, isCallable, arginfo_reflection__void, 0)
6424 ZEND_ME(reflection_parameter, allowsNull, arginfo_reflection__void, 0)
6425 ZEND_ME(reflection_parameter, getPosition, arginfo_reflection__void, 0)
6426 ZEND_ME(reflection_parameter, isOptional, arginfo_reflection__void, 0)
6427 ZEND_ME(reflection_parameter, isDefaultValueAvailable, arginfo_reflection__void, 0)
6428 ZEND_ME(reflection_parameter, getDefaultValue, arginfo_reflection__void, 0)
6429 ZEND_ME(reflection_parameter, isDefaultValueConstant, arginfo_reflection__void, 0)
6430 ZEND_ME(reflection_parameter, getDefaultValueConstantName, arginfo_reflection__void, 0)
6431 ZEND_ME(reflection_parameter, isVariadic, arginfo_reflection__void, 0)
6432 PHP_FE_END
6433 };
6434
6435 static const zend_function_entry reflection_type_functions[] = {
6436 ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
6437 ZEND_ME(reflection_type, allowsNull, arginfo_reflection__void, 0)
6438 ZEND_ME(reflection_type, isBuiltin, arginfo_reflection__void, 0)
6439 ZEND_ME(reflection_type, __toString, arginfo_reflection__void, 0)
6440 PHP_FE_END
6441 };
6442
6443 ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_extension_export, 0, 0, 1)
6444 ZEND_ARG_INFO(0, name)
6445 ZEND_ARG_INFO(0, return)
6446 ZEND_END_ARG_INFO()
6447
6448 ZEND_BEGIN_ARG_INFO(arginfo_reflection_extension___construct, 0)
6449 ZEND_ARG_INFO(0, name)
6450 ZEND_END_ARG_INFO()
6451
6452 static const zend_function_entry reflection_extension_functions[] = {
6453 ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
6454 ZEND_ME(reflection_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
6455 ZEND_ME(reflection_extension, __construct, arginfo_reflection_extension___construct, 0)
6456 ZEND_ME(reflection_extension, __toString, arginfo_reflection__void, 0)
6457 ZEND_ME(reflection_extension, getName, arginfo_reflection__void, 0)
6458 ZEND_ME(reflection_extension, getVersion, arginfo_reflection__void, 0)
6459 ZEND_ME(reflection_extension, getFunctions, arginfo_reflection__void, 0)
6460 ZEND_ME(reflection_extension, getConstants, arginfo_reflection__void, 0)
6461 ZEND_ME(reflection_extension, getINIEntries, arginfo_reflection__void, 0)
6462 ZEND_ME(reflection_extension, getClasses, arginfo_reflection__void, 0)
6463 ZEND_ME(reflection_extension, getClassNames, arginfo_reflection__void, 0)
6464 ZEND_ME(reflection_extension, getDependencies, arginfo_reflection__void, 0)
6465 ZEND_ME(reflection_extension, info, arginfo_reflection__void, 0)
6466 ZEND_ME(reflection_extension, isPersistent, arginfo_reflection__void, 0)
6467 ZEND_ME(reflection_extension, isTemporary, arginfo_reflection__void, 0)
6468 PHP_FE_END
6469 };
6470
6471 ZEND_BEGIN_ARG_INFO(arginfo_reflection_zend_extension___construct, 0)
6472 ZEND_ARG_INFO(0, name)
6473 ZEND_END_ARG_INFO()
6474
6475 static const zend_function_entry reflection_zend_extension_functions[] = {
6476 ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
6477 ZEND_ME(reflection_zend_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
6478 ZEND_ME(reflection_zend_extension, __construct, arginfo_reflection_zend_extension___construct, 0)
6479 ZEND_ME(reflection_zend_extension, __toString, arginfo_reflection__void, 0)
6480 ZEND_ME(reflection_zend_extension, getName, arginfo_reflection__void, 0)
6481 ZEND_ME(reflection_zend_extension, getVersion, arginfo_reflection__void, 0)
6482 ZEND_ME(reflection_zend_extension, getAuthor, arginfo_reflection__void, 0)
6483 ZEND_ME(reflection_zend_extension, getURL, arginfo_reflection__void, 0)
6484 ZEND_ME(reflection_zend_extension, getCopyright, arginfo_reflection__void, 0)
6485 PHP_FE_END
6486 };
6487
6488
6489 const zend_function_entry reflection_ext_functions[] = {
6490 PHP_FE_END
6491 };
6492
6493 static zend_object_handlers *zend_std_obj_handlers;
6494
6495
6496 static void _reflection_write_property(zval *object, zval *member, zval *value, void **cache_slot)
6497 {
6498 if ((Z_TYPE_P(member) == IS_STRING)
6499 && zend_hash_exists(&Z_OBJCE_P(object)->properties_info, Z_STR_P(member))
6500 && ((Z_STRLEN_P(member) == sizeof("name") - 1 && !memcmp(Z_STRVAL_P(member), "name", sizeof("name")))
6501 || (Z_STRLEN_P(member) == sizeof("class") - 1 && !memcmp(Z_STRVAL_P(member), "class", sizeof("class")))))
6502 {
6503 zend_throw_exception_ex(reflection_exception_ptr, 0,
6504 "Cannot set read-only property %s::$%s", ZSTR_VAL(Z_OBJCE_P(object)->name), Z_STRVAL_P(member));
6505 }
6506 else
6507 {
6508 zend_std_obj_handlers->write_property(object, member, value, cache_slot);
6509 }
6510 }
6511
6512
6513 PHP_MINIT_FUNCTION(reflection)
6514 {
6515 zend_class_entry _reflection_entry;
6516
6517 zend_std_obj_handlers = zend_get_std_object_handlers();
6518 memcpy(&reflection_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
6519 reflection_object_handlers.offset = XtOffsetOf(reflection_object, zo);
6520 reflection_object_handlers.free_obj = reflection_free_objects_storage;
6521 reflection_object_handlers.clone_obj = NULL;
6522 reflection_object_handlers.write_property = _reflection_write_property;
6523
6524 INIT_CLASS_ENTRY(_reflection_entry, "ReflectionException", reflection_exception_functions);
6525 reflection_exception_ptr = zend_register_internal_class_ex(&_reflection_entry, zend_ce_exception);
6526
6527 INIT_CLASS_ENTRY(_reflection_entry, "Reflection", reflection_functions);
6528 reflection_ptr = zend_register_internal_class(&_reflection_entry);
6529
6530 INIT_CLASS_ENTRY(_reflection_entry, "Reflector", reflector_functions);
6531 reflector_ptr = zend_register_internal_interface(&_reflection_entry);
6532
6533 INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunctionAbstract", reflection_function_abstract_functions);
6534 _reflection_entry.create_object = reflection_objects_new;
6535 reflection_function_abstract_ptr = zend_register_internal_class(&_reflection_entry);
6536 zend_class_implements(reflection_function_abstract_ptr, 1, reflector_ptr);
6537 zend_declare_property_string(reflection_function_abstract_ptr, "name", sizeof("name")-1, "", ZEND_ACC_ABSTRACT);
6538
6539 INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunction", reflection_function_functions);
6540 _reflection_entry.create_object = reflection_objects_new;
6541 reflection_function_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr);
6542 zend_declare_property_string(reflection_function_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
6543
6544 REGISTER_REFLECTION_CLASS_CONST_LONG(function, "IS_DEPRECATED", ZEND_ACC_DEPRECATED);
6545
6546 INIT_CLASS_ENTRY(_reflection_entry, "ReflectionGenerator", reflection_generator_functions);
6547 _reflection_entry.create_object = reflection_objects_new;
6548 reflection_generator_ptr = zend_register_internal_class(&_reflection_entry);
6549
6550 INIT_CLASS_ENTRY(_reflection_entry, "ReflectionParameter", reflection_parameter_functions);
6551 _reflection_entry.create_object = reflection_objects_new;
6552 reflection_parameter_ptr = zend_register_internal_class(&_reflection_entry);
6553 zend_class_implements(reflection_parameter_ptr, 1, reflector_ptr);
6554 zend_declare_property_string(reflection_parameter_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
6555
6556 INIT_CLASS_ENTRY(_reflection_entry, "ReflectionType", reflection_type_functions);
6557 _reflection_entry.create_object = reflection_objects_new;
6558 reflection_type_ptr = zend_register_internal_class(&_reflection_entry);
6559
6560 INIT_CLASS_ENTRY(_reflection_entry, "ReflectionMethod", reflection_method_functions);
6561 _reflection_entry.create_object = reflection_objects_new;
6562 reflection_method_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr);
6563 zend_declare_property_string(reflection_method_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
6564 zend_declare_property_string(reflection_method_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC);
6565
6566 REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_STATIC", ZEND_ACC_STATIC);
6567 REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PUBLIC", ZEND_ACC_PUBLIC);
6568 REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PROTECTED", ZEND_ACC_PROTECTED);
6569 REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PRIVATE", ZEND_ACC_PRIVATE);
6570 REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_ABSTRACT", ZEND_ACC_ABSTRACT);
6571 REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_FINAL", ZEND_ACC_FINAL);
6572
6573 INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClass", reflection_class_functions);
6574 _reflection_entry.create_object = reflection_objects_new;
6575 reflection_class_ptr = zend_register_internal_class(&_reflection_entry);
6576 zend_class_implements(reflection_class_ptr, 1, reflector_ptr);
6577 zend_declare_property_string(reflection_class_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
6578
6579 REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_IMPLICIT_ABSTRACT", ZEND_ACC_IMPLICIT_ABSTRACT_CLASS);
6580 REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_EXPLICIT_ABSTRACT", ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
6581 REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_FINAL", ZEND_ACC_FINAL);
6582
6583 INIT_CLASS_ENTRY(_reflection_entry, "ReflectionObject", reflection_object_functions);
6584 _reflection_entry.create_object = reflection_objects_new;
6585 reflection_object_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_class_ptr);
6586
6587 INIT_CLASS_ENTRY(_reflection_entry, "ReflectionProperty", reflection_property_functions);
6588 _reflection_entry.create_object = reflection_objects_new;
6589 reflection_property_ptr = zend_register_internal_class(&_reflection_entry);
6590 zend_class_implements(reflection_property_ptr, 1, reflector_ptr);
6591 zend_declare_property_string(reflection_property_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
6592 zend_declare_property_string(reflection_property_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC);
6593
6594 REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_STATIC", ZEND_ACC_STATIC);
6595 REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PUBLIC", ZEND_ACC_PUBLIC);
6596 REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PROTECTED", ZEND_ACC_PROTECTED);
6597 REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PRIVATE", ZEND_ACC_PRIVATE);
6598
6599 INIT_CLASS_ENTRY(_reflection_entry, "ReflectionExtension", reflection_extension_functions);
6600 _reflection_entry.create_object = reflection_objects_new;
6601 reflection_extension_ptr = zend_register_internal_class(&_reflection_entry);
6602 zend_class_implements(reflection_extension_ptr, 1, reflector_ptr);
6603 zend_declare_property_string(reflection_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
6604
6605 INIT_CLASS_ENTRY(_reflection_entry, "ReflectionZendExtension", reflection_zend_extension_functions);
6606 _reflection_entry.create_object = reflection_objects_new;
6607 reflection_zend_extension_ptr = zend_register_internal_class(&_reflection_entry);
6608 zend_class_implements(reflection_zend_extension_ptr, 1, reflector_ptr);
6609 zend_declare_property_string(reflection_zend_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
6610
6611 return SUCCESS;
6612 }
6613
6614 PHP_MINFO_FUNCTION(reflection)
6615 {
6616 php_info_print_table_start();
6617 php_info_print_table_header(2, "Reflection", "enabled");
6618
6619 php_info_print_table_row(2, "Version", "$Id: 50d0ba002342d41efa753927261e5e09f295ecf9 $");
6620
6621 php_info_print_table_end();
6622 }
6623
6624 zend_module_entry reflection_module_entry = {
6625 STANDARD_MODULE_HEADER,
6626 "Reflection",
6627 reflection_ext_functions,
6628 PHP_MINIT(reflection),
6629 NULL,
6630 NULL,
6631 NULL,
6632 PHP_MINFO(reflection),
6633 PHP_REFLECTION_VERSION,
6634 STANDARD_MODULE_PROPERTIES
6635 };
6636
6637
6638
6639
6640
6641
6642
6643
6644