#define ZEND_CLOSURE_PROPERTY_ERROR() \
zend_throw_error(NULL, "Closure object cannot have properties")
-/* reuse bit to mark "fake" closures (it wasn't used for functions before) */
-#define ZEND_ACC_FAKE_CLOSURE ZEND_ACC_INTERFACE
-
typedef struct _zend_closure {
zend_object std;
zend_function func;
#define ZEND_ACC_CLOSURE 0x100000
+#define ZEND_ACC_FAKE_CLOSURE 0x40
#define ZEND_ACC_GENERATOR 0x800000
#define ZEND_ACC_NO_RT_ARENA 0x80000
#define ZEND_CALL_ALLOCATED (1 << 7)
#define ZEND_CALL_GENERATOR (1 << 8)
#define ZEND_CALL_DYNAMIC (1 << 9)
+#define ZEND_CALL_FAKE_CLOSURE (1 << 10)
#define ZEND_CALL_INFO_SHIFT 16
ZEND_ASSERT(GC_TYPE((zend_object*)fbc->common.prototype) == IS_OBJECT);
GC_REFCOUNT((zend_object*)fbc->common.prototype)++;
call_info |= ZEND_CALL_CLOSURE;
+ if (fbc->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
+ call_info |= ZEND_CALL_FAKE_CLOSURE;
+ }
} else if (object) {
call_info |= ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(object)++; /* For $this pointer */
}
if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
+ uint32_t call_info;
+
ZEND_ASSERT(GC_TYPE((zend_object*)func->op_array.prototype) == IS_OBJECT);
GC_REFCOUNT((zend_object*)func->op_array.prototype)++;
- ZEND_ADD_CALL_FLAG(call, ZEND_CALL_CLOSURE);
+ call_info = ZEND_CALL_CLOSURE;
+ if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
+ call_info |= ZEND_CALL_FAKE_CLOSURE;
+ }
+ ZEND_ADD_CALL_FLAG(call, call_info);
}
if (func->type == ZEND_USER_FUNCTION) {
ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT);
GC_REFCOUNT((zend_object*)func->common.prototype)++;
call_info |= ZEND_CALL_CLOSURE;
+ if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
+ call_info |= ZEND_CALL_FAKE_CLOSURE;
+ }
} else if (object) {
call_info |= ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(object)++; /* For $this pointer */
ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT);
GC_REFCOUNT((zend_object*)func->common.prototype)++;
call_info |= ZEND_CALL_CLOSURE;
+ if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
+ call_info |= ZEND_CALL_FAKE_CLOSURE;
+ }
} else if (object) {
call_info |= ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(object)++; /* For $this pointer */
ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT);
GC_REFCOUNT((zend_object*)func->common.prototype)++;
call_info |= ZEND_CALL_CLOSURE;
+ if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
+ call_info |= ZEND_CALL_FAKE_CLOSURE;
+ }
} else if (object) {
call_info |= ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(object)++; /* For $this pointer */
ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT);
GC_REFCOUNT((zend_object*)func->common.prototype)++;
call_info |= ZEND_CALL_CLOSURE;
+ if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
+ call_info |= ZEND_CALL_FAKE_CLOSURE;
+ }
} else if (object) {
call_info |= ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(object)++; /* For $this pointer */