cvs: php4 /ext/overload overload.c

From: Date: Fri, 07 Dec 2001 06:08:15 +0000
Subject: cvs: php4 /ext/overload overload.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-8494@lists.php.net to get a copy of this message
andrei Fri Dec 7 01:08:15 2001 EDT Modified files: /php4/ext/overload overload.c Log: If the method exists in object's function table, call it directly without using __call() handler. Index: php4/ext/overload/overload.c diff -u php4/ext/overload/overload.c:1.3 php4/ext/overload/overload.c:1.4 --- php4/ext/overload/overload.c:1.3 Fri Dec 7 00:46:02 2001 +++ php4/ext/overload/overload.c Fri Dec 7 01:08:15 2001 @@ -12,8 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: | - | | + | Authors: Andrei Zmievski <andrei@php.net> | +----------------------------------------------------------------------+ */ @@ -27,8 +26,7 @@ * - handle both OE_IS_OBJECT and OE_IS_ARRAY in the whole chain * + see how to fix the issue of object trying to set its own property inside * the handler - * - don't overload constructors? - * - flag to check if function exists in function table, then call it, otherwise + * + check if function exists in function table, then call it, otherwise * call handler (aka AUTOLOAD in Perl) * + should it check for existing properties first before calling __get/__set: * yes @@ -419,42 +417,60 @@ { zval ***args; zval *retval = NULL; - int call_result; + int call_result, arg_offset = 1; + zend_bool use_call_handler = 1; zend_class_entry temp_ce, *orig_ce; zval *object = property_reference->object; zval call_handler, method_name, *method_name_ptr = &method_name; zend_overloaded_element *method = (zend_overloaded_element *)property_reference->elements_list->tail->data; - args = (zval ***)emalloc((ZEND_NUM_ARGS() + 1) * sizeof(zval **)); + if (zend_hash_exists(&Z_OBJCE_P(object)->function_table, + Z_STRVAL(method->element), + Z_STRLEN(method->element) + 1)) { + use_call_handler = 0; + arg_offset = 0; + } + + args = (zval ***)emalloc((ZEND_NUM_ARGS() + arg_offset) * sizeof(zval **)); - if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), &args[1]) == FAILURE) { + if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), &args[arg_offset]) == FAILURE) { efree(args); php_error(E_WARNING, "unable to obtain arguments"); return; } - temp_ce = *Z_OBJCE_P(object); - DISABLE_HANDLERS(temp_ce); - orig_ce = Z_OBJCE_P(object); - Z_OBJCE_P(object) = &temp_ce; - - ZVAL_STRINGL(&call_handler, CALL_HANDLER, sizeof(CALL_HANDLER)-1, 0); - ZVAL_STRINGL(&method_name, Z_STRVAL(method->element), Z_STRLEN(method->element), 0); - INIT_PZVAL(method_name_ptr); - args[0] = &method_name_ptr; + if (use_call_handler) { + temp_ce = *Z_OBJCE_P(object); + DISABLE_HANDLERS(temp_ce); + orig_ce = Z_OBJCE_P(object); + Z_OBJCE_P(object) = &temp_ce; + + ZVAL_STRINGL(&call_handler, CALL_HANDLER, sizeof(CALL_HANDLER)-1, 0); + ZVAL_STRINGL(&method_name, Z_STRVAL(method->element), Z_STRLEN(method->element), 0); + INIT_PZVAL(method_name_ptr); + args[0] = &method_name_ptr; + } else { + ZVAL_STRINGL(&call_handler, Z_STRVAL(method->element), Z_STRLEN(method->element), 0); + } call_result = call_user_function_ex(NULL, &object, &call_handler, &retval, - ZEND_NUM_ARGS() + 1, args, + ZEND_NUM_ARGS() + arg_offset, args, 0, NULL TSRMLS_CC); - /* Restore object's original CE. */ - Z_OBJCE_P(object) = orig_ce; + + if (use_call_handler) { + /* Restore object's original CE. */ + Z_OBJCE_P(object) = orig_ce; + } if (call_result == FAILURE || !retval) { efree(args); - php_error(E_WARNING, "unable to call %s::__call() handler", orig_ce->name); + if (use_call_handler) + php_error(E_WARNING, "unable to call %s::__call() handler", orig_ce->name); + else + php_error(E_WARNING, "unable to call %s::%s() method", orig_ce->name, Z_STRVAL(method->element)); return; }

« previous php.cvs (#8494) next »