Implement explicit value and reference captures for closures
Build / AerScript (push) Successful in 40s
Build / AerScript (push) Successful in 40s
This commit is contained in:
+20
-9
@@ -1108,15 +1108,31 @@ PH7_PRIVATE ph7_class_instance *PH7_CloneClassInstance(ph7_class_instance *pSrc)
|
||||
return pClone;
|
||||
}
|
||||
#define CLASS_INSTANCE_DESTROYED 0x001 /* Instance is released */
|
||||
#define CLASS_INSTANCE_FINALIZED 0x002 /* Destructor has already been invoked */
|
||||
/* Run user finalization separately from storage release so VM teardown can
|
||||
* keep every closure environment valid until destructors have finished. */
|
||||
PH7_PRIVATE sxi32 PH7_ClassInstanceFinalize(ph7_class_instance *pThis) {
|
||||
ph7_class_method *pDestr;
|
||||
if(pThis == 0 || (pThis->iFlags & CLASS_INSTANCE_FINALIZED)) {
|
||||
return 0;
|
||||
}
|
||||
pThis->iFlags |= CLASS_INSTANCE_FINALIZED;
|
||||
pDestr = PH7_ClassExtractMethod(pThis->pClass, "__destruct", sizeof("__destruct") - 1);
|
||||
if(pDestr) {
|
||||
/* A destructor may remove its own last ordinary reference. */
|
||||
pThis->iRef++;
|
||||
PH7_VmCallClassMethod(pThis->pVm, pThis, pDestr, 0, 0, 0);
|
||||
PH7_ClassInstanceUnref(pThis);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* Release a class instance [i.e: Object in the PHP jargon] and invoke any defined destructor.
|
||||
* This routine is invoked as soon as there are no other references to a particular
|
||||
* class instance.
|
||||
*/
|
||||
static void PH7_ClassInstanceRelease(ph7_class_instance *pThis) {
|
||||
ph7_class_method *pDestr;
|
||||
SyHashEntry *pEntry;
|
||||
ph7_class *pClass;
|
||||
ph7_vm *pVm;
|
||||
if(pThis->iFlags & CLASS_INSTANCE_DESTROYED) {
|
||||
/*
|
||||
@@ -1129,13 +1145,8 @@ static void PH7_ClassInstanceRelease(ph7_class_instance *pThis) {
|
||||
pThis->iFlags |= CLASS_INSTANCE_DESTROYED;
|
||||
/* Invoke any defined destructor if available */
|
||||
pVm = pThis->pVm;
|
||||
pClass = pThis->pClass;
|
||||
pDestr = PH7_ClassExtractMethod(pClass, "__destruct", sizeof("__destruct") - 1);
|
||||
if(pDestr) {
|
||||
/* Invoke the destructor */
|
||||
pThis->iRef = 2; /* Prevent garbage collection */
|
||||
PH7_VmCallClassMethod(pVm, pThis, pDestr, 0, 0, 0);
|
||||
}
|
||||
pThis->iRef = 1; /* Finalization adds its temporary reference */
|
||||
PH7_ClassInstanceFinalize(pThis);
|
||||
/* Release non-static attributes */
|
||||
SyHashResetLoopCursor(&pThis->hAttr);
|
||||
while((pEntry = SyHashGetNextEntry(&pThis->hAttr)) != 0) {
|
||||
|
||||
Reference in New Issue
Block a user