Implement explicit value and reference captures for closures
Build / AerScript (push) Successful in 40s

This commit is contained in:
2026-10-26 00:05:05 +01:00
parent 85f59a2998
commit 4fe0f4dcd9
4 changed files with 219 additions and 32 deletions
+20 -9
View File
@@ -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) {