Browse Source

Fix bug #19859 - allow fast_call_user_function to support __call

PEAR_1_4DEV
Stanislav Malyshev 23 years ago
parent
commit
5a7b07701b
  1. 10
      Zend/zend_API.c
  2. 35
      Zend/zend_execute_API.c

10
Zend/zend_API.c

@ -1535,12 +1535,18 @@ zend_bool zend_is_callable(zval *callable, zend_bool syntax_only, char **callabl
if (ce) {
lcname = zend_str_tolower_dup(Z_STRVAL_PP(method), Z_STRLEN_PP(method));
if (zend_hash_exists(&ce->function_table, lcname, Z_STRLEN_PP(method)+1))
if (zend_hash_exists(&ce->function_table, lcname, Z_STRLEN_PP(method)+1)) {
retval = 1;
}
/* check for __call too */
if (retval == 0 && ce->__call != 0) {
retval = 1;
}
efree(lcname);
}
} else if (callable_name)
} else if (callable_name) {
*callable_name = estrndup("Array", sizeof("Array")-1);
}
}
break;

35
Zend/zend_execute_API.c

@ -492,6 +492,9 @@ int fast_call_user_function(HashTable *function_table, zval **object_pp, zval *f
char *function_name_lc;
zval *current_this;
zend_execute_data execute_data;
zval *method_name;
zval *params_array;
int call_via_handler = 0;
/* Initialize execute_data */
EX(fbc) = NULL;
@ -573,8 +576,20 @@ int fast_call_user_function(HashTable *function_table, zval **object_pp, zval *f
original_function_state_ptr = EG(function_state_ptr);
if (zend_hash_find(function_table, function_name_lc, function_name->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
efree(function_name_lc);
return FAILURE;
/* try calling __call */
if(calling_scope && calling_scope->__call) {
EX(function_state).function = calling_scope->__call;
/* prepare params */
ALLOC_INIT_ZVAL(method_name);
ZVAL_STRING(method_name, function_name_lc, 1);
ALLOC_INIT_ZVAL(params_array);
array_init(params_array);
call_via_handler = 1;
} else {
efree(function_name_lc);
return FAILURE;
}
}
efree(function_name_lc);
*function_pointer = EX(function_state).function;
@ -614,7 +629,17 @@ int fast_call_user_function(HashTable *function_table, zval **object_pp, zval *f
*param = **(params[i]);
INIT_PZVAL(param);
}
zend_ptr_stack_push(&EG(argument_stack), param);
if(call_via_handler) {
add_next_index_zval(params_array, param);
} else {
zend_ptr_stack_push(&EG(argument_stack), param);
}
}
if(call_via_handler) {
zend_ptr_stack_push(&EG(argument_stack), method_name);
zend_ptr_stack_push(&EG(argument_stack), params_array);
param_count = 2;
}
zend_ptr_stack_n_push(&EG(argument_stack), 2, (void *) (long) param_count, NULL);
@ -684,6 +709,10 @@ int fast_call_user_function(HashTable *function_table, zval **object_pp, zval *f
INIT_PZVAL(*retval_ptr_ptr);
}
zend_ptr_stack_clear_multiple(TSRMLS_C);
if(call_via_handler) {
zval_ptr_dtor(&method_name);
zval_ptr_dtor(&params_array);
}
EG(function_state_ptr) = original_function_state_ptr;
if (EG(This)) {

Loading…
Cancel
Save