Hello.
This patch allows __autoload to be called to not only for
classes but for functions too. It adds two defines:
AUTOLOAD_CLASS and AUTOLOAD_FUNCTION. The prototype
for __autoload becomes:
function autoload ($autoload_name, $autoload_type);
where $autoload_type is AUTOLOAD_CLASS or
AUTOLOAD_FUNCTION.

vesselin

diff -ru php5-200308212130.orig/Zend/zend_constants.c
php5-200308212130/Zend/zend_constants.c
--- php5-200308212130.orig/Zend/zend_constants.c        2003-07-27
13:06:49.000000000 +0000
+++ php5-200308212130/Zend/zend_constants.c     2003-08-22 05:43:25.000000000
+0000
@@ -106,6 +106,9 @@
        REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE,
CONST_PERSISTENT | CONST_CS);

        REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
+
+       REGISTER_MAIN_LONG_CONSTANT("AUTOLOAD_CLASS", AUTOLOAD_CLASS,
CONST_PERSISTENT | CONST_CS);
+       REGISTER_MAIN_LONG_CONSTANT("AUTOLOAD_FUNCTION", AUTOLOAD_FUNCTION,
CONST_PERSISTENT | CONST_CS);

        /* true/false constants */
        {
diff -ru php5-200308212130.orig/Zend/zend_constants.h
php5-200308212130/Zend/zend_constants.h
--- php5-200308212130.orig/Zend/zend_constants.h        2003-06-10
20:07:17.000000000 +0000
+++ php5-200308212130/Zend/zend_constants.h     2003-08-22 05:42:45.000000000
+0000
@@ -64,6 +64,9 @@

 #define ZEND_CONSTANT_DTOR (void (*)(void *)) free_zend_constant

+#define AUTOLOAD_CLASS                 0
+#define AUTOLOAD_FUNCTION      1
+
 #endif

 /*
diff -ru php5-200308212130.orig/Zend/zend_execute.c
php5-200308212130/Zend/zend_execute.c
--- php5-200308212130.orig/Zend/zend_execute.c  2003-08-19 02:07:34.000000000
+0000
+++ php5-200308212130/Zend/zend_execute.c       2003-08-22 06:42:08.000000000
+0000
@@ -2449,6 +2449,17 @@
        NEXT_OPCODE();
 }

+static inline int zend_lookup_function (char *name, int name_length,
zend_function **function)
+{
+       if (zend_hash_find(EG(function_table), name, name_length+1, (void **)
function) == SUCCESS) {
+               return SUCCESS;
+       }
+       if (zend_autoload_name(name, name_length, AUTOLOAD_FUNCTION) == FAILURE) {
+               return FAILURE;
+       }
+       return zend_hash_find(EG(function_table), name, name_length+1, (void **)
function);
+}
+
 int zend_init_fcall_by_name_handler(ZEND_OPCODE_HANDLER_ARGS)
 {
        zval *function_name;
@@ -2473,8 +2484,8 @@
                function_name_strval = 
zend_str_tolower_dup(function_name->value.str.val,
function_name->value.str.len);
                function_name_strlen = function_name->value.str.len;
        }
-
-       if (zend_hash_find(EG(function_table), function_name_strval,
function_name_strlen+1, (void **) &function)==FAILURE) {
+
+       if (zend_lookup_function(function_name_strval, function_name_strlen,
&function) == FAILURE) {
                zend_error(E_ERROR, "Call to undefined function:  %s()",
function_name_strval);
        }

diff -ru php5-200308212130.orig/Zend/zend_execute.h
php5-200308212130/Zend/zend_execute.h
--- php5-200308212130.orig/Zend/zend_execute.h  2003-08-03 09:07:21.000000000
+0000
+++ php5-200308212130/Zend/zend_execute.h       2003-08-22 06:26:14.000000000
+0000
@@ -148,6 +148,8 @@
 ZEND_API void zend_unset_timeout(TSRMLS_D);
 ZEND_API void zend_timeout(int dummy);
 ZEND_API zend_class_entry *zend_fetch_class(char *class_name, uint
class_name_len, int fetch_type TSRMLS_DC);
+ZEND_API int zend_autoload_name(char *name, int name_length, long type);
+

 #ifdef ZEND_WIN32
 void zend_init_timeout_thread();
diff -ru php5-200308212130.orig/Zend/zend_execute_API.c
php5-200308212130/Zend/zend_execute_API.c
--- php5-200308212130.orig/Zend/zend_execute_API.c      2003-08-07
08:06:15.000000000 +0000
+++ php5-200308212130/Zend/zend_execute_API.c   2003-08-22 06:26:17.000000000
+0000
@@ -757,39 +757,13 @@

 ZEND_API int zend_lookup_class(char *name, int name_length,
zend_class_entry ***ce TSRMLS_DC)
 {
-       zval **args[1];
-       zval *autoload_function;
-       zval *class_name;
-       zval *retval_ptr;
-       int retval;

        if (zend_hash_find(EG(class_table), name, name_length+1, (void **) ce) ==
SUCCESS) {
                return SUCCESS;
        }
-
-       MAKE_STD_ZVAL(autoload_function);
-       ZVAL_STRINGL(autoload_function, "__autoload", sizeof("__autoload")-1,  1);
-
-       MAKE_STD_ZVAL(class_name);
-       ZVAL_STRINGL(class_name, name, name_length, 1);
-       args[0] = &class_name;
-
-       retval = call_user_function_ex(EG(function_table), NULL,
autoload_function, &retval_ptr, 1, args, 0, NULL TSRMLS_CC);
-
-       zval_ptr_dtor(&autoload_function);
-       zval_ptr_dtor(&class_name);
-
-       if (retval == FAILURE) {
+       if (zend_autoload_name(name, name_length, AUTOLOAD_CLASS) == FAILURE) {
                return FAILURE;
        }
-
-       if (EG(exception)) {
-               zend_error(E_ERROR, "__autoload threw an exception");
-       }
-
-       /* If an exception is thrown retval_ptr will be NULL but we bailout before
we reach this point */
-       zval_ptr_dtor(&retval_ptr);
-
        return zend_hash_find(EG(class_table), name, name_length + 1, (void **)
ce);
 }

