Hi Andi et al.,

the attached patch adds the module registering an internal function to the 
zend_internal_function structure. This information can be (and is by this 
patch) used by the reflection API - currently it's quite hard to get the 
extension defining a function. I additionally used this information to make a 
more verbose error messages when redefining an internal function.

Please take a look at it and commit at will.

johannes

p.s. If the patch doesn't reach the list it's available at 
http://svn.schlueters.de/phpatches/HEAD/zend_function_module.diff, too.

p.p.s. In Steph's PAT directory is my ReflectionProptery::getLinenumber() 
patch still waiting, too ;-) http://www.zend.com/zend/week/pat/pat26.txt
Index: Zend/zend_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.313
diff -u -p -r1.313 zend_API.c
--- Zend/zend_API.c     23 Aug 2005 12:53:19 -0000      1.313
+++ Zend/zend_API.c     27 Aug 2005 01:15:56 -0000
@@ -1914,12 +1914,15 @@ ZEND_API zend_module_entry* zend_registe
        }
        efree(lcname);
        module = module_ptr;
+       EG(current_module) = module;
 
        if (module->functions && zend_register_functions(NULL, 
module->functions, NULL, module->type TSRMLS_CC)==FAILURE) {
+               EG(current_module) = NULL;
                zend_error(E_CORE_WARNING,"%s:  Unable to register functions, 
unable to load", module->name);
                return NULL;
        }
 
+       EG(current_module) = NULL;
        return module;
 }
 
@@ -1996,7 +1999,8 @@ ZEND_API int zend_register_functions(zen
                target_function_table = CG(function_table);
        }
        internal_function->type = ZEND_INTERNAL_FUNCTION;
-       
+       internal_function->module = EG(current_module);
+
        if (scope) {
                class_name_len = scope->name_length;
                lc_class_name = zend_str_tolower_dup(scope->name, 
class_name_len);
Index: Zend/zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.658
diff -u -p -r1.658 zend_compile.c
--- Zend/zend_compile.c 24 Aug 2005 20:42:05 -0000      1.658
+++ Zend/zend_compile.c 27 Aug 2005 01:15:57 -0000
@@ -2277,6 +2277,10 @@ ZEND_API int do_bind_function(zend_op *o
                                Z_TYPE(opline->op2.u.constant), 
Z_UNIVAL(opline->op2.u.constant),
                                                ((zend_op_array *) 
function)->filename,
                                                ((zend_op_array *) 
function)->opcodes[0].lineno);
+               } else if (((zend_internal_function *)function)->module) {
+                       zend_error(error_level, "Cannot redeclare %R() 
(internal function exists in module %s)",
+                               Z_TYPE(opline->op2.u.constant), 
Z_UNIVAL(opline->op2.u.constant),
+                                               ((zend_internal_function 
*)function)->module->name);
                } else {
                        zend_error(error_level, "Cannot redeclare %R()", 
Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant));
                }
Index: Zend/zend_compile.h
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.h,v
retrieving revision 1.321
diff -u -p -r1.321 zend_compile.h
--- Zend/zend_compile.h 24 Aug 2005 20:42:06 -0000      1.321
+++ Zend/zend_compile.h 27 Aug 2005 01:15:57 -0000
@@ -238,6 +238,7 @@ typedef struct _zend_internal_function {
        /* END of common elements */
 
        void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
+       struct _zend_module_entry *module;
 } zend_internal_function;
 
 #define ZEND_FN_SCOPE_NAME(function)  ((function) && (function)->common.scope 
