zval *dim = spl_get_zval_ptr(op2, Ts, &EG(free_op2) TSRMLS_CC);
zval *exists;
- spl_begin_method_call_arg_ex1(obj, obj_ce, NULL, "exists", sizeof("exists")-1, &exists, dim TSRMLS_CC);
+ spl_begin_method_call_arg_ex1(obj, obj_ce, NULL, "exists", sizeof("exists")-1, &exists, dim);
if (!i_zend_is_true(exists)) {
if (type == BP_VAR_R || type == BP_VAR_RW) {
SEPARATE_ZVAL(&dim);
}
DELETE_RET_ZVAL(exists);
if (type == BP_VAR_R || type == BP_VAR_IS) {
- spl_begin_method_call_arg_ex1(obj, obj_ce, NULL, "get", sizeof("get")-1, retval, dim TSRMLS_CC);
+ spl_begin_method_call_arg_ex1(obj, obj_ce, NULL, "get", sizeof("get")-1, retval, dim);
}
FREE_OP(Ts, op2, EG(free_op2));
return 0;
value->refcount = 0;
}
- spl_begin_method_call_arg_ex2(obj, obj_ce, NULL, "set", sizeof("set")-1, &retval, index, value TSRMLS_CC);
+ spl_begin_method_call_arg_ex2(obj, obj_ce, NULL, "set", sizeof("set")-1, &retval, index, value);
if (index == &tmp) {
zval_dtor(index);
break;
}
- spl_begin_method_call_arg_ex1(obj, obj_ce, NULL, "del", sizeof("del")-1, &retval, index TSRMLS_CC);
+ spl_begin_method_call_arg_ex1(obj, obj_ce, NULL, "del", sizeof("del")-1, &retval, index);
if (index == &tmp) {
zval_dtor(index);
/* }}} */
/* {{{ spl_instanciate_arg_ex2 */
-int spl_instanciate_arg_ex2(zend_class_entry *pce, zval **retval, zval *arg1, zval *arg2, HashTable *symbol_table TSRMLS_DC)
+int spl_instanciate_arg_ex2(zend_class_entry *pce, zval **retval, zval *arg1, zval *arg2 TSRMLS_DC)
{
zval *object;
retval = &EG(uninitialized_zval_ptr);
- spl_call_method(&object, pce, &pce->constructor, pce->constructor->common.function_name, strlen(pce->constructor->common.function_name), retval, NULL TSRMLS_CC, 2, arg1, arg2);
+ spl_call_method(&object, pce, &pce->constructor, pce->constructor->common.function_name, strlen(pce->constructor->common.function_name), retval, 2, arg1, arg2 TSRMLS_CC);
*retval = object;
return 0;
}
}
/* }}} */
-#undef EX
-#define EX(element) execute_data.element
-
/* {{{ spl_call_method */
-int spl_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len, zval **retval, HashTable *symbol_table TSRMLS_DC, int param_count, ...)
+int spl_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC)
{
- int i;
- zval *arg;
- zval *param;
- zval **original_return_value;
- HashTable *calling_symbol_table;
- zend_function_state *original_function_state_ptr;
- zend_op_array *original_op_array;
- zend_op **original_opline_ptr;
- zval *orig_free_op1, *orig_free_op2;
- int (*orig_unary_op)(zval *result, zval *op1);
- int (*orig_binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC);
- zend_class_entry *current_scope;
- zval *current_this;
- zend_execute_data execute_data;
- va_list args;
-
- if (!object_pp || (!obj_ce && (obj_ce = spl_get_class_entry(*object_pp TSRMLS_CC)) == NULL)) {
- return FAILURE;
- }
-
- /* Initialize execute_data */
- EX(fbc) = NULL;
- EX(Ts) = NULL;
- EX(op_array) = NULL;
- EX(opline) = NULL;
-
- EX(object) = *object_pp;
-
- original_function_state_ptr = EG(function_state_ptr);
- if (fn_proxy && *fn_proxy) {
- EX(function_state).function = *fn_proxy;
- } else {
- if (zend_hash_find(&obj_ce->function_table, function_name, fname_len+1, (void **) &EX(function_state).function)==FAILURE) {
- return FAILURE;
- }
- if (fn_proxy) {
- *fn_proxy = EX(function_state).function;
- }
- }
-
- va_start(args, param_count);
- if (param_count) {
- for (i=1; i<=param_count; i++) {
- arg = va_arg(args, zval*);
+ int result;
+ zend_fcall_info fci;
+ zval z_fname;
+
+ zval **params[2];
+
+ params[0] = &arg1;
+ params[1] = &arg2;
+
+ fci.size = sizeof(fci);
+ /*fci.function_table = NULL; will be read form zend_class_entry of object if needed */
+ fci.object_pp = object_pp;
+ fci.function_name = &z_fname;
+ fci.retval_ptr_ptr = retval_ptr;
+ fci.param_count = param_count;
+ fci.params = params;
+ fci.no_separation = 1;
+ fci.symbol_table = NULL;
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i)
- && !PZVAL_IS_REF(arg)) {
- if (arg->refcount > 1) {
- zval *new_zval;
-
- ALLOC_ZVAL(new_zval);
- *new_zval = *arg;
- zval_copy_ctor(new_zval);
- new_zval->refcount = 2;
- new_zval->is_ref = 1;
- arg->refcount--;
- param = new_zval;
- } else {
- arg->refcount++;
- arg->is_ref = 1;
- param = arg;
- }
- } else if (arg != &EG(uninitialized_zval)) {
- arg->refcount++;
- param = arg;
- } else {
- ALLOC_ZVAL(param);
- *param = *arg;
- INIT_PZVAL(param);
- }
- zend_ptr_stack_push(&EG(argument_stack), param);
- }
- }
- va_end(args);
-
- zend_ptr_stack_push(&EG(argument_stack), (void *) (long) param_count);
- zend_ptr_stack_push(&EG(argument_stack), NULL);
-
- EG(function_state_ptr) = &EX(function_state);
-
- current_scope = EG(scope);
- EG(scope) = obj_ce;
-
- current_this = EG(This);
- EG(This) = *object_pp;
-
- if (!PZVAL_IS_REF(EG(This))) {
- EG(This)->refcount++; /* For $this pointer */
+ if (!fn_proxy && !obj_ce) {
+ ZVAL_STRINGL(&z_fname, function_name, function_name_len, 0);
+ result = zend_call_function(&fci, NULL TSRMLS_CC);
} else {
- zval *this_ptr;
-
- ALLOC_ZVAL(this_ptr);
- *this_ptr = *EG(This);
- INIT_PZVAL(this_ptr);
- zval_copy_ctor(this_ptr);
- EG(This) = this_ptr;
- }
-
- EX(prev_execute_data) = EG(current_execute_data);
- EG(current_execute_data) = &execute_data;
-
- if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
- calling_symbol_table = EG(active_symbol_table);
- if (symbol_table) {
- EG(active_symbol_table) = symbol_table;
+ zend_fcall_info_cache fcic;
+
+ if (fn_proxy && !*fn_proxy) {
+ fcic.initialized = 0;
+ ZVAL_STRINGL(&z_fname, function_name, function_name_len, 0);
+ result = zend_call_function(&fci, &fcic TSRMLS_CC);
+ *fn_proxy = fcic.function_handler;
} else {
- ALLOC_HASHTABLE(EG(active_symbol_table));
- zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
- }
-
- original_return_value = EG(return_value_ptr_ptr);
- original_op_array = EG(active_op_array);
- EG(return_value_ptr_ptr) = retval;
- EG(active_op_array) = (zend_op_array *) EX(function_state).function;
- original_opline_ptr = EG(opline_ptr);
- orig_free_op1 = EG(free_op1);
- orig_free_op2 = EG(free_op2);
- orig_unary_op = EG(unary_op);
- orig_binary_op = EG(binary_op);
- zend_execute(EG(active_op_array) TSRMLS_CC);
- if (!symbol_table) {
- zend_hash_destroy(EG(active_symbol_table));
- FREE_HASHTABLE(EG(active_symbol_table));
+ fcic.initialized = 1;
+ if (!fn_proxy) {
+ /* this doesn't handle 'function not found' error! */
+ zend_hash_find(&obj_ce->function_table, function_name, function_name_len+1, (void **) &fcic.function_handler);
+ } else {
+ fcic.function_handler = *fn_proxy;
+ }
+ fcic.calling_scope = obj_ce;
+ fcic.object_pp = object_pp;
+ result = zend_call_function(&fci, &fcic TSRMLS_CC);
}
- EG(active_symbol_table) = calling_symbol_table;
- EG(active_op_array) = original_op_array;
- EG(return_value_ptr_ptr)=original_return_value;
- EG(opline_ptr) = original_opline_ptr;
- EG(free_op1) = orig_free_op1;
- EG(free_op2) = orig_free_op2;
- EG(unary_op) = orig_unary_op;
- EG(binary_op) = orig_binary_op;
- } else {
- ALLOC_INIT_ZVAL(*retval);
- ((zend_internal_function *) EX(function_state).function)->handler(param_count, *retval, *object_pp, 1 TSRMLS_CC);
- INIT_PZVAL(*retval);
- }
- zend_ptr_stack_clear_multiple(TSRMLS_C);
- EG(function_state_ptr) = original_function_state_ptr;
-
- if (EG(This)) {
- zval_ptr_dtor(&EG(This));
}
- EG(scope) = current_scope;
- EG(This) = current_this;
- EG(current_execute_data) = EX(prev_execute_data); \
-
- return SUCCESS;
+ return result;
}
/* }}} */
int zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS);
-int spl_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr, HashTable *symbol_table TSRMLS_DC, int param_count, ...);
+int spl_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC);
/* {{{ zend_class_entry */
static inline zend_class_entry *spl_get_class_entry(zval *obj TSRMLS_DC)
static inline int spl_begin_method_call_arg(zval **obj, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len, zval *retval, zval *arg1 TSRMLS_DC)
{
zval *local_retval;
- int ret = spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, &local_retval, NULL TSRMLS_CC, 1, arg1);
+ int ret = spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, &local_retval, 1, arg1, NULL TSRMLS_CC);
if (local_retval) {
COPY_PZVAL_TO_ZVAL(*retval, local_retval);
} else {
static inline int spl_begin_method_call_no_retval(zval **obj, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len TSRMLS_DC)
{
zval *retval;
- int ret = spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, &retval, NULL TSRMLS_CC, 0);
+ int ret = spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, &retval, 0, NULL, NULL TSRMLS_CC);
if (retval) {
zval_dtor(retval);
FREE_ZVAL(retval);
/* }}} */
#define spl_begin_method_call_ex(obj, obj_ce, fn_proxy, function_name, fname_len, retval) \
- spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 0)
+ spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, retval, 0, NULL, NULL TSRMLS_CC)
#define spl_begin_method_call_arg_ex1(obj, obj_ce, fn_proxy, function_name, fname_len, retval, arg1) \
- spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 1, arg1)
+ spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, retval, 1, arg1, NULL TSRMLS_CC)
#define spl_begin_method_call_arg_ex2(obj, obj_ce, fn_proxy, function_name, fname_len, retval, arg1, arg2) \
- spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 2, arg1, arg2)
+ spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, retval, 2, arg1, arg2 TSRMLS_CC)
void spl_instanciate(zend_class_entry *pce, zval **object TSRMLS_DC);
-int spl_instanciate_arg_ex2(zend_class_entry *pce, zval **retval, zval *arg1, zval *arg2, HashTable *symbol_table TSRMLS_DC);
+int spl_instanciate_arg_ex2(zend_class_entry *pce, zval **retval, zval *arg1, zval *arg2 TSRMLS_DC);
zval ** spl_get_zval_ptr_ptr(znode *node, temp_variable *Ts TSRMLS_DC);
void spl_unlock_zval_ptr_ptr(znode *node, temp_variable *Ts TSRMLS_DC);