1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2007 The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 of the PHP license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.php.net/license/3_01.txt |
11 : | If you did not receive a copy of the PHP license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@php.net so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Authors: Timm Friebe <thekid@thekid.de> |
16 : | George Schlossnagle <george@omniti.com> |
17 : | Andrei Zmievski <andrei@gravitonic.com> |
18 : | Marcus Boerger <helly@php.net> |
19 : | Johannes Schlueter <johannes@php.net> |
20 : +----------------------------------------------------------------------+
21 : */
22 :
23 : /* $Id: php_reflection.c,v 1.164.2.33.2.36 2007/03/17 23:00:49 tony2001 Exp $ */
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 :
42 : /* Undefine "getParameters" macro defined in "main/php3_compat.h" */
43 : #ifdef getParameters
44 : # undef getParameters
45 : #endif
46 :
47 : /* Class entry pointers */
48 : PHPAPI zend_class_entry *reflector_ptr;
49 : PHPAPI zend_class_entry *reflection_exception_ptr;
50 : PHPAPI zend_class_entry *reflection_ptr;
51 : PHPAPI zend_class_entry *reflection_function_abstract_ptr;
52 : PHPAPI zend_class_entry *reflection_function_ptr;
53 : PHPAPI zend_class_entry *reflection_parameter_ptr;
54 : PHPAPI zend_class_entry *reflection_class_ptr;
55 : PHPAPI zend_class_entry *reflection_object_ptr;
56 : PHPAPI zend_class_entry *reflection_method_ptr;
57 : PHPAPI zend_class_entry *reflection_property_ptr;
58 : PHPAPI zend_class_entry *reflection_extension_ptr;
59 :
60 : #if MBO_0
61 : ZEND_BEGIN_MODULE_GLOBALS(reflection)
62 : int dummy;
63 : ZEND_END_MODULE_GLOBALS(reflection)
64 :
65 : #ifdef ZTS
66 : # define REFLECTION_G(v) \
67 : TSRMG(reflection_globals_id, zend_reflection_globals*, v)
68 : extern int reflection_globals_id;
69 : #else
70 : # define REFLECTION_G(v) (reflection_globals.v)
71 : extern zend_reflection_globals reflectionglobals;
72 : #endif
73 :
74 : ZEND_DECLARE_MODULE_GLOBALS(reflection)
75 : #endif /* MBO_0 */
76 :
77 : /* Method macros */
78 :
79 : #define METHOD_NOTSTATIC(ce) \
80 : if (!this_ptr || !instanceof_function(Z_OBJCE_P(this_ptr), ce TSRMLS_CC)) { \
81 : zend_error(E_ERROR, "%s() cannot be called statically", get_active_function_name(TSRMLS_C)); \
82 : return; \
83 : } \
84 :
85 : #define METHOD_NOTSTATIC_NUMPARAMS(ce, c) METHOD_NOTSTATIC(ce) \
86 : if (ZEND_NUM_ARGS() > c) { \
87 : ZEND_WRONG_PARAM_COUNT(); \
88 : } \
89 :
90 : /* Exception throwing macro */
91 : #define _DO_THROW(msg) \
92 : zend_throw_exception(reflection_exception_ptr, msg, 0 TSRMLS_CC); \
93 : return; \
94 :
95 : #define RETURN_ON_EXCEPTION \
96 : if (EG(exception) && Z_OBJCE_P(EG(exception)) == reflection_exception_ptr) { \
97 : return; \
98 : }
99 :
100 : #define GET_REFLECTION_OBJECT_PTR(target) \
101 : intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC); \
102 : if (intern == NULL || intern->ptr == NULL) { \
103 : RETURN_ON_EXCEPTION \
104 : zend_error(E_ERROR, "Internal error: Failed to retrieve the reflection object"); \
105 : } \
106 : target = intern->ptr; \
107 :
108 : /* Class constants */
109 : #define REGISTER_REFLECTION_CLASS_CONST_LONG(class_name, const_name, value) \
110 : zend_declare_class_constant_long(reflection_ ## class_name ## _ptr, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
111 :
112 : /* {{{ Smart string functions */
113 : typedef struct _string {
114 : char *string;
115 : int len;
116 : int alloced;
117 : } string;
118 :
119 : static void string_init(string *str)
120 0 : {
121 0 : str->string = (char *) emalloc(1024);
122 0 : str->len = 1;
123 0 : str->alloced = 1024;
124 0 : *str->string = '\0';
125 0 : }
126 :
127 : static string *string_printf(string *str, const char *format, ...)
128 0 : {
129 : int len;
130 : va_list arg;
131 : char *s_tmp;
132 :
133 0 : va_start(arg, format);
134 0 : len = zend_vspprintf(&s_tmp, 0, format, arg);
135 0 : if (len) {
136 0 : register int nlen = (str->len + len + (1024 - 1)) & ~(1024 - 1);
137 0 : if (str->alloced < nlen) {
138 0 : str->alloced = nlen;
139 0 : str->string = erealloc(str->string, str->alloced);
140 : }
141 0 : memcpy(str->string + str->len - 1, s_tmp, len + 1);
142 0 : str->len += len;
143 : }
144 0 : efree(s_tmp);
145 0 : va_end(arg);
146 0 : return str;
147 : }
148 :
149 : static string *string_write(string *str, char *buf, int len)
150 0 : {
151 0 : register int nlen = (str->len + len + (1024 - 1)) & ~(1024 - 1);
152 0 : if (str->alloced < nlen) {
153 0 : str->alloced = nlen;
154 0 : str->string = erealloc(str->string, str->alloced);
155 : }
156 0 : memcpy(str->string + str->len - 1, buf, len);
157 0 : str->len += len;
158 0 : str->string[str->len - 1] = '\0';
159 0 : return str;
160 : }
161 :
162 : static string *string_append(string *str, string *append)
163 0 : {
164 0 : if (append->len > 1) {
165 0 : string_write(str, append->string, append->len - 1);
166 : }
167 0 : return str;
168 : }
169 :
170 : static void string_free(string *str)
171 0 : {
172 0 : efree(str->string);
173 0 : str->len = 0;
174 0 : str->alloced = 0;
175 0 : str->string = NULL;
176 0 : }
177 : /* }}} */
178 :
179 : /* Struct for properties */
180 : typedef struct _property_reference {
181 : zend_class_entry *ce;
182 : zend_property_info prop;
183 : } property_reference;
184 :
185 : /* Struct for parameters */
186 : typedef struct _parameter_reference {
187 : zend_uint offset;
188 : zend_uint required;
189 : struct _zend_arg_info *arg_info;
190 : zend_function *fptr;
191 : } parameter_reference;
192 :
193 : /* Struct for reflection objects */
194 : typedef struct {
195 : zend_object zo;
196 : void *ptr;
197 : unsigned int free_ptr:1;
198 : zval *obj;
199 : zend_class_entry *ce;
200 : } reflection_object;
201 :
202 : static zend_object_handlers reflection_object_handlers;
203 :
204 : static void _default_get_entry(zval *object, char *name, int name_len, zval *return_value TSRMLS_DC)
205 0 : {
206 : zval **value;
207 :
208 0 : if (zend_hash_find(Z_OBJPROP_P(object), name, name_len, (void **) &value) == FAILURE) {
209 0 : RETURN_FALSE;
210 : }
211 :
212 0 : *return_value = **value;
213 0 : zval_copy_ctor(return_value);
214 0 : INIT_PZVAL(return_value);
215 : }
216 :
217 : static void reflection_register_implement(zend_class_entry *class_entry, zend_class_entry *interface_entry TSRMLS_DC)
218 1100 : {
219 1100 : zend_uint num_interfaces = ++class_entry->num_interfaces;
220 :
221 1100 : class_entry->interfaces = (zend_class_entry **) realloc(class_entry->interfaces, sizeof(zend_class_entry *) * num_interfaces);
222 1100 : class_entry->interfaces[num_interfaces - 1] = interface_entry;
223 1100 : }
224 :
225 : static void reflection_free_objects_storage(void *object TSRMLS_DC)
226 0 : {
227 0 : reflection_object *intern = (reflection_object *) object;
228 :
229 0 : if (intern->free_ptr && intern->ptr) {
230 0 : efree(intern->ptr);
231 0 : intern->ptr = NULL;
232 : }
233 0 : if (intern->obj) {
234 0 : zval_ptr_dtor(&intern->obj);
235 : }
236 0 : zend_objects_free_object_storage(object TSRMLS_CC);
237 0 : }
238 :
239 : static void reflection_objects_clone(void *object, void **object_clone TSRMLS_DC)
240 0 : {
241 0 : reflection_object *intern = (reflection_object *) object;
242 0 : reflection_object **intern_clone = (reflection_object **) object_clone;
243 :
244 0 : *intern_clone = emalloc(sizeof(reflection_object));
245 0 : zend_object_std_init(&(*intern_clone)->zo, intern->zo.ce TSRMLS_CC);
246 0 : (*intern_clone)->ptr = intern->ptr;
247 0 : (*intern_clone)->free_ptr = intern->free_ptr;
248 0 : (*intern_clone)->obj = intern->obj;
249 0 : if (intern->obj) {
250 0 : zval_add_ref(&intern->obj);
251 : }
252 0 : }
253 :
254 : static zend_object_value reflection_objects_new(zend_class_entry *class_type TSRMLS_DC)
255 0 : {
256 : zval tmp;
257 : zend_object_value retval;
258 : reflection_object *intern;
259 :
260 0 : intern = emalloc(sizeof(reflection_object));
261 0 : intern->zo.ce = class_type;
262 0 : intern->zo.guards = NULL;
263 0 : intern->ptr = NULL;
264 0 : intern->obj = NULL;
265 0 : intern->free_ptr = 0;
266 :
267 0 : zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
268 0 : zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
269 0 : retval.handle = zend_objects_store_put(intern, NULL, reflection_free_objects_storage, reflection_objects_clone TSRMLS_CC);
270 0 : retval.handlers = &reflection_object_handlers;
271 0 : return retval;
272 : }
273 :
274 : static zval * reflection_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC)
275 0 : {
276 0 : if (!object) {
277 0 : ALLOC_ZVAL(object);
278 : }
279 0 : Z_TYPE_P(object) = IS_OBJECT;
280 0 : object_init_ex(object, pce);
281 0 : object->refcount = 1;
282 0 : object->is_ref = 1;
283 0 : return object;
284 : }
285 :
286 : static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC);
287 : static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char *indent TSRMLS_DC);
288 : static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC);
289 : static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC);
290 : static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC);
291 :
292 : /* {{{ _class_string */
293 : static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC)
294 0 : {
295 0 : int count, count_static_props = 0, count_static_funcs = 0, count_shadow_props = 0;
296 : string sub_indent;
297 :
298 0 : string_init(&sub_indent);
299 0 : string_printf(&sub_indent, "%s ", indent);
300 :
301 : /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) */
302 0 : if (ce->type == ZEND_USER_CLASS && ce->doc_comment) {
303 0 : string_printf(str, "%s%s", indent, ce->doc_comment);
304 0 : string_write(str, "\n", 1);
305 : }
306 :
307 0 : if (obj) {
308 0 : string_printf(str, "%sObject of class [ ", indent);
309 : } else {
310 0 : string_printf(str, "%s%s [ ", indent, (ce->ce_flags & ZEND_ACC_INTERFACE) ? "Interface" : "Class");
311 : }
312 0 : string_printf(str, (ce->type == ZEND_USER_CLASS) ? "<user" : "<internal");
313 0 : if (ce->module) {
314 0 : string_printf(str, ":%s", ce->module->name);
315 : }
316 0 : string_printf(str, "> ");
317 0 : if (ce->get_iterator != NULL) {
318 0 : string_printf(str, "<iterateable> ");
319 : }
320 0 : if (ce->ce_flags & ZEND_ACC_INTERFACE) {
321 0 : string_printf(str, "interface ");
322 : } else {
323 0 : if (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
324 0 : string_printf(str, "abstract ");
325 : }
326 0 : if (ce->ce_flags & ZEND_ACC_FINAL_CLASS) {
327 0 : string_printf(str, "final ");
328 : }
329 0 : string_printf(str, "class ");
330 : }
331 0 : string_printf(str, "%s", ce->name);
332 0 : if (ce->parent) {
333 0 : string_printf(str, " extends %s", ce->parent->name);
334 : }
335 :
336 0 : if (ce->num_interfaces) {
337 : zend_uint i;
338 :
339 0 : string_printf(str, " implements %s", ce->interfaces[0]->name);
340 0 : for (i = 1; i < ce->num_interfaces; ++i) {
341 0 : string_printf(str, ", %s", ce->interfaces[i]->name);
342 : }
343 : }
344 0 : string_printf(str, " ] {\n");
345 :
346 : /* The information where a class is declared is only available for user classes */
347 0 : if (ce->type == ZEND_USER_CLASS) {
348 0 : string_printf(str, "%s @@ %s %d-%d\n", indent, ce->filename,
349 : ce->line_start, ce->line_end);
350 : }
351 :
352 : /* Constants */
353 : if (&ce->constants_table) {
354 0 : zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
355 0 : string_printf(str, "\n");
356 0 : count = zend_hash_num_elements(&ce->constants_table);
357 0 : string_printf(str, "%s - Constants [%d] {\n", indent, count);
358 0 : if (count > 0) {
359 : HashPosition pos;
360 : zval **value;
361 : char *key;
362 : uint key_len;
363 : ulong num_index;
364 :
365 0 : zend_hash_internal_pointer_reset_ex(&ce->constants_table, &pos);
366 :
367 0 : while (zend_hash_get_current_data_ex(&ce->constants_table, (void **) &value, &pos) == SUCCESS) {
368 0 : zend_hash_get_current_key_ex(&ce->constants_table, &key, &key_len, &num_index, 0, &pos);
369 :
370 0 : _const_string(str, key, *value, indent TSRMLS_CC);
371 0 : zend_hash_move_forward_ex(&ce->constants_table, &pos);
372 : }
373 : }
374 0 : string_printf(str, "%s }\n", indent);
375 : }
376 :
377 : /* Static properties */
378 : if (&ce->properties_info) {
379 : /* counting static properties */
380 0 : count = zend_hash_num_elements(&ce->properties_info);
381 0 : if (count > 0) {
382 : HashPosition pos;
383 : zend_property_info *prop;
384 :
385 0 : zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
386 :
387 0 : while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
388 0 : if(prop->flags & ZEND_ACC_SHADOW) {
389 0 : count_shadow_props++;
390 0 : } else if (prop->flags & ZEND_ACC_STATIC) {
391 0 : count_static_props++;
392 : }
393 0 : zend_hash_move_forward_ex(&ce->properties_info, &pos);
394 : }
395 : }
396 :
397 : /* static properties */
398 0 : string_printf(str, "\n%s - Static properties [%d] {\n", indent, count_static_props);
399 0 : if (count_static_props > 0) {
400 : HashPosition pos;
401 : zend_property_info *prop;
402 :
403 0 : zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
404 :
405 0 : while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
406 0 : if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) {
407 0 : _property_string(str, prop, NULL, sub_indent.string TSRMLS_CC);
408 : }
409 :
410 0 : zend_hash_move_forward_ex(&ce->properties_info, &pos);
411 : }
412 : }
413 0 : string_printf(str, "%s }\n", indent);
414 : }
415 :
416 : /* Static methods */
417 : if (&ce->function_table) {
418 : /* counting static properties */
419 0 : count = zend_hash_num_elements(&ce->function_table);
420 0 : if (count > 0) {
421 : HashPosition pos;
422 : zend_function *mptr;
423 :
424 0 : zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
425 :
426 0 : while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
427 0 : if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
428 0 : count_static_funcs++;
429 : }
430 0 : zend_hash_move_forward_ex(&ce->function_table, &pos);
431 : }
432 : }
433 :
434 : /* static properties */
435 0 : string_printf(str, "\n%s - Static methods [%d] {", indent, count_static_funcs);
436 0 : if (count_static_funcs > 0) {
437 : HashPosition pos;
438 : zend_function *mptr;
439 :
440 0 : zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
441 :
442 0 : while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
443 0 : if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
444 0 : string_printf(str, "\n");
445 0 : _function_string(str, mptr, ce, sub_indent.string TSRMLS_CC);
446 : }
447 0 : zend_hash_move_forward_ex(&ce->function_table, &pos);
448 : }
449 : } else {
450 0 : string_printf(str, "\n");
451 : }
452 0 : string_printf(str, "%s }\n", indent);
453 : }
454 :
455 : /* Default/Implicit properties */
456 : if (&ce->properties_info) {
457 0 : count = zend_hash_num_elements(&ce->properties_info) - count_static_props - count_shadow_props;
458 0 : string_printf(str, "\n%s - Properties [%d] {\n", indent, count);
459 0 : if (count > 0) {
460 : HashPosition pos;
461 : zend_property_info *prop;
462 :
463 0 : zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
464 :
465 0 : while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
466 0 : if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) {
467 0 : _property_string(str, prop, NULL, sub_indent.string TSRMLS_CC);
468 : }
469 0 : zend_hash_move_forward_ex(&ce->properties_info, &pos);
470 : }
471 : }
472 0 : string_printf(str, "%s }\n", indent);
473 : }
474 :
475 0 : if (obj && Z_OBJ_HT_P(obj)->get_properties) {
476 : string dyn;
477 0 : HashTable *properties = Z_OBJ_HT_P(obj)->get_properties(obj TSRMLS_CC);
478 : HashPosition pos;
479 : zval **prop;
480 :
481 0 : string_init(&dyn);
482 0 : count = 0;
483 :
484 0 : zend_hash_internal_pointer_reset_ex(properties, &pos);
485 :
486 0 : while (zend_hash_get_current_data_ex(properties, (void **) &prop, &pos) == SUCCESS) {
487 : char *prop_name;
488 : uint prop_name_size;
489 : ulong index;
490 :
491 0 : if (zend_hash_get_current_key_ex(properties, &prop_name, &prop_name_size, &index, 1, &pos) == HASH_KEY_IS_STRING) {
492 0 : if (prop_name_size && prop_name[0]) { /* skip all private and protected properties */
493 0 : if (!zend_hash_quick_exists(&ce->properties_info, prop_name, prop_name_size, zend_get_hash_value(prop_name, prop_name_size))) {
494 0 : count++;
495 0 : _property_string(&dyn, NULL, prop_name, sub_indent.string TSRMLS_CC);
496 : }
497 : }
498 0 : efree(prop_name);
499 : }
500 0 : zend_hash_move_forward_ex(properties, &pos);
501 : }
502 :
503 0 : string_printf(str, "\n%s - Dynamic properties [%d] {\n", indent, count);
504 0 : string_append(str, &dyn);
505 0 : string_printf(str, "%s }\n", indent);
506 0 : string_free(&dyn);
507 : }
508 :
509 : /* Non static methods */
510 : if (&ce->function_table) {
511 0 : count = zend_hash_num_elements(&ce->function_table) - count_static_funcs;
512 0 : if (count > 0) {
513 : HashPosition pos;
514 : zend_function *mptr;
515 : string dyn;
516 :
517 0 : count = 0;
518 0 : string_init(&dyn);
519 0 : zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
520 :
521 0 : while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
522 0 : if (!(mptr->common.fn_flags & ZEND_ACC_STATIC)) {
523 : char *key;
524 : uint key_len;
525 : ulong num_index;
526 0 : uint len = strlen(mptr->common.function_name);
527 :
528 : /* Do not display old-style inherited constructors */
529 0 : if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 ||
530 : mptr->common.scope == ce ||
531 : zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len, &num_index, 0, &pos) != HASH_KEY_IS_STRING ||
532 : zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0) {
533 :
534 0 : string_printf(&dyn, "\n");
535 0 : _function_string(&dyn, mptr, ce, sub_indent.string TSRMLS_CC);
536 0 : count++;
537 : }
538 : }
539 0 : zend_hash_move_forward_ex(&ce->function_table, &pos);
540 : }
541 0 : string_printf(str, "\n%s - Methods [%d] {", indent, count);
542 0 : string_append(str, &dyn);
543 0 : string_free(&dyn);
544 : } else {
545 0 : string_printf(str, "\n%s - Methods [0] {\n", indent);
546 : }
547 0 : string_printf(str, "%s }\n", indent);
548 : }
549 :
550 0 : string_printf(str, "%s}\n", indent);
551 0 : string_free(&sub_indent);
552 0 : }
553 : /* }}} */
554 :
555 : /* {{{ _const_string */
556 : static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC)
557 0 : {
558 : char *type;
559 : zval value_copy;
560 : int use_copy;
561 :
562 0 : type = zend_zval_type_name(value);
563 :
564 0 : zend_make_printable_zval(value, &value_copy, &use_copy);
565 0 : if (use_copy) {
566 0 : value = &value_copy;
567 : }
568 :
569 0 : string_printf(str, "%s Constant [ %s %s ] { %s }\n",
570 : indent,
571 : type,
572 : name,
573 : Z_STRVAL_P(value));
574 :
575 0 : if (use_copy) {
576 0 : zval_dtor(value);
577 : }
578 0 : }
579 : /* }}} */
580 :
581 : /* {{{ _get_recv_opcode */
582 : static zend_op* _get_recv_op(zend_op_array *op_array, zend_uint offset)
583 0 : {
584 0 : zend_op *op = op_array->opcodes;
585 0 : zend_op *end = op + op_array->last;
586 :
587 0 : ++offset;
588 0 : while (op < end) {
589 0 : if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT) &&
590 : op->op1.u.constant.value.lval == (long)offset) {
591 0 : return op;
592 : }
593 0 : ++op;
594 : }
595 0 : return NULL;
596 : }
597 : /* }}} */
598 :
599 : /* {{{ _parameter_string */
600 : static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, char* indent TSRMLS_DC)
601 0 : {
602 0 : string_printf(str, "Parameter #%d [ ", offset);
603 0 : if (offset >= required) {
604 0 : string_printf(str, "<optional> ");
605 : } else {
606 0 : string_printf(str, "<required> ");
607 : }
608 0 : if (arg_info->class_name) {
609 0 : string_printf(str, "%s ", arg_info->class_name);
610 0 : if (arg_info->allow_null) {
611 0 : string_printf(str, "or NULL ");
612 : }
613 0 : } else if (arg_info->array_type_hint) {
614 0 : string_printf(str, "array ");
615 0 : if (arg_info->allow_null) {
616 0 : string_printf(str, "or NULL ");
617 : }
618 : }
619 0 : if (arg_info->pass_by_reference) {
620 0 : string_write(str, "&", sizeof("&")-1);
621 : }
622 0 : if (arg_info->name) {
623 0 : string_printf(str, "$%s", arg_info->name);
624 : } else {
625 0 : string_printf(str, "$param%d", offset);
626 : }
627 0 : if (fptr->type == ZEND_USER_FUNCTION && offset >= required) {
628 0 : zend_op *precv = _get_recv_op((zend_op_array*)fptr, offset);
629 0 : if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2.op_type != IS_UNUSED) {
630 : zval *zv, zv_copy;
631 : int use_copy;
632 0 : string_write(str, " = ", sizeof(" = ")-1);
633 0 : ALLOC_ZVAL(zv);
634 0 : *zv = precv->op2.u.constant;
635 0 : zval_copy_ctor(zv);
636 0 : INIT_PZVAL(zv);
637 0 : zval_update_constant(&zv, (void*)1 TSRMLS_CC);
638 0 : if (Z_TYPE_P(zv) == IS_BOOL) {
639 0 : if (Z_LVAL_P(zv)) {
640 0 : string_write(str, "true", sizeof("true")-1);
641 : } else {
642 0 : string_write(str, "false", sizeof("false")-1);
643 : }
644 0 : } else if (Z_TYPE_P(zv) == IS_NULL) {
645 0 : string_write(str, "NULL", sizeof("NULL")-1);
646 0 : } else if (Z_TYPE_P(zv) == IS_STRING) {
647 0 : string_write(str, "'", sizeof("'")-1);
648 0 : string_write(str, Z_STRVAL_P(zv), MIN(Z_STRLEN_P(zv), 15));
649 0 : if (Z_STRLEN_P(zv) > 15) {
650 0 : string_write(str, "...", sizeof("...")-1);
651 : }
652 0 : string_write(str, "'", sizeof("'")-1);
653 : } else {
654 0 : zend_make_printable_zval(zv, &zv_copy, &use_copy);
655 0 : string_write(str, Z_STRVAL(zv_copy), Z_STRLEN(zv_copy));
656 0 : if (use_copy) {
657 0 : zval_dtor(&zv_copy);
658 : }
659 : }
660 0 : zval_ptr_dtor(&zv);
661 : }
662 : }
663 0 : string_write(str, " ]", sizeof(" ]")-1);
664 0 : }
665 : /* }}} */
666 :
667 : /* {{{ _function_parameter_string */
668 : static void _function_parameter_string(string *str, zend_function *fptr, char* indent TSRMLS_DC)
669 0 : {
670 0 : struct _zend_arg_info *arg_info = fptr->common.arg_info;
671 0 : zend_uint i, required = fptr->common.required_num_args;
672 :
673 0 : if (!arg_info) {
674 0 : return;
675 : }
676 :
677 0 : string_printf(str, "\n");
678 0 : string_printf(str, "%s- Parameters [%d] {\n", indent, fptr->common.num_args);
679 0 : for (i = 0; i < fptr->common.num_args; i++) {
680 0 : string_printf(str, "%s ", indent);
681 0 : _parameter_string(str, fptr, arg_info, i, required, indent TSRMLS_CC);
682 0 : string_write(str, "\n", sizeof("\n")-1);
683 0 : arg_info++;
684 : }
685 0 : string_printf(str, "%s}\n", indent);
686 : }
687 : /* }}} */
688 :
689 : /* {{{ _function_string */
690 : static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent TSRMLS_DC)
691 0 : {
692 : string param_indent;
693 : zend_function *overwrites;
694 : char *lc_name;
695 : unsigned int lc_name_len;
696 :
697 : /* TBD: Repair indenting of doc comment (or is this to be done in the parser?)
698 : * What's "wrong" is that any whitespace before the doc comment start is
699 : * swallowed, leading to an unaligned comment.
700 : */
701 0 : if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
702 0 : string_printf(str, "%s%s\n", indent, fptr->op_array.doc_comment);
703 : }
704 :
705 0 : string_printf(str, fptr->common.scope ? "%sMethod [ " : "%sFunction [ ", indent);
706 0 : string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal");
707 0 : if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) {
708 0 : string_printf(str, ", deprecated");
709 : }
710 : #if MBO_0
711 : if (fptr->type == ZEND_INTERNAL_FUNCTION && ((zend_internal_function*)fptr)->module) {
712 : string_printf(str, ":%s", ((zend_internal_function*)fptr)->module->name);
713 : }
714 : #endif
715 0 : if (scope && fptr->common.scope) {
716 0 : if (fptr->common.scope != scope) {
717 0 : string_printf(str, ", inherits %s", fptr->common.scope->name);
718 0 : } else if (fptr->common.scope->parent) {
719 0 : lc_name_len = strlen(fptr->common.function_name);
720 0 : lc_name = zend_str_tolower_dup(fptr->common.function_name, lc_name_len);
721 0 : if (zend_hash_find(&fptr->common.scope->parent->function_table, lc_name, lc_name_len + 1, (void**) &overwrites) == SUCCESS) {
722 0 : if (fptr->common.scope != overwrites->common.scope) {
723 0 : string_printf(str, ", overwrites %s", overwrites->common.scope->name);
724 : }
725 : }
726 0 : efree(lc_name);
727 : }
728 : }
729 0 : if (fptr->common.prototype && fptr->common.prototype->common.scope) {
730 0 : string_printf(str, ", prototype %s", fptr->common.prototype->common.scope->name);
731 : }
732 0 : if (fptr->common.fn_flags & ZEND_ACC_CTOR) {
733 0 : string_printf(str, ", ctor");
734 : }
735 0 : if (fptr->common.fn_flags & ZEND_ACC_DTOR) {
736 0 : string_printf(str, ", dtor");
737 : }
738 0 : string_printf(str, "> ");
739 :
740 0 : if (fptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
741 0 : string_printf(str, "abstract ");
742 : }
743 0 : if (fptr->common.fn_flags & ZEND_ACC_FINAL) {
744 0 : string_printf(str, "final ");
745 : }
746 0 : if (fptr->common.fn_flags & ZEND_ACC_STATIC) {
747 0 : string_printf(str, "static ");
748 : }
749 :
750 : /* These are mutually exclusive */
751 0 : switch (fptr->common.fn_flags & ZEND_ACC_PPP_MASK) {
752 : case ZEND_ACC_PUBLIC:
753 0 : string_printf(str, "public ");
754 0 : break;
755 : case ZEND_ACC_PRIVATE:
756 0 : string_printf(str, "private ");
757 0 : break;
758 : case ZEND_ACC_PROTECTED:
759 0 : string_printf(str, "protected ");
760 0 : break;
761 : default:
762 0 : string_printf(str, "<visibility error> ");
763 : break;
764 : }
765 :
766 0 : string_printf(str, fptr->common.scope ? "method " : "function ");
767 0 : if (fptr->op_array.return_reference) {
768 0 : string_printf(str, "&");
769 : }
770 0 : string_printf(str, "%s ] {\n", fptr->common.function_name);
771 : /* The information where a function is declared is only available for user classes */
772 0 : if (fptr->type == ZEND_USER_FUNCTION) {
773 0 : string_printf(str, "%s @@ %s %d - %d\n", indent,
774 : fptr->op_array.filename,
775 : fptr->op_array.line_start,
776 : fptr->op_array.line_end);
777 : }
778 0 : string_init(¶m_indent);
779 0 : string_printf(¶m_indent, "%s ", indent);
780 0 : _function_parameter_string(str, fptr, param_indent.string TSRMLS_CC);
781 0 : string_free(¶m_indent);
782 0 : string_printf(str, "%s}\n", indent);
783 0 : }
784 : /* }}} */
785 :
786 : /* {{{ _property_string */
787 : static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC)
788 0 : {
789 : char *class_name;
790 :
791 0 : string_printf(str, "%sProperty [ ", indent);
792 0 : if (!prop) {
793 0 : string_printf(str, "<dynamic> public $%s", prop_name);
794 : } else {
795 0 : if (!(prop->flags & ZEND_ACC_STATIC)) {
796 0 : if (prop->flags & ZEND_ACC_IMPLICIT_PUBLIC) {
797 0 : string_write(str, "<implicit> ", sizeof("<implicit> ") - 1);
798 : } else {
799 0 : string_write(str, "<default> ", sizeof("<default> ") - 1);
800 : }
801 : }
802 :
803 : /* These are mutually exclusive */
804 0 : switch (prop->flags & ZEND_ACC_PPP_MASK) {
805 : case ZEND_ACC_PUBLIC:
806 0 : string_printf(str, "public ");
807 0 : break;
808 : case ZEND_ACC_PRIVATE:
809 0 : string_printf(str, "private ");
810 0 : break;
811 : case ZEND_ACC_PROTECTED:
812 0 : string_printf(str, "protected ");
813 : break;
814 : }
815 0 : if(prop->flags & ZEND_ACC_STATIC) {
816 0 : string_printf(str, "static ");
817 : }
818 :
819 0 : zend_unmangle_property_name(prop->name, prop->name_length, &class_name, &prop_name);
820 0 : string_printf(str, "$%s", prop_name);
821 : }
822 :
823 0 : string_printf(str, " ]\n");
824 0 : }
825 : /* }}} */
826 :
827 : static int _extension_ini_string(zend_ini_entry *ini_entry, int num_args, va_list args, zend_hash_key *hash_key)
828 0 : {
829 0 : string *str = va_arg(args, string *);
830 0 : char *indent = va_arg(args, char *);
831 0 : int number = va_arg(args, int);
832 0 : char *comma = "";
833 :
834 0 : if (number == ini_entry->module_number) {
835 0 : string_printf(str, " %sEntry [ %s <", indent, ini_entry->name);
836 0 : if (ini_entry->modifiable & ZEND_INI_ALL) {
837 0 : string_printf(str, "ALL");
838 : } else {
839 0 : if (ini_entry->modifiable & ZEND_INI_USER) {
840 0 : string_printf(str, "USER");
841 0 : comma = ",";
842 : }
843 0 : if (ini_entry->modifiable & ZEND_INI_PERDIR) {
844 0 : string_printf(str, "%sPERDIR", comma);
845 0 : comma = ",";
846 : }
847 0 : if (ini_entry->modifiable & ZEND_INI_SYSTEM) {
848 0 : string_printf(str, "%sSYSTEM", comma);
849 : }
850 : }
851 :
852 0 : string_printf(str, "> ]\n");
853 0 : string_printf(str, " %s Current = '%s'\n", indent, ini_entry->value ? ini_entry->value : "");
854 0 : if (ini_entry->modified) {
855 0 : string_printf(str, " %s Default = '%s'\n", indent, ini_entry->orig_value ? ini_entry->orig_value : "");
856 : }
857 0 : string_printf(str, " %s}\n", indent);
858 : }
859 0 : return ZEND_HASH_APPLY_KEEP;
860 : }
861 :
862 : static int _extension_class_string(zend_class_entry **pce, int num_args, va_list args, zend_hash_key *hash_key)
863 0 : {
864 0 : string *str = va_arg(args, string *);
865 0 : char *indent = va_arg(args, char *);
866 0 : struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
867 0 : int *num_classes = va_arg(args, int*);
868 : TSRMLS_FETCH();
869 :
870 0 : if ((*pce)->module && !strcasecmp((*pce)->module->name, module->name)) {
871 0 : string_printf(str, "\n");
872 0 : _class_string(str, *pce, NULL, indent TSRMLS_CC);
873 0 : (*num_classes)++;
874 : }
875 0 : return ZEND_HASH_APPLY_KEEP;
876 : }
877 :
878 : static int _extension_const_string(zend_constant *constant, int num_args, va_list args, zend_hash_key *hash_key)
879 0 : {
880 0 : string *str = va_arg(args, string *);
881 0 : char *indent = va_arg(args, char *);
882 0 : struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
883 0 : int *num_classes = va_arg(args, int*);
884 :
885 0 : if (constant->module_number == module->module_number) {
886 : TSRMLS_FETCH();
887 0 : _const_string(str, constant->name, &constant->value, indent TSRMLS_CC);
888 0 : (*num_classes)++;
889 : }
890 0 : return ZEND_HASH_APPLY_KEEP;
891 : }
892 :
893 : /* {{{ _extension_string */
894 : static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC)
895 0 : {
896 0 : string_printf(str, "%sExtension [ ", indent);
897 0 : if (module->type == MODULE_PERSISTENT) {
898 0 : string_printf(str, "<persistent>");
899 : }
900 0 : if (module->type == MODULE_TEMPORARY) {
901 0 : string_printf(str, "<temporary>" );
902 : }
903 0 : string_printf(str, " extension #%d %s version %s ] {\n",
904 : module->module_number, module->name,
905 : (module->version == NO_VERSION_YET) ? "<no_version>" : module->version);
906 :
907 0 : if (module->deps) {
908 0 : zend_module_dep* dep = module->deps;
909 :
910 0 : string_printf(str, "\n - Dependencies {\n");
911 :
912 0 : while(dep->name) {
913 0 : string_printf(str, "%s Dependency [ %s (", indent, dep->name);
914 :
915 0 : switch(dep->type) {
916 : case MODULE_DEP_REQUIRED:
917 0 : string_write(str, "Required", sizeof("Required") - 1);
918 0 : break;
919 : case MODULE_DEP_CONFLICTS:
920 0 : string_write(str, "Conflicts", sizeof("Conflicts") - 1);
921 0 : break;
922 : case MODULE_DEP_OPTIONAL:
923 0 : string_write(str, "Optional", sizeof("Optional") - 1);
924 0 : break;
925 : default:
926 0 : string_write(str, "Error", sizeof("Error") - 1); /* shouldn't happen */
927 : break;
928 : }
929 :
930 0 : if (dep->rel) {
931 0 : string_printf(str, " %s", dep->rel);
932 : }
933 0 : if (dep->version) {
934 0 : string_printf(str, " %s", dep->version);
935 : }
936 0 : string_write(str, ") ]\n", sizeof(") ]\n") - 1);
937 0 : dep++;
938 : }
939 0 : string_printf(str, "%s }\n", indent);
940 : }
941 :
942 : {
943 : string str_ini;
944 0 : string_init(&str_ini);
945 0 : zend_hash_apply_with_arguments(EG(ini_directives), (apply_func_args_t) _extension_ini_string, 3, &str_ini, indent, module->module_number);
946 0 : if (str_ini.len > 1) {
947 0 : string_printf(str, "\n - INI {\n");
948 0 : string_append(str, &str_ini);
949 0 : string_printf(str, "%s }\n", indent);
950 : }
951 0 : string_free(&str_ini);
952 : }
953 :
954 : {
955 : string str_constants;
956 0 : int num_constants = 0;
957 :
958 0 : string_init(&str_constants);
959 0 : zend_hash_apply_with_arguments(EG(zend_constants), (apply_func_args_t) _extension_const_string, 4, &str_constants, indent, module, &num_constants TSRMLS_CC);
960 0 : if (num_constants) {
961 0 : string_printf(str, "\n - Constants [%d] {\n", num_constants);
962 0 : string_append(str, &str_constants);
963 0 : string_printf(str, "%s }\n", indent);
964 : }
965 0 : string_free(&str_constants);
966 : }
967 :
968 0 : if (module->functions && module->functions->fname) {
969 : zend_function *fptr;
970 0 : zend_function_entry *func = module->functions;
971 :
972 0 : string_printf(str, "\n - Functions {\n");
973 :
974 : /* Is there a better way of doing this? */
975 0 : while (func->fname) {
976 0 : if (zend_hash_find(EG(function_table), func->fname, strlen(func->fname) + 1, (void**) &fptr) == FAILURE) {
977 0 : zend_error(E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname);
978 0 : continue;
979 : }
980 :
981 0 : _function_string(str, fptr, NULL, " " TSRMLS_CC);
982 0 : func++;
983 : }
984 0 : string_printf(str, "%s }\n", indent);
985 : }
986 :
987 : {
988 : string str_classes;
989 : string sub_indent;
990 0 : int num_classes = 0;
991 :
992 0 : string_init(&sub_indent);
993 0 : string_printf(&sub_indent, "%s ", indent);
994 0 : string_init(&str_classes);
995 0 : zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) _extension_class_string, 4, &str_classes, sub_indent.string, module, &num_classes TSRMLS_CC);
996 0 : if (num_classes) {
997 0 : string_printf(str, "\n - Classes [%d] {", num_classes);
998 0 : string_append(str, &str_classes);
999 0 : string_printf(str, "%s }\n", indent);
1000 : }
1001 0 : string_free(&str_classes);
1002 0 : string_free(&sub_indent);
1003 : }
1004 :
1005 0 : string_printf(str, "%s}\n", indent);
1006 0 : }
1007 : /* }}} */
1008 :
1009 : /* {{{ _function_check_flag */
1010 : static void _function_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
1011 0 : {
1012 : reflection_object *intern;
1013 : zend_function *mptr;
1014 :
1015 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_method_ptr, 0);
1016 0 : GET_REFLECTION_OBJECT_PTR(mptr);
1017 0 : RETURN_BOOL(mptr->common.fn_flags & mask);
1018 : }
1019 : /* }}} */
1020 :
1021 : /* {{{ zend_reflection_class_factory */
1022 : PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object TSRMLS_DC)
1023 0 : {
1024 : reflection_object *intern;
1025 : zval *name;
1026 :
1027 0 : MAKE_STD_ZVAL(name);
1028 0 : ZVAL_STRINGL(name, ce->name, ce->name_length, 1);
1029 0 : reflection_instantiate(reflection_class_ptr, object TSRMLS_CC);
1030 0 : intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
1031 0 : intern->ptr = ce;
1032 0 : intern->free_ptr = 0;
1033 0 : intern->ce = ce;
1034 0 : zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
1035 0 : }
1036 : /* }}} */
1037 :
1038 : /* {{{ reflection_extension_factory */
1039 : static void reflection_extension_factory(zval *object, char *name_str TSRMLS_DC)
1040 0 : {
1041 : reflection_object *intern;
1042 : zval *name;
1043 0 : int name_len = strlen(name_str);
1044 : char *lcname;
1045 : struct _zend_module_entry *module;
1046 :
1047 0 : lcname = do_alloca(name_len + 1);
1048 0 : zend_str_tolower_copy(lcname, name_str, name_len);
1049 0 : if (zend_hash_find(&module_registry, lcname, name_len + 1, (void **)&module) == FAILURE) {
1050 : free_alloca(lcname);
1051 0 : return;
1052 : }
1053 : free_alloca(lcname);
1054 :
1055 0 : reflection_instantiate(reflection_extension_ptr, object TSRMLS_CC);
1056 0 : intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
1057 0 : MAKE_STD_ZVAL(name);
1058 0 : ZVAL_STRINGL(name, module->name, name_len, 1);
1059 0 : intern->ptr = module;
1060 0 : intern->free_ptr = 0;
1061 0 : intern->ce = NULL;
1062 0 : zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
1063 : }
1064 : /* }}} */
1065 :
1066 : /* {{{ reflection_parameter_factory */
1067 : static void reflection_parameter_factory(zend_function *fptr, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, zval *object TSRMLS_DC)
1068 0 : {
1069 : reflection_object *intern;
1070 : parameter_reference *reference;
1071 : zval *name;
1072 :
1073 0 : MAKE_STD_ZVAL(name);
1074 0 : if (arg_info->name) {
1075 0 : ZVAL_STRINGL(name, arg_info->name, arg_info->name_len, 1);
1076 : } else {
1077 0 : ZVAL_NULL(name);
1078 : }
1079 0 : reflection_instantiate(reflection_parameter_ptr, object TSRMLS_CC);
1080 0 : intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
1081 0 : reference = (parameter_reference*) emalloc(sizeof(parameter_reference));
1082 0 : reference->arg_info = arg_info;
1083 0 : reference->offset = offset;
1084 0 : reference->required = required;
1085 0 : reference->fptr = fptr;
1086 0 : intern->ptr = reference;
1087 0 : intern->free_ptr = 1;
1088 0 : intern->ce = fptr->common.scope;
1089 0 : zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
1090 0 : }
1091 : /* }}} */
1092 :
1093 : /* {{{ reflection_function_factory */
1094 : static void reflection_function_factory(zend_function *function, zval *object TSRMLS_DC)
1095 0 : {
1096 : reflection_object *intern;
1097 : zval *name;
1098 :
1099 0 : MAKE_STD_ZVAL(name);
1100 0 : ZVAL_STRING(name, function->common.function_name, 1);
1101 :
1102 0 : reflection_instantiate(reflection_function_ptr, object TSRMLS_CC);
1103 0 : intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
1104 0 : intern->ptr = function;
1105 0 : intern->free_ptr = 0;
1106 0 : intern->ce = NULL;
1107 0 : zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
1108 0 : }
1109 : /* }}} */
1110 :
1111 : /* {{{ reflection_method_factory */
1112 : static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *object TSRMLS_DC)
1113 0 : {
1114 : reflection_object *intern;
1115 : zval *name;
1116 : zval *classname;
1117 :
1118 0 : MAKE_STD_ZVAL(name);
1119 0 : MAKE_STD_ZVAL(classname);
1120 0 : ZVAL_STRING(name, method->common.function_name, 1);
1121 0 : ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
1122 0 : reflection_instantiate(reflection_method_ptr, object TSRMLS_CC);
1123 0 : intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
1124 0 : intern->ptr = method;
1125 0 : intern->free_ptr = 0;
1126 0 : intern->ce = ce;
1127 0 : zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
1128 0 : zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
1129 0 : }
1130 : /* }}} */
1131 :
1132 : /* {{{ reflection_property_factory */
1133 : static void reflection_property_factory(zend_class_entry *ce, zend_property_info *prop, zval *object TSRMLS_DC)
1134 0 : {
1135 : reflection_object *intern;
1136 : zval *name;
1137 : zval *classname;
1138 : property_reference *reference;
1139 : char *class_name, *prop_name;
1140 :
1141 0 : zend_unmangle_property_name(prop->name, prop->name_length, &class_name, &prop_name);
1142 :
1143 0 : if (!(prop->flags & ZEND_ACC_PRIVATE)) {
1144 : /* we have to search the class hierarchy for this (implicit) public or protected property */
1145 0 : zend_class_entry *tmp_ce = ce, *store_ce = ce;
1146 0 : zend_property_info *tmp_info = NULL;
1147 :
1148 0 : while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, prop_name, strlen(prop_name) + 1, (void **) &tmp_info) != SUCCESS) {
1149 0 : ce = tmp_ce;
1150 0 : tmp_ce = tmp_ce->parent;
1151 : }
1152 :
1153 0 : if (tmp_info && !(tmp_info->flags & ZEND_ACC_SHADOW)) { /* found something and it's not a parent's private */
1154 0 : prop = tmp_info;
1155 : } else { /* not found, use initial value */
1156 0 : ce = store_ce;
1157 : }
1158 : }
1159 :
1160 0 : MAKE_STD_ZVAL(name);
1161 0 : MAKE_STD_ZVAL(classname);
1162 0 : ZVAL_STRING(name, prop_name, 1);
1163 0 : ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
1164 :
1165 0 : reflection_instantiate(reflection_property_ptr, object TSRMLS_CC);
1166 0 : intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
1167 0 : reference = (property_reference*) emalloc(sizeof(property_reference));
1168 0 : reference->ce = ce;
1169 0 : reference->prop = *prop;
1170 0 : intern->ptr = reference;
1171 0 : intern->free_ptr = 1;
1172 0 : intern->ce = ce;
1173 0 : zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
1174 0 : zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
1175 0 : }
1176 : /* }}} */
1177 :
1178 : /* {{{ _reflection_export */
1179 : static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_ptr, int ctor_argc)
1180 0 : {
1181 : zval *reflector_ptr;
1182 0 : zval output, *output_ptr = &output;
1183 : zval *argument_ptr, *argument2_ptr;
1184 : zval *retval_ptr, **params[2];
1185 : int result;
1186 0 : int return_output = 0;
1187 : zend_fcall_info fci;
1188 : zend_fcall_info_cache fcc;
1189 : zval fname;
1190 :
1191 0 : if (ctor_argc == 1) {
1192 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &argument_ptr, &return_output) == FAILURE) {
1193 0 : return;
1194 : }
1195 : } else {
1196 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|b", &argument_ptr, &argument2_ptr, &return_output) == FAILURE) {
1197 0 : return;
1198 : }
1199 : }
1200 :
1201 0 : INIT_PZVAL(&output);
1202 :
1203 : /* Create object */
1204 0 : MAKE_STD_ZVAL(reflector_ptr);
1205 0 : if (object_and_properties_init(reflector_ptr, ce_ptr, NULL) == FAILURE) {
1206 0 : _DO_THROW("Could not create reflector");
1207 : }
1208 :
1209 : /* Call __construct() */
1210 0 : params[0] = &argument_ptr;
1211 0 : params[1] = &argument2_ptr;
1212 :
1213 0 : fci.size = sizeof(fci);
1214 0 : fci.function_table = NULL;
1215 0 : fci.function_name = NULL;
1216 0 : fci.symbol_table = NULL;
1217 0 : fci.object_pp = &reflector_ptr;
1218 0 : fci.retval_ptr_ptr = &retval_ptr;
1219 0 : fci.param_count = ctor_argc;
1220 0 : fci.params = params;
1221 0 : fci.no_separation = 1;
1222 :
1223 0 : fcc.initialized = 1;
1224 0 : fcc.function_handler = ce_ptr->constructor;
1225 0 : fcc.calling_scope = ce_ptr;
1226 0 : fcc.object_pp = &reflector_ptr;
1227 :
1228 0 : result = zend_call_function(&fci, &fcc TSRMLS_CC);
1229 :
1230 0 : if (retval_ptr) {
1231 0 : zval_ptr_dtor(&retval_ptr);
1232 : }
1233 :
1234 0 : if (EG(exception)) {
1235 0 : zval_ptr_dtor(&reflector_ptr);
1236 0 : return;
1237 : }
1238 0 : if (result == FAILURE) {
1239 0 : zval_ptr_dtor(&reflector_ptr);
1240 0 : _DO_THROW("Could not create reflector");
1241 : }
1242 :
1243 : /* Call static reflection::export */
1244 0 : ZVAL_BOOL(&output, return_output);
1245 0 : params[0] = &reflector_ptr;
1246 0 : params[1] = &output_ptr;
1247 :
1248 0 : ZVAL_STRINGL(&fname, "export", sizeof("export") - 1, 0);
1249 0 : fci.function_table = &reflection_ptr->function_table;
1250 0 : fci.function_name = &fname;
1251 0 : fci.object_pp = NULL;
1252 0 : fci.retval_ptr_ptr = &retval_ptr;
1253 0 : fci.param_count = 2;
1254 0 : fci.params = params;
1255 0 : fci.no_separation = 1;
1256 :
1257 0 : result = zend_call_function(&fci, NULL TSRMLS_CC);
1258 :
1259 0 : if (result == FAILURE && EG(exception) == NULL) {
1260 0 : zval_ptr_dtor(&reflector_ptr);
1261 0 : zval_ptr_dtor(&retval_ptr);
1262 0 : _DO_THROW("Could not execute reflection::export()");
1263 : }
1264 :
1265 0 : if (return_output) {
1266 0 : COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
1267 : } else {
1268 0 : zval_ptr_dtor(&retval_ptr);
1269 : }
1270 :
1271 : /* Destruct reflector which is no longer needed */
1272 0 : zval_ptr_dtor(&reflector_ptr);
1273 : }
1274 : /* }}} */
1275 :
1276 : /* {{{ Preventing __clone from being called */
1277 : ZEND_METHOD(reflection, __clone)
1278 0 : {
1279 : /* Should never be executable */
1280 0 : _DO_THROW("Cannot clone object using __clone()");
1281 : }
1282 : /* }}} */
1283 :
1284 : /* {{{ proto public static mixed Reflection::export(Reflector r [, bool return])
1285 : Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
1286 : ZEND_METHOD(reflection, export)
1287 0 : {
1288 : zval *object, fname, *retval_ptr;
1289 : int result;
1290 0 : zend_bool return_output = 0;
1291 :
1292 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &object, reflector_ptr, &return_output) == FAILURE) {
1293 0 : return;
1294 : }
1295 :
1296 : /* Invoke the __toString() method */
1297 0 : ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring") - 1, 1);
1298 0 : result= call_user_function_ex(NULL, &object, &fname, &retval_ptr, 0, NULL, 0, NULL TSRMLS_CC);
1299 0 : zval_dtor(&fname);
1300 :
1301 0 : if (result == FAILURE) {
1302 0 : _DO_THROW("Invocation of method __toString() failed");
1303 : /* Returns from this function */
1304 : }
1305 :
1306 0 : if (!retval_ptr) {
1307 0 : zend_error(E_WARNING, "%s::__toString() did not return anything", Z_OBJCE_P(object)->name);
1308 0 : RETURN_FALSE;
1309 : }
1310 :
1311 0 : if (return_output) {
1312 0 : COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
1313 : } else {
1314 : /* No need for _r variant, return of __toString should always be a string */
1315 0 : zend_print_zval(retval_ptr, 0);
1316 0 : zend_printf("\n");
1317 0 : zval_ptr_dtor(&retval_ptr);
1318 : }
1319 : }
1320 : /* }}} */
1321 :
1322 : /* {{{ proto public static array Reflection::getModifierNames(int modifiers)
1323 : Returns an array of modifier names */
1324 : ZEND_METHOD(reflection, getModifierNames)
1325 0 : {
1326 : long modifiers;
1327 :
1328 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &modifiers) == FAILURE) {
1329 0 : return;
1330 : }
1331 :
1332 0 : array_init(return_value);
1333 :
1334 0 : if (modifiers & (ZEND_ACC_ABSTRACT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
1335 0 : add_next_index_stringl(return_value, "abstract", sizeof("abstract")-1, 1);
1336 : }
1337 0 : if (modifiers & (ZEND_ACC_FINAL | ZEND_ACC_FINAL_CLASS)) {
1338 0 : add_next_index_stringl(return_value, "final", sizeof("final")-1, 1);
1339 : }
1340 :
1341 : /* These are mutually exclusive */
1342 0 : switch (modifiers & ZEND_ACC_PPP_MASK) {
1343 : case ZEND_ACC_PUBLIC:
1344 0 : add_next_index_stringl(return_value, "public", sizeof("public")-1, 1);
1345 0 : break;
1346 : case ZEND_ACC_PRIVATE:
1347 0 : add_next_index_stringl(return_value, "private", sizeof("private")-1, 1);
1348 0 : break;
1349 : case ZEND_ACC_PROTECTED:
1350 0 : add_next_index_stringl(return_value, "protected", sizeof("protected")-1, 1);
1351 : break;
1352 : }
1353 :
1354 0 : if (modifiers & ZEND_ACC_STATIC) {
1355 0 : add_next_index_stringl(return_value, "static", sizeof("static")-1, 1);
1356 : }
1357 : }
1358 : /* }}} */
1359 :
1360 : /* {{{ proto public static mixed ReflectionFunction::export(string name [, bool return])
1361 : Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
1362 : ZEND_METHOD(reflection_function, export)
1363 0 : {
1364 0 : _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_function_ptr, 1);
1365 0 : }
1366 : /* }}} */
1367 :
1368 : /* {{{ proto public void ReflectionFunction::__construct(string name)
1369 : Constructor. Throws an Exception in case the given function does not exist */
1370 : ZEND_METHOD(reflection_function, __construct)
1371 0 : {
1372 : zval *name;
1373 : zval *object;
1374 : char *lcname;
1375 : reflection_object *intern;
1376 : zend_function *fptr;
1377 : char *name_str;
1378 : int name_len;
1379 :
1380 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
1381 0 : return;
1382 : }
1383 :
1384 0 : object = getThis();
1385 0 : intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
1386 0 : if (intern == NULL) {
1387 0 : return;
1388 : }
1389 0 : lcname = zend_str_tolower_dup(name_str, name_len);
1390 0 : if (zend_hash_find(EG(function_table), lcname, name_len + 1, (void **)&fptr) == FAILURE) {
1391 0 : efree(lcname);
1392 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
1393 : "Function %s() does not exist", name_str);
1394 0 : return;
1395 : }
1396 0 : efree(lcname);
1397 0 : MAKE_STD_ZVAL(name);
1398 0 : ZVAL_STRING(name, fptr->common.function_name, 1);
1399 0 : zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
1400 0 : intern->ptr = fptr;
1401 0 : intern->free_ptr = 0;
1402 0 : intern->ce = NULL;
1403 : }
1404 : /* }}} */
1405 :
1406 : /* {{{ proto public string ReflectionFunction::__toString()
1407 : Returns a string representation */
1408 : ZEND_METHOD(reflection_function, __toString)
1409 0 : {
1410 : reflection_object *intern;
1411 : zend_function *fptr;
1412 : string str;
1413 :
1414 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_function_abstract_ptr, 0);
1415 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1416 0 : string_init(&str);
1417 0 : _function_string(&str, fptr, intern->ce, "" TSRMLS_CC);
1418 0 : RETURN_STRINGL(str.string, str.len - 1, 0);
1419 : }
1420 : /* }}} */
1421 :
1422 : /* {{{ proto public string ReflectionFunction::getName()
1423 : Returns this function's name */
1424 : ZEND_METHOD(reflection, function_getName)
1425 0 : {
1426 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_function_abstract_ptr, 0);
1427 0 : _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
1428 : }
1429 : /* }}} */
1430 :
1431 : /* {{{ proto public bool ReflectionFunction::isInternal()
1432 : Returns whether this is an internal function */
1433 : ZEND_METHOD(reflection, function_isInternal)
1434 0 : {
1435 : reflection_object *intern;
1436 : zend_function *fptr;
1437 :
1438 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_function_abstract_ptr, 0);
1439 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1440 0 : RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION);
1441 : }
1442 : /* }}} */
1443 :
1444 : /* {{{ proto public bool ReflectionFunction::isUserDefined()
1445 : Returns whether this is an user-defined function */
1446 : ZEND_METHOD(reflection_function, isUserDefined)
1447 0 : {
1448 : reflection_object *intern;
1449 : zend_function *fptr;
1450 :
1451 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_function_abstract_ptr, 0);
1452 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1453 0 : RETURN_BOOL(fptr->type == ZEND_USER_FUNCTION);
1454 : }
1455 : /* }}} */
1456 :
1457 : /* {{{ proto public bool ReflectionFunction::isDisabled()
1458 : Returns whether this function has been disabled or not */
1459 : ZEND_METHOD(reflection_function, isDisabled)
1460 0 : {
1461 : reflection_object *intern;
1462 : zend_function *fptr;
1463 :
1464 0 : METHOD_NOTSTATIC(reflection_function_ptr);
1465 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1466 0 : RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION && fptr->internal_function.handler == zif_display_disabled_function);
1467 : }
1468 : /* }}} */
1469 :
1470 : /* {{{ proto public string ReflectionFunction::getFileName()
1471 : Returns the filename of the file this function was declared in */
1472 : ZEND_METHOD(reflection_function, getFileName)
1473 0 : {
1474 : reflection_object *intern;
1475 : zend_function *fptr;
1476 :
1477 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_function_abstract_ptr, 0);
1478 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1479 0 : if (fptr->type == ZEND_USER_FUNCTION) {
1480 0 : RETURN_STRING(fptr->op_array.filename, 1);
1481 : }
1482 0 : RETURN_FALSE;
1483 : }
1484 : /* }}} */
1485 :
1486 : /* {{{ proto public int ReflectionFunction::getStartLine()
1487 : Returns the line this function's declaration starts at */
1488 : ZEND_METHOD(reflection_function, getStartLine)
1489 0 : {
1490 : reflection_object *intern;
1491 : zend_function *fptr;
1492 :
1493 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_function_abstract_ptr, 0);
1494 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1495 0 : if (fptr->type == ZEND_USER_FUNCTION) {
1496 0 : RETURN_LONG(fptr->op_array.line_start);
1497 : }
1498 0 : RETURN_FALSE;
1499 : }
1500 : /* }}} */
1501 :
1502 : /* {{{ proto public int ReflectionFunction::getEndLine()
1503 : Returns the line this function's declaration ends at */
1504 : ZEND_METHOD(reflection_function, getEndLine)
1505 0 : {
1506 : reflection_object *intern;
1507 : zend_function *fptr;
1508 :
1509 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_function_abstract_ptr, 0);
1510 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1511 0 : if (fptr->type == ZEND_USER_FUNCTION) {
1512 0 : RETURN_LONG(fptr->op_array.line_end);
1513 : }
1514 0 : RETURN_FALSE;
1515 : }
1516 : /* }}} */
1517 :
1518 : /* {{{ proto public string ReflectionFunction::getDocComment()
1519 : Returns the doc comment for this function */
1520 : ZEND_METHOD(reflection_function, getDocComment)
1521 0 : {
1522 : reflection_object *intern;
1523 : zend_function *fptr;
1524 :
1525 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_function_abstract_ptr, 0);
1526 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1527 0 : if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
1528 0 : RETURN_STRINGL(fptr->op_array.doc_comment, fptr->op_array.doc_comment_len, 1);
1529 : }
1530 0 : RETURN_FALSE;
1531 : }
1532 : /* }}} */
1533 :
1534 : /* {{{ proto public array ReflectionFunction::getStaticVariables()
1535 : Returns an associative array containing this function's static variables and their values */
1536 : ZEND_METHOD(reflection_function, getStaticVariables)
1537 0 : {
1538 : zval *tmp_copy;
1539 : reflection_object *intern;
1540 : zend_function *fptr;
1541 :
1542 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_function_abstract_ptr, 0);
1543 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1544 :
1545 : /* Return an empty array in case no static variables exist */
1546 0 : array_init(return_value);
1547 0 : if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.static_variables != NULL) {
1548 0 : zend_hash_apply_with_argument(fptr->op_array.static_variables, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
1549 0 : zend_hash_copy(Z_ARRVAL_P(return_value), fptr->op_array.static_variables, (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *));
1550 : }
1551 : }
1552 : /* }}} */
1553 :
1554 : /* {{{ proto public mixed ReflectionFunction::invoke(mixed* args)
1555 : Invokes the function */
1556 : ZEND_METHOD(reflection_function, invoke)
1557 0 : {
1558 : zval *retval_ptr;
1559 : zval ***params;
1560 : int result;
1561 0 : int argc = ZEND_NUM_ARGS();
1562 : zend_fcall_info fci;
1563 : zend_fcall_info_cache fcc;
1564 : reflection_object *intern;
1565 : zend_function *fptr;
1566 :
1567 0 : METHOD_NOTSTATIC(reflection_function_ptr);
1568 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1569 :
1570 0 : params = safe_emalloc(sizeof(zval **), argc, 0);
1571 0 : if (zend_get_parameters_array_ex(argc, params) == FAILURE) {
1572 0 : efree(params);
1573 0 : RETURN_FALSE;
1574 : }
1575 :
1576 0 : fci.size = sizeof(fci);
1577 0 : fci.function_table = NULL;
1578 0 : fci.function_name = NULL;
1579 0 : fci.symbol_table = NULL;
1580 0 : fci.object_pp = NULL;
1581 0 : fci.retval_ptr_ptr = &retval_ptr;
1582 0 : fci.param_count = argc;
1583 0 : fci.params = params;
1584 0 : fci.no_separation = 1;
1585 :
1586 0 : fcc.initialized = 1;
1587 0 : fcc.function_handler = fptr;
1588 0 : fcc.calling_scope = EG(scope);
1589 0 : fcc.object_pp = NULL;
1590 :
1591 0 : result = zend_call_function(&fci, &fcc TSRMLS_CC);
1592 :
1593 0 : efree(params);
1594 :
1595 0 : if (result == FAILURE) {
1596 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
1597 : "Invocation of function %s() failed", fptr->common.function_name);
1598 0 : return;
1599 : }
1600 :
1601 0 : if (retval_ptr) {
1602 0 : COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
1603 : }
1604 : }
1605 : /* }}} */
1606 :
1607 : static int _zval_array_to_c_array(zval **arg, zval ****params TSRMLS_DC) /* {{{ */
1608 0 : {
1609 0 : *(*params)++ = arg;
1610 0 : return ZEND_HASH_APPLY_KEEP;
1611 : } /* }}} */
1612 :
1613 : /* {{{ proto public mixed ReflectionFunction::invokeArgs(array args)
1614 : Invokes the function and pass its arguments as array. */
1615 : ZEND_METHOD(reflection_function, invokeArgs)
1616 0 : {
1617 : zval *retval_ptr;
1618 : zval ***params;
1619 : int result;
1620 : int argc;
1621 : zend_fcall_info fci;
1622 : zend_fcall_info_cache fcc;
1623 : reflection_object *intern;
1624 : zend_function *fptr;
1625 : zval *param_array;
1626 :
1627 0 : METHOD_NOTSTATIC(reflection_function_ptr);
1628 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1629 :
1630 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", ¶m_array) == FAILURE) {
1631 0 : return;
1632 : }
1633 :
1634 0 : argc = zend_hash_num_elements(Z_ARRVAL_P(param_array));
1635 :
1636 0 : params = safe_emalloc(sizeof(zval **), argc, 0);
1637 0 : zend_hash_apply_with_argument(Z_ARRVAL_P(param_array), (apply_func_arg_t)_zval_array_to_c_array, ¶ms TSRMLS_CC);
1638 0 : params -= argc;
1639 :
1640 0 : fci.size = sizeof(fci);
1641 0 : fci.function_table = NULL;
1642 0 : fci.function_name = NULL;
1643 0 : fci.symbol_table = NULL;
1644 0 : fci.object_pp = NULL;
1645 0 : fci.retval_ptr_ptr = &retval_ptr;
1646 0 : fci.param_count = argc;
1647 0 : fci.params = params;
1648 0 : fci.no_separation = 1;
1649 :
1650 0 : fcc.initialized = 1;
1651 0 : fcc.function_handler = fptr;
1652 0 : fcc.calling_scope = EG(scope);
1653 0 : fcc.object_pp = NULL;
1654 :
1655 0 : result = zend_call_function(&fci, &fcc TSRMLS_CC);
1656 :
1657 0 : efree(params);
1658 :
1659 0 : if (result == FAILURE) {
1660 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
1661 : "Invocation of function %s() failed", fptr->common.function_name);
1662 0 : return;
1663 : }
1664 :
1665 0 : if (retval_ptr) {
1666 0 : COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
1667 : }
1668 : }
1669 : /* }}} */
1670 :
1671 : /* {{{ proto public bool ReflectionFunction::returnsReference()
1672 : Gets whether this function returns a reference */
1673 : ZEND_METHOD(reflection_function, returnsReference)
1674 0 : {
1675 : reflection_object *intern;
1676 : zend_function *fptr;
1677 :
1678 0 : METHOD_NOTSTATIC(reflection_function_abstract_ptr);
1679 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1680 :
1681 0 : RETURN_BOOL(fptr->op_array.return_reference);
1682 : }
1683 : /* }}} */
1684 :
1685 : /* {{{ proto public bool ReflectionFunction::getNumberOfParameters()
1686 : Gets the number of required parameters */
1687 : ZEND_METHOD(reflection_function, getNumberOfParameters)
1688 0 : {
1689 : reflection_object *intern;
1690 : zend_function *fptr;
1691 :
1692 0 : METHOD_NOTSTATIC(reflection_function_abstract_ptr);
1693 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1694 :
1695 0 : RETURN_LONG(fptr->common.num_args);
1696 : }
1697 : /* }}} */
1698 :
1699 : /* {{{ proto public bool ReflectionFunction::getNumberOfRequiredParameters()
1700 : Gets the number of required parameters */
1701 : ZEND_METHOD(reflection_function, getNumberOfRequiredParameters)
1702 0 : {
1703 : reflection_object *intern;
1704 : zend_function *fptr;
1705 :
1706 0 : METHOD_NOTSTATIC(reflection_function_abstract_ptr);
1707 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1708 :
1709 0 : RETURN_LONG(fptr->common.required_num_args);
1710 : }
1711 : /* }}} */
1712 :
1713 : /* {{{ proto public ReflectionParameter[] ReflectionFunction::getParameters()
1714 : Returns an array of parameter objects for this function */
1715 : ZEND_METHOD(reflection_function, getParameters)
1716 0 : {
1717 : reflection_object *intern;
1718 : zend_function *fptr;
1719 : zend_uint i;
1720 : struct _zend_arg_info *arg_info;
1721 :
1722 0 : METHOD_NOTSTATIC(reflection_function_abstract_ptr);
1723 0 : GET_REFLECTION_OBJECT_PTR(fptr);
1724 :
1725 0 : arg_info= fptr->common.arg_info;
1726 :
1727 0 : array_init(return_value);
1728 0 : for (i = 0; i < fptr->common.num_args; i++) {
1729 : zval *parameter;
1730 :
1731 0 : ALLOC_ZVAL(parameter);
1732 0 : reflection_parameter_factory(fptr, arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC);
1733 0 : add_next_index_zval(return_value, parameter);
1734 :
1735 0 : arg_info++;
1736 : }
1737 : }
1738 : /* }}} */
1739 :
1740 : #if MBO_0
1741 : /* {{{ proto public ReflectionExtension|NULL ReflectionFunction::getExtension()
1742 : Returns NULL or the extension the function belongs to */
1743 : ZEND_METHOD(reflection_function, getExtension)
1744 : {
1745 : reflection_object *intern;
1746 : zend_function *fptr;
1747 : zend_internal_function *internal;
1748 :
1749 : METHOD_NOTSTATIC(reflection_function_abstract_ptr);
1750 : GET_REFLECTION_OBJECT_PTR(fptr);
1751 :
1752 : if (fptr->type != ZEND_INTERNAL_FUNCTION) {
1753 : RETURN_NULL();
1754 : }
1755 :
1756 : internal = (zend_internal_function *)fptr;
1757 : if (internal->module) {
1758 : reflection_extension_factory(return_value, internal->module->name TSRMLS_CC);
1759 : } else {
1760 : RETURN_NULL();
1761 : }
1762 : }
1763 : /* }}} */
1764 : #endif
1765 :
1766 : #if MBO_0
1767 : /* {{{ proto public string|false ReflectionFunction::getExtensionName()
1768 : Returns false or the name of the extension the function belongs to */
1769 : ZEND_METHOD(reflection_function, getExtensionName)
1770 : {
1771 : reflection_object *intern;
1772 : zend_function *fptr;
1773 : zend_internal_function *internal;
1774 :
1775 : METHOD_NOTSTATIC(reflection_function_abstract_ptr);
1776 : GET_REFLECTION_OBJECT_PTR(fptr);
1777 :
1778 : if (fptr->type != ZEND_INTERNAL_FUNCTION) {
1779 : RETURN_FALSE;
1780 : }
1781 :
1782 : internal = (zend_internal_function *)fptr;
1783 : if (internal->module) {
1784 : RETURN_STRING(internal->module->name, 1);
1785 : } else {
1786 : RETURN_FALSE;
1787 : }
1788 : }
1789 : /* }}} */
1790 : #endif
1791 :
1792 : /* {{{ proto public static mixed ReflectionParameter::export(mixed function, mixed parameter [, bool return]) throws ReflectionException
1793 : Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
1794 : ZEND_METHOD(reflection_parameter, export)
1795 0 : {
1796 0 : _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_parameter_ptr, 2);
1797 0 : }
1798 : /* }}} */
1799 :
1800 : /* {{{ proto public void ReflectionParameter::__construct(mixed function, mixed parameter)
1801 : Constructor. Throws an Exception in case the given method does not exist */
1802 : ZEND_METHOD(reflection_parameter, __construct)
1803 0 : {
1804 : parameter_reference *ref;
1805 : zval *reference, **parameter;
1806 : zval *object;
1807 : zval *name;
1808 : reflection_object *intern;
1809 : zend_function *fptr;
1810 : struct _zend_arg_info *arg_info;
1811 : int position;
1812 0 : zend_class_entry *ce = NULL;
1813 :
1814 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zZ", &reference, ¶meter) == FAILURE) {
1815 0 : return;
1816 : }
1817 :
1818 0 : object = getThis();
1819 0 : intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
1820 0 : if (intern == NULL) {
1821 0 : return;
1822 : }
1823 :
1824 : /* First, find the function */
1825 0 : switch (Z_TYPE_P(reference)) {
1826 : case IS_STRING: {
1827 : unsigned int lcname_len;
1828 : char *lcname;
1829 :
1830 0 : lcname_len = Z_STRLEN_P(reference);
1831 0 : lcname = zend_str_tolower_dup(Z_STRVAL_P(reference), lcname_len);
1832 0 : if (zend_hash_find(EG(function_table), lcname, lcname_len + 1, (void**) &fptr) == FAILURE) {
1833 0 : efree(lcname);
1834 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
1835 : "Function %s() does not exist", Z_STRVAL_P(reference));
1836 0 : return;
1837 : }
1838 0 : efree(lcname);
1839 : }
1840 0 : ce = fptr->common.scope;
1841 0 : break;
1842 :
1843 : case IS_ARRAY: {
1844 : zval **classref;
1845 : zval **method;
1846 : zend_class_entry **pce;
1847 : unsigned int lcname_len;
1848 : char *lcname;
1849 :
1850 0 : if ((zend_hash_index_find(Z_ARRVAL_P(reference), 0, (void **) &classref) == FAILURE)
1851 : || (zend_hash_index_find(Z_ARRVAL_P(reference), 1, (void **) &method) == FAILURE)) {
1852 0 : _DO_THROW("Expected array($object, $method) or array($classname, $method)");
1853 : /* returns out of this function */
1854 : }
1855 :
1856 0 : if (Z_TYPE_PP(classref) == IS_OBJECT) {
1857 0 : ce = Z_OBJCE_PP(classref);
1858 : } else {
1859 0 : convert_to_string_ex(classref);
1860 0 : if (zend_lookup_class(Z_STRVAL_PP(classref), Z_STRLEN_PP(classref), &pce TSRMLS_CC) == FAILURE) {
1861 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
1862 : "Class %s does not exist", Z_STRVAL_PP(classref));
1863 0 : return;
1864 : }
1865 0 : ce = *pce;
1866 : }
1867 :
1868 0 : convert_to_string_ex(method);
1869 0 : lcname_len = Z_STRLEN_PP(method);
1870 0 : lcname = zend_str_tolower_dup(Z_STRVAL_PP(method), lcname_len);
1871 0 : if (zend_hash_find(&ce->function_table, lcname, lcname_len + 1, (void **) &fptr) == FAILURE) {
1872 0 : efree(lcname);
1873 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
1874 : "Method %s::%s() does not exist", Z_STRVAL_PP(classref), Z_TYPE_PP(method), Z_STRVAL_PP(method));
1875 0 : return;
1876 : }
1877 0 : efree(lcname);
1878 : }
1879 0 : break;
1880 :
1881 : default:
1882 0 : _DO_THROW("The parameter class is expected to be either a string or an array(class, method)");
1883 : /* returns out of this function */
1884 : }
1885 :
1886 : /* Now, search for the parameter */
1887 0 : arg_info = fptr->common.arg_info;
1888 0 : if (Z_TYPE_PP(parameter) == IS_LONG) {
1889 0 : position= Z_LVAL_PP(parameter);
1890 0 : if (position < 0 || (zend_uint)position >= fptr->common.num_args) {
1891 0 : _DO_THROW("The parameter specified by its offset could not be found");
1892 : /* returns out of this function */
1893 : }
1894 : } else {
1895 : zend_uint i;
1896 :
1897 0 : position= -1;
1898 0 : convert_to_string_ex(parameter);
1899 0 : for (i = 0; i < fptr->common.num_args; i++) {
1900 0 : if (arg_info[i].name && strcmp(arg_info[i].name, Z_STRVAL_PP(parameter)) == 0) {
1901 0 : position= i;
1902 0 : break;
1903 : }
1904 : }
1905 0 : if (position == -1) {
1906 0 : _DO_THROW("The parameter specified by its name could not be found");
1907 : /* returns out of this function */
1908 : }
1909 : }
1910 :
1911 0 : MAKE_STD_ZVAL(name);
1912 0 : if (arg_info[position].name) {
1913 0 : ZVAL_STRINGL(name, arg_info[position].name, arg_info[position].name_len, 1);
1914 : } else {
1915 0 : ZVAL_NULL(name);
1916 : }
1917 0 : zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
1918 :
1919 0 : ref = (parameter_reference*) emalloc(sizeof(parameter_reference));
1920 0 : ref->arg_info = &arg_info[position];
1921 0 : ref->offset = (zend_uint)position;
1922 0 : ref->required = fptr->common.required_num_args;
1923 0 : ref->fptr = fptr;
1924 0 : intern->ptr = ref;
1925 0 : intern->free_ptr = 1;
1926 0 : intern->ce = ce;
1927 : }
1928 : /* }}} */
1929 :
1930 : /* {{{ proto public string ReflectionParameter::__toString()
1931 : Returns a string representation */
1932 : ZEND_METHOD(reflection_parameter, __toString)
1933 0 : {
1934 : reflection_object *intern;
1935 : parameter_reference *param;
1936 : string str;
1937 :
1938 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0);
1939 0 : GET_REFLECTION_OBJECT_PTR(param);
1940 0 : string_init(&str);
1941 0 : _parameter_string(&str, param->fptr, param->arg_info, param->offset, param->required, "" TSRMLS_CC);
1942 0 : RETURN_STRINGL(str.string, str.len - 1, 0);
1943 : }
1944 : /* }}} */
1945 :
1946 : /* {{{ proto public string ReflectionParameter::getName()
1947 : Returns this parameters's name */
1948 : ZEND_METHOD(reflection_parameter, getName)
1949 0 : {
1950 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0);
1951 0 : _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
1952 : }
1953 : /* }}} */
1954 :
1955 : #if MBO_0
1956 : /* {{{ proto public ReflectionFunction ReflectionParameter::getDeclaringFunction()
1957 : Returns the ReflectionFunction for the function of this parameter */
1958 : ZEND_METHOD(reflection_parameter, getDeclaringFunction)
1959 : {
1960 : reflection_object *intern;
1961 : parameter_reference *param;
1962 :
1963 : METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0);
1964 : GET_REFLECTION_OBJECT_PTR(param);
1965 :
1966 : if (!param->fptr->common.scope) {
1967 : reflection_function_factory(param->fptr, return_value TSRMLS_CC);
1968 : } else {
1969 : reflection_method_factory(param->fptr->common.scope, param->fptr, return_value TSRMLS_CC);
1970 : }
1971 : }
1972 : /* }}} */
1973 : #endif
1974 :
1975 : /* {{{ proto public ReflectionClass|NULL ReflectionParameter::getDeclaringClass()
1976 : Returns in which class this parameter is defined (not the typehint of the parameter) */
1977 : ZEND_METHOD(reflection_parameter, getDeclaringClass)
1978 0 : {
1979 : reflection_object *intern;
1980 : parameter_reference *param;
1981 :
1982 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0);
1983 0 : GET_REFLECTION_OBJECT_PTR(param);
1984 :
1985 0 : if (param->fptr->common.scope) {
1986 0 : zend_reflection_class_factory(param->fptr->common.scope, return_value TSRMLS_CC);
1987 : }
1988 : }
1989 : /* }}} */
1990 :
1991 : /* {{{ proto public ReflectionClass|NULL ReflectionParameter::getClass()
1992 : Returns this parameters's class hint or NULL if there is none */
1993 : ZEND_METHOD(reflection_parameter, getClass)
1994 0 : {
1995 : reflection_object *intern;
1996 : parameter_reference *param;
1997 : zend_class_entry **pce;
1998 :
1999 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0);
2000 0 : GET_REFLECTION_OBJECT_PTR(param);
2001 :
2002 0 : if (param->arg_info->class_name) {
2003 : /* Class name is stored as a string, we might also get "self" or "parent"
2004 : * - For "self", simply use the function scope. If scope is NULL then
2005 : * the function is global and thus self does not make any sense
2006 : *
2007 : * - For "parent", use the function scope's parent. If scope is NULL then
2008 : * the function is global and thus parent does not make any sense.
2009 : * If the parent is NULL then the class does not extend anything and
2010 : * thus parent does not make any sense, either.
2011 : *
2012 : * TODO: Think about moving these checks to the compiler or some sort of
2013 : * lint-mode.
2014 : */
2015 0 : if (0 == strncmp(param->arg_info->class_name, "self", sizeof("self")- 1)) {
2016 0 : zend_class_entry *ce= param->fptr->common.scope;
2017 0 : if (!ce) {
2018 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2019 : "Parameter uses 'self' as type hint but function is not a class member!");
2020 0 : return;
2021 : }
2022 0 : pce= &ce;
2023 0 : } else if (0 == strncmp(param->arg_info->class_name, "parent", sizeof("parent")- 1)) {
2024 0 : zend_class_entry *ce= param->fptr->common.scope;
2025 0 : if (!ce) {
2026 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2027 : "Parameter uses 'parent' as type hint but function is not a class member!");
2028 0 : return;
2029 : }
2030 0 : if (!ce->parent) {
2031 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2032 : "Parameter uses 'parent' as type hint although class does not have a parent!");
2033 0 : return;
2034 : }
2035 0 : pce= &ce->parent;
2036 0 : } else if (zend_lookup_class(param->arg_info->class_name, param->arg_info->class_name_len, &pce TSRMLS_CC) == FAILURE) {
2037 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2038 : "Class %s does not exist", param->arg_info->class_name);
2039 0 : return;
2040 : }
2041 0 : zend_reflection_class_factory(*pce, return_value TSRMLS_CC);
2042 : }
2043 : }
2044 : /* }}} */
2045 :
2046 : /* {{{ proto public bool ReflectionParameter::isArray()
2047 : Returns whether parameter MUST be an array */
2048 : ZEND_METHOD(reflection_parameter, isArray)
2049 0 : {
2050 : reflection_object *intern;
2051 : parameter_reference *param;
2052 :
2053 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0);
2054 0 : GET_REFLECTION_OBJECT_PTR(param);
2055 :
2056 0 : RETVAL_BOOL(param->arg_info->array_type_hint);
2057 : }
2058 : /* }}} */
2059 :
2060 : /* {{{ proto public bool ReflectionParameter::allowsNull()
2061 : Returns whether NULL is allowed as this parameters's value */
2062 : ZEND_METHOD(reflection_parameter, allowsNull)
2063 0 : {
2064 : reflection_object *intern;
2065 : parameter_reference *param;
2066 :
2067 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0);
2068 0 : GET_REFLECTION_OBJECT_PTR(param);
2069 :
2070 0 : RETVAL_BOOL(param->arg_info->allow_null);
2071 : }
2072 : /* }}} */
2073 :
2074 : /* {{{ proto public bool ReflectionParameter::isPassedByReference()
2075 : Returns whether this parameters is passed to by reference */
2076 : ZEND_METHOD(reflection_parameter, isPassedByReference)
2077 0 : {
2078 : reflection_object *intern;
2079 : parameter_reference *param;
2080 :
2081 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0);
2082 0 : GET_REFLECTION_OBJECT_PTR(param);
2083 :
2084 0 : RETVAL_BOOL(param->arg_info->pass_by_reference);
2085 : }
2086 : /* }}} */
2087 :
2088 : #if MBO_0
2089 : /* {{{ proto public bool ReflectionParameter::getPosition()
2090 : Returns whether this parameter is an optional parameter */
2091 : ZEND_METHOD(reflection_parameter, getPosition)
2092 : {
2093 : reflection_object *intern;
2094 : parameter_reference *param;
2095 :
2096 : METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0);
2097 : GET_REFLECTION_OBJECT_PTR(param);
2098 :
2099 : RETVAL_LONG(param->offset);
2100 : }
2101 : /* }}} */
2102 : #endif
2103 :
2104 : /* {{{ proto public bool ReflectionParameter::isOptional()
2105 : Returns whether this parameter is an optional parameter */
2106 : ZEND_METHOD(reflection_parameter, isOptional)
2107 0 : {
2108 : reflection_object *intern;
2109 : parameter_reference *param;
2110 :
2111 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0);
2112 0 : GET_REFLECTION_OBJECT_PTR(param);
2113 :
2114 0 : RETVAL_BOOL(param->offset >= param->required);
2115 : }
2116 : /* }}} */
2117 :
2118 : /* {{{ proto public bool ReflectionParameter::isDefaultValueAvailable()
2119 : Returns whether the default value of this parameter is available */
2120 : ZEND_METHOD(reflection_parameter, isDefaultValueAvailable)
2121 0 : {
2122 : reflection_object *intern;
2123 : parameter_reference *param;
2124 : zend_op *precv;
2125 :
2126 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0);
2127 0 : GET_REFLECTION_OBJECT_PTR(param);
2128 :
2129 0 : if (param->fptr->type != ZEND_USER_FUNCTION)
2130 : {
2131 0 : RETURN_FALSE;
2132 : }
2133 0 : if (param->offset < param->required) {
2134 0 : RETURN_FALSE;
2135 : }
2136 0 : precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
2137 0 : if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) {
2138 0 : RETURN_FALSE;
2139 : }
2140 0 : RETURN_TRUE;
2141 : }
2142 : /* }}} */
2143 :
2144 : /* {{{ proto public bool ReflectionParameter::getDefaultValue()
2145 : Returns the default value of this parameter or throws an exception */
2146 : ZEND_METHOD(reflection_parameter, getDefaultValue)
2147 0 : {
2148 : reflection_object *intern;
2149 : parameter_reference *param;
2150 : zend_op *precv;
2151 : zval *zv, zv_copy;
2152 :
2153 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0);
2154 0 : GET_REFLECTION_OBJECT_PTR(param);
2155 :
2156 0 : if (param->fptr->type != ZEND_USER_FUNCTION)
2157 : {
2158 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Cannot determine default value for internal functions");
2159 0 : return;
2160 : }
2161 0 : if (param->offset < param->required) {
2162 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Parameter is not optional");
2163 0 : return;
2164 : }
2165 0 : precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
2166 0 : if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) {
2167 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Internal error");
2168 0 : return;
2169 : }
2170 :
2171 0 : zv_copy = precv->op2.u.constant;
2172 0 : zv = &zv_copy;
2173 0 : zval_update_constant_ex(&zv, (void*)0, param->fptr->common.scope TSRMLS_CC);
2174 0 : RETURN_ZVAL(zv, 1, 1);
2175 : }
2176 : /* }}} */
2177 :
2178 : /* {{{ proto public static mixed ReflectionMethod::export(mixed class, string name [, bool return]) throws ReflectionException
2179 : Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
2180 : ZEND_METHOD(reflection_method, export)
2181 0 : {
2182 0 : _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_method_ptr, 2);
2183 0 : }
2184 : /* }}} */
2185 :
2186 : /* {{{ proto public void ReflectionMethod::__construct(mixed class_or_method [, string name])
2187 : Constructor. Throws an Exception in case the given method does not exist */
2188 : ZEND_METHOD(reflection_method, __construct)
2189 0 : {
2190 : zval *name, *classname;
2191 : zval *object;
2192 : reflection_object *intern;
2193 : char *lcname;
2194 : zend_class_entry **pce;
2195 : zend_class_entry *ce;
2196 : zend_function *mptr;
2197 : char *name_str, *tmp;
2198 : int name_len, tmp_len;
2199 : zval ztmp;
2200 :
2201 0 : if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
2202 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
2203 0 : return;
2204 : }
2205 0 : if ((tmp = strstr(name_str, "::")) == NULL) {
2206 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Invalid method name %s", name_str);
2207 0 : return;
2208 : }
2209 0 : classname = &ztmp;
2210 0 : tmp_len = tmp - name_str;
2211 0 : ZVAL_STRINGL(classname, name_str, tmp_len, 1);
2212 0 : name_len = name_len - (tmp_len + 2);
2213 0 : name_str = tmp + 2;
2214 : }
2215 :
2216 0 : object = getThis();
2217 0 : intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
2218 0 : if (intern == NULL) {
2219 0 : return;
2220 : }
2221 :
2222 : /* Find the class entry */
2223 0 : switch (Z_TYPE_P(classname)) {
2224 : case IS_STRING:
2225 0 : if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
2226 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2227 : "Class %s does not exist", Z_STRVAL_P(classname));
2228 0 : if (classname == &ztmp) {
2229 0 : zval_dtor(&ztmp);
2230 : }
2231 0 : return;
2232 : }
2233 0 : ce = *pce;
2234 0 : break;
2235 :
2236 : case IS_OBJECT:
2237 0 : ce = Z_OBJCE_P(classname);
2238 0 : break;
2239 :
2240 : default:
2241 0 : if (classname == &ztmp) {
2242 0 : zval_dtor(&ztmp);
2243 : }
2244 0 : _DO_THROW("The parameter class is expected to be either a string or an object");
2245 : /* returns out of this function */
2246 : }
2247 :
2248 0 : if (classname == &ztmp) {
2249 0 : zval_dtor(&ztmp);
2250 : }
2251 :
2252 0 : MAKE_STD_ZVAL(classname);
2253 0 : ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
2254 :
2255 0 : zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
2256 :
2257 0 : lcname = zend_str_tolower_dup(name_str, name_len);
2258 :
2259 0 : if (zend_hash_find(&ce->function_table, lcname, name_len + 1, (void **) &mptr) == FAILURE) {
2260 0 : efree(lcname);
2261 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2262 : "Method %s::%s() does not exist", ce->name, name_str);
2263 0 : return;
2264 : }
2265 0 : efree(lcname);
2266 :
2267 0 : MAKE_STD_ZVAL(name);
2268 0 : ZVAL_STRING(name, mptr->common.function_name, 1);
2269 0 : zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
2270 0 : intern->ptr = mptr;
2271 0 : intern->free_ptr = 0;
2272 0 : intern->ce = ce;
2273 : }
2274 : /* }}} */
2275 :
2276 : /* {{{ proto public string ReflectionMethod::__toString()
2277 : Returns a string representation */
2278 : ZEND_METHOD(reflection_method, __toString)
2279 0 : {
2280 : reflection_object *intern;
2281 : zend_function *mptr;
2282 : string str;
2283 :
2284 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_method_ptr, 0);
2285 0 : GET_REFLECTION_OBJECT_PTR(mptr);
2286 0 : string_init(&str);
2287 0 : _function_string(&str, mptr, intern->ce, "" TSRMLS_CC);
2288 0 : RETURN_STRINGL(str.string, str.len - 1, 0);
2289 : }
2290 : /* }}} */
2291 :
2292 : /* {{{ proto public mixed ReflectionMethod::invoke(mixed object, mixed* args)
2293 : Invokes the method. */
2294 : ZEND_METHOD(reflection_method, invoke)
2295 0 : {
2296 : zval *retval_ptr;
2297 : zval ***params;
2298 : zval **object_pp;
2299 : reflection_object *intern;
2300 : zend_function *mptr;
2301 0 : int argc = ZEND_NUM_ARGS();
2302 : int result;
2303 : zend_fcall_info fci;
2304 : zend_fcall_info_cache fcc;
2305 : zend_class_entry *obj_ce;
2306 :
2307 0 : METHOD_NOTSTATIC(reflection_method_ptr);
2308 :
2309 0 : if (argc < 1) {
2310 0 : zend_error(E_WARNING, "Invoke() expects at least one parameter, none given");
2311 0 : RETURN_FALSE;
2312 : }
2313 :
2314 0 : GET_REFLECTION_OBJECT_PTR(mptr);
2315 :
2316 0 : if (!(mptr->common.fn_flags & ZEND_ACC_PUBLIC) ||
2317 : (mptr->common.fn_flags & ZEND_ACC_ABSTRACT)) {
2318 0 : if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
2319 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2320 : "Trying to invoke abstract method %s::%s()",
2321 : mptr->common.scope->name, mptr->common.function_name);
2322 : } else {
2323 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2324 : "Trying to invoke %s method %s::%s() from scope %s",
2325 : mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
2326 : mptr->common.scope->name, mptr->common.function_name,
2327 : Z_OBJCE_P(getThis())->name);
2328 : }
2329 0 : return;
2330 : }
2331 :
2332 0 : params = safe_emalloc(sizeof(zval **), argc, 0);
2333 0 : if (zend_get_parameters_array_ex(argc, params) == FAILURE) {
2334 0 : efree(params);
2335 0 : RETURN_FALSE;
2336 : }
2337 :
2338 : /* In case this is a static method, we should'nt pass an object_pp
2339 : * (which is used as calling context aka $this). We can thus ignore the
2340 : * first parameter.
2341 : *
2342 : * Else, we verify that the given object is an instance of the class.
2343 : */
2344 0 : if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
2345 0 : object_pp = NULL;
2346 0 : obj_ce = NULL;
2347 : } else {
2348 0 : if ((Z_TYPE_PP(params[0]) != IS_OBJECT)) {
2349 0 : efree(params);
2350 0 : _DO_THROW("Non-object passed to Invoke()");
2351 : /* Returns from this function */
2352 : }
2353 0 : obj_ce = Z_OBJCE_PP(params[0]);
2354 :
2355 0 : if (!instanceof_function(obj_ce, mptr->common.scope TSRMLS_CC)) {
2356 0 : efree(params);
2357 0 : _DO_THROW("Given object is not an instance of the class this method was declared in");
2358 : /* Returns from this function */
2359 : }
2360 :
2361 0 : object_pp = params[0];
2362 : }
2363 :
2364 0 : fci.size = sizeof(fci);
2365 0 : fci.function_table = NULL;
2366 0 : fci.function_name = NULL;
2367 0 : fci.symbol_table = NULL;
2368 0 : fci.object_pp = object_pp;
2369 0 : fci.retval_ptr_ptr = &retval_ptr;
2370 0 : fci.param_count = argc-1;
2371 0 : fci.params = params+1;
2372 0 : fci.no_separation = 1;
2373 :
2374 0 : fcc.initialized = 1;
2375 0 : fcc.function_handler = mptr;
2376 0 : fcc.calling_scope = obj_ce;
2377 0 : fcc.object_pp = object_pp;
2378 :
2379 0 : result = zend_call_function(&fci, &fcc TSRMLS_CC);
2380 :
2381 0 : efree(params);
2382 :
2383 0 : if (result == FAILURE) {
2384 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2385 : "Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name);
2386 0 : return;
2387 : }
2388 :
2389 0 : if (retval_ptr) {
2390 0 : COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
2391 : }
2392 : }
2393 : /* }}} */
2394 :
2395 : /* {{{ proto public mixed ReflectionMethod::invokeArgs(mixed object, array args)
2396 : Invokes the function and pass its arguments as array. */
2397 : ZEND_METHOD(reflection_method, invokeArgs)
2398 0 : {
2399 : zval *retval_ptr;
2400 : zval ***params;
2401 : zval *object;
2402 : reflection_object *intern;
2403 : zend_function *mptr;
2404 : int argc;
2405 : int result;
2406 : zend_fcall_info fci;
2407 : zend_fcall_info_cache fcc;
2408 : zend_class_entry *obj_ce;
2409 : zval *param_array;
2410 :
2411 0 : METHOD_NOTSTATIC(reflection_method_ptr);
2412 :
2413 0 : GET_REFLECTION_OBJECT_PTR(mptr);
2414 :
2415 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o!a", &object, ¶m_array) == FAILURE) {
2416 0 : return;
2417 : }
2418 :
2419 0 : if (!(mptr->common.fn_flags & ZEND_ACC_PUBLIC) ||
2420 : (mptr->common.fn_flags & ZEND_ACC_ABSTRACT)) {
2421 0 : if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
2422 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2423 : "Trying to invoke abstract method %s::%s",
2424 : mptr->common.scope->name, mptr->common.function_name);
2425 : } else {
2426 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2427 : "Trying to invoke %s method %s::%s from scope %s",
2428 : mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
2429 : mptr->common.scope->name, mptr->common.function_name,
2430 : Z_OBJCE_P(getThis())->name);
2431 : }
2432 0 : return;
2433 : }
2434 :
2435 0 : argc = zend_hash_num_elements(Z_ARRVAL_P(param_array));
2436 :
2437 0 : params = safe_emalloc(sizeof(zval **), argc, 0);
2438 0 : zend_hash_apply_with_argument(Z_ARRVAL_P(param_array), (apply_func_arg_t)_zval_array_to_c_array, ¶ms TSRMLS_CC);
2439 0 : params -= argc;
2440 :
2441 : /* In case this is a static method, we should'nt pass an object_pp
2442 : * (which is used as calling context aka $this). We can thus ignore the
2443 : * first parameter.
2444 : *
2445 : * Else, we verify that the given object is an instance of the class.
2446 : */
2447 0 : if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
2448 0 : object = NULL;
2449 0 : obj_ce = NULL;
2450 : } else {
2451 0 : if (!object) {
2452 0 : efree(params);
2453 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2454 : "Trying to invoke non static method %s::%s without an object",
2455 : mptr->common.scope->name, mptr->common.function_name);
2456 0 : return;
2457 : }
2458 :
2459 0 : obj_ce = Z_OBJCE_P(object);
2460 :
2461 0 : if (!instanceof_function(obj_ce, mptr->common.scope TSRMLS_CC)) {
2462 0 : efree(params);
2463 0 : _DO_THROW("Given object is not an instance of the class this method was declared in");
2464 : /* Returns from this function */
2465 : }
2466 : }
2467 :
2468 0 : fci.size = sizeof(fci);
2469 0 : fci.function_table = NULL;
2470 0 : fci.function_name = NULL;
2471 0 : fci.symbol_table = NULL;
2472 0 : fci.object_pp = &object;
2473 0 : fci.retval_ptr_ptr = &retval_ptr;
2474 0 : fci.param_count = argc;
2475 0 : fci.params = params;
2476 0 : fci.no_separation = 1;
2477 :
2478 0 : fcc.initialized = 1;
2479 0 : fcc.function_handler = mptr;
2480 0 : fcc.calling_scope = obj_ce;
2481 0 : fcc.object_pp = &object;
2482 :
2483 0 : result = zend_call_function(&fci, &fcc TSRMLS_CC);
2484 :
2485 0 : efree(params);
2486 :
2487 0 : if (result == FAILURE) {
2488 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2489 : "Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name);
2490 0 : return;
2491 : }
2492 :
2493 0 : if (retval_ptr) {
2494 0 : COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
2495 : }
2496 : }
2497 : /* }}} */
2498 :
2499 : /* {{{ proto public bool ReflectionMethod::isFinal()
2500 : Returns whether this method is final */
2501 : ZEND_METHOD(reflection_method, isFinal)
2502 0 : {
2503 0 : _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL);
2504 0 : }
2505 : /* }}} */
2506 :
2507 : /* {{{ proto public bool ReflectionMethod::isAbstract()
2508 : Returns whether this method is abstract */
2509 : ZEND_METHOD(reflection_method, isAbstract)
2510 0 : {
2511 0 : _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_ABSTRACT);
2512 0 : }
2513 : /* }}} */
2514 :
2515 : /* {{{ proto public bool ReflectionMethod::isPublic()
2516 : Returns whether this method is public */
2517 : ZEND_METHOD(reflection_method, isPublic)
2518 0 : {
2519 0 : _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC);
2520 0 : }
2521 : /* }}} */
2522 :
2523 : /* {{{ proto public bool ReflectionMethod::isPrivate()
2524 : Returns whether this method is private */
2525 : ZEND_METHOD(reflection_method, isPrivate)
2526 0 : {
2527 0 : _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
2528 0 : }
2529 : /* }}} */
2530 :
2531 : /* {{{ proto public bool ReflectionMethod::isProtected()
2532 : Returns whether this method is protected */
2533 : ZEND_METHOD(reflection_method, isProtected)
2534 0 : {
2535 0 : _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
2536 0 : }
2537 : /* }}} */
2538 :
2539 : /* {{{ proto public bool ReflectionMethod::isStatic()
2540 : Returns whether this method is static */
2541 : ZEND_METHOD(reflection_method, isStatic)
2542 0 : {
2543 0 : _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC);
2544 0 : }
2545 : /* }}} */
2546 :
2547 : /* {{{ proto public bool ReflectionFunction::isDeprecated()
2548 : Returns whether this function is deprecated */
2549 : ZEND_METHOD(reflection_function, isDeprecated)
2550 0 : {
2551 0 : _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_DEPRECATED);
2552 0 : }
2553 : /* }}} */
2554 :
2555 : /* {{{ proto public bool ReflectionMethod::isConstructor()
2556 : Returns whether this method is the constructor */
2557 : ZEND_METHOD(reflection_method, isConstructor)
2558 0 : {
2559 : reflection_object *intern;
2560 : zend_function *mptr;
2561 :
2562 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_method_ptr, 0);
2563 0 : GET_REFLECTION_OBJECT_PTR(mptr);
2564 : /* we need to check if the ctor is the ctor of the class level we we
2565 : * looking at since we might be looking at an inherited old style ctor
2566 : * defined in base class. */
2567 0 : RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_CTOR && intern->ce->constructor && intern->ce->constructor->common.scope == mptr->common.scope);
2568 : }
2569 : /* }}} */
2570 :
2571 : /* {{{ proto public bool ReflectionMethod::isDestructor()
2572 : Returns whether this method is static */
2573 : ZEND_METHOD(reflection_method, isDestructor)
2574 0 : {
2575 : reflection_object *intern;
2576 : zend_function *mptr;
2577 :
2578 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_method_ptr, 0);
2579 0 : GET_REFLECTION_OBJECT_PTR(mptr);
2580 0 : RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_DTOR);
2581 : }
2582 : /* }}} */
2583 :
2584 : /* {{{ proto public int ReflectionMethod::getModifiers()
2585 : Returns a bitfield of the access modifiers for this method */
2586 : ZEND_METHOD(reflection_method, getModifiers)
2587 0 : {
2588 : reflection_object *intern;
2589 : zend_function *mptr;
2590 :
2591 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_method_ptr, 0);
2592 0 : GET_REFLECTION_OBJECT_PTR(mptr);
2593 :
2594 0 : RETURN_LONG(mptr->common.fn_flags);
2595 : }
2596 : /* }}} */
2597 :
2598 : /* {{{ proto public ReflectionClass ReflectionMethod::getDeclaringClass()
2599 : Get the declaring class */
2600 : ZEND_METHOD(reflection_method, getDeclaringClass)
2601 0 : {
2602 : reflection_object *intern;
2603 : zend_function *mptr;
2604 :
2605 0 : METHOD_NOTSTATIC(reflection_method_ptr);
2606 0 : GET_REFLECTION_OBJECT_PTR(mptr);
2607 :
2608 0 : zend_reflection_class_factory(mptr->common.scope, return_value TSRMLS_CC);
2609 : }
2610 : /* }}} */
2611 :
2612 : /* {{{ proto public ReflectionClass ReflectionMethod::getPrototype()
2613 : Get the prototype */
2614 : ZEND_METHOD(reflection_method, getPrototype)
2615 0 : {
2616 : reflection_object *intern;
2617 : zend_function *mptr;
2618 :
2619 0 : METHOD_NOTSTATIC(reflection_method_ptr);
2620 0 : GET_REFLECTION_OBJECT_PTR(mptr);
2621 :
2622 0 : if (!mptr->common.prototype) {
2623 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2624 : "Method %s::%s does not have a prototype", intern->ce->name, mptr->common.function_name);
2625 0 : return;
2626 : }
2627 :
2628 0 : reflection_method_factory(mptr->common.prototype->common.scope, mptr->common.prototype, return_value TSRMLS_CC);
2629 : }
2630 : /* }}} */
2631 :
2632 : /* {{{ proto public static mixed ReflectionClass::export(mixed argument [, bool return]) throws ReflectionException
2633 : Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
2634 : ZEND_METHOD(reflection_class, export)
2635 0 : {
2636 0 : _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_class_ptr, 1);
2637 0 : }
2638 : /* }}} */
2639 :
2640 : /* {{{ reflection_class_object_ctor */
2641 : static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_object)
2642 0 : {
2643 : zval *argument;
2644 : zval *object;
2645 : zval *classname;
2646 : reflection_object *intern;
2647 : zend_class_entry **ce;
2648 :
2649 0 : if (is_object) {
2650 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &argument) == FAILURE) {
2651 0 : return;
2652 : }
2653 : } else {
2654 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &argument) == FAILURE) {
2655 0 : return;
2656 : }
2657 : }
2658 :
2659 0 : object = getThis();
2660 0 : intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
2661 0 : if (intern == NULL) {
2662 0 : return;
2663 : }
2664 :
2665 0 : if (Z_TYPE_P(argument) == IS_OBJECT) {
2666 0 : MAKE_STD_ZVAL(classname);
2667 0 : ZVAL_STRINGL(classname, Z_OBJCE_P(argument)->name, Z_OBJCE_P(argument)->name_length, 1);
2668 0 : zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &classname, sizeof(zval *), NULL);
2669 0 : intern->ptr = Z_OBJCE_P(argument);
2670 0 : if (is_object) {
2671 0 : intern->obj = argument;
2672 0 : zval_add_ref(&argument);
2673 : }
2674 : } else {
2675 0 : convert_to_string_ex(&argument);
2676 0 : if (zend_lookup_class(Z_STRVAL_P(argument), Z_STRLEN_P(argument), &ce TSRMLS_CC) == FAILURE) {
2677 0 : if (!EG(exception)) {
2678 0 : zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Class %s does not exist", Z_STRVAL_P(argument));
2679 : }
2680 0 : return;
2681 : }
2682 :
2683 0 : MAKE_STD_ZVAL(classname);
2684 0 : ZVAL_STRINGL(classname, (*ce)->name, (*ce)->name_length, 1);
2685 0 : zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &classname, sizeof(zval *), NULL);
2686 :
2687 0 : intern->ptr = *ce;
2688 : }
2689 0 : intern->free_ptr = 0;
2690 : }
2691 : /* }}} */
2692 :
2693 : /* {{{ proto public void ReflectionClass::__construct(mixed argument) throws ReflectionException
2694 : Constructor. Takes a string or an instance as an argument */
2695 : ZEND_METHOD(reflection_class, __construct)
2696 0 : {
2697 0 : reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
2698 0 : }
2699 : /* }}} */
2700 :
2701 : /* {{{ proto public array ReflectionClass::getStaticProperties()
2702 : Returns an associative array containing all static property values of the class */
2703 : ZEND_METHOD(reflection_class, getStaticProperties)
2704 0 : {
2705 : reflection_object *intern;
2706 : zend_class_entry *ce;
2707 : HashPosition pos;
2708 : zval **value;
2709 :
2710 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
2711 0 : GET_REFLECTION_OBJECT_PTR(ce);
2712 :
2713 0 : zend_update_class_constants(ce TSRMLS_CC);
2714 :
2715 0 : array_init(return_value);
2716 :
2717 0 : zend_hash_internal_pointer_reset_ex(CE_STATIC_MEMBERS(ce), &pos);
2718 :
2719 0 : while (zend_hash_get_current_data_ex(CE_STATIC_MEMBERS(ce), (void **) &value, &pos) == SUCCESS) {
2720 : uint key_len;
2721 : char *key;
2722 : ulong num_index;
2723 :
2724 0 : if (zend_hash_get_current_key_ex(CE_STATIC_MEMBERS(ce), &key, &key_len, &num_index, 0, &pos) != FAILURE && key) {
2725 : char *prop_name, *class_name;
2726 :
2727 0 : zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
2728 :
2729 0 : zval_add_ref(value);
2730 :
2731 0 : zend_hash_update(Z_ARRVAL_P(return_value), prop_name, strlen(prop_name)+1, value, sizeof(zval *), NULL);
2732 : }
2733 0 : zend_hash_move_forward_ex(CE_STATIC_MEMBERS(ce), &pos);
2734 : }
2735 : }
2736 : /* }}} */
2737 :
2738 : /* {{{ proto public mixed ReflectionClass::getStaticPropertyValue(string name [, mixed default])
2739 : Returns the value of a tsstic property */
2740 : ZEND_METHOD(reflection_class, getStaticPropertyValue)
2741 0 : {
2742 : reflection_object *intern;
2743 : zend_class_entry *ce;
2744 : char *name;
2745 : int name_len;
2746 0 : zval **prop, *def_value = NULL;
2747 :
2748 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &name, &name_len, &def_value) == FAILURE) {
2749 0 : return;
2750 : }
2751 :
2752 0 : GET_REFLECTION_OBJECT_PTR(ce);
2753 :
2754 0 : zend_update_class_constants(ce TSRMLS_CC);
2755 0 : prop = zend_std_get_static_property(ce, name, name_len, 1 TSRMLS_CC);
2756 0 : if (!prop) {
2757 0 : if (def_value) {
2758 0 : RETURN_ZVAL(def_value, 1, 0);
2759 : } else {
2760 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2761 : "Class %s does not have a property named %s", ce->name, name);
2762 : }
2763 0 : return;
2764 : } else {
2765 0 : RETURN_ZVAL(*prop, 1, 0);
2766 : }
2767 : }
2768 : /* }}} */
2769 :
2770 : /* {{{ proto public void ReflectionClass::setStaticPropertyValue($name, $value)
2771 : Sets the value of a static property */
2772 : ZEND_METHOD(reflection_class, setStaticPropertyValue)
2773 0 : {
2774 : reflection_object *intern;
2775 : zend_class_entry *ce;
2776 : char *name;
2777 : int name_len;
2778 : zval **variable_ptr, *value;
2779 : int refcount;
2780 : zend_uchar is_ref;
2781 :
2782 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &name_len, &value) == FAILURE) {
2783 0 : return;
2784 : }
2785 :
2786 0 : GET_REFLECTION_OBJECT_PTR(ce);
2787 :
2788 0 : zend_update_class_constants(ce TSRMLS_CC);
2789 0 : variable_ptr = zend_std_get_static_property(ce, name, name_len, 1 TSRMLS_CC);
2790 0 : if (!variable_ptr) {
2791 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
2792 : "Class %s does not have a property named %s", ce->name, name);
2793 0 : return;
2794 : }
2795 0 : refcount = (*variable_ptr)->refcount;
2796 0 : is_ref = (*variable_ptr)->is_ref;
2797 0 : zval_dtor(*variable_ptr);
2798 0 : **variable_ptr = *value;
2799 0 : zval_copy_ctor(*variable_ptr);
2800 0 : (*variable_ptr)->refcount = refcount;
2801 0 : (*variable_ptr)->is_ref = is_ref;
2802 :
2803 : }
2804 : /* }}} */
2805 :
2806 : /* {{{ proto public array ReflectionClass::getDefaultProperties()
2807 : Returns an associative array containing copies of all default property values of the class */
2808 : ZEND_METHOD(reflection_class, getDefaultProperties)
2809 0 : {
2810 : reflection_object *intern;
2811 : zend_class_entry *ce;
2812 : int count;
2813 :
2814 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
2815 0 : GET_REFLECTION_OBJECT_PTR(ce);
2816 0 : array_init(return_value);
2817 :
2818 0 : zend_update_class_constants(ce TSRMLS_CC);
2819 :
2820 0 : count = zend_hash_num_elements(&ce->default_properties);
2821 0 : if (count > 0) {
2822 : HashPosition pos;
2823 : zval **prop;
2824 :
2825 0 : zend_hash_internal_pointer_reset_ex(&ce->default_properties, &pos);
2826 0 : while (zend_hash_get_current_data_ex(&ce->default_properties, (void **) &prop, &pos) == SUCCESS) {
2827 : char *key, *class_name, *prop_name;
2828 : uint key_len;
2829 : ulong num_index;
2830 : zval *prop_copy;
2831 :
2832 0 : zend_hash_get_current_key_ex(&ce->default_properties, &key, &key_len, &num_index, 0, &pos);
2833 0 : zend_hash_move_forward_ex(&ce->default_properties, &pos);
2834 0 : zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
2835 0 : if (class_name && class_name[0] != '*' && strcmp(class_name, ce->name)) {
2836 : /* filter privates from base classes */
2837 0 : continue;
2838 : }
2839 :
2840 : /* copy: enforce read only access */
2841 0 : ALLOC_ZVAL(prop_copy);
2842 0 : *prop_copy = **prop;
2843 0 : zval_copy_ctor(prop_copy);
2844 0 : INIT_PZVAL(prop_copy);
2845 :
2846 0 : add_assoc_zval(return_value, prop_name, prop_copy);
2847 : }
2848 : }
2849 : }
2850 : /* }}} */
2851 :
2852 : /* {{{ proto public string ReflectionClass::__toString()
2853 : Returns a string representation */
2854 : ZEND_METHOD(reflection_class, __toString)
2855 0 : {
2856 : reflection_object *intern;
2857 : zend_class_entry *ce;
2858 : string str;
2859 :
2860 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
2861 0 : GET_REFLECTION_OBJECT_PTR(ce);
2862 0 : string_init(&str);
2863 0 : _class_string(&str, ce, intern->obj, "" TSRMLS_CC);
2864 0 : RETURN_STRINGL(str.string, str.len - 1, 0);
2865 : }
2866 : /* }}} */
2867 :
2868 : /* {{{ proto public string ReflectionClass::getName()
2869 : Returns the class' name */
2870 : ZEND_METHOD(reflection_class, getName)
2871 0 : {
2872 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
2873 0 : _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
2874 : }
2875 : /* }}} */
2876 :
2877 : /* {{{ proto public bool ReflectionClass::isInternal()
2878 : Returns whether this class is an internal class */
2879 : ZEND_METHOD(reflection_class, isInternal)
2880 0 : {
2881 : reflection_object *intern;
2882 : zend_class_entry *ce;
2883 :
2884 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
2885 0 : GET_REFLECTION_OBJECT_PTR(ce);
2886 0 : RETURN_BOOL(ce->type == ZEND_INTERNAL_CLASS);
2887 : }
2888 : /* }}} */
2889 :
2890 : /* {{{ proto public bool ReflectionClass::isUserDefined()
2891 : Returns whether this class is user-defined */
2892 : ZEND_METHOD(reflection_class, isUserDefined)
2893 0 : {
2894 : reflection_object *intern;
2895 : zend_class_entry *ce;
2896 :
2897 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
2898 0 : GET_REFLECTION_OBJECT_PTR(ce);
2899 0 : RETURN_BOOL(ce->type == ZEND_USER_CLASS);
2900 : }
2901 : /* }}} */
2902 :
2903 : /* {{{ proto public string ReflectionClass::getFileName()
2904 : Returns the filename of the file this class was declared in */
2905 : ZEND_METHOD(reflection_class, getFileName)
2906 0 : {
2907 : reflection_object *intern;
2908 : zend_class_entry *ce;
2909 :
2910 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
2911 0 : GET_REFLECTION_OBJECT_PTR(ce);
2912 0 : if (ce->type == ZEND_USER_CLASS) {
2913 0 : RETURN_STRING(ce->filename, 1);
2914 : }
2915 0 : RETURN_FALSE;
2916 : }
2917 : /* }}} */
2918 :
2919 : /* {{{ proto public int ReflectionClass::getStartLine()
2920 : Returns the line this class' declaration starts at */
2921 : ZEND_METHOD(reflection_class, getStartLine)
2922 0 : {
2923 : reflection_object *intern;
2924 : zend_class_entry *ce;
2925 :
2926 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
2927 0 : GET_REFLECTION_OBJECT_PTR(ce);
2928 0 : if (ce->type == ZEND_USER_FUNCTION) {
2929 0 : RETURN_LONG(ce->line_start);
2930 : }
2931 0 : RETURN_FALSE;
2932 : }
2933 : /* }}} */
2934 :
2935 : /* {{{ proto public int ReflectionClass::getEndLine()
2936 : Returns the line this class' declaration ends at */
2937 : ZEND_METHOD(reflection_class, getEndLine)
2938 0 : {
2939 : reflection_object *intern;
2940 : zend_class_entry *ce;
2941 :
2942 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
2943 0 : GET_REFLECTION_OBJECT_PTR(ce);
2944 0 : if (ce->type == ZEND_USER_CLASS) {
2945 0 : RETURN_LONG(ce->line_end);
2946 : }
2947 0 : RETURN_FALSE;
2948 : }
2949 : /* }}} */
2950 :
2951 : /* {{{ proto public string ReflectionClass::getDocComment()
2952 : Returns the doc comment for this class */
2953 : ZEND_METHOD(reflection_class, getDocComment)
2954 0 : {
2955 : reflection_object *intern;
2956 : zend_class_entry *ce;
2957 :
2958 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
2959 0 : GET_REFLECTION_OBJECT_PTR(ce);
2960 0 : if (ce->type == ZEND_USER_CLASS && ce->doc_comment) {
2961 0 : RETURN_STRINGL(ce->doc_comment, ce->doc_comment_len, 1);
2962 : }
2963 0 : RETURN_FALSE;
2964 : }
2965 : /* }}} */
2966 :
2967 : /* {{{ proto public ReflectionMethod ReflectionClass::getConstructor()
2968 : Returns the class' constructor if there is one, NULL otherwise */
2969 : ZEND_METHOD(reflection_class, getConstructor)
2970 0 : {
2971 : reflection_object *intern;
2972 : zend_class_entry *ce;
2973 :
2974 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
2975 0 : GET_REFLECTION_OBJECT_PTR(ce);
2976 :
2977 0 : if (ce->constructor) {
2978 0 : reflection_method_factory(ce, ce->constructor, return_value TSRMLS_CC);
2979 : } else {
2980 0 : RETURN_NULL();
2981 : }
2982 : }
2983 : /* }}} */
2984 :
2985 : /* {{{ proto public bool ReflectionClass::hasMethod(string name)
2986 : Returns whether a method exists or not */
2987 : ZEND_METHOD(reflection_class, hasMethod)
2988 0 : {
2989 : reflection_object *intern;
2990 : zend_class_entry *ce;
2991 : char *name, *lc_name;
2992 : int name_len;
2993 :
2994 0 : METHOD_NOTSTATIC(reflection_class_ptr);
2995 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
2996 0 : return;
2997 : }
2998 :
2999 0 : GET_REFLECTION_OBJECT_PTR(ce);
3000 0 : lc_name = zend_str_tolower_dup(name, name_len);
3001 0 : if (zend_hash_exists(&ce->function_table, lc_name, name_len + 1)) {
3002 0 : efree(lc_name);
3003 0 : RETURN_TRUE;
3004 : } else {
3005 0 : efree(lc_name);
3006 0 : RETURN_FALSE;
3007 : }
3008 : }
3009 : /* }}} */
3010 :
3011 : /* {{{ proto public ReflectionMethod ReflectionClass::getMethod(string name) throws ReflectionException
3012 : Returns the class' method specified by its name */
3013 : ZEND_METHOD(reflection_class, getMethod)
3014 0 : {
3015 : reflection_object *intern;
3016 : zend_class_entry *ce;
3017 : zend_function *mptr;
3018 : char *name, *lc_name;
3019 : int name_len;
3020 :
3021 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3022 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
3023 0 : return;
3024 : }
3025 :
3026 0 : GET_REFLECTION_OBJECT_PTR(ce);
3027 0 : lc_name = zend_str_tolower_dup(name, name_len);
3028 0 : if (zend_hash_find(&ce->function_table, lc_name, name_len + 1, (void**) &mptr) == SUCCESS) {
3029 0 : reflection_method_factory(ce, mptr, return_value TSRMLS_CC);
3030 0 : efree(lc_name);
3031 : } else {
3032 0 : efree(lc_name);
3033 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
3034 : "Method %s does not exist", name);
3035 0 : return;
3036 : }
3037 : }
3038 : /* }}} */
3039 :
3040 : /* {{{ _addmethod */
3041 : static int _addmethod(zend_function *mptr, int num_args, va_list args, zend_hash_key *hash_key)
3042 0 : {
3043 : zval *method;
3044 0 : zend_class_entry *ce = *va_arg(args, zend_class_entry**);
3045 0 : zval *retval = va_arg(args, zval*);
3046 0 : long filter = va_arg(args, long);
3047 :
3048 0 : if (mptr->common.fn_flags & filter) {
3049 : TSRMLS_FETCH();
3050 0 : ALLOC_ZVAL(method);
3051 0 : reflection_method_factory(ce, mptr, method TSRMLS_CC);
3052 0 : add_next_index_zval(retval, method);
3053 : }
3054 0 : return 0;
3055 : }
3056 : /* }}} */
3057 :
3058 : /* {{{ proto public ReflectionMethod[] ReflectionClass::getMethods([long $filter])
3059 : Returns an array of this class' methods */
3060 : ZEND_METHOD(reflection_class, getMethods)
3061 0 : {
3062 : reflection_object *intern;
3063 : zend_class_entry *ce;
3064 0 : long filter = 0;
3065 0 : int argc = ZEND_NUM_ARGS();
3066 :
3067 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3068 0 : if (argc) {
3069 0 : if (zend_parse_parameters(argc TSRMLS_CC, "|l", &filter) == FAILURE) {
3070 0 : return;
3071 : }
3072 : } else {
3073 : /* No parameters given, default to "return all" */
3074 0 : filter = ZEND_ACC_PPP_MASK | ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL | ZEND_ACC_STATIC;
3075 : }
3076 :
3077 0 : GET_REFLECTION_OBJECT_PTR(ce);
3078 :
3079 0 : array_init(return_value);
3080 0 : zend_hash_apply_with_arguments(&ce->function_table, (apply_func_args_t) _addmethod, 3, &ce, return_value, filter);
3081 : }
3082 : /* }}} */
3083 :
3084 : /* {{{ proto public bool ReflectionClass::hasProperty(string name)
3085 : Returns whether a property exists or not */
3086 : ZEND_METHOD(reflection_class, hasProperty)
3087 0 : {
3088 : reflection_object *intern;
3089 : zend_class_entry *ce;
3090 : char *name;
3091 : int name_len;
3092 : zval *property;
3093 :
3094 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3095 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
3096 0 : return;
3097 : }
3098 :
3099 0 : GET_REFLECTION_OBJECT_PTR(ce);
3100 0 : if (zend_hash_exists(&ce->properties_info, name, name_len + 1)) {
3101 0 : RETURN_TRUE;
3102 : } else {
3103 0 : if (intern->obj && Z_OBJ_HANDLER_P(intern->obj, has_property))
3104 : {
3105 0 : MAKE_STD_ZVAL(property);
3106 0 : ZVAL_STRINGL(property, name, name_len, 1);
3107 0 : if (Z_OBJ_HANDLER_P(intern->obj, has_property)(intern->obj, property, 2 TSRMLS_CC)) {
3108 0 : zval_ptr_dtor(&property);
3109 0 : RETURN_TRUE;
3110 : }
3111 0 : zval_ptr_dtor(&property);
3112 : }
3113 0 : RETURN_FALSE;
3114 : }
3115 : }
3116 : /* }}} */
3117 :
3118 : /* {{{ proto public ReflectionProperty ReflectionClass::getProperty(string name) throws ReflectionException
3119 : Returns the class' property specified by its name */
3120 : ZEND_METHOD(reflection_class, getProperty)
3121 0 : {
3122 : reflection_object *intern;
3123 : zend_class_entry *ce, **pce;
3124 : zend_property_info *property_info;
3125 : char *name, *tmp, *classname;
3126 : int name_len, classname_len;
3127 :
3128 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3129 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
3130 0 : return;
3131 : }
3132 :
3133 0 : GET_REFLECTION_OBJECT_PTR(ce);
3134 0 : if (zend_hash_find(&ce->properties_info, name, name_len + 1, (void**) &property_info) == SUCCESS && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
3135 0 : reflection_property_factory(ce, property_info, return_value TSRMLS_CC);
3136 0 : return;
3137 : }
3138 0 : if ((tmp = strstr(name, "::")) != NULL) {
3139 0 : classname_len = tmp - name;
3140 0 : classname = zend_str_tolower_dup(name, classname_len);
3141 0 : classname[classname_len] = '\0';
3142 0 : name_len = name_len - (classname_len + 2);
3143 0 : name = tmp + 2;
3144 :
3145 0 : if (zend_lookup_class(classname, classname_len, &pce TSRMLS_CC) == FAILURE) {
3146 0 : if (!EG(exception)) {
3147 0 : zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Class %s does not exist", classname);
3148 : }
3149 0 : efree(classname);
3150 0 : return;
3151 : }
3152 0 : efree(classname);
3153 :
3154 0 : if (!instanceof_function(ce, *pce TSRMLS_CC)) {
3155 0 : zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Fully qualified property name %s::%s does not specify a base class of %s", (*pce)->name, name, ce->name);
3156 0 : return;
3157 : }
3158 0 : ce = *pce;
3159 :
3160 0 : if (zend_hash_find(&ce->properties_info, name, name_len + 1, (void**) &property_info) == SUCCESS && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
3161 0 : reflection_property_factory(ce, property_info, return_value TSRMLS_CC);
3162 0 : return;
3163 : }
3164 : }
3165 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
3166 : "Property %s does not exist", name);
3167 : }
3168 : /* }}} */
3169 :
3170 : /* {{{ _addproperty */
3171 : static int _addproperty(zend_property_info *pptr, int num_args, va_list args, zend_hash_key *hash_key)
3172 0 : {
3173 : zval *property;
3174 0 : zend_class_entry *ce = *va_arg(args, zend_class_entry**);
3175 0 : zval *retval = va_arg(args, zval*);
3176 0 : long filter = va_arg(args, long);
3177 :
3178 0 : if (pptr->flags & ZEND_ACC_SHADOW) {
3179 0 : return 0;
3180 : }
3181 :
3182 0 : if (pptr->flags & filter) {
3183 : TSRMLS_FETCH();
3184 0 : ALLOC_ZVAL(property);
3185 0 : reflection_property_factory(ce, pptr, property TSRMLS_CC);
3186 0 : add_next_index_zval(retval, property);
3187 : }
3188 0 : return 0;
3189 : }
3190 : /* }}} */
3191 :
3192 : /* {{{ _adddynproperty */
3193 : static int _adddynproperty(zval **pptr, int num_args, va_list args, zend_hash_key *hash_key)
3194 0 : {
3195 : zval *property;
3196 0 : zend_class_entry *ce = *va_arg(args, zend_class_entry**);
3197 0 : zval *retval = va_arg(args, zval*), member;
3198 : TSRMLS_FETCH();
3199 :
3200 0 : if (hash_key->arKey[0] == '\0') {
3201 0 : return 0; /* non public cannot be dynamic */
3202 : }
3203 :
3204 0 : ZVAL_STRINGL(&member, hash_key->arKey, hash_key->nKeyLength-1, 0);
3205 0 : if (zend_get_property_info(ce, &member, 1 TSRMLS_CC) == &EG(std_property_info)) {
3206 0 : MAKE_STD_ZVAL(property);
3207 0 : reflection_property_factory(ce, &EG(std_property_info), property TSRMLS_CC);
3208 0 : add_next_index_zval(retval, property);
3209 : }
3210 0 : return 0;
3211 : }
3212 : /* }}} */
3213 :
3214 : /* {{{ proto public ReflectionProperty[] ReflectionClass::getProperties([long $filter])
3215 : Returns an array of this class' properties */
3216 : ZEND_METHOD(reflection_class, getProperties)
3217 0 : {
3218 : reflection_object *intern;
3219 : zend_class_entry *ce;
3220 0 : long filter = 0;
3221 0 : int argc = ZEND_NUM_ARGS();
3222 :
3223 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3224 0 : if (argc) {
3225 0 : if (zend_parse_parameters(argc TSRMLS_CC, "|l", &filter) == FAILURE) {
3226 0 : return;
3227 : }
3228 : } else {
3229 : /* No parameters given, default to "return all" */
3230 0 : filter = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC;
3231 : }
3232 :
3233 0 : GET_REFLECTION_OBJECT_PTR(ce);
3234 :
3235 0 : array_init(return_value);
3236 0 : zend_hash_apply_with_arguments(&ce->properties_info, (apply_func_args_t) _addproperty, 3, &ce, return_value, filter);
3237 :
3238 0 : if (intern->obj && (filter & ZEND_ACC_PUBLIC) != 0 && Z_OBJ_HT_P(intern->obj)->get_properties) {
3239 0 : HashTable *properties = Z_OBJ_HT_P(intern->obj)->get_properties(intern->obj TSRMLS_CC);
3240 0 : zend_hash_apply_with_arguments(properties, (apply_func_args_t) _adddynproperty, 2, &ce, return_value);
3241 : }
3242 : }
3243 : /* }}} */
3244 :
3245 : /* {{{ proto public bool ReflectionClass::hasConstant(string name)
3246 : Returns whether a constant exists or not */
3247 : ZEND_METHOD(reflection_class, hasConstant)
3248 0 : {
3249 : reflection_object *intern;
3250 : zend_class_entry *ce;
3251 : char *name;
3252 : int name_len;
3253 :
3254 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3255 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
3256 0 : return;
3257 : }
3258 :
3259 0 : GET_REFLECTION_OBJECT_PTR(ce);
3260 0 : if (zend_hash_exists(&ce->constants_table, name, name_len + 1)) {
3261 0 : RETURN_TRUE;
3262 : } else {
3263 0 : RETURN_FALSE;
3264 : }
3265 : }
3266 : /* }}} */
3267 :
3268 : /* {{{ proto public array ReflectionClass::getConstants()
3269 : Returns an associative array containing this class' constants and their values */
3270 : ZEND_METHOD(reflection_class, getConstants)
3271 0 : {
3272 : zval *tmp_copy;
3273 : reflection_object *intern;
3274 : zend_class_entry *ce;
3275 :
3276 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
3277 0 : GET_REFLECTION_OBJECT_PTR(ce);
3278 0 : array_init(return_value);
3279 0 : zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
3280 0 : zend_hash_copy(Z_ARRVAL_P(return_value), &ce->constants_table, (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *));
3281 : }
3282 : /* }}} */
3283 :
3284 : /* {{{ proto public mixed ReflectionClass::getConstant(string name)
3285 : Returns the class' constant specified by its name */
3286 : ZEND_METHOD(reflection_class, getConstant)
3287 0 : {
3288 : reflection_object *intern;
3289 : zend_class_entry *ce;
3290 : zval **value;
3291 : char *name;
3292 : int name_len;
3293 :
3294 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3295 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
3296 0 : return;
3297 : }
3298 :
3299 0 : GET_REFLECTION_OBJECT_PTR(ce);
3300 0 : zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
3301 0 : if (zend_hash_find(&ce->constants_table, name, name_len + 1, (void **) &value) == FAILURE) {
3302 0 : RETURN_FALSE;
3303 : }
3304 0 : *return_value = **value;
3305 0 : zval_copy_ctor(return_value);
3306 0 : INIT_PZVAL(return_value);
3307 : }
3308 : /* }}} */
3309 :
3310 : /* {{{ _class_check_flag */
3311 : static void _class_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
3312 0 : {
3313 : reflection_object *intern;
3314 : zend_class_entry *ce;
3315 :
3316 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
3317 0 : GET_REFLECTION_OBJECT_PTR(ce);
3318 0 : RETVAL_BOOL(ce->ce_flags & mask);
3319 : }
3320 : /* }}} */
3321 :
3322 : /* {{{ proto public bool ReflectionClass::isInstantiable()
3323 : Returns whether this class is instantiable */
3324 : ZEND_METHOD(reflection_class, isInstantiable)
3325 0 : {
3326 : reflection_object *intern;
3327 : zend_class_entry *ce;
3328 :
3329 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
3330 0 : GET_REFLECTION_OBJECT_PTR(ce);
3331 0 : if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS)) {
3332 0 : RETURN_FALSE;
3333 : }
3334 :
3335 : /* Basically, the class is instantiable. Though, if there is a constructor
3336 : * and it is not publicly accessible, it isn't! */
3337 0 : if (!ce->constructor) {
3338 0 : RETURN_TRUE;
3339 : }
3340 :
3341 0 : RETURN_BOOL(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC);
3342 : }
3343 : /* }}} */
3344 :
3345 : /* {{{ proto public bool ReflectionClass::isInterface()
3346 : Returns whether this is an interface or a class */
3347 : ZEND_METHOD(reflection_class, isInterface)
3348 0 : {
3349 0 : _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_INTERFACE);
3350 0 : }
3351 : /* }}} */
3352 :
3353 : /* {{{ proto public bool ReflectionClass::isFinal()
3354 : Returns whether this class is final */
3355 : ZEND_METHOD(reflection_class, isFinal)
3356 0 : {
3357 0 : _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL_CLASS);
3358 0 : }
3359 : /* }}} */
3360 :
3361 : /* {{{ proto public bool ReflectionClass::isAbstract()
3362 : Returns whether this class is abstract */
3363 : ZEND_METHOD(reflection_class, isAbstract)
3364 0 : {
3365 0 : _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
3366 0 : }
3367 : /* }}} */
3368 :
3369 : /* {{{ proto public int ReflectionClass::getModifiers()
3370 : Returns a bitfield of the access modifiers for this class */
3371 : ZEND_METHOD(reflection_class, getModifiers)
3372 0 : {
3373 : reflection_object *intern;
3374 : zend_class_entry *ce;
3375 :
3376 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
3377 0 : GET_REFLECTION_OBJECT_PTR(ce);
3378 :
3379 0 : RETURN_LONG(ce->ce_flags);
3380 : }
3381 : /* }}} */
3382 :
3383 : /* {{{ proto public bool ReflectionClass::isInstance(stdclass object)
3384 : Returns whether the given object is an instance of this class */
3385 : ZEND_METHOD(reflection_class, isInstance)
3386 0 : {
3387 : reflection_object *intern;
3388 : zend_class_entry *ce;
3389 : zval *object;
3390 :
3391 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3392 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) {
3393 0 : return;
3394 : }
3395 0 : GET_REFLECTION_OBJECT_PTR(ce);
3396 0 : RETURN_BOOL(ce == Z_OBJCE_P(object));
3397 : }
3398 : /* }}} */
3399 :
3400 : /* {{{ proto public stdclass ReflectionClass::newInstance(mixed* args, ...)
3401 : Returns an instance of this class */
3402 : ZEND_METHOD(reflection_class, newInstance)
3403 0 : {
3404 : zval *retval_ptr;
3405 : reflection_object *intern;
3406 : zend_class_entry *ce;
3407 0 : int argc = ZEND_NUM_ARGS();
3408 :
3409 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3410 0 : GET_REFLECTION_OBJECT_PTR(ce);
3411 :
3412 : /* Run the constructor if there is one */
3413 0 : if (ce->constructor) {
3414 : zval ***params;
3415 : zend_fcall_info fci;
3416 : zend_fcall_info_cache fcc;
3417 :
3418 0 : if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
3419 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
3420 0 : return;
3421 : }
3422 :
3423 0 : params = safe_emalloc(sizeof(zval **), argc, 0);
3424 0 : if (zend_get_parameters_array_ex(argc, params) == FAILURE) {
3425 0 : efree(params);
3426 0 : RETURN_FALSE;
3427 : }
3428 :
3429 0 : object_init_ex(return_value, ce);
3430 :
3431 0 : fci.size = sizeof(fci);
3432 0 : fci.function_table = EG(function_table);
3433 0 : fci.function_name = NULL;
3434 0 : fci.symbol_table = NULL;
3435 0 : fci.object_pp = &return_value;
3436 0 : fci.retval_ptr_ptr = &retval_ptr;
3437 0 : fci.param_count = argc;
3438 0 : fci.params = params;
3439 0 : fci.no_separation = 1;
3440 :
3441 0 : fcc.initialized = 1;
3442 0 : fcc.function_handler = ce->constructor;
3443 0 : fcc.calling_scope = EG(scope);
3444 0 : fcc.object_pp = &return_value;
3445 :
3446 0 : if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
3447 0 : efree(params);
3448 0 : zval_ptr_dtor(&retval_ptr);
3449 0 : zend_error(E_WARNING, "Invocation of %s's constructor failed", ce->name);
3450 0 : RETURN_NULL();
3451 : }
3452 0 : if (retval_ptr) {
3453 0 : zval_ptr_dtor(&retval_ptr);
3454 : }
3455 0 : efree(params);
3456 0 : } else if (!ZEND_NUM_ARGS()) {
3457 0 : object_init_ex(return_value, ce);
3458 : } else {
3459 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ce->name);
3460 : }
3461 : }
3462 : /* }}} */
3463 :
3464 : /* {{{ proto public stdclass ReflectionClass::newInstanceArgs([array args])
3465 : Returns an instance of this class */
3466 : ZEND_METHOD(reflection_class, newInstanceArgs)
3467 0 : {
3468 : zval *retval_ptr;
3469 : reflection_object *intern;
3470 : zend_class_entry *ce;
3471 0 : int argc = 0;
3472 : HashTable *args;
3473 :
3474 :
3475 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3476 0 : GET_REFLECTION_OBJECT_PTR(ce);
3477 :
3478 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|h", &args) == FAILURE) {
3479 0 : return;
3480 : }
3481 0 : if (ZEND_NUM_ARGS() > 0) {
3482 0 : argc = args->nNumOfElements;
3483 : }
3484 :
3485 : /* Run the constructor if there is one */
3486 0 : if (ce->constructor) {
3487 0 : zval ***params = NULL;
3488 : zend_fcall_info fci;
3489 : zend_fcall_info_cache fcc;
3490 :
3491 0 : if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
3492 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
3493 0 : return;
3494 : }
3495 :
3496 0 : if (argc) {
3497 0 : params = safe_emalloc(sizeof(zval **), argc, 0);
3498 0 : zend_hash_apply_with_argument(args, (apply_func_arg_t)_zval_array_to_c_array, ¶ms TSRMLS_CC);
3499 0 : params -= argc;
3500 : }
3501 :
3502 0 : object_init_ex(return_value, ce);
3503 :
3504 0 : fci.size = sizeof(fci);
3505 0 : fci.function_table = EG(function_table);
3506 0 : fci.function_name = NULL;
3507 0 : fci.symbol_table = NULL;
3508 0 : fci.object_pp = &return_value;
3509 0 : fci.retval_ptr_ptr = &retval_ptr;
3510 0 : fci.param_count = argc;
3511 0 : fci.params = params;
3512 0 : fci.no_separation = 1;
3513 :
3514 0 : fcc.initialized = 1;
3515 0 : fcc.function_handler = ce->constructor;
3516 0 : fcc.calling_scope = EG(scope);
3517 0 : fcc.object_pp = &return_value;
3518 :
3519 0 : if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
3520 0 : if (params) {
3521 0 : efree(params);
3522 : }
3523 0 : zval_ptr_dtor(&retval_ptr);
3524 0 : zend_error(E_WARNING, "Invocation of %s's constructor failed", ce->name);
3525 0 : RETURN_NULL();
3526 : }
3527 0 : if (retval_ptr) {
3528 0 : zval_ptr_dtor(&retval_ptr);
3529 : }
3530 0 : if (params) {
3531 0 : efree(params);
3532 : }
3533 0 : } else if (!ZEND_NUM_ARGS()) {
3534 0 : object_init_ex(return_value, ce);
3535 : } else {
3536 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ce->name);
3537 : }
3538 : }
3539 : /* }}} */
3540 :
3541 : /* {{{ proto public ReflectionClass[] ReflectionClass::getInterfaces()
3542 : Returns an array of interfaces this class implements */
3543 : ZEND_METHOD(reflection_class, getInterfaces)
3544 0 : {
3545 : reflection_object *intern;
3546 : zend_class_entry *ce;
3547 :
3548 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
3549 0 : GET_REFLECTION_OBJECT_PTR(ce);
3550 :
3551 : /* Return an empty array if this class implements no interfaces */
3552 0 : array_init(return_value);
3553 :
3554 0 : if (ce->num_interfaces) {
3555 : zend_uint i;
3556 :
3557 0 : for (i=0; i < ce->num_interfaces; i++) {
3558 : zval *interface;
3559 0 : ALLOC_ZVAL(interface);
3560 0 : zend_reflection_class_factory(ce->interfaces[i], interface TSRMLS_CC);
3561 0 : add_assoc_zval_ex(return_value, ce->interfaces[i]->name, ce->interfaces[i]->name_length + 1, interface);
3562 : }
3563 : }
3564 : }
3565 : /* }}} */
3566 :
3567 : /* {{{ proto public String[] ReflectionClass::getInterfaceNames()
3568 : Returns an array of names of interfaces this class implements */
3569 : ZEND_METHOD(reflection_class, getInterfaceNames)
3570 0 : {
3571 : reflection_object *intern;
3572 : zend_class_entry *ce;
3573 : zend_uint i;
3574 :
3575 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
3576 0 : GET_REFLECTION_OBJECT_PTR(ce);
3577 :
3578 : /* Return an empty array if this class implements no interfaces */
3579 0 : array_init(return_value);
3580 :
3581 0 : for (i=0; i < ce->num_interfaces; i++) {
3582 0 : add_next_index_stringl(return_value, ce->interfaces[i]->name, ce->interfaces[i]->name_length, 1);
3583 : }
3584 : }
3585 : /* }}} */
3586 :
3587 : /* {{{ proto public ReflectionClass ReflectionClass::getParentClass()
3588 : Returns the class' parent class, or, if none exists, FALSE */
3589 : ZEND_METHOD(reflection_class, getParentClass)
3590 0 : {
3591 : reflection_object *intern;
3592 : zend_class_entry *ce;
3593 :
3594 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_class_ptr, 0);
3595 0 : GET_REFLECTION_OBJECT_PTR(ce);
3596 :
3597 0 : if (ce->parent) {
3598 0 : zend_reflection_class_factory(ce->parent, return_value TSRMLS_CC);
3599 : } else {
3600 0 : RETURN_FALSE;
3601 : }
3602 : }
3603 : /* }}} */
3604 :
3605 : /* {{{ proto public bool ReflectionClass::isSubclassOf(string|ReflectionClass class)
3606 : Returns whether this class is a subclass of another class */
3607 : ZEND_METHOD(reflection_class, isSubclassOf)
3608 0 : {
3609 : reflection_object *intern, *argument;
3610 : zend_class_entry *ce, **pce, *class_ce;
3611 : zval *class_name;
3612 :
3613 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3614 0 : GET_REFLECTION_OBJECT_PTR(ce);
3615 :
3616 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &class_name) == FAILURE) {
3617 0 : return;
3618 : }
3619 :
3620 0 : switch(class_name->type) {
3621 : case IS_STRING:
3622 0 : if (zend_lookup_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), &pce TSRMLS_CC) == FAILURE) {
3623 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
3624 : "Interface %s does not exist", Z_STRVAL_P(class_name));
3625 0 : return;
3626 : }
3627 0 : class_ce = *pce;
3628 0 : break;
3629 : case IS_OBJECT:
3630 0 : if (instanceof_function(Z_OBJCE_P(class_name), reflection_class_ptr TSRMLS_CC)) {
3631 0 : argument = (reflection_object *) zend_object_store_get_object(class_name TSRMLS_CC);
3632 0 : if (argument == NULL || argument->ptr == NULL) {
3633 0 : zend_error(E_ERROR, "Internal error: Failed to retrieve the argument's reflection object");
3634 : /* Bails out */
3635 : }
3636 0 : class_ce = argument->ptr;
3637 0 : break;
3638 : }
3639 : /* no break */
3640 : default:
3641 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
3642 : "Parameter one must either be a string or a ReflectionClass object");
3643 0 : return;
3644 : }
3645 :
3646 0 : RETURN_BOOL((ce != class_ce && instanceof_function(ce, class_ce TSRMLS_CC)));
3647 : }
3648 : /* }}} */
3649 :
3650 : /* {{{ proto public bool ReflectionClass::implementsInterface(string|ReflectionClass interface_name)
3651 : Returns whether this class is a subclass of another class */
3652 : ZEND_METHOD(reflection_class, implementsInterface)
3653 0 : {
3654 : reflection_object *intern, *argument;
3655 : zend_class_entry *ce, *interface_ce, **pce;
3656 : zval *interface;
3657 :
3658 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3659 0 : GET_REFLECTION_OBJECT_PTR(ce);
3660 :
3661 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &interface) == FAILURE) {
3662 0 : return;
3663 : }
3664 :
3665 0 : switch(interface->type) {
3666 : case IS_STRING:
3667 0 : if (zend_lookup_class(Z_STRVAL_P(interface), Z_STRLEN_P(interface), &pce TSRMLS_CC) == FAILURE) {
3668 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
3669 : "Interface %s does not exist", Z_STRVAL_P(interface));
3670 0 : return;
3671 : }
3672 0 : interface_ce = *pce;
3673 0 : break;
3674 : case IS_OBJECT:
3675 0 : if (instanceof_function(Z_OBJCE_P(interface), reflection_class_ptr TSRMLS_CC)) {
3676 0 : argument = (reflection_object *) zend_object_store_get_object(interface TSRMLS_CC);
3677 0 : if (argument == NULL || argument->ptr == NULL) {
3678 0 : zend_error(E_ERROR, "Internal error: Failed to retrieve the argument's reflection object");
3679 : /* Bails out */
3680 : }
3681 0 : interface_ce = argument->ptr;
3682 0 : break;
3683 : }
3684 : /* no break */
3685 : default:
3686 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
3687 : "Parameter one must either be a string or a ReflectionClass object");
3688 0 : return;
3689 : }
3690 :
3691 0 : if (!(interface_ce->ce_flags & ZEND_ACC_INTERFACE)) {
3692 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
3693 : "Interface %s is a Class", interface_ce->name);
3694 0 : return;
3695 : }
3696 0 : RETURN_BOOL(instanceof_function(ce, interface_ce TSRMLS_CC));
3697 : }
3698 : /* }}} */
3699 :
3700 : /* {{{ proto public bool ReflectionClass::isIterateable()
3701 : Returns whether this class is iterateable (can be used inside foreach) */
3702 : ZEND_METHOD(reflection_class, isIterateable)
3703 0 : {
3704 : reflection_object *intern;
3705 : zend_class_entry *ce;
3706 :
3707 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3708 0 : GET_REFLECTION_OBJECT_PTR(ce);
3709 :
3710 0 : RETURN_BOOL(ce->get_iterator != NULL);
3711 : }
3712 : /* }}} */
3713 :
3714 : /* {{{ proto public ReflectionExtension|NULL ReflectionClass::getExtension()
3715 : Returns NULL or the extension the class belongs to */
3716 : ZEND_METHOD(reflection_class, getExtension)
3717 0 : {
3718 : reflection_object *intern;
3719 : zend_class_entry *ce;
3720 :
3721 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3722 0 : GET_REFLECTION_OBJECT_PTR(ce);
3723 :
3724 0 : if (ce->module) {
3725 0 : reflection_extension_factory(return_value, ce->module->name TSRMLS_CC);
3726 : }
3727 : }
3728 : /* }}} */
3729 :
3730 : /* {{{ proto public string|false ReflectionClass::getExtensionName()
3731 : Returns false or the name of the extension the class belongs to */
3732 : ZEND_METHOD(reflection_class, getExtensionName)
3733 0 : {
3734 : reflection_object *intern;
3735 : zend_class_entry *ce;
3736 :
3737 0 : METHOD_NOTSTATIC(reflection_class_ptr);
3738 0 : GET_REFLECTION_OBJECT_PTR(ce);
3739 :
3740 0 : if (ce->module) {
3741 0 : RETURN_STRING(ce->module->name, 1);
3742 : } else {
3743 0 : RETURN_FALSE;
3744 : }
3745 : }
3746 : /* }}} */
3747 :
3748 : /* {{{ proto public static mixed ReflectionObject::export(mixed argument [, bool return]) throws ReflectionException
3749 : Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
3750 : ZEND_METHOD(reflection_object, export)
3751 0 : {
3752 0 : _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_object_ptr, 1);
3753 0 : }
3754 : /* }}} */
3755 :
3756 : /* {{{ proto public void ReflectionObject::__construct(mixed argument) throws ReflectionException
3757 : Constructor. Takes an instance as an argument */
3758 : ZEND_METHOD(reflection_object, __construct)
3759 0 : {
3760 0 : reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
3761 0 : }
3762 : /* }}} */
3763 :
3764 : /* {{{ proto public static mixed ReflectionProperty::export(mixed class, string name [, bool return]) throws ReflectionException
3765 : Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
3766 : ZEND_METHOD(reflection_property, export)
3767 0 : {
3768 0 : _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_property_ptr, 2);
3769 0 : }
3770 : /* }}} */
3771 :
3772 : /* {{{ proto public void ReflectionProperty::__construct(mixed class, string name)
3773 : Constructor. Throws an Exception in case the given property does not exist */
3774 : ZEND_METHOD(reflection_property, __construct)
3775 0 : {
3776 : zval *propname, *classname;
3777 : char *name_str, *class_name, *prop_name;
3778 : int name_len;
3779 : zval *object;
3780 : reflection_object *intern;
3781 : zend_class_entry **pce;
3782 : zend_class_entry *ce;
3783 : zend_property_info *property_info;
3784 : property_reference *reference;
3785 :
3786 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
3787 0 : return;
3788 : }
3789 :
3790 0 : object = getThis();
3791 0 : intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
3792 0 : if (intern == NULL) {
3793 0 : return;
3794 : }
3795 :
3796 : /* Find the class entry */
3797 0 : switch (Z_TYPE_P(classname)) {
3798 : case IS_STRING:
3799 0 : if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
3800 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
3801 : "Class %s does not exist", Z_STRVAL_P(classname));
3802 0 : return;
3803 : }
3804 0 : ce = *pce;
3805 0 : break;
3806 :
3807 : case IS_OBJECT:
3808 0 : ce = Z_OBJCE_P(classname);
3809 0 : break;
3810 :
3811 : default:
3812 0 : _DO_THROW("The parameter class is expected to be either a string or an object");
3813 : /* returns out of this function */
3814 : }
3815 :
3816 0 : if (zend_hash_find(&ce->properties_info, name_str, name_len + 1, (void **) &property_info) == FAILURE || (property_info->flags & ZEND_ACC_SHADOW)) {
3817 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
3818 : "Property %s::$%s does not exist", ce->name, name_str);
3819 0 : return;
3820 : }
3821 :
3822 0 : if (!(property_info->flags & ZEND_ACC_PRIVATE)) {
3823 : /* we have to search the class hierarchy for this (implicit) public or protected property */
3824 0 : zend_class_entry *tmp_ce = ce;
3825 : zend_property_info *tmp_info;
3826 :
3827 0 : while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, name_str, name_len + 1, (void **) &tmp_info) != SUCCESS) {
3828 0 : ce = tmp_ce;
3829 0 : property_info = tmp_info;
3830 0 : tmp_ce = tmp_ce->parent;
3831 : }
3832 : }
3833 :
3834 0 : MAKE_STD_ZVAL(classname);
3835 0 : ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
3836 0 : zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
3837 :
3838 0 : zend_unmangle_property_name(property_info->name, property_info->name_length, &class_name, &prop_name);
3839 0 : MAKE_STD_ZVAL(propname);
3840 0 : ZVAL_STRING(propname, prop_name, 1);
3841 0 : zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &propname, sizeof(zval *), NULL);
3842 :
3843 0 : reference = (property_reference*) emalloc(sizeof(property_reference));
3844 0 : reference->ce = ce;
3845 0 : reference->prop = *property_info;
3846 0 : intern->ptr = reference;
3847 0 : intern->free_ptr = 1;
3848 0 : intern->ce = ce;
3849 : }
3850 : /* }}} */
3851 :
3852 : /* {{{ proto public string ReflectionProperty::__toString()
3853 : Returns a string representation */
3854 : ZEND_METHOD(reflection_property, __toString)
3855 0 : {
3856 : reflection_object *intern;
3857 : property_reference *ref;
3858 : string str;
3859 :
3860 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_property_ptr, 0);
3861 0 : GET_REFLECTION_OBJECT_PTR(ref);
3862 0 : string_init(&str);
3863 0 : _property_string(&str, &ref->prop, NULL, "" TSRMLS_CC);
3864 0 : RETURN_STRINGL(str.string, str.len - 1, 0);
3865 : }
3866 : /* }}} */
3867 :
3868 : /* {{{ proto public string ReflectionProperty::getName()
3869 : Returns the class' name */
3870 : ZEND_METHOD(reflection_property, getName)
3871 0 : {
3872 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_property_ptr, 0);
3873 0 : _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
3874 : }
3875 : /* }}} */
3876 :
3877 : static void _property_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
3878 0 : {
3879 : reflection_object *intern;
3880 : property_reference *ref;
3881 :
3882 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_property_ptr, 0);
3883 0 : GET_REFLECTION_OBJECT_PTR(ref);
3884 0 : RETURN_BOOL(ref->prop.flags & mask);
3885 : }
3886 :
3887 : /* {{{ proto public bool ReflectionProperty::isPublic()
3888 : Returns whether this property is public */
3889 : ZEND_METHOD(reflection_property, isPublic)
3890 0 : {
3891 0 : _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC);
3892 0 : }
3893 : /* }}} */
3894 :
3895 : /* {{{ proto public bool ReflectionProperty::isPrivate()
3896 : Returns whether this property is private */
3897 : ZEND_METHOD(reflection_property, isPrivate)
3898 0 : {
3899 0 : _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
3900 0 : }
3901 : /* }}} */
3902 :
3903 : /* {{{ proto public bool ReflectionProperty::isProtected()
3904 : Returns whether this property is protected */
3905 : ZEND_METHOD(reflection_property, isProtected)
3906 0 : {
3907 0 : _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
3908 0 : }
3909 : /* }}} */
3910 :
3911 : /* {{{ proto public bool ReflectionProperty::isStatic()
3912 : Returns whether this property is static */
3913 : ZEND_METHOD(reflection_property, isStatic)
3914 0 : {
3915 0 : _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC);
3916 0 : }
3917 : /* }}} */
3918 :
3919 : /* {{{ proto public bool ReflectionProperty::isDefault()
3920 : Returns whether this property is default (declared at compilation time). */
3921 : ZEND_METHOD(reflection_property, isDefault)
3922 0 : {
3923 0 : _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ~ZEND_ACC_IMPLICIT_PUBLIC);
3924 0 : }
3925 : /* }}} */
3926 :
3927 : /* {{{ proto public int ReflectionProperty::getModifiers()
3928 : Returns a bitfield of the access modifiers for this property */
3929 : ZEND_METHOD(reflection_property, getModifiers)
3930 0 : {
3931 : reflection_object *intern;
3932 : property_reference *ref;
3933 :
3934 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_property_ptr, 0);
3935 0 : GET_REFLECTION_OBJECT_PTR(ref);
3936 :
3937 0 : RETURN_LONG(ref->prop.flags);
3938 : }
3939 : /* }}} */
3940 :
3941 : /* {{{ proto public mixed ReflectionProperty::getValue([stdclass object])
3942 : Returns this property's value */
3943 : ZEND_METHOD(reflection_property, getValue)
3944 0 : {
3945 : reflection_object *intern;
3946 : property_reference *ref;
3947 : zval *object, name;
3948 0 : zval **member = NULL, *member_p = NULL;
3949 :
3950 0 : METHOD_NOTSTATIC(reflection_property_ptr);
3951 0 : GET_REFLECTION_OBJECT_PTR(ref);
3952 :
3953 0 : if (!(ref->prop.flags & ZEND_ACC_PUBLIC)) {
3954 0 : _default_get_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
3955 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
3956 : "Cannot access non-public member %s::%s", intern->ce->name, Z_STRVAL(name));
3957 0 : zval_dtor(&name);
3958 0 : return;
3959 : }
3960 :
3961 0 : if ((ref->prop.flags & ZEND_ACC_STATIC)) {
3962 0 : zend_update_class_constants(intern->ce TSRMLS_CC);
3963 0 : if (zend_hash_quick_find(CE_STATIC_MEMBERS(intern->ce), ref->prop.name, ref->prop.name_length + 1, ref->prop.h, (void **) &member) == FAILURE) {
3964 0 : zend_error(E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name);
3965 : /* Bails out */
3966 : }
3967 0 : *return_value= **member;
3968 0 : zval_copy_ctor(return_value);
3969 0 : INIT_PZVAL(return_value);
3970 : } else {
3971 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) {
3972 0 : return;
3973 : }
3974 0 : member_p = zend_read_property(Z_OBJCE_P(object), object, ref->prop.name, ref->prop.name_length, 1 TSRMLS_CC);
3975 0 : *return_value= *member_p;
3976 0 : zval_copy_ctor(return_value);
3977 0 : INIT_PZVAL(return_value);
3978 0 : if (member_p != EG(uninitialized_zval_ptr)) {
3979 0 : zval_add_ref(&member_p);
3980 0 : zval_ptr_dtor(&member_p);
3981 : }
3982 : }
3983 : }
3984 : /* }}} */
3985 :
3986 : /* {{{ proto public void ReflectionProperty::setValue([stdclass object,] mixed value)
3987 : Sets this property's value */
3988 : ZEND_METHOD(reflection_property, setValue)
3989 0 : {
3990 : reflection_object *intern;
3991 : property_reference *ref;
3992 : zval **variable_ptr;
3993 : zval *object, name;
3994 : zval *value;
3995 0 : int setter_done = 0;
3996 : zval *tmp;
3997 : HashTable *prop_table;
3998 :
3999 0 : METHOD_NOTSTATIC(reflection_property_ptr);
4000 0 : GET_REFLECTION_OBJECT_PTR(ref);
4001 :
4002 0 : if (!(ref->prop.flags & ZEND_ACC_PUBLIC)) {
4003 0 : _default_get_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
4004 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
4005 : "Cannot access non-public member %s::%s", intern->ce->name, Z_STRVAL(name));
4006 0 : zval_dtor(&name);
4007 0 : return;
4008 : }
4009 :
4010 0 : if ((ref->prop.flags & ZEND_ACC_STATIC)) {
4011 0 : if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
4012 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &tmp, &value) == FAILURE) {
4013 0 : return;
4014 : }
4015 : }
4016 0 : zend_update_class_constants(intern->ce TSRMLS_CC);
4017 0 : prop_table = CE_STATIC_MEMBERS(intern->ce);
4018 :
4019 0 : if (zend_hash_quick_find(prop_table, ref->prop.name, ref->prop.name_length + 1, ref->prop.h, (void **) &variable_ptr) == FAILURE) {
4020 0 : zend_error(E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name);
4021 : /* Bails out */
4022 : }
4023 0 : if (*variable_ptr == value) {
4024 0 : setter_done = 1;
4025 : } else {
4026 0 : if (PZVAL_IS_REF(*variable_ptr)) {
4027 0 : zval_dtor(*variable_ptr);
4028 0 : (*variable_ptr)->type = value->type;
4029 0 : (*variable_ptr)->value = value->value;
4030 0 : if (value->refcount > 0) {
4031 0 : zval_copy_ctor(*variable_ptr);
4032 : }
4033 0 : setter_done = 1;
4034 : }
4035 : }
4036 0 : if (!setter_done) {
4037 : zval **foo;
4038 :
4039 0 : value->refcount++;
4040 0 : if (PZVAL_IS_REF(value)) {
4041 0 : SEPARATE_ZVAL(&value);
4042 : }
4043 0 : zend_hash_quick_update(prop_table, ref->prop.name, ref->prop.name_length+1, ref->prop.h, &value, sizeof(zval *), (void **) &foo);
4044 : }
4045 : } else {
4046 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oz", &object, &value) == FAILURE) {
4047 0 : return;
4048 : }
4049 0 : zend_update_property(Z_OBJCE_P(object), object, ref->prop.name, ref->prop.name_length, value TSRMLS_CC);
4050 : }
4051 : }
4052 : /* }}} */
4053 :
4054 : /* {{{ proto public ReflectionClass ReflectionProperty::getDeclaringClass()
4055 : Get the declaring class */
4056 : ZEND_METHOD(reflection_property, getDeclaringClass)
4057 0 : {
4058 : reflection_object *intern;
4059 : property_reference *ref;
4060 : zend_class_entry *tmp_ce, *ce;
4061 : zend_property_info *tmp_info;
4062 : char *prop_name, *class_name;
4063 : int prop_name_len;
4064 :
4065 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_property_ptr, 0);
4066 0 : GET_REFLECTION_OBJECT_PTR(ref);
4067 :
4068 0 : if (zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name) != SUCCESS) {
4069 0 : RETURN_FALSE;
4070 : }
4071 :
4072 0 : prop_name_len = strlen(prop_name);
4073 0 : ce = tmp_ce = ref->ce;
4074 0 : while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, prop_name, prop_name_len + 1, (void **) &tmp_info) == SUCCESS) {
4075 0 : if (tmp_info->flags & ZEND_ACC_PRIVATE) {
4076 : /* it's a private property, so it can't be inherited */
4077 0 : break;
4078 : }
4079 0 : ce = tmp_ce;
4080 0 : tmp_ce = tmp_ce->parent;
4081 : }
4082 :
4083 0 : zend_reflection_class_factory(ce, return_value TSRMLS_CC);
4084 : }
4085 : /* }}} */
4086 :
4087 : /* {{{ proto public string ReflectionProperty::getDocComment()
4088 : Returns the doc comment for this property */
4089 : ZEND_METHOD(reflection_property, getDocComment)
4090 0 : {
4091 : reflection_object *intern;
4092 : property_reference *ref;
4093 :
4094 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_property_ptr, 0);
4095 0 : GET_REFLECTION_OBJECT_PTR(ref);
4096 0 : if (ref->prop.doc_comment) {
4097 0 : RETURN_STRINGL(ref->prop.doc_comment, ref->prop.doc_comment_len, 1);
4098 : }
4099 0 : RETURN_FALSE;
4100 : }
4101 : /* }}} */
4102 :
4103 : /* {{{ proto public static mixed ReflectionExtension::export(string name [, bool return]) throws ReflectionException
4104 : Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
4105 : ZEND_METHOD(reflection_extension, export)
4106 0 : {
4107 0 : _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_extension_ptr, 1);
4108 0 : }
4109 : /* }}} */
4110 :
4111 : /* {{{ proto public void ReflectionExtension::__construct(string name)
4112 : Constructor. Throws an Exception in case the given extension does not exist */
4113 : ZEND_METHOD(reflection_extension, __construct)
4114 0 : {
4115 : zval *name;
4116 : zval *object;
4117 : char *lcname;
4118 : reflection_object *intern;
4119 : zend_module_entry *module;
4120 : char *name_str;
4121 : int name_len;
4122 :
4123 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
4124 0 : return;
4125 : }
4126 :
4127 0 : object = getThis();
4128 0 : intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
4129 0 : if (intern == NULL) {
4130 0 : return;
4131 : }
4132 0 : lcname = do_alloca(name_len + 1);
4133 0 : zend_str_tolower_copy(lcname, name_str, name_len);
4134 0 : if (zend_hash_find(&module_registry, lcname, name_len + 1, (void **)&module) == FAILURE) {
4135 : free_alloca(lcname);
4136 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
4137 : "Extension %s does not exist", name_str);
4138 0 : return;
4139 : }
4140 : free_alloca(lcname);
4141 0 : MAKE_STD_ZVAL(name);
4142 0 : ZVAL_STRING(name, module->name, 1);
4143 0 : zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
4144 0 : intern->ptr = module;
4145 0 : intern->free_ptr = 0;
4146 0 : intern->ce = NULL;
4147 : }
4148 : /* }}} */
4149 :
4150 : /* {{{ proto public string ReflectionExtension::__toString()
4151 : Returns a string representation */
4152 : ZEND_METHOD(reflection_extension, __toString)
4153 0 : {
4154 : reflection_object *intern;
4155 : zend_module_entry *module;
4156 : string str;
4157 :
4158 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_extension_ptr, 0);
4159 0 : GET_REFLECTION_OBJECT_PTR(module);
4160 0 : string_init(&str);
4161 0 : _extension_string(&str, module, "" TSRMLS_CC);
4162 0 : RETURN_STRINGL(str.string, str.len - 1, 0);
4163 : }
4164 : /* }}} */
4165 :
4166 : /* {{{ proto public string ReflectionExtension::getName()
4167 : Returns this extension's name */
4168 : ZEND_METHOD(reflection_extension, getName)
4169 0 : {
4170 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_extension_ptr, 0);
4171 0 : _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
4172 : }
4173 : /* }}} */
4174 :
4175 : /* {{{ proto public string ReflectionExtension::getVersion()
4176 : Returns this extension's version */
4177 : ZEND_METHOD(reflection_extension, getVersion)
4178 0 : {
4179 : reflection_object *intern;
4180 : zend_module_entry *module;
4181 :
4182 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_extension_ptr, 0);
4183 0 : GET_REFLECTION_OBJECT_PTR(module);
4184 :
4185 : /* An extension does not necessarily have a version number */
4186 0 : if (module->version == NO_VERSION_YET) {
4187 0 : RETURN_NULL();
4188 : } else {
4189 0 : RETURN_STRING(module->version, 1);
4190 : }
4191 : }
4192 : /* }}} */
4193 :
4194 : /* {{{ proto public ReflectionFunction[] ReflectionExtension::getFunctions()
4195 : Returns an array of this extension's fuctions */
4196 : ZEND_METHOD(reflection_extension, getFunctions)
4197 0 : {
4198 : reflection_object *intern;
4199 : zend_module_entry *module;
4200 :
4201 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_extension_ptr, 0);
4202 0 : GET_REFLECTION_OBJECT_PTR(module);
4203 :
4204 0 : array_init(return_value);
4205 0 : if (module->functions) {
4206 : zval *function;
4207 : zend_function *fptr;
4208 0 : zend_function_entry *func = module->functions;
4209 :
4210 : /* Is there a better way of doing this? */
4211 0 : while (func->fname) {
4212 0 : if (zend_hash_find(EG(function_table), func->fname, strlen(func->fname) + 1, (void**) &fptr) == FAILURE) {
4213 0 : zend_error(E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname);
4214 0 : continue;
4215 : }
4216 :
4217 0 : ALLOC_ZVAL(function);
4218 0 : reflection_function_factory(fptr, function TSRMLS_CC);
4219 0 : add_assoc_zval_ex(return_value, func->fname, strlen(func->fname)+1, function);
4220 0 : func++;
4221 : }
4222 : }
4223 : }
4224 : /* }}} */
4225 :
4226 : static int _addconstant(zend_constant *constant, int num_args, va_list args, zend_hash_key *hash_key)
4227 0 : {
4228 : zval *const_val;
4229 0 : zval *retval = va_arg(args, zval*);
4230 0 : int number = va_arg(args, int);
4231 :
4232 0 : if (number == constant->module_number) {
4233 0 : ALLOC_ZVAL(const_val);
4234 0 : *const_val = constant->value;
4235 0 : zval_copy_ctor(const_val);
4236 0 : INIT_PZVAL(const_val);
4237 0 : add_assoc_zval_ex(retval, constant->name, constant->name_len, const_val);
4238 : }
4239 0 : return 0;
4240 : }
4241 :
4242 : /* {{{ proto public array ReflectionExtension::getConstants()
4243 : Returns an associative array containing this extension's constants and their values */
4244 : ZEND_METHOD(reflection_extension, getConstants)
4245 0 : {
4246 : reflection_object *intern;
4247 : zend_module_entry *module;
4248 :
4249 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_extension_ptr, 0);
4250 0 : GET_REFLECTION_OBJECT_PTR(module);
4251 :
4252 0 : array_init(return_value);
4253 0 : zend_hash_apply_with_arguments(EG(zend_constants), (apply_func_args_t) _addconstant, 2, return_value, module->module_number);
4254 : }
4255 : /* }}} */
4256 :
4257 : /* {{{ _addinientry */
4258 : static int _addinientry(zend_ini_entry *ini_entry, int num_args, va_list args, zend_hash_key *hash_key)
4259 0 : {
4260 0 : zval *retval = va_arg(args, zval*);
4261 0 : int number = va_arg(args, int);
4262 :
4263 0 : if (number == ini_entry->module_number) {
4264 0 : if (ini_entry->value) {
4265 0 : add_assoc_stringl(retval, ini_entry->name, ini_entry->value, ini_entry->value_length, 1);
4266 : } else {
4267 0 : add_assoc_null(retval, ini_entry->name);
4268 : }
4269 : }
4270 0 : return ZEND_HASH_APPLY_KEEP;
4271 : }
4272 : /* }}} */
4273 :
4274 : /* {{{ proto public array ReflectionExtension::getINIEntries()
4275 : Returns an associative array containing this extension's INI entries and their values */
4276 : ZEND_METHOD(reflection_extension, getINIEntries)
4277 0 : {
4278 : reflection_object *intern;
4279 : zend_module_entry *module;
4280 :
4281 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_extension_ptr, 0);
4282 0 : GET_REFLECTION_OBJECT_PTR(module);
4283 :
4284 0 : array_init(return_value);
4285 0 : zend_hash_apply_with_arguments(EG(ini_directives), (apply_func_args_t) _addinientry, 2, return_value, module->module_number);
4286 : }
4287 : /* }}} */
4288 :
4289 : /* {{{ add_extension_class */
4290 : static int add_extension_class(zend_class_entry **pce, int num_args, va_list args, zend_hash_key *hash_key)
4291 0 : {
4292 0 : zval *class_array = va_arg(args, zval*), *zclass;
4293 0 : struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
4294 0 : int add_reflection_class = va_arg(args, int);
4295 :
4296 0 : if ((*pce)->module && !strcasecmp((*pce)->module->name, module->name)) {
4297 : TSRMLS_FETCH();
4298 0 : if (add_reflection_class) {
4299 0 : ALLOC_ZVAL(zclass);
4300 0 : zend_reflection_class_factory(*pce, zclass TSRMLS_CC);
4301 0 : add_assoc_zval_ex(class_array, (*pce)->name, (*pce)->name_length + 1, zclass);
4302 : } else {
4303 0 : add_next_index_stringl(class_array, (*pce)->name, (*pce)->name_length, 1);
4304 : }
4305 : }
4306 0 : return ZEND_HASH_APPLY_KEEP;
4307 : }
4308 : /* }}} */
4309 :
4310 : /* {{{ proto public ReflectionClass[] ReflectionExtension::getClasses()
4311 : Returns an array containing ReflectionClass objects for all classes of this extension */
4312 : ZEND_METHOD(reflection_extension, getClasses)
4313 0 : {
4314 : reflection_object *intern;
4315 : zend_module_entry *module;
4316 :
4317 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_extension_ptr, 0);
4318 0 : GET_REFLECTION_OBJECT_PTR(module);
4319 :
4320 0 : array_init(return_value);
4321 0 : zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) add_extension_class, 3, return_value, module, 1 TSRMLS_CC);
4322 : }
4323 : /* }}} */
4324 :
4325 : /* {{{ proto public array ReflectionExtension::getClassNames()
4326 : Returns an array containing all names of all classes of this extension */
4327 : ZEND_METHOD(reflection_extension, getClassNames)
4328 0 : {
4329 : reflection_object *intern;
4330 : zend_module_entry *module;
4331 :
4332 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_extension_ptr, 0);
4333 0 : GET_REFLECTION_OBJECT_PTR(module);
4334 :
4335 0 : array_init(return_value);
4336 0 : zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) add_extension_class, 3, return_value, module, 0 TSRMLS_CC);
4337 : }
4338 : /* }}} */
4339 :
4340 : /* {{{ proto public array ReflectionExtension::getDependencies()
4341 : Returns an array containing all names of all extensions this extension depends on */
4342 : ZEND_METHOD(reflection_extension, getDependencies)
4343 0 : {
4344 : reflection_object *intern;
4345 : zend_module_entry *module;
4346 : zend_module_dep *dep;
4347 :
4348 0 : METHOD_NOTSTATIC_NUMPARAMS(reflection_extension_ptr, 0);
4349 0 : GET_REFLECTION_OBJECT_PTR(module);
4350 :
4351 0 : array_init(return_value);
4352 :
4353 0 : dep = module->deps;
4354 :
4355 0 : if (!dep)
4356 : {
4357 0 : return;
4358 : }
4359 :
4360 0 : while(dep->name) {
4361 : char *relation;
4362 : char *rel_type;
4363 : int len;
4364 :
4365 0 : switch(dep->type) {
4366 : case MODULE_DEP_REQUIRED:
4367 0 : rel_type = "Required";
4368 0 : break;
4369 : case MODULE_DEP_CONFLICTS:
4370 0 : rel_type = "Conflicts";
4371 0 : break;
4372 : case MODULE_DEP_OPTIONAL:
4373 0 : rel_type = "Optional";
4374 0 : break;
4375 : default:
4376 0 : rel_type = "Error"; /* shouldn't happen */
4377 : break;
4378 : }
4379 :
4380 0 : len = spprintf(&relation, 0, "%s%s%s%s%s",
4381 : rel_type,
4382 : dep->rel ? " " : "",
4383 : dep->rel ? dep->rel : "",
4384 : dep->version ? " " : "",
4385 : dep->version ? dep->version : "");
4386 0 : add_assoc_stringl(return_value, dep->name, relation, len, 0);
4387 0 : dep++;
4388 : }
4389 : }
4390 : /* }}} */
4391 :
4392 : /* {{{ method tables */
4393 : static zend_function_entry reflection_exception_functions[] = {
4394 : {NULL, NULL, NULL}
4395 : };
4396 :
4397 :
4398 : static
4399 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_getModifierNames, 0)
4400 : ZEND_ARG_INFO(0, modifiers)
4401 : ZEND_END_ARG_INFO()
4402 :
4403 : static
4404 : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_export, 0, 0, 1)
4405 : ZEND_ARG_OBJ_INFO(0, reflector, Reflector, 0)
4406 : ZEND_ARG_INFO(0, return)
4407 : ZEND_END_ARG_INFO()
4408 :
4409 : static zend_function_entry reflection_functions[] = {
4410 : ZEND_ME(reflection, getModifierNames, arginfo_reflection_getModifierNames, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
4411 : ZEND_ME(reflection, export, arginfo_reflection_export, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
4412 : {NULL, NULL, NULL}
4413 : };
4414 :
4415 : static zend_function_entry reflector_functions[] = {
4416 : ZEND_FENTRY(export, NULL, NULL, ZEND_ACC_STATIC|ZEND_ACC_ABSTRACT|ZEND_ACC_PUBLIC)
4417 : ZEND_ABSTRACT_ME(reflector, __toString, NULL)
4418 : {NULL, NULL, NULL}
4419 : };
4420 :
4421 : static
4422 : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_export, 0, 0, 1)
4423 : ZEND_ARG_INFO(0, name)
4424 : ZEND_ARG_INFO(0, return)
4425 : ZEND_END_ARG_INFO()
4426 :
4427 : static
4428 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_function___construct, 0)
4429 : ZEND_ARG_INFO(0, name)
4430 : ZEND_END_ARG_INFO()
4431 :
4432 : static
4433 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_function_invoke, 0)
4434 : ZEND_ARG_INFO(0, args)
4435 : ZEND_END_ARG_INFO()
4436 :
4437 : static
4438 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_function_invokeArgs, 0)
4439 : ZEND_ARG_ARRAY_INFO(0, args, 0)
4440 : ZEND_END_ARG_INFO()
4441 :
4442 : static zend_function_entry reflection_function_abstract_functions[] = {
4443 : ZEND_ME(reflection, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
4444 : PHP_ABSTRACT_ME(reflection_function, __toString, NULL)
4445 : ZEND_ME(reflection_function, isInternal, NULL, 0)
4446 : ZEND_ME(reflection_function, isUserDefined, NULL, 0)
4447 : ZEND_ME(reflection_function, getName, NULL, 0)
4448 : ZEND_ME(reflection_function, getFileName, NULL, 0)
4449 : ZEND_ME(reflection_function, getStartLine, NULL, 0)
4450 : ZEND_ME(reflection_function, getEndLine, NULL, 0)
4451 : ZEND_ME(reflection_function, getDocComment, NULL, 0)
4452 : ZEND_ME(reflection_function, getStaticVariables, NULL, 0)
4453 : ZEND_ME(reflection_function, returnsReference, NULL, 0)
4454 : ZEND_ME(reflection_function, getParameters, NULL, 0)
4455 : ZEND_ME(reflection_function, getNumberOfParameters, NULL, 0)
4456 : ZEND_ME(reflection_function, getNumberOfRequiredParameters, NULL, 0)
4457 : #if MBO_0
4458 : ZEND_ME(reflection_function, getExtension, NULL, 0)
4459 : ZEND_ME(reflection_function, getExtensionName, NULL, 0)
4460 : #endif
4461 : ZEND_ME(reflection_function, isDeprecated, NULL, 0)
4462 : {NULL, NULL, NULL}
4463 : };
4464 :
4465 : static zend_function_entry reflection_function_functions[] = {
4466 : ZEND_ME(reflection_function, __construct, arginfo_reflection_function___construct, 0)
4467 : ZEND_ME(reflection_function, __toString, NULL, 0)
4468 : ZEND_ME(reflection_function, export, arginfo_reflection_function_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
4469 : ZEND_ME(reflection_function, isDisabled, NULL, 0)
4470 : ZEND_ME(reflection_function, invoke, arginfo_reflection_function_invoke, 0)
4471 : ZEND_ME(reflection_function, invokeArgs, arginfo_reflection_function_invokeArgs, 0)
4472 : {NULL, NULL, NULL}
4473 : };
4474 :
4475 : static
4476 : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method_export, 0, 0, 2)
4477 : ZEND_ARG_INFO(0, class)
4478 : ZEND_ARG_INFO(0, name)
4479 : ZEND_ARG_INFO(0, return)
4480 : ZEND_END_ARG_INFO()
4481 :
4482 : static
4483 : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method___construct, 0, 0, 1)
4484 : ZEND_ARG_INFO(0, class_or_method)
4485 : ZEND_ARG_INFO(0, name)
4486 : ZEND_END_ARG_INFO()
4487 :
4488 : static
4489 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invoke, 0)
4490 : ZEND_ARG_INFO(0, object)
4491 : ZEND_ARG_INFO(0, args)
4492 : ZEND_END_ARG_INFO()
4493 :
4494 : static
4495 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invokeArgs, 0)
4496 : ZEND_ARG_INFO(0, object)
4497 : ZEND_ARG_ARRAY_INFO(0, args, 0)
4498 : ZEND_END_ARG_INFO()
4499 :
4500 : static zend_function_entry reflection_method_functions[] = {
4501 : ZEND_ME(reflection_method, export, arginfo_reflection_method_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
4502 : ZEND_ME(reflection_method, __construct, arginfo_reflection_method___construct, 0)
4503 : ZEND_ME(reflection_method, __toString, NULL, 0)
4504 : ZEND_ME(reflection_method, isPublic, NULL, 0)
4505 : ZEND_ME(reflection_method, isPrivate, NULL, 0)
4506 : ZEND_ME(reflection_method, isProtected, NULL, 0)
4507 : ZEND_ME(reflection_method, isAbstract, NULL, 0)
4508 : ZEND_ME(reflection_method, isFinal, NULL, 0)
4509 : ZEND_ME(reflection_method, isStatic, NULL, 0)
4510 : ZEND_ME(reflection_method, isConstructor, NULL, 0)
4511 : ZEND_ME(reflection_method, isDestructor, NULL, 0)
4512 : ZEND_ME(reflection_method, getModifiers, NULL, 0)
4513 : ZEND_ME(reflection_method, invoke, arginfo_reflection_method_invoke, 0)
4514 : ZEND_ME(reflection_method, invokeArgs, arginfo_reflection_method_invokeArgs, 0)
4515 : ZEND_ME(reflection_method, getDeclaringClass, NULL, 0)
4516 : ZEND_ME(reflection_method, getPrototype, NULL, 0)
4517 : {NULL, NULL, NULL}
4518 : };
4519 :
4520 :
4521 : static
4522 : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_export, 0, 0, 1)
4523 : ZEND_ARG_INFO(0, argument)
4524 : ZEND_ARG_INFO(0, return)
4525 : ZEND_END_ARG_INFO()
4526 :
4527 : static
4528 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class___construct, 0)
4529 : ZEND_ARG_INFO(0, argument)
4530 : ZEND_END_ARG_INFO()
4531 :
4532 : static
4533 : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getStaticPropertyValue, 0, 0, 1)
4534 : ZEND_ARG_INFO(0, name)
4535 : ZEND_ARG_INFO(0, default)
4536 : ZEND_END_ARG_INFO()
4537 :
4538 : static
4539 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_setStaticPropertyValue, 0)
4540 : ZEND_ARG_INFO(0, name)
4541 : ZEND_ARG_INFO(0, value)
4542 : ZEND_END_ARG_INFO()
4543 :
4544 : static
4545 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasMethod, 0)
4546 : ZEND_ARG_INFO(0, name)
4547 : ZEND_END_ARG_INFO()
4548 :
4549 : static
4550 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getMethod, 0)
4551 : ZEND_ARG_INFO(0, name)
4552 : ZEND_END_ARG_INFO()
4553 :
4554 : static
4555 : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getMethods, 0, 0, 0)
4556 : ZEND_ARG_INFO(0, filter)
4557 : ZEND_END_ARG_INFO()
4558 :
4559 : static
4560 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasProperty, 0)
4561 : ZEND_ARG_INFO(0, name)
4562 : ZEND_END_ARG_INFO()
4563 :
4564 : static
4565 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getProperty, 0)
4566 : ZEND_ARG_INFO(0, name)
4567 : ZEND_END_ARG_INFO()
4568 :
4569 : static
4570 : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getProperties, 0, 0, 0)
4571 : ZEND_ARG_INFO(0, filter)
4572 : ZEND_END_ARG_INFO()
4573 :
4574 : static
4575 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasConstant, 0)
4576 : ZEND_ARG_INFO(0, name)
4577 : ZEND_END_ARG_INFO()
4578 :
4579 : static
4580 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getConstant, 0)
4581 : ZEND_ARG_INFO(0, name)
4582 : ZEND_END_ARG_INFO()
4583 :
4584 : static
4585 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isInstance, 0)
4586 : ZEND_ARG_INFO(0, object)
4587 : ZEND_END_ARG_INFO()
4588 :
4589 : static
4590 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_newInstance, 0)
4591 : ZEND_ARG_INFO(0, args)
4592 : ZEND_END_ARG_INFO()
4593 :
4594 : static
4595 : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_newInstanceArgs, 0, 0, 0)
4596 : ZEND_ARG_ARRAY_INFO(0, args, 0)
4597 : ZEND_END_ARG_INFO()
4598 :
4599 : static
4600 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isSubclassOf, 0)
4601 : ZEND_ARG_INFO(0, class)
4602 : ZEND_END_ARG_INFO()
4603 :
4604 : static
4605 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_implementsInterface, 0)
4606 : ZEND_ARG_INFO(0, interface)
4607 : ZEND_END_ARG_INFO()
4608 :
4609 : static zend_function_entry reflection_class_functions[] = {
4610 : ZEND_ME(reflection, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
4611 : ZEND_ME(reflection_class, export, arginfo_reflection_class_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
4612 : ZEND_ME(reflection_class, __construct, arginfo_reflection_class___construct, 0)
4613 : ZEND_ME(reflection_class, __toString, NULL, 0)
4614 : ZEND_ME(reflection_class, getName, NULL, 0)
4615 : ZEND_ME(reflection_class, isInternal, NULL, 0)
4616 : ZEND_ME(reflection_class, isUserDefined, NULL, 0)
4617 : ZEND_ME(reflection_class, isInstantiable, NULL, 0)
4618 : ZEND_ME(reflection_class, getFileName, NULL, 0)
4619 : ZEND_ME(reflection_class, getStartLine, NULL, 0)
4620 : ZEND_ME(reflection_class, getEndLine, NULL, 0)
4621 : ZEND_ME(reflection_class, getDocComment, NULL, 0)
4622 : ZEND_ME(reflection_class, getConstructor, NULL, 0)
4623 : ZEND_ME(reflection_class, hasMethod, arginfo_reflection_class_hasMethod, 0)
4624 : ZEND_ME(reflection_class, getMethod, arginfo_reflection_class_getMethod, 0)
4625 : ZEND_ME(reflection_class, getMethods, arginfo_reflection_class_getMethods, 0)
4626 : ZEND_ME(reflection_class, hasProperty, arginfo_reflection_class_hasProperty, 0)
4627 : ZEND_ME(reflection_class, getProperty, arginfo_reflection_class_getProperty, 0)
4628 : ZEND_ME(reflection_class, getProperties, arginfo_reflection_class_getProperties, 0)
4629 : ZEND_ME(reflection_class, hasConstant, arginfo_reflection_class_hasConstant, 0)
4630 : ZEND_ME(reflection_class, getConstants, NULL, 0)
4631 : ZEND_ME(reflection_class, getConstant, arginfo_reflection_class_getConstant, 0)
4632 : ZEND_ME(reflection_class, getInterfaces, NULL, 0)
4633 : ZEND_ME(reflection_class, getInterfaceNames, NULL, 0)
4634 : ZEND_ME(reflection_class, isInterface, NULL, 0)
4635 : ZEND_ME(reflection_class, isAbstract, NULL, 0)
4636 : ZEND_ME(reflection_class, isFinal, NULL, 0)
4637 : ZEND_ME(reflection_class, getModifiers, NULL, 0)
4638 : ZEND_ME(reflection_class, isInstance, arginfo_reflection_class_isInstance, 0)
4639 : ZEND_ME(reflection_class, newInstance, arginfo_reflection_class_newInstance, 0)
4640 : ZEND_ME(reflection_class, newInstanceArgs, arginfo_reflection_class_newInstanceArgs, 0)
4641 : ZEND_ME(reflection_class, getParentClass, NULL, 0)
4642 : ZEND_ME(reflection_class, isSubclassOf, arginfo_reflection_class_isSubclassOf, 0)
4643 : ZEND_ME(reflection_class, getStaticProperties, NULL, 0)
4644 : ZEND_ME(reflection_class, getStaticPropertyValue, arginfo_reflection_class_getStaticPropertyValue, 0)
4645 : ZEND_ME(reflection_class, setStaticPropertyValue, arginfo_reflection_class_setStaticPropertyValue, 0)
4646 : ZEND_ME(reflection_class, getDefaultProperties, NULL, 0)
4647 : ZEND_ME(reflection_class, isIterateable, NULL, 0)
4648 : ZEND_ME(reflection_class, implementsInterface, arginfo_reflection_class_implementsInterface, 0)
4649 : ZEND_ME(reflection_class, getExtension, NULL, 0)
4650 : ZEND_ME(reflection_class, getExtensionName, NULL, 0)
4651 : {NULL, NULL, NULL}
4652 : };
4653 :
4654 :
4655 : static
4656 : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_object_export, 0, 0, 1)
4657 : ZEND_ARG_INFO(0, argument)
4658 : ZEND_ARG_INFO(0, return)
4659 : ZEND_END_ARG_INFO()
4660 :
4661 : static
4662 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_object___construct, 0)
4663 : ZEND_ARG_INFO(0, argument)
4664 : ZEND_END_ARG_INFO()
4665 :
4666 : static zend_function_entry reflection_object_functions[] = {
4667 : ZEND_ME(reflection_object, export, arginfo_reflection_object_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
4668 : ZEND_ME(reflection_object, __construct, arginfo_reflection_object___construct, 0)
4669 : {NULL, NULL, NULL}
4670 : };
4671 :
4672 :
4673 : static
4674 : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_export, 0, 0, 1)
4675 : ZEND_ARG_INFO(0, argument)
4676 : ZEND_ARG_INFO(0, return)
4677 : ZEND_END_ARG_INFO()
4678 :
4679 : static
4680 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_property___construct, 0)
4681 : ZEND_ARG_INFO(0, argument)
4682 : ZEND_END_ARG_INFO()
4683 :
4684 : static
4685 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_property_getValue, 0)
4686 : ZEND_ARG_INFO(0, object)
4687 : ZEND_END_ARG_INFO()
4688 :
4689 : static
4690 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_property_setValue, 0)
4691 : ZEND_ARG_INFO(0, object)
4692 : ZEND_ARG_INFO(0, value)
4693 : ZEND_END_ARG_INFO()
4694 :
4695 : static zend_function_entry reflection_property_functions[] = {
4696 : ZEND_ME(reflection, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
4697 : ZEND_ME(reflection_property, export, arginfo_reflection_property_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
4698 : ZEND_ME(reflection_property, __construct, arginfo_reflection_property___construct, 0)
4699 : ZEND_ME(reflection_property, __toString, NULL, 0)
4700 : ZEND_ME(reflection_property, getName, NULL, 0)
4701 : ZEND_ME(reflection_property, getValue, arginfo_reflection_property_getValue, 0)
4702 : ZEND_ME(reflection_property, setValue, arginfo_reflection_property_setValue, 0)
4703 : ZEND_ME(reflection_property, isPublic, NULL, 0)
4704 : ZEND_ME(reflection_property, isPrivate, NULL, 0)
4705 : ZEND_ME(reflection_property, isProtected, NULL, 0)
4706 : ZEND_ME(reflection_property, isStatic, NULL, 0)
4707 : ZEND_ME(reflection_property, isDefault, NULL, 0)
4708 : ZEND_ME(reflection_property, getModifiers, NULL, 0)
4709 : ZEND_ME(reflection_property, getDeclaringClass, NULL, 0)
4710 : ZEND_ME(reflection_property, getDocComment, NULL, 0)
4711 : {NULL, NULL, NULL}
4712 : };
4713 :
4714 : static
4715 : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_parameter_export, 0, 0, 2)
4716 : ZEND_ARG_INFO(0, function)
4717 : ZEND_ARG_INFO(0, parameter)
4718 : ZEND_ARG_INFO(0, return)
4719 : ZEND_END_ARG_INFO()
4720 :
4721 : static
4722 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_parameter___construct, 0)
4723 : ZEND_ARG_INFO(0, function)
4724 : ZEND_ARG_INFO(0, parameter)
4725 : ZEND_END_ARG_INFO()
4726 :
4727 : static zend_function_entry reflection_parameter_functions[] = {
4728 : ZEND_ME(reflection, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
4729 : ZEND_ME(reflection_parameter, export, arginfo_reflection_parameter_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
4730 : ZEND_ME(reflection_parameter, __construct, arginfo_reflection_parameter___construct, 0)
4731 : ZEND_ME(reflection_parameter, __toString, NULL, 0)
4732 : ZEND_ME(reflection_parameter, getName, NULL, 0)
4733 : ZEND_ME(reflection_parameter, isPassedByReference, NULL, 0)
4734 : #if MBO_0
4735 : ZEND_ME(reflection_parameter, getDeclaringFunction, NULL, 0)
4736 : #endif
4737 : ZEND_ME(reflection_parameter, getDeclaringClass, NULL, 0)
4738 : ZEND_ME(reflection_parameter, getClass, NULL, 0)
4739 : ZEND_ME(reflection_parameter, isArray, NULL, 0)
4740 : ZEND_ME(reflection_parameter, allowsNull, NULL, 0)
4741 : #if MBO_0
4742 : ZEND_ME(reflection_parameter, getPosition, NULL, 0)
4743 : #endif
4744 : ZEND_ME(reflection_parameter, isOptional, NULL, 0)
4745 : ZEND_ME(reflection_parameter, isDefaultValueAvailable, NULL, 0)
4746 : ZEND_ME(reflection_parameter, getDefaultValue, NULL, 0)
4747 : {NULL, NULL, NULL}
4748 : };
4749 :
4750 : static
4751 : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_extension_export, 0, 0, 1)
4752 : ZEND_ARG_INFO(0, name)
4753 : ZEND_ARG_INFO(0, return)
4754 : ZEND_END_ARG_INFO()
4755 :
4756 : static
4757 : ZEND_BEGIN_ARG_INFO(arginfo_reflection_extension___construct, 0)
4758 : ZEND_ARG_INFO(0, name)
4759 : ZEND_END_ARG_INFO()
4760 :
4761 : static zend_function_entry reflection_extension_functions[] = {
4762 : ZEND_ME(reflection, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
4763 : ZEND_ME(reflection_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
4764 : ZEND_ME(reflection_extension, __construct, arginfo_reflection_extension___construct, 0)
4765 : ZEND_ME(reflection_extension, __toString, NULL, 0)
4766 : ZEND_ME(reflection_extension, getName, NULL, 0)
4767 : ZEND_ME(reflection_extension, getVersion, NULL, 0)
4768 : ZEND_ME(reflection_extension, getFunctions, NULL, 0)
4769 : ZEND_ME(reflection_extension, getConstants, NULL, 0)
4770 : ZEND_ME(reflection_extension, getINIEntries, NULL, 0)
4771 : ZEND_ME(reflection_extension, getClasses, NULL, 0)
4772 : ZEND_ME(reflection_extension, getClassNames, NULL, 0)
4773 : ZEND_ME(reflection_extension, getDependencies, NULL, 0)
4774 : {NULL, NULL, NULL}
4775 : };
4776 : /* }}} */
4777 :
4778 : zend_function_entry reflection_ext_functions[] = { /* {{{ */
4779 : {NULL, NULL, NULL}
4780 : }; /* }}} */
4781 :
4782 : static zend_object_handlers *zend_std_obj_handlers;
4783 :
4784 : /* {{{ _reflection_write_property */
4785 : static void _reflection_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
4786 0 : {
4787 0 : if ((Z_TYPE_P(member) == IS_STRING)
4788 : && zend_hash_exists(&Z_OBJCE_P(object)->default_properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1)
4789 : && ((Z_STRLEN_P(member) == sizeof("name") - 1 && !memcmp(Z_STRVAL_P(member), "name", sizeof("name"))) ||
4790 : (Z_STRLEN_P(member) == sizeof("class") - 1 && !memcmp(Z_STRVAL_P(member), "class", sizeof("class")))))
4791 : {
4792 0 : zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
4793 : "Cannot set read-only property %s::$%s", Z_OBJCE_P(object)->name, Z_STRVAL_P(member));
4794 : }
4795 : else
4796 : {
4797 0 : zend_std_obj_handlers->write_property(object, member, value TSRMLS_CC);
4798 : }
4799 0 : }
4800 : /* }}} */
4801 :
4802 : PHP_MINIT_FUNCTION(reflection) /* {{{ */
4803 220 : {
4804 : zend_class_entry _reflection_entry;
4805 :
4806 220 : zend_std_obj_handlers = zend_get_std_object_handlers();
4807 220 : memcpy(&reflection_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
4808 220 : reflection_object_handlers.clone_obj = NULL;
4809 220 : reflection_object_handlers.write_property = _reflection_write_property;
4810 :
4811 220 : INIT_CLASS_ENTRY(_reflection_entry, "ReflectionException", reflection_exception_functions);
4812 220 : reflection_exception_ptr = zend_register_internal_class_ex(&_reflection_entry, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
4813 :
4814 220 : INIT_CLASS_ENTRY(_reflection_entry, "Reflection", reflection_functions);
4815 220 : reflection_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
4816 :
4817 220 : INIT_CLASS_ENTRY(_reflection_entry, "Reflector", reflector_functions);
4818 220 : reflector_ptr = zend_register_internal_interface(&_reflection_entry TSRMLS_CC);
4819 :
4820 220 : INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunctionAbstract", reflection_function_abstract_functions);
4821 220 : _reflection_entry.create_object = reflection_objects_new;
4822 220 : reflection_function_abstract_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
4823 220 : reflection_register_implement(reflection_function_abstract_ptr, reflector_ptr TSRMLS_CC);
4824 220 : zend_declare_property_string(reflection_function_abstract_ptr, "name", sizeof("name")-1, "", ZEND_ACC_ABSTRACT TSRMLS_CC);
4825 :
4826 220 : INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunction", reflection_function_functions);
4827 220 : _reflection_entry.create_object = reflection_objects_new;
4828 220 : reflection_function_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr, NULL TSRMLS_CC);
4829 220 : zend_declare_property_string(reflection_function_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
4830 :
4831 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(function, "IS_DEPRECATED", ZEND_ACC_DEPRECATED);
4832 :
4833 220 : INIT_CLASS_ENTRY(_reflection_entry, "ReflectionParameter", reflection_parameter_functions);
4834 220 : _reflection_entry.create_object = reflection_objects_new;
4835 220 : reflection_parameter_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
4836 220 : reflection_register_implement(reflection_parameter_ptr, reflector_ptr TSRMLS_CC);
4837 220 : zend_declare_property_string(reflection_parameter_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
4838 :
4839 220 : INIT_CLASS_ENTRY(_reflection_entry, "ReflectionMethod", reflection_method_functions);
4840 220 : _reflection_entry.create_object = reflection_objects_new;
4841 220 : reflection_method_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr, NULL TSRMLS_CC);
4842 220 : zend_declare_property_string(reflection_method_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
4843 220 : zend_declare_property_string(reflection_method_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
4844 :
4845 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_STATIC", ZEND_ACC_STATIC);
4846 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PUBLIC", ZEND_ACC_PUBLIC);
4847 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PROTECTED", ZEND_ACC_PROTECTED);
4848 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PRIVATE", ZEND_ACC_PRIVATE);
4849 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_ABSTRACT", ZEND_ACC_ABSTRACT);
4850 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_FINAL", ZEND_ACC_FINAL);
4851 :
4852 220 : INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClass", reflection_class_functions);
4853 220 : _reflection_entry.create_object = reflection_objects_new;
4854 220 : reflection_class_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
4855 220 : reflection_register_implement(reflection_class_ptr, reflector_ptr TSRMLS_CC);
4856 220 : zend_declare_property_string(reflection_class_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
4857 :
4858 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_IMPLICIT_ABSTRACT", ZEND_ACC_IMPLICIT_ABSTRACT_CLASS);
4859 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_EXPLICIT_ABSTRACT", ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
4860 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_FINAL", ZEND_ACC_FINAL_CLASS);
4861 :
4862 220 : INIT_CLASS_ENTRY(_reflection_entry, "ReflectionObject", reflection_object_functions);
4863 220 : _reflection_entry.create_object = reflection_objects_new;
4864 220 : reflection_object_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_class_ptr, NULL TSRMLS_CC);
4865 :
4866 220 : INIT_CLASS_ENTRY(_reflection_entry, "ReflectionProperty", reflection_property_functions);
4867 220 : _reflection_entry.create_object = reflection_objects_new;
4868 220 : reflection_property_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
4869 220 : reflection_register_implement(reflection_property_ptr, reflector_ptr TSRMLS_CC);
4870 220 : zend_declare_property_string(reflection_property_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
4871 220 : zend_declare_property_string(reflection_property_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
4872 :
4873 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_STATIC", ZEND_ACC_STATIC);
4874 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PUBLIC", ZEND_ACC_PUBLIC);
4875 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PROTECTED", ZEND_ACC_PROTECTED);
4876 220 : REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PRIVATE", ZEND_ACC_PRIVATE);
4877 :
4878 220 : INIT_CLASS_ENTRY(_reflection_entry, "ReflectionExtension", reflection_extension_functions);
4879 220 : _reflection_entry.create_object = reflection_objects_new;
4880 220 : reflection_extension_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
4881 220 : reflection_register_implement(reflection_extension_ptr, reflector_ptr TSRMLS_CC);
4882 220 : zend_declare_property_string(reflection_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
4883 :
4884 220 : return SUCCESS;
4885 : } /* }}} */
4886 :
4887 : PHP_MINFO_FUNCTION(reflection) /* {{{ */
4888 0 : {
4889 0 : php_info_print_table_start();
4890 0 : php_info_print_table_header(2, "Reflection", "enabled");
4891 :
4892 0 : php_info_print_table_row(2, "Version", "$Id: php_reflection.c,v 1.164.2.33.2.36 2007/03/17 23:00:49 tony2001 Exp $");
4893 :
4894 0 : php_info_print_table_end();
4895 0 : } /* }}} */
4896 :
4897 : zend_module_entry reflection_module_entry = { /* {{{ */
4898 : STANDARD_MODULE_HEADER,
4899 : "Reflection",
4900 : reflection_ext_functions,
4901 : PHP_MINIT(reflection),
4902 : NULL,
4903 : NULL,
4904 : NULL,
4905 : PHP_MINFO(reflection),
4906 : "0.1",
4907 : STANDARD_MODULE_PROPERTIES
4908 : }; /* }}} */
4909 :
4910 : /*
4911 : * Local variables:
4912 : * tab-width: 4
4913 : * c-basic-offset: 4
4914 : * indent-tabs-mode: t
4915 : * End:
4916 : * vim600: noet sw=4 ts=4 fdm=marker
4917 : */
|