This commit is contained in:
+31
-11
@@ -6496,11 +6496,12 @@ static ph7_class_method *VmEntryPoint(ph7_vm *pVm, ph7_class *pClass) {
|
|||||||
*/
|
*/
|
||||||
PH7_PRIVATE sxi32 PH7_VmByteCodeExec(ph7_vm *pVm) {
|
PH7_PRIVATE sxi32 PH7_VmByteCodeExec(ph7_vm *pVm) {
|
||||||
ph7_class *pClass;
|
ph7_class *pClass;
|
||||||
ph7_class_instance *pInstance;
|
ph7_class_instance *pInstance = 0;
|
||||||
ph7_class_method *pMethod;
|
ph7_class_method *pMethod;
|
||||||
ph7_class_method *pMain;
|
ph7_class_method *pMain;
|
||||||
ph7_value *pArgs, *sArgv;
|
ph7_value *pArgs, *sArgv;
|
||||||
ph7_value pResult;
|
ph7_value pResult;
|
||||||
|
sxi32 rc;
|
||||||
const char *zParam;
|
const char *zParam;
|
||||||
sxu32 nByte, nOffset;
|
sxu32 nByte, nOffset;
|
||||||
/* Make sure we are ready to execute this program */
|
/* Make sure we are ready to execute this program */
|
||||||
@@ -6511,25 +6512,42 @@ PH7_PRIVATE sxi32 PH7_VmByteCodeExec(ph7_vm *pVm) {
|
|||||||
pVm->nMagic = PH7_VM_EXEC;
|
pVm->nMagic = PH7_VM_EXEC;
|
||||||
/* Execute the byte code */
|
/* Execute the byte code */
|
||||||
VmByteCodeExec(&(*pVm), (VmInstr *)SySetBasePtr(pVm->pByteContainer), pVm->aOps, -1, 0, FALSE);
|
VmByteCodeExec(&(*pVm), (VmInstr *)SySetBasePtr(pVm->pByteContainer), pVm->aOps, -1, 0, FALSE);
|
||||||
/* Extract and instantiate the entry point */
|
/* Extract the entry class */
|
||||||
pClass = PH7_VmExtractClass(&(*pVm), "Program", 7, TRUE /* Only loadable class but not 'interface' or 'virtual' class*/);
|
pClass = PH7_VmExtractClass(&(*pVm), "Program", 7, TRUE /* Only loadable class but not 'interface' or 'virtual' class*/);
|
||||||
if(!pClass) {
|
if(!pClass) {
|
||||||
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Cannot find an entry 'Program' class");
|
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Cannot find an entry 'Program' class");
|
||||||
}
|
}
|
||||||
/* Reject invalid entry points before running the Program constructor. */
|
/* Reject invalid entry points before running the Program constructor. */
|
||||||
pMain = VmEntryPoint(pVm, pClass);
|
pMain = VmEntryPoint(pVm, pClass);
|
||||||
pInstance = PH7_NewClassInstance(&(*pVm), pClass);
|
if((pMain->iFlags & PH7_CLASS_ATTR_STATIC) == 0) {
|
||||||
if(pInstance == 0) {
|
PH7_MemObjInit(pVm, &pResult);
|
||||||
PH7_VmMemoryError(&(*pVm));
|
rc = PH7_NewClassInstanceWithResult(pVm, pClass, &pInstance, &pResult);
|
||||||
}
|
|
||||||
/* Check if a constructor is available */
|
|
||||||
pMethod = PH7_ClassExtractMethod(pClass, "__construct", sizeof("__construct") - 1);
|
pMethod = PH7_ClassExtractMethod(pClass, "__construct", sizeof("__construct") - 1);
|
||||||
if(pMethod) {
|
if(rc == SXRET_OK && pMethod) {
|
||||||
/* Call the class constructor */
|
/* Use ordinary constructor access and overload selection, with no arguments. */
|
||||||
VmCallClassMethod(pVm, pInstance, pMethod, 0, 0, 0, FALSE);
|
rc = VmCallClassMethod(pVm, pInstance, pMethod, &pResult, 0, 0, FALSE);
|
||||||
|
if(pInstance->iRef < 1) {
|
||||||
|
pInstance->iRef = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if(rc != SXRET_OK) {
|
||||||
|
if(pInstance) {
|
||||||
|
PH7_ClassInstanceAbort(pInstance);
|
||||||
|
}
|
||||||
|
if(rc == PH7_EXCEPTION) {
|
||||||
|
VmUncaughtException(pVm, (pResult.nType & MEMOBJ_OBJ) ? (ph7_class_instance *)pResult.x.pOther : 0);
|
||||||
|
}
|
||||||
|
PH7_MemObjRelease(&pResult);
|
||||||
|
if(rc == SXERR_MEM) {
|
||||||
|
PH7_VmMemoryError(pVm);
|
||||||
|
}
|
||||||
|
/* Construction may stop via exit(); skip main, not shutdown. */
|
||||||
|
goto Shutdown;
|
||||||
|
}
|
||||||
|
PH7_MemObjRelease(&pResult);
|
||||||
/* Enable garbage collector */
|
/* Enable garbage collector */
|
||||||
pInstance->iRef--;
|
pInstance->iRef--;
|
||||||
|
}
|
||||||
pArgs = ph7_new_array(&(*pVm));
|
pArgs = ph7_new_array(&(*pVm));
|
||||||
sArgv = ph7_new_scalar(&(*pVm));
|
sArgv = ph7_new_scalar(&(*pVm));
|
||||||
if(!pArgs || !sArgv) {
|
if(!pArgs || !sArgv) {
|
||||||
@@ -6561,6 +6579,8 @@ PH7_PRIVATE sxi32 PH7_VmByteCodeExec(ph7_vm *pVm) {
|
|||||||
pVm->iExitStatus = 0;
|
pVm->iExitStatus = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rc = SXRET_OK;
|
||||||
|
Shutdown:
|
||||||
/* Preserve end-of-execution finalization before shutdown, but keep capture
|
/* Preserve end-of-execution finalization before shutdown, but keep capture
|
||||||
* environments and their indexed contents alive until VM release. */
|
* environments and their indexed contents alive until VM release. */
|
||||||
VmFinalizeObjects(pVm);
|
VmFinalizeObjects(pVm);
|
||||||
@@ -6571,7 +6591,7 @@ PH7_PRIVATE sxi32 PH7_VmByteCodeExec(ph7_vm *pVm) {
|
|||||||
* so that any following call to [ph7_vm_exec()] without calling
|
* so that any following call to [ph7_vm_exec()] without calling
|
||||||
* [ph7_vm_reset()] first would fail.
|
* [ph7_vm_reset()] first would fail.
|
||||||
*/
|
*/
|
||||||
return SXRET_OK;
|
return rc;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Invoke the installed VM output consumer callback to consume
|
* Invoke the installed VM output consumer callback to consume
|
||||||
|
|||||||
Reference in New Issue
Block a user