zend_object *zobj = Z_OBJ_P(callable);
if (zobj->handlers->get_closure
- && zobj->handlers->get_closure(zobj, &calling_scope, &fptr, &object) == SUCCESS) {
+ && zobj->handlers->get_closure(zobj, &calling_scope, &fptr, &object, 1) == SUCCESS) {
zend_class_entry *ce = zobj->ce;
zend_string *callable_name = zend_string_alloc(
ZSTR_LEN(ce->name) + sizeof("::__invoke") - 1, 0);
}
return 0;
case IS_OBJECT:
- if (Z_OBJ_HANDLER_P(callable, get_closure)) {
- if (Z_OBJ_HANDLER_P(callable, get_closure)(Z_OBJ_P(callable), &fcc->calling_scope, &fcc->function_handler, &fcc->object) == SUCCESS) {
+ if (Z_OBJ_HANDLER_P(callable, get_closure) && Z_OBJ_HANDLER_P(callable, get_closure)(Z_OBJ_P(callable), &fcc->calling_scope, &fcc->function_handler, &fcc->object, 1) == SUCCESS) {
fcc->called_scope = fcc->calling_scope;
if (fcc == &fcc_local) {
zend_release_fcall_info_cache(fcc);
}
return 1;
- } else {
- /* Discard exceptions thrown from Z_OBJ_HANDLER_P(callable, get_closure)
- TODO: extend get_closure() with additional argument and prevent exception throwing in the first place */
- zend_clear_exception();
- }
}
if (error) *error = estrdup("no array or string given");
return 0;
}
/* }}} */
-int zend_closure_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr) /* {{{ */
+int zend_closure_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr, zend_bool check_only) /* {{{ */
{
zend_closure *closure = (zend_closure *)obj;
*fptr_ptr = &closure->func;
uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC;
if (EXPECTED(function->handlers->get_closure) &&
- EXPECTED(function->handlers->get_closure(function, &called_scope, &fbc, &object) == SUCCESS)) {
+ EXPECTED(function->handlers->get_closure(function, &called_scope, &fbc, &object, 0) == SUCCESS)) {
object_or_called_scope = called_scope;
if (fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
}
/* }}} */
-ZEND_API int zend_std_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr) /* {{{ */
+ZEND_API int zend_std_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr, zend_bool check_only) /* {{{ */
{
zval *func;
zend_class_entry *ce = obj->ce;
* Returns FAILURE if the object does not have any sense of overloaded dimensions */
typedef int (*zend_object_count_elements_t)(zend_object *object, zend_long *count);
-typedef int (*zend_object_get_closure_t)(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr);
+typedef int (*zend_object_get_closure_t)(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr, zend_bool check_only);
typedef HashTable *(*zend_object_get_gc_t)(zend_object *object, zval **table, int *n);
ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *method_name, const zval *key);
ZEND_API zend_string *zend_std_get_class_name(const zend_object *zobj);
ZEND_API int zend_std_compare_objects(zval *o1, zval *o2);
-ZEND_API int zend_std_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr);
+ZEND_API int zend_std_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr, zend_bool check_only);
ZEND_API void rebuild_object_properties(zend_object *zobj);
ZEND_API int zend_check_protected(zend_class_entry *ce, zend_class_entry *scope);
}
/* }}} */
-static int zend_ffi_cdata_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr) /* {{{ */
+static int zend_ffi_cdata_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr, zend_bool check_only) /* {{{ */
{
zend_ffi_cdata *cdata = (zend_ffi_cdata*)obj;
zend_ffi_type *type = ZEND_FFI_TYPE(cdata->type);
zend_function *func;
if (type->kind != ZEND_FFI_TYPE_POINTER) {
- zend_throw_error(zend_ffi_exception_ce, "Attempt to call non C function pointer");
+ if (!check_only) {
+ zend_throw_error(zend_ffi_exception_ce, "Attempt to call non C function pointer");
+ }
return FAILURE;
}
type = ZEND_FFI_TYPE(type->pointer.type);
if (type->kind != ZEND_FFI_TYPE_FUNC) {
- zend_throw_error(zend_ffi_exception_ce, "Attempt to call non C function pointer");
+ if (!check_only) {
+ zend_throw_error(zend_ffi_exception_ce, "Attempt to call non C function pointer");
+ }
return FAILURE;
}
if (!cdata->ptr) {
- zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
+ if (!check_only) {
+ zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
+ }
return FAILURE;
}
if (!Z_ISUNDEF(intern->obj)) {
Z_OBJ_HT(intern->obj)->get_closure(
- Z_OBJ(intern->obj), &fcc.called_scope, &fcc.function_handler, &fcc.object);
+ Z_OBJ(intern->obj), &fcc.called_scope, &fcc.function_handler, &fcc.object, 0);
}
result = zend_call_function(&fci, &fcc);
if (!Z_ISUNDEF(intern->obj)) {
Z_OBJ_HT(intern->obj)->get_closure(
- Z_OBJ(intern->obj), &fcc.called_scope, &fcc.function_handler, &fcc.object);
+ Z_OBJ(intern->obj), &fcc.called_scope, &fcc.function_handler, &fcc.object, 0);
}
result = zend_call_function(&fci, &fcc);