/* }}} */
/* {{{ spl_call_method */
-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)
+zval * 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 result;
zend_fcall_info fci;
fci.params = params;
fci.no_separation = 1;
fci.symbol_table = NULL;
-
+
if (!fn_proxy && !obj_ce) {
+ /* no interest in caching and no information already present that is
+ * needed later inside zend_call_function. */
ZVAL_STRINGL(&z_fname, function_name, function_name_len, 0);
result = zend_call_function(&fci, NULL TSRMLS_CC);
} else {
}
if (!fn_proxy || !*fn_proxy) {
if (zend_hash_find(&obj_ce->function_table, function_name, function_name_len+1, (void **) &fcic.function_handler) == FAILURE) {
+ /* error at c-level */
zend_error(E_CORE_ERROR, "Couldn't find implementation for method %s::%s\n", obj_ce->name, function_name);
}
if (fn_proxy) {
fcic.object_pp = object_pp;
result = zend_call_function(&fci, &fcic TSRMLS_CC);
}
+ if (result == FAILURE) {
+ /* error at c-level */
+ if (!obj_ce) {
+ obj_ce = Z_OBJCE_PP(object_pp);
+ }
+ zend_error(E_CORE_ERROR, "Couldn't execute method %s::%s\n", obj_ce->name, function_name);
+ }
if (!retval_ptr && retval) {
zval_dtor(retval);
FREE_ZVAL(retval);
+ return NULL;
}
- return result;
+ return *retval_ptr;
}
/* }}} */
EX(opline)++; \
return 0;
-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);
+zval * 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)
spl_foreach_proxy *proxy;
if (Z_TYPE_PP(obj) == IS_STRING) {
+ int has_more;
proxy = (spl_foreach_proxy*)Z_STRVAL_PP(obj);
obj = &proxy->obj; /* will be optimized out */
}
spl_call_method_0(obj, proxy->obj_ce, &proxy->funcs.more, "has_more", sizeof("has_more")-1, &more);
- if (!more->type == IS_BOOL && !more->type == IS_LONG) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Method %s::has_more implements spl_forward::has_more and should return a value of type boolean or int");
- convert_to_boolean(more);
- }
- if (more->value.lval) {
- zval_dtor(more);
- FREE_ZVAL(more);
+ has_more = i_zend_is_true(more);
+ zval_dtor(more);
+ FREE_ZVAL(more);
+ if (has_more) {
result = &EX_T(EX(opline)->result.u.var).tmp_var;
spl_call_method_0(obj, proxy->obj_ce, &proxy->funcs.current, "current", sizeof("current")-1, &value);
#endif
NEXT_OPCODE();
}
- zval_dtor(more);
- FREE_ZVAL(more);
EX(opline) = op_array->opcodes+EX(opline)->op2.u.opline_num;
return 0;
}