@@ -1104,6 +1078,46 @@
        return *pce;
 }

+int zend_autoload_name(char *name, int name_length, long type)
+{
+       zval **args[2];
+       zval *autoload_function;
+       zval *autoload_name;
+       zval *autoload_type;
+       zval *retval_ptr;
+       int retval;
+
+       MAKE_STD_ZVAL(autoload_function);
+       ZVAL_STRINGL(autoload_function, "__autoload", sizeof("__autoload")-1,  1);
+
+       MAKE_STD_ZVAL(autoload_name);
+       ZVAL_STRINGL(autoload_name, name, name_length, 1);
+       args[0] = &autoload_name;
+
+       MAKE_STD_ZVAL(autoload_type);
+       ZVAL_LONG(autoload_type, type);
+       args[1] = &autoload_type;
+
+       retval = call_user_function_ex(EG(function_table), NULL,
autoload_function, &retval_ptr, 2, args, 0, NULL TSRMLS_CC);
+
+       zval_ptr_dtor(&autoload_function);
+       zval_ptr_dtor(&autoload_name);
+       zval_ptr_dtor(&autoload_type);
+
+       if (retval == FAILURE) {
+               return FAILURE;
+       }
+
+       if (EG(exception)) {
+               zend_error(E_ERROR, "__autoload threw an exception");
+       }
+
+       /* If an exception is thrown retval_ptr will be NULL but we bailout before
we reach this point */
+       zval_ptr_dtor(&retval_ptr);
+
+       return SUCCESS;
+}
+
 /*
  * Local variables:
  * tab-width: 4


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

Reply via email to