Skip to content

Commit 529bf73

Browse files
committed
Accurate use of proxy_call
1 parent 5d62837 commit 529bf73

File tree

7 files changed

+23
-135
lines changed

7 files changed

+23
-135
lines changed

Zend/zend_API.c

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3070,16 +3070,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
30703070
get_function_via_handler:
30713071
if (fcc->object && fcc->calling_scope == ce_org) {
30723072
if (strict_class && ce_org->__call) {
3073-
fcc->function_handler = emalloc(sizeof(zend_internal_function));
3074-
fcc->function_handler->internal_function.type = ZEND_INTERNAL_FUNCTION;
3075-
fcc->function_handler->internal_function.module = (ce_org->type == ZEND_INTERNAL_CLASS) ? ce_org->info.internal.module : NULL;
3076-
fcc->function_handler->internal_function.handler = zend_std_call_user_call;
3077-
fcc->function_handler->internal_function.arg_info = NULL;
3078-
fcc->function_handler->internal_function.num_args = 0;
3079-
fcc->function_handler->internal_function.scope = ce_org;
3080-
fcc->function_handler->internal_function.fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
3081-
fcc->function_handler->internal_function.function_name = mname;
3082-
zend_string_addref(mname);
3073+
fcc->function_handler = zend_get_proxy_call_func(ce_org, mname, 0);
30833074
call_via_handler = 1;
30843075
retval = 1;
30853076
} else if (fcc->object->handlers->get_method) {
@@ -3092,7 +3083,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
30923083
if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
30933084
zend_string_release(fcc->function_handler->common.function_name);
30943085
}
3095-
efree(fcc->function_handler);
3086+
zend_free_proxy_call_func(fcc->function_handler);
30963087
}
30973088
} else {
30983089
retval = 1;
@@ -3250,14 +3241,13 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zend_object *object, uint
32503241
ret = zend_is_callable_check_func(check_flags, callable, fcc, 0, error);
32513242
if (fcc == &fcc_local &&
32523243
fcc->function_handler &&
3253-
((fcc->function_handler->type == ZEND_INTERNAL_FUNCTION &&
3254-
(fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER)) ||
3244+
((fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) ||
32553245
fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
32563246
fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
32573247
if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
32583248
zend_string_release(fcc->function_handler->common.function_name);
32593249
}
3260-
efree(fcc->function_handler);
3250+
zend_free_proxy_call_func(fcc->function_handler);
32613251
}
32623252
return ret;
32633253

@@ -3338,14 +3328,13 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zend_object *object, uint
33383328
ret = zend_is_callable_check_func(check_flags, method, fcc, strict_class, error);
33393329
if (fcc == &fcc_local &&
33403330
fcc->function_handler &&
3341-
((fcc->function_handler->type == ZEND_INTERNAL_FUNCTION &&
3342-
(fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER)) ||
3331+
((fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) ||
33433332
fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
33443333
fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
33453334
if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
33463335
zend_string_release(fcc->function_handler->common.function_name);
33473336
}
3348-
efree(fcc->function_handler);
3337+
zend_free_proxy_call_func(fcc->function_handler);
33493338
}
33503339
return ret;
33513340

@@ -3414,14 +3403,13 @@ ZEND_API zend_bool zend_make_callable(zval *callable, zend_string **callable_nam
34143403
add_next_index_str(callable, zend_string_copy(fcc.function_handler->common.function_name));
34153404
}
34163405
if (fcc.function_handler &&
3417-
((fcc.function_handler->type == ZEND_INTERNAL_FUNCTION &&
3418-
(fcc.function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER)) ||
3406+
((fcc.function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) ||
34193407
fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
34203408
fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
34213409
if (fcc.function_handler->type != ZEND_OVERLOADED_FUNCTION) {
34223410
zend_string_release(fcc.function_handler->common.function_name);
34233411
}
3424-
efree(fcc.function_handler);
3412+
zend_free_proxy_call_func(fcc.function_handler);
34253413
}
34263414
return 1;
34273415
}

Zend/zend_builtin_functions.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2506,8 +2506,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
25062506
if (prev_call &&
25072507
prev_call->func &&
25082508
!ZEND_USER_CODE(prev_call->func->common.type) &&
2509-
!(prev_call->func->common.type == ZEND_INTERNAL_FUNCTION &&
2510-
(prev_call->func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER))) {
2509+
!(prev_call->func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER)) {
25112510
break;
25122511
}
25132512
if (prev->func && ZEND_USER_CODE(prev->func->common.type)) {

Zend/zend_object_handlers.c

Lines changed: 7 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -915,47 +915,6 @@ static void zend_std_unset_dimension(zval *object, zval *offset) /* {{{ */
915915
}
916916
/* }}} */
917917

918-
ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
919-
{
920-
zend_internal_function *func = (zend_internal_function *)EX(func);
921-
zval method_name, method_args;
922-
zval method_result;
923-
zend_class_entry *ce = Z_OBJCE_P(getThis());
924-
925-
array_init_size(&method_args, ZEND_NUM_ARGS());
926-
927-
if (UNEXPECTED(zend_copy_parameters_array(ZEND_NUM_ARGS(), &method_args) == FAILURE)) {
928-
zval_dtor(&method_args);
929-
zend_error(E_EXCEPTION | E_ERROR, "Cannot get arguments for __call");
930-
RETURN_FALSE;
931-
}
932-
933-
ZVAL_STR(&method_name, func->function_name); /* no dup - it's a copy */
934-
935-
/* __call handler is called with two arguments:
936-
method name
937-
array of method parameters
938-
939-
*/
940-
zend_call_method_with_2_params(getThis(), ce, &ce->__call, ZEND_CALL_FUNC_NAME, &method_result, &method_name, &method_args);
941-
942-
if (Z_TYPE(method_result) != IS_UNDEF) {
943-
RETVAL_ZVAL_FAST(&method_result);
944-
zval_ptr_dtor(&method_result);
945-
}
946-
947-
/* now destruct all auxiliaries */
948-
zval_ptr_dtor(&method_args);
949-
zval_ptr_dtor(&method_name);
950-
951-
/* destruct the function also, then - we have allocated it in get_method */
952-
efree_size(func, sizeof(zend_internal_function));
953-
#if ZEND_DEBUG
954-
execute_data->func = NULL;
955-
#endif
956-
}
957-
/* }}} */
958-
959918
/* Ensures that we're allowed to call a private method.
960919
* Returns the function address that should be called, or NULL
961920
* if no such function exists.
@@ -1034,12 +993,6 @@ ZEND_API int zend_check_protected(zend_class_entry *ce, zend_class_entry *scope)
1034993
}
1035994
/* }}} */
1036995

1037-
static inline union _zend_function *zend_get_user_call_function(zend_class_entry *ce, zend_string *method_name) /* {{{ */
1038-
{
1039-
return (union _zend_function *)zend_get_proxy_call_func(ce, method_name, 0);
1040-
}
1041-
/* }}} */
1042-
1043996
static union _zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *method_name, const zval *key) /* {{{ */
1044997
{
1045998
zend_object *zobj = *obj_ptr;
@@ -1063,7 +1016,7 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr, zend_str
10631016
STR_ALLOCA_FREE(lc_method_name, use_heap);
10641017
}
10651018
if (zobj->ce->__call) {
1066-
return zend_get_user_call_function(zobj->ce, method_name);
1019+
return zend_get_proxy_call_func(zobj->ce, method_name, 0);
10671020
} else {
10681021
return NULL;
10691022
}
@@ -1082,7 +1035,7 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr, zend_str
10821035
fbc = updated_fbc;
10831036
} else {
10841037
if (zobj->ce->__call) {
1085-
fbc = zend_get_user_call_function(zobj->ce, method_name);
1038+
fbc = zend_get_proxy_call_func(zobj->ce, method_name, 0);
10861039
} else {
10871040
zend_error(E_EXCEPTION | E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name->val, EG(scope) ? EG(scope)->name->val : "");
10881041
fbc = NULL;
@@ -1109,7 +1062,7 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr, zend_str
11091062
*/
11101063
if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), EG(scope)))) {
11111064
if (zobj->ce->__call) {
1112-
fbc = zend_get_user_call_function(zobj->ce, method_name);
1065+
fbc = zend_get_proxy_call_func(zobj->ce, method_name, 0);
11131066
} else {
11141067
zend_error(E_EXCEPTION | E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name->val, EG(scope) ? EG(scope)->name->val : "");
11151068
fbc = NULL;
@@ -1125,54 +1078,6 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr, zend_str
11251078
}
11261079
/* }}} */
11271080

1128-
ZEND_API void zend_std_callstatic_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
1129-
{
1130-
zend_internal_function *func = (zend_internal_function *)EX(func);
1131-
zval method_name, method_args;
1132-
zval method_result;
1133-
zend_class_entry *ce = EG(scope);
1134-
1135-
array_init_size(&method_args, ZEND_NUM_ARGS());
1136-
1137-
if (UNEXPECTED(zend_copy_parameters_array(ZEND_NUM_ARGS(), &method_args) == FAILURE)) {
1138-
zval_dtor(&method_args);
1139-
zend_error(E_EXCEPTION | E_ERROR, "Cannot get arguments for " ZEND_CALLSTATIC_FUNC_NAME);
1140-
RETURN_FALSE;
1141-
}
1142-
1143-
ZVAL_STR(&method_name, func->function_name); /* no dup - it's a copy */
1144-
1145-
/* __callStatic handler is called with two arguments:
1146-
method name
1147-
array of method parameters
1148-
*/
1149-
zend_call_method_with_2_params(NULL, ce, &ce->__callstatic, ZEND_CALLSTATIC_FUNC_NAME, &method_result, &method_name, &method_args);
1150-
1151-
if (Z_TYPE(method_result) != IS_UNDEF) {
1152-
RETVAL_ZVAL_FAST(&method_result);
1153-
zval_ptr_dtor(&method_result);
1154-
}
1155-
1156-
/* now destruct all auxiliaries */
1157-
zval_ptr_dtor(&method_args);
1158-
zval_ptr_dtor(&method_name);
1159-
1160-
/* destruct the function also, then - we have allocated it in get_method */
1161-
efree_size(func, sizeof(zend_internal_function));
1162-
#if ZEND_DEBUG
1163-
execute_data->func = NULL;
1164-
#endif
1165-
}
1166-
/* }}} */
1167-
1168-
static inline union _zend_function *zend_get_user_callstatic_function(zend_class_entry *ce, zend_string *method_name) /* {{{ */
1169-
{
1170-
return (union _zend_function *)zend_get_proxy_call_func(ce, method_name, 1);
1171-
}
1172-
/* }}} */
1173-
1174-
/* This is not (yet?) in the API, but it belongs in the built-in objects callbacks */
1175-
11761081
ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_string *function_name, const zval *key) /* {{{ */
11771082
{
11781083
zend_function *fbc = NULL;
@@ -1207,9 +1112,9 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
12071112
if (ce->__call &&
12081113
Z_OBJ(EG(current_execute_data)->This) &&
12091114
instanceof_function(Z_OBJCE(EG(current_execute_data)->This), ce)) {
1210-
return zend_get_user_call_function(ce, function_name);
1115+
return zend_get_proxy_call_func(ce, function_name, 0);
12111116
} else if (ce->__callstatic) {
1212-
return zend_get_user_callstatic_function(ce, function_name);
1117+
return zend_get_proxy_call_func(ce, function_name, 1);
12131118
} else {
12141119
return NULL;
12151120
}
@@ -1235,7 +1140,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
12351140
fbc = updated_fbc;
12361141
} else {
12371142
if (ce->__callstatic) {
1238-
fbc = zend_get_user_callstatic_function(ce, function_name);
1143+
fbc = zend_get_proxy_call_func(ce, function_name, 1);
12391144
} else {
12401145
zend_error(E_EXCEPTION | E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name->val, EG(scope) ? EG(scope)->name->val : "");
12411146
fbc = NULL;
@@ -1246,7 +1151,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
12461151
*/
12471152
if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), EG(scope)))) {
12481153
if (ce->__callstatic) {
1249-
fbc = zend_get_user_callstatic_function(ce, function_name);
1154+
fbc = zend_get_proxy_call_func(ce, function_name, 1);
12501155
} else {
12511156
zend_error(E_EXCEPTION | E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name->val, EG(scope) ? EG(scope)->name->val : "");
12521157
fbc = NULL;

Zend/zend_object_handlers.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@ ZEND_API int zend_check_protected(zend_class_entry *ce, zend_class_entry *scope)
179179

180180
ZEND_API int zend_check_property_access(zend_object *zobj, zend_string *prop_info_name);
181181

182-
ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS);
183182
END_EXTERN_C()
184183

185184
#endif

Zend/zend_objects_API.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ ZEND_API void zend_init_proxy_call_func(zend_op_array *func, zend_op *opline)
242242
func->opcodes = opline;
243243
}
244244

