cvs: php4 /ext/overload overload.c

From: Date: Fri, 07 Dec 2001 05:46:02 +0000
Subject: cvs: php4 /ext/overload overload.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-8493@lists.php.net to get a copy of this message
andrei Fri Dec 7 00:46:02 2001 EDT Modified files: /php4/ext/overload overload.c Log: Support overloaded method calls via __call(). Index: php4/ext/overload/overload.c diff -u php4/ext/overload/overload.c:1.2 php4/ext/overload/overload.c:1.3 --- php4/ext/overload/overload.c:1.2 Fri Nov 16 10:04:12 2001 +++ php4/ext/overload/overload.c Fri Dec 7 00:46:02 2001 @@ -19,7 +19,7 @@ /* * TODO: - * - provide a way for user to enable/disabling overloading of get/set/call + * + provide a way for user to enable/disabling overloading of get/set/call * individually * - call original overloaded handlers if necessary * + use local copy of CE with NULL'ed out handler when calling object's @@ -137,7 +137,7 @@ int call_result; zend_class_entry temp_ce, *orig_ce; zval result, *result_ptr = &result; - zval method_name; + zval get_handler; zval **args[2]; zval *retval = NULL; oo_class_data oo_data; @@ -158,13 +158,13 @@ result_ptr->refcount = 1; ZVAL_NULL(result_ptr); - ZVAL_STRINGL(&method_name, GET_HANDLER, sizeof(GET_HANDLER)-1, 0); + ZVAL_STRINGL(&get_handler, GET_HANDLER, sizeof(GET_HANDLER)-1, 0); args[0] = &prop_name; args[1] = &result_ptr; call_result = call_user_function_ex(NULL, &object, - &method_name, + &get_handler, &retval, 2, args, 0, NULL TSRMLS_CC); @@ -203,7 +203,7 @@ { int call_result; zend_class_entry temp_ce, *orig_ce; - zval method_name; + zval set_handler; zval *value_copy; zval **args[2]; zval *retval = NULL; @@ -221,7 +221,7 @@ orig_ce = Z_OBJCE_P(object); Z_OBJCE_P(object) = &temp_ce; - ZVAL_STRINGL(&method_name, SET_HANDLER, sizeof(SET_HANDLER)-1, 0); + ZVAL_STRINGL(&set_handler, SET_HANDLER, sizeof(SET_HANDLER)-1, 0); if (value->refcount == 0) { MAKE_STD_ZVAL(value_copy); *value_copy = *value; @@ -233,7 +233,7 @@ call_result = call_user_function_ex(NULL, &object, - &method_name, + &set_handler, &retval, 2, args, 0, NULL TSRMLS_CC); @@ -417,6 +417,52 @@ static void overload_call_method(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference) { + zval ***args; + zval *retval = NULL; + int call_result; + 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_get_parameters_array_ex(ZEND_NUM_ARGS(), &args[1]) == 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; + + call_result = call_user_function_ex(NULL, + &object, + &call_handler, + &retval, + ZEND_NUM_ARGS() + 1, args, + 0, NULL TSRMLS_CC); + /* 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); + return; + } + + *return_value = *retval; + INIT_PZVAL(return_value); + FREE_ZVAL(retval); + efree(args); + zval_dtor(&method->element); } /* {{{ proto void overload(string class_entry) @@ -455,9 +501,11 @@ } else oo_data.handle_property_set = NULL; - /* - oo_data.handle_function_call = ce->handle_function_call; - */ + if (zend_hash_exists(&ce->function_table, CALL_HANDLER, sizeof(CALL_HANDLER))) { + oo_data.handle_function_call = ce->handle_function_call; + ce->handle_function_call = overload_call_method; + } else + oo_data.handle_function_call = NULL; zend_hash_index_update(&OOG(overloaded_classes), (long)ce, &oo_data, sizeof(oo_data), NULL);

« previous php.cvs (#8493) next »