diff options
-rw-r--r-- | UPGRADING.INTERNALS | 12 | ||||
-rw-r--r-- | Zend/tests/overloaded_func_001.phpt | 10 | ||||
-rw-r--r-- | Zend/zend_API.c | 18 | ||||
-rw-r--r-- | Zend/zend_compile.h | 2 | ||||
-rw-r--r-- | Zend/zend_execute.c | 37 | ||||
-rw-r--r-- | Zend/zend_execute.h | 2 | ||||
-rw-r--r-- | Zend/zend_execute_API.c | 28 | ||||
-rw-r--r-- | Zend/zend_iterators.c | 1 | ||||
-rw-r--r-- | Zend/zend_object_handlers.c | 1 | ||||
-rw-r--r-- | Zend/zend_object_handlers.h | 2 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 19 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 38 | ||||
-rw-r--r-- | ext/com_dotnet/com_handlers.c | 78 | ||||
-rw-r--r-- | ext/com_dotnet/com_saproxy.c | 6 | ||||
-rw-r--r-- | ext/pdo/pdo_stmt.c | 6 | ||||
-rw-r--r-- | ext/reflection/php_reflection.c | 8 | ||||
-rw-r--r-- | ext/spl/spl_iterators.c | 42 | ||||
-rw-r--r-- | ext/zend_test/test.c | 43 |
18 files changed, 94 insertions, 259 deletions
diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 7dea050f66..9c48ad1588 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -2,6 +2,7 @@ PHP 8.0 INTERNALS UPGRADE NOTES 1. Internal API changes a. Object Handlers API + b. ZEND_OVERLOADED_FUNCTION and corresponding call_method() object handler 2. Build system changes a. Abstract @@ -14,10 +15,15 @@ PHP 8.0 INTERNALS UPGRADE NOTES 1. Internal API changes ======================== - a. Object Handlers API and some related functions, e.g. zend_call_method() and - zend_objects_clone_obj() were changed to receive zend_object* instead of - zval* and zend_string* instead of zval* for property names. + a. Object Handlers API and some related functions, e.g. zend_call_method() and + zend_objects_clone_obj() were changed to receive zend_object* instead of + zval* and zend_string* instead of zval* for property names. + b. ZEND_OVERLOADED_FUNCTION and corresponding call_method() object handler + were removed. ZEND_INTERNAL_FUNCTION with ZEND_ACC_CALL_VIA_HANDLER and + defined "handler" callback should be used instead. This "handler" callback + should also take care about function cleanup. See ext/zend_test/test.c + for example. ======================== 2. Build system changes diff --git a/Zend/tests/overloaded_func_001.phpt b/Zend/tests/overloaded_func_001.phpt index 31585d505a..7fc435f920 100644 --- a/Zend/tests/overloaded_func_001.phpt +++ b/Zend/tests/overloaded_func_001.phpt @@ -6,10 +6,10 @@ if (!extension_loaded('zend-test')) die('skip zend-test extension not loaded'); ?> --FILE-- <?php +$o = new _ZendTestChildClass(); +var_dump($o->test()); var_dump(_ZendTestClass::test()); ?> ---EXPECTF-- -Fatal error: Uncaught Error: Cannot call overloaded function for non-object in %soverloaded_func_001.php:%d -Stack trace: -#0 {main} - thrown in %soverloaded_func_001.php on line %d +--EXPECT-- +string(4) "test" +string(4) "test" diff --git a/Zend/zend_API.c b/Zend/zend_API.c index b51d6bd408..0b745161ff 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3014,8 +3014,7 @@ get_function_via_handler: (!fcc->function_handler->common.scope || !instanceof_function(ce_org, fcc->function_handler->common.scope))) { if (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { - if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION && - fcc->function_handler->common.function_name) { + if (fcc->function_handler->common.function_name) { zend_string_release_ex(fcc->function_handler->common.function_name, 0); } zend_free_trampoline(fcc->function_handler); @@ -3206,11 +3205,8 @@ check_func: ret = zend_is_callable_check_func(check_flags, callable, fcc, strict_class, error); if (fcc == &fcc_local && fcc->function_handler && - ((fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) || - fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY || - fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) { - if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION && - fcc->function_handler->common.function_name) { + (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { + if (fcc->function_handler->common.function_name) { zend_string_release_ex(fcc->function_handler->common.function_name, 0); } zend_free_trampoline(fcc->function_handler); @@ -3322,12 +3318,8 @@ ZEND_API zend_bool zend_make_callable(zval *callable, zend_string **callable_nam add_next_index_str(callable, zend_string_copy(fcc.function_handler->common.function_name)); } if (fcc.function_handler && - ((fcc.function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) || - fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY || - fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION)) { - if (fcc.function_handler->type != ZEND_OVERLOADED_FUNCTION) { - zend_string_release_ex(fcc.function_handler->common.function_name, 0); - } + (fcc.function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { + zend_string_release_ex(fcc.function_handler->common.function_name, 0); zend_free_trampoline(fcc.function_handler); } return 1; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 62d17b4e11..6c1be2fdc0 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -875,9 +875,7 @@ void zend_assert_valid_class_name(const zend_string *const_name); #define ZEND_INTERNAL_FUNCTION 1 #define ZEND_USER_FUNCTION 2 -#define ZEND_OVERLOADED_FUNCTION 3 #define ZEND_EVAL_CODE 4 -#define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5 /* A quick check (type == ZEND_USER_FUNCTION || type == ZEND_EVAL_CODE) */ #define ZEND_USER_CODE(type) ((type & 1) == 0) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index edaed2c63f..e33506d775 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -4069,43 +4069,6 @@ already_compiled: } /* }}} */ -ZEND_API int ZEND_FASTCALL zend_do_fcall_overloaded(zend_execute_data *call, zval *ret) /* {{{ */ -{ - zend_function *fbc = call->func; - zend_object *object; - - /* Not sure what should be done here if it's a static method */ - if (UNEXPECTED(Z_TYPE(call->This) != IS_OBJECT)) { - zend_vm_stack_free_args(call); - if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) { - zend_string_release_ex(fbc->common.function_name, 0); - } - efree(fbc); - zend_vm_stack_free_call_frame(call); - - zend_throw_error(NULL, "Cannot call overloaded function for non-object"); - return 0; - } - - object = Z_OBJ(call->This); - - ZVAL_NULL(ret); - - EG(current_execute_data) = call; - object->handlers->call_method(fbc->common.function_name, object, call, ret); - EG(current_execute_data) = call->prev_execute_data; - - zend_vm_stack_free_args(call); - - if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) { - zend_string_release_ex(fbc->common.function_name, 0); - } - efree(fbc); - - return 1; -} -/* }}} */ - static zend_never_inline zend_bool ZEND_FASTCALL zend_fe_reset_iterator(zval *array_ptr, int by_ref OPLINE_DC EXECUTE_DATA_DC) /* {{{ */ { zend_class_entry *ce = Z_OBJCE_P(array_ptr); diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index a73982ab91..76f7d09f43 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -375,8 +375,6 @@ ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table); ZEND_API void zend_free_compiled_variables(zend_execute_data *execute_data); ZEND_API void zend_cleanup_unfinished_execution(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num); -ZEND_API int ZEND_FASTCALL zend_do_fcall_overloaded(zend_execute_data *call, zval *ret); - #define CACHE_ADDR(num) \ ((void**)((char*)EX_RUN_TIME_CACHE() + (num))) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index fb6faad8af..de85e2ea6c 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -772,8 +772,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / /* We must re-initialize function again */ fci_cache->function_handler = NULL; } - } else if (func->type == ZEND_INTERNAL_FUNCTION) { + } else { int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0; + + ZEND_ASSERT(func->type == ZEND_INTERNAL_FUNCTION); ZVAL_NULL(fci->retval); call->prev_execute_data = EG(current_execute_data); call->return_value = NULL; /* this is not a constructor call */ @@ -796,30 +798,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / /* We must re-initialize function again */ fci_cache->function_handler = NULL; } - } else { /* ZEND_OVERLOADED_FUNCTION */ - ZVAL_NULL(fci->retval); - - /* Not sure what should be done here if it's a static method */ - if (fci->object) { - call->prev_execute_data = EG(current_execute_data); - EG(current_execute_data) = call; - fci->object->handlers->call_method(func->common.function_name, fci->object, call, fci->retval); - EG(current_execute_data) = call->prev_execute_data; - } else { - zend_throw_error(NULL, "Cannot call overloaded function for non-object"); - } - - zend_vm_stack_free_args(call); - - if (func->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) { - zend_string_release_ex(func->common.function_name, 0); - } - efree(func); - - if (EG(exception)) { - zval_ptr_dtor(fci->retval); - ZVAL_UNDEF(fci->retval); - } } zend_vm_stack_free_call_frame(call); diff --git a/Zend/zend_iterators.c b/Zend/zend_iterators.c index bb3cf1b6a2..7e920c00d8 100644 --- a/Zend/zend_iterators.c +++ b/Zend/zend_iterators.c @@ -44,7 +44,6 @@ static const zend_object_handlers iterator_object_handlers = { NULL, /* unset dim */ NULL, /* props get */ NULL, /* method get */ - NULL, /* call */ NULL, /* get ctor */ NULL, /* get class name */ NULL, /* compare */ diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index eb853064c2..520610327f 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1845,7 +1845,6 @@ ZEND_API const zend_object_handlers std_object_handlers = { zend_std_unset_dimension, /* unset_dimension */ zend_std_get_properties, /* get_properties */ zend_std_get_method, /* get_method */ - NULL, /* call_method */ zend_std_get_constructor, /* get_constructor */ zend_std_get_class_name, /* get_class_name */ zend_std_compare_objects, /* compare_objects */ diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 64356bcb04..ff4f025970 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -120,7 +120,6 @@ typedef zend_array *(*zend_object_get_properties_for_t)(zend_object *object, zen /* args on stack! */ /* Andi - EX(fbc) (function being called) needs to be initialized already in the INIT fcall opcode so that the parameters can be parsed the right way. We need to add another callback for this. */ -typedef int (*zend_object_call_method_t)(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS); typedef zend_function *(*zend_object_get_method_t)(zend_object **object, zend_string *method, const zval *key); typedef zend_function *(*zend_object_get_constructor_t)(zend_object *object); @@ -171,7 +170,6 @@ struct _zend_object_handlers { zend_object_unset_dimension_t unset_dimension; /* required */ zend_object_get_properties_t get_properties; /* required */ zend_object_get_method_t get_method; /* required */ - zend_object_call_method_t call_method; /* optional */ zend_object_get_constructor_t get_constructor; /* required */ zend_object_get_class_name_t get_class_name; /* required */ zend_object_compare_t compare_objects; /* optional */ diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 9b808a6e12..5114b2275c 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4019,9 +4019,10 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL)) ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); zend_execute_ex(call); } - } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) { + } else { zval retval; + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); call->prev_execute_data = execute_data; EG(current_execute_data) = call; @@ -4056,22 +4057,6 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL)) if (!RETURN_VALUE_USED(opline)) { zval_ptr_dtor(ret); } - - } else { /* ZEND_OVERLOADED_FUNCTION */ - zval retval; - - ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; - - call->prev_execute_data = execute_data; - - if (UNEXPECTED(!zend_do_fcall_overloaded(call, ret))) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - if (!RETURN_VALUE_USED(opline)) { - zval_ptr_dtor(ret); - } } ZEND_VM_C_LABEL(fcall_end): diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 13e096363d..a7a17c64af 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -963,9 +963,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); zend_execute_ex(call); } - } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) { + } else { zval retval; + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); call->prev_execute_data = execute_data; EG(current_execute_data) = call; @@ -1000,22 +1001,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV if (!0) { zval_ptr_dtor(ret); } - - } else { /* ZEND_OVERLOADED_FUNCTION */ - zval retval; - - ret = 0 ? EX_VAR(opline->result.var) : &retval; - - call->prev_execute_data = execute_data; - - if (UNEXPECTED(!zend_do_fcall_overloaded(call, ret))) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - if (!0) { - zval_ptr_dtor(ret); - } } fcall_end: @@ -1084,9 +1069,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); zend_execute_ex(call); } - } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) { + } else { zval retval; + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); call->prev_execute_data = execute_data; EG(current_execute_data) = call; @@ -1121,22 +1107,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV if (!1) { zval_ptr_dtor(ret); } - - } else { /* ZEND_OVERLOADED_FUNCTION */ - zval retval; - - ret = 1 ? EX_VAR(opline->result.var) : &retval; - - call->prev_execute_data = execute_data; - - if (UNEXPECTED(!zend_do_fcall_overloaded(call, ret))) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - if (!1) { - zval_ptr_dtor(ret); - } } fcall_end: diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c index 6e5cc8c4d8..4f64b5502e 100644 --- a/ext/com_dotnet/com_handlers.c +++ b/ext/com_dotnet/com_handlers.c @@ -246,11 +246,42 @@ static void function_dtor(zval *zv) static PHP_FUNCTION(com_method_handler) { zval *object = getThis(); + zend_string *method = EX(func)->common.function_name; + zval *args = NULL; + php_com_dotnet_object *obj = CDNO_FETCH(object); + int nargs; + VARIANT v; + int ret = FAILURE; + + if (V_VT(&obj->v) != VT_DISPATCH) { + goto exit; + } + + nargs = ZEND_NUM_ARGS(); + + if (nargs) { + args = (zval *)safe_emalloc(sizeof(zval), nargs, 0); + zend_get_parameters_array_ex(nargs, args); + } + + VariantInit(&v); + + if (SUCCESS == php_com_do_invoke_byref(obj, (zend_internal_function*)EX(func), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, nargs, args)) { + php_com_zval_from_variant(return_value, &v, obj->code_page); + ret = SUCCESS; + VariantClear(&v); + } - Z_OBJ_HANDLER_P(object, call_method)( - ((zend_internal_function*)EX(func))->function_name, - Z_OBJ_P(object), - INTERNAL_FUNCTION_PARAM_PASSTHRU); + if (args) { + efree(args); + } + +exit: + /* Cleanup trampoline */ + ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE); + zend_string_release(EX(func)->common.function_name); + zend_free_trampoline(EX(func)); + EX(func) = NULL; } static zend_function *com_method_get(zend_object **object_ptr, zend_string *name, const zval *key) @@ -270,7 +301,8 @@ static zend_function *com_method_get(zend_object **object_ptr, zend_string *name /* check cache */ if (obj->method_cache == NULL || NULL == (fptr = zend_hash_find_ptr(obj->method_cache, name))) { - f.type = ZEND_OVERLOADED_FUNCTION; + memset(&f, 0, sizeof(zend_internal_function)); + f.type = ZEND_INTERNAL_FUNCTION; f.num_args = 0; f.arg_info = NULL; f.scope = obj->ce; @@ -345,6 +377,7 @@ static zend_function *com_method_get(zend_object **object_ptr, zend_string *name if (fptr) { /* duplicate this into a new chunk of emalloc'd memory, * since the engine will efree it */ + zend_string_addref(fptr->function_name); func = emalloc(sizeof(*fptr)); memcpy(func, fptr, sizeof(*fptr)); @@ -354,40 +387,6 @@ static zend_function *com_method_get(zend_object **object_ptr, zend_string *name return NULL; } -static int com_call_method(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS) -{ - zval *args = NULL; - php_com_dotnet_object *obj = (php_com_dotnet_object*)object; - int nargs; - VARIANT v; - int ret = FAILURE; - - if (V_VT(&obj->v) != VT_DISPATCH) { - return FAILURE; - } - - nargs = ZEND_NUM_ARGS(); - - if (nargs) { - args = (zval *)safe_emalloc(sizeof(zval), nargs, 0); - zend_get_parameters_array_ex(nargs, args); - } - - VariantInit(&v); - - if (SUCCESS == php_com_do_invoke_byref(obj, (zend_internal_function*)EX(func), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, nargs, args)) { - php_com_zval_from_variant(return_value, &v, obj->code_page); - ret = SUCCESS; - VariantClear(&v); - } - - if (args) { - efree(args); - } - - return ret; -} - static zend_function *com_constructor_get(zend_object *object) { php_com_dotnet_object *obj = (php_com_dotnet_object *) object; @@ -554,7 +553,6 @@ zend_object_handlers php_com_object_handlers = { com_dimension_delete, com_properties_get, com_method_get, - com_call_method, com_constructor_get, com_class_name_get, com_objects_compare, diff --git a/ext/com_dotnet/com_saproxy.c b/ext/com_dotnet/com_saproxy.c index 7ce57ce915..225786bde8 100644 --- a/ext/com_dotnet/com_saproxy.c +++ b/ext/com_dotnet/com_saproxy.c @@ -319,11 +319,6 @@ static zend_function *saproxy_method_get(zend_object **object, zend_string *name return NULL; } -static int saproxy_call_method(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS) -{ - return FAILURE; -} - static zend_function *saproxy_constructor_get(zend_object *object) { /* user cannot instantiate */ @@ -410,7 +405,6 @@ zend_object_handlers php_com_saproxy_handlers = { saproxy_dimension_delete, saproxy_properties_get, saproxy_method_get, - saproxy_call_method, saproxy_constructor_get, saproxy_class_name_get, saproxy_objects_compare, diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 50820499cf..9a84fe7067 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -2656,11 +2656,6 @@ static zend_function *row_method_get( return fbc; } -static int row_call_method(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS) -{ - return FAILURE; -} - static zend_function *row_get_ctor(zend_object *object) { zend_throw_exception_ex(php_pdo_get_exception(), 0, "You may not create a PDORow manually"); @@ -2739,7 +2734,6 @@ void pdo_stmt_init(void) pdo_row_object_handlers.unset_dimension = row_dim_delete; pdo_row_object_handlers.get_properties_for = row_get_properties_for; pdo_row_object_handlers.get_method = row_method_get; - pdo_row_object_handlers.call_method = row_call_method; pdo_row_object_handlers.get_constructor = row_get_ctor; pdo_row_object_handlers.get_class_name = row_get_classname; pdo_row_object_handlers.compare_objects = row_compare; diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 92d9d9138a..f834c947e6 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2341,9 +2341,7 @@ ZEND_METHOD(reflection_parameter, __construct) position= (int)Z_LVAL_P(parameter); if (position < 0 || (uint32_t)position >= num_args) { if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { - if (fptr->type != ZEND_OVERLOADED_FUNCTION) { - zend_string_release_ex(fptr->common.function_name, 0); - } + zend_string_release_ex(fptr->common.function_name, 0); zend_free_trampoline(fptr); } if (is_closure) { @@ -2380,9 +2378,7 @@ ZEND_METHOD(reflection_parameter, __construct) } if (position == -1) { if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { - if (fptr->type != ZEND_OVERLOADED_FUNCTION) { - zend_string_release_ex(fptr->common.function_name, 0); - } + zend_string_release_ex(fptr->common.function_name, 0); zend_free_trampoline(fptr); } if (is_closure) { diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index dcd9a05f9e..ecefa1c2c0 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -1367,47 +1367,6 @@ static zend_function *spl_dual_it_get_method(zend_object **object, zend_string * return function_handler; } -#if MBO_0 -int spl_dual_it_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) -{ - zval ***func_params, func; - zval retval; - int arg_count; - int current = 0; - int success; - void **p; - spl_dual_it_object *intern; - - intern = Z_SPLDUAL_IT_P(ZEND_THIS); - - ZVAL_STRING(&func, method, 0); - - p = EG(argument_stack).top_element-2; - arg_count = (zend_ulong) *p; - - func_params = safe_emalloc(sizeof(zval **), arg_count, 0); - - current = 0; - while (arg_count-- > 0) { - func_params[current] = (zval **) p - (arg_count-current); - current++; - } - arg_count = current; /* restore */ - - if (call_user_function_ex(EG(function_table), NULL, &func, &retval, arg_count, func_params, 0, NULL) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { - RETURN_ZVAL(&retval, 0, 0); - - success = SUCCESS; - } else { - zend_throw_error(NULL, "Unable to call %s::%s()", intern->inner.ce->name, method); - success = FAILURE; - } - - efree(func_params); - return success; -} -#endif - #define SPL_CHECK_CTOR(intern, classname) \ if (intern->dit_type == DIT_Unknown) { \ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Classes derived from %s must call %s::__construct()", \ @@ -3682,7 +3641,6 @@ PHP_MINIT_FUNCTION(spl_iterators) memcpy(&spl_handlers_dual_it, &std_object_handlers, sizeof(zend_object_handlers)); spl_handlers_dual_it.offset = XtOffsetOf(spl_dual_it_object, std); spl_handlers_dual_it.get_method = spl_dual_it_get_method; - /*spl_handlers_dual_it.call_method = spl_dual_it_call_method;*/ spl_handlers_dual_it.clone_obj = NULL; spl_handlers_dual_it.dtor_obj = spl_dual_it_dtor; spl_handlers_dual_it.free_obj = spl_dual_it_free_storage; diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index 53af862d24..48aea6856a 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -50,7 +50,13 @@ ZEND_END_ARG_INFO() ZEND_FUNCTION(zend_test_func) { - /* dummy */ + RETVAL_STR_COPY(EX(func)->common.function_name); + + /* Cleanup trampoline */ + ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE); + zend_string_release(EX(func)->common.function_name); + zend_free_trampoline(EX(func)); + EX(func) = NULL; } ZEND_FUNCTION(zend_test_array_return) @@ -144,41 +150,45 @@ static zend_object *zend_test_class_new(zend_class_entry *class_type) /* {{{ */ /* }}} */ static zend_function *zend_test_class_method_get(zend_object **object, zend_string *name, const zval *key) /* {{{ */ { - zend_internal_function *fptr = emalloc(sizeof(zend_internal_function)); - fptr->type = ZEND_OVERLOADED_FUNCTION_TEMPORARY; + zend_internal_function *fptr; + + if (EXPECTED(EG(trampoline).common.function_name == NULL)) { + fptr = &EG(trampoline); + } else { + fptr = emalloc(sizeof(zend_internal_function)); + } + memset(fptr, 0, sizeof(zend_internal_function)); + fptr->type = ZEND_INTERNAL_FUNCTION; fptr->num_args = 1; - fptr->arg_info = NULL; fptr->scope = (*object)->ce; fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER; fptr->function_name = zend_string_copy(name); fptr->handler = ZEND_FN(zend_test_func); - zend_set_function_arg_flags((zend_function*)fptr); return (zend_function*)fptr; } /* }}} */ static zend_function *zend_test_class_static_method_get(zend_class_entry *ce, zend_string *name) /* {{{ */ { - zend_internal_function *fptr = emalloc(sizeof(zend_internal_function)); - fptr->type = ZEND_OVERLOADED_FUNCTION; + zend_internal_function *fptr; + + if (EXPECTED(EG(trampoline).common.function_name == NULL)) { + fptr = &EG(trampoline); + } else { + fptr = emalloc(sizeof(zend_internal_function)); + } + memset(fptr, 0, sizeof(zend_internal_function)); + fptr->type = ZEND_INTERNAL_FUNCTION; fptr->num_args = 1; - fptr->arg_info = NULL; fptr->scope = ce; fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_STATIC; - fptr->function_name = name; + fptr->function_name = zend_string_copy(name); fptr->handler = ZEND_FN(zend_test_func); - zend_set_function_arg_flags((zend_function*)fptr); return (zend_function*)fptr; } /* }}} */ -static int zend_test_class_call_method(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { - RETVAL_STR(zend_string_copy(method)); - return 0; -} -/* }}} */ - static ZEND_METHOD(_ZendTestTrait, testMethod) /* {{{ */ { RETURN_TRUE; } @@ -239,7 +249,6 @@ PHP_MINIT_FUNCTION(zend_test) memcpy(&zend_test_class_handlers, &std_object_handlers, sizeof(zend_object_handlers)); zend_test_class_handlers.get_method = zend_test_class_method_get; - zend_test_class_handlers.call_method = zend_test_class_call_method; INIT_CLASS_ENTRY(class_entry, "_ZendTestTrait", zend_test_trait_methods); zend_test_trait = zend_register_internal_class(&class_entry); |