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_class *pClass;
|
||||
ph7_class_instance *pInstance;
|
||||
ph7_class_instance *pInstance = 0;
|
||||
ph7_class_method *pMethod;
|
||||
ph7_class_method *pMain;
|
||||
ph7_value *pArgs, *sArgv;
|
||||
ph7_value pResult;
|
||||
sxi32 rc;
|
||||
const char *zParam;
|
||||
sxu32 nByte, nOffset;
|
||||
/* 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;
|
||||
/* Execute the byte code */
|
||||
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*/);
|
||||
if(!pClass) {
|
||||
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Cannot find an entry 'Program' class");
|
||||
}
|
||||
/* Reject invalid entry points before running the Program constructor. */
|
||||
pMain = VmEntryPoint(pVm, pClass);
|
||||
pInstance = PH7_NewClassInstance(&(*pVm), pClass);
|
||||
if(pInstance == 0) {
|
||||
PH7_VmMemoryError(&(*pVm));
|
||||
}
|
||||
/* Check if a constructor is available */
|
||||
if((pMain->iFlags & PH7_CLASS_ATTR_STATIC) == 0) {
|
||||
PH7_MemObjInit(pVm, &pResult);
|
||||
rc = PH7_NewClassInstanceWithResult(pVm, pClass, &pInstance, &pResult);
|
||||
pMethod = PH7_ClassExtractMethod(pClass, "__construct", sizeof("__construct") - 1);
|
||||
if(pMethod) {
|
||||
/* Call the class constructor */
|
||||
VmCallClassMethod(pVm, pInstance, pMethod, 0, 0, 0, FALSE);
|
||||
if(rc == SXRET_OK && pMethod) {
|
||||
/* Use ordinary constructor access and overload selection, with no arguments. */
|
||||
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 */
|
||||
pInstance->iRef--;
|
||||
}
|
||||
pArgs = ph7_new_array(&(*pVm));
|
||||
sArgv = ph7_new_scalar(&(*pVm));
|
||||
if(!pArgs || !sArgv) {
|
||||
@@ -6561,6 +6579,8 @@ PH7_PRIVATE sxi32 PH7_VmByteCodeExec(ph7_vm *pVm) {
|
||||
pVm->iExitStatus = 0;
|
||||
}
|
||||
}
|
||||
rc = SXRET_OK;
|
||||
Shutdown:
|
||||
/* Preserve end-of-execution finalization before shutdown, but keep capture
|
||||
* environments and their indexed contents alive until VM release. */
|
||||
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
|
||||
* [ph7_vm_reset()] first would fail.
|
||||
*/
|
||||
return SXRET_OK;
|
||||
return rc;
|
||||
}
|
||||
/*
|
||||
* Invoke the installed VM output consumer callback to consume
|
||||
|
||||
Reference in New Issue
Block a user