? (function)->common.scope->name : EMPTY_STR)
Index: Zend/zend_object_handlers.c
===================================================================
RCS file: /repository/ZendEngine2/zend_object_handlers.c,v
retrieving revision 1.144
diff -u -p -r1.144 zend_object_handlers.c
--- Zend/zend_object_handlers.c 19 Aug 2005 22:33:39 -0000      1.144
+++ Zend/zend_object_handlers.c 27 Aug 2005 01:15:57 -0000
@@ -716,6 +716,7 @@ static union _zend_function *zend_std_ge
                if (zobj->ce->__call) {
                        zend_internal_function *call_user_call = 
emalloc(sizeof(zend_internal_function));
                        call_user_call->type = ZEND_INTERNAL_FUNCTION;
+                       call_user_call->module = zobj->ce->module;
                        call_user_call->handler = zend_std_call_user_call;
                        call_user_call->arg_info = NULL;
                        call_user_call->num_args = 0;
Index: Zend/zend_reflection_api.c
===================================================================
RCS file: /repository/ZendEngine2/zend_reflection_api.c,v
retrieving revision 1.172
diff -u -p -r1.172 zend_reflection_api.c
--- Zend/zend_reflection_api.c  19 Aug 2005 13:20:14 -0000      1.172
+++ Zend/zend_reflection_api.c  27 Aug 2005 01:15:58 -0000
@@ -648,7 +648,13 @@ static void _function_string(string *str
        }
 
        string_printf(str, fptr->common.scope ? "%sMethod [ " : "%sFunction [ 
", indent);
-       string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user> " : 
"<internal> ");
+       string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : 
"<internal");
+       if (fptr->type == ZEND_INTERNAL_FUNCTION && 
((zend_internal_function*)fptr)->module) {
+               string_printf(str, ":%s", 
((zend_internal_function*)fptr)->module->name);
+       }
+       string_printf(str, "> ");
+
+
        if (fptr->common.fn_flags & ZEND_ACC_CTOR) {
                string_printf(str, "<ctor> ");
        }
@@ -1552,7 +1558,7 @@ ZEND_METHOD(reflection_function, getNumb
 }
 /* }}} */
 
-/* {{{ proto public ReflectionParameter[] Reflection_Function::getParameters()
+/* {{{ proto public ReflectionParameter[] ReflectionFunction::getParameters()
    Returns an array of parameter objects for this function */
 ZEND_METHOD(reflection_function, getParameters)
 {
@@ -1579,6 +1585,54 @@ ZEND_METHOD(reflection_function, getPara
 }
 /* }}} */
 
+/* {{{ proto public ReflectionExtension|NULL ReflectionFunction::getExtension()
+   Returns NULL or the extension the function belongs to */
+ZEND_METHOD(reflection_function, getExtension)
+{
+       reflection_object *intern;
+       zend_function *fptr;
+       zend_internal_function *internal;
+
+       METHOD_NOTSTATIC;
+       GET_REFLECTION_OBJECT_PTR(fptr);
+
+       if (fptr->type != ZEND_INTERNAL_FUNCTION) {
+               RETURN_NULL();
+       }
+
+       internal = (zend_internal_function *)fptr;
+       if (internal->module) {
+               reflection_extension_factory(return_value, 
internal->module->name TSRMLS_CC);
+       } else {
+               RETURN_NULL();
+       }
+}
+/* }}} */
+
+/* {{{ proto public string|false ReflectionFunction::getExtensionName()
+   Returns false or the name of the extension the function belongs to */
+ZEND_METHOD(reflection_function, getExtensionName)
+{
+       reflection_object *intern;
+       zend_function *fptr;
+       zend_internal_function *internal;
+
+       METHOD_NOTSTATIC;
+       GET_REFLECTION_OBJECT_PTR(fptr);
+
+       if (fptr->type != ZEND_INTERNAL_FUNCTION) {
+               RETURN_FALSE;
+       }
+
+       internal = (zend_internal_function *)fptr;
+       if (internal->module) {
+               RETURN_STRING(internal->module->name, 1);
+       } else {
+               RETURN_FALSE;
+       }
+}
+/* }}} */
+
 /* {{{ proto public static mixed ReflectionParameter::export(mixed function, 
mixed parameter [, bool return]) throws ReflectionException
    Exports a reflection object. Returns the output if TRUE is specified for 
return, printing it otherwise. */
 ZEND_METHOD(reflection_parameter, export)
@@ -3849,6 +3903,8 @@ static zend_function_entry reflection_fu
        ZEND_ME(reflection_function, getParameters, NULL, 0)
        ZEND_ME(reflection_function, getNumberOfParameters, NULL, 0)
        ZEND_ME(reflection_function, getNumberOfRequiredParameters, NULL, 0)
+       ZEND_ME(reflection_function, getExtension, NULL, 0)
+       ZEND_ME(reflection_function, getExtensionName, NULL, 0)
        {NULL, NULL, NULL}
 };
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to