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