245-
ZEND_API zend_op_array *zend_get_proxy_call_func(zend_class_entry *ce, zend_string *method_name, int is_static)
245+
ZEND_API zend_function *zend_get_proxy_call_func(zend_class_entry *ce, zend_string *method_name, int is_static)
246246
{
247247
zend_op_array *func;
248248
zend_function *fbc = is_static? ce->__callstatic : ce->__call;
@@ -273,7 +273,7 @@ ZEND_API zend_op_array *zend_get_proxy_call_func(zend_class_entry *ce, zend_stri
273273
func->function_name = zend_string_copy(method_name);
274274
}
275275

276-
return func;
276+
return (zend_function*)func;
277277
}
278278

279279
/*

Zend/zend_objects_API.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ ZEND_API zend_object_handlers *zend_get_std_object_handlers(void);
7373

7474
ZEND_API void zend_init_proxy_call_func(zend_op_array *func, zend_op *opline);
7575

76-
ZEND_API zend_op_array *zend_get_proxy_call_func(zend_class_entry *ce, zend_string *method_name, int is_static);
76+
ZEND_API zend_function *zend_get_proxy_call_func(zend_class_entry *ce, zend_string *method_name, int is_static);
7777

7878
END_EXTERN_C()
7979

ext/reflection/php_reflection.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,6 @@ static void _default_lookup_entry(zval *object, char *name, int name_len, zval *
265265
static zend_function *_copy_function(zend_function *fptr) /* {{{ */
266266
{
267267
if (fptr
268-
&& fptr->type == ZEND_INTERNAL_FUNCTION
269268
&& (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
270269
{
271270
zend_function *copy_fptr;
@@ -283,11 +282,10 @@ static zend_function *_copy_function(zend_function *fptr) /* {{{ */
283282
static void _free_function(zend_function *fptr) /* {{{ */
284283
{
285284
if (fptr
286-
&& fptr->type == ZEND_INTERNAL_FUNCTION
287285
&& (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
288286
{
289287
zend_string_release(fptr->internal_function.function_name);
290-
efree(fptr);
288+
zend_free_proxy_call_func(fptr);
291289
}
292290
}
293291
/* }}} */
@@ -2280,7 +2278,7 @@ ZEND_METHOD(reflection_parameter, __construct)
22802278
if (fptr->type != ZEND_OVERLOADED_FUNCTION) {
22812279
zend_string_release(fptr->common.function_name);
22822280
}
2283-
efree(fptr);
2281+
zend_free_proxy_call_func(fptr);
22842282
}
22852283
if (is_closure) {
22862284
zval_ptr_dtor(reference);
@@ -2841,7 +2839,7 @@ ZEND_METHOD(reflection_method, getClosure)
28412839
}
28422840

28432841
/* This is an original closure object and __invoke is to be called. */
2844-
if (Z_OBJCE_P(obj) == zend_ce_closure && mptr->type == ZEND_INTERNAL_FUNCTION &&
2842+
if (Z_OBJCE_P(obj) == zend_ce_closure &&
28452843
(mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
28462844
{
28472845
RETURN_ZVAL(obj, 1, 0);
@@ -3043,8 +3041,7 @@ ZEND_METHOD(reflection_method, invokeArgs)
30433041
/*
30443042
* Copy the zend_function when calling via handler (e.g. Closure::__invoke())
30453043
*/
3046-
if (mptr->type == ZEND_INTERNAL_FUNCTION &&
3047-
(mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0) {
3044+
if ((mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0) {
30483045
fcc.function_handler = _copy_function(mptr);
30493046
}
30503047

0 commit comments

Comments
 (0)