diff --git a/engine/vm.c b/engine/vm.c index 23c46c1..5f09f4c 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -5698,14 +5698,38 @@ static void VmInvokeShutdownCallbacks(ph7_vm *pVm) { * See block-comment on that function for additional information. */ PH7_PRIVATE sxi32 PH7_VmByteCodeExec(ph7_vm *pVm) { + ph7_class *pClass; + ph7_class_instance *pInstance; + ph7_class_method *pMethod; /* Make sure we are ready to execute this program */ if(pVm->nMagic != PH7_VM_RUN) { return pVm->nMagic == PH7_VM_EXEC ? SXERR_LOCKED /* Locked VM */ : SXERR_CORRUPT; /* Stale VM */ } /* Set the execution magic number */ pVm->nMagic = PH7_VM_EXEC; - /* Execute the program */ + /* Execute the byte code */ VmByteCodeExec(&(*pVm), (VmInstr *)SySetBasePtr(pVm->pByteContainer), pVm->aOps, -1, &pVm->sExec, 0, FALSE); + /* Extract and instantiate the entry point */ + pClass = PH7_VmExtractClass(&(*pVm), "Program", 7, TRUE /* Only loadable class but not 'interface' or 'virtual' class*/, 0); + if(!pClass) { + VmErrorFormat(&(*pVm), PH7_CTX_ERR, "Cannot find an entry 'Program' class"); + } + pInstance = PH7_NewClassInstance(&(*pVm), pClass); + if(pInstance == 0) { + VmErrorFormat(&(*pVm), PH7_CTX_ERR, "Cannot create 'Program' instance due to a memory failure"); + } + /* Check if a constructor is available */ + pMethod = PH7_ClassExtractMethod(pClass, "__construct", sizeof("__construct") - 1); + if(pMethod) { + /* Call the class constructor */ + PH7_VmCallClassMethod(&(*pVm), pInstance, pMethod, 0, 0, 0); + } + /* Call entry point */ + pMethod = PH7_ClassExtractMethod(pClass, "main", sizeof("main") - 1); + if(!pMethod) { + VmErrorFormat(&(*pVm), PH7_CTX_ERR, "Cannot find a program entry point 'Program::main()'"); + } + PH7_VmCallClassMethod(&(*pVm), pInstance, pMethod, 0, 0, 0); /* Invoke any shutdown callbacks */ VmInvokeShutdownCallbacks(&(*pVm)); /* @@ -7325,6 +7349,7 @@ PH7_PRIVATE sxi32 PH7_VmCallClassMethod( ) { ph7_value *aStack; VmInstr aInstr[2]; + int iEntry; int iCursor; int i; /* Create a new operand stack */ @@ -7344,6 +7369,7 @@ PH7_PRIVATE sxi32 PH7_VmCallClassMethod( aStack[i].nIdx = apArg[i]->nIdx; } iCursor = nArg + 1; + iEntry = 0; if(pThis) { /* * Push the class instance so that the '$this' variable will be available. @@ -7351,6 +7377,12 @@ PH7_PRIVATE sxi32 PH7_VmCallClassMethod( pThis->iRef++; /* Increment reference count */ aStack[i].x.pOther = pThis; aStack[i].iFlags = MEMOBJ_OBJ; + if(SyStrncmp(pThis->pClass->sName.zString, "Program", 7) == 0) { + if((SyStrncmp(pMethod->sFunc.sName.zString, "main", 4) == 0) || (SyStrncmp(pMethod->sFunc.sName.zString, "__construct", 11) == 0)) { + /* Do not overload entry point */ + iEntry = 1; + } + } } aStack[i].nIdx = SXU32_HIGH; /* Mark as constant */ i++; @@ -7362,7 +7394,7 @@ PH7_PRIVATE sxi32 PH7_VmCallClassMethod( /* Emit the CALL instruction */ aInstr[0].iOp = PH7_OP_CALL; aInstr[0].iP1 = nArg; /* Total number of given arguments */ - aInstr[0].iP2 = 0; + aInstr[0].iP2 = iEntry; aInstr[0].p3 = 0; /* Emit the DONE instruction */ aInstr[1].iOp = PH7_OP_DONE; diff --git a/tests/arab_to_roman.aer b/tests/arab_to_roman.aer index fa977a1..b5a8cfa 100644 --- a/tests/arab_to_roman.aer +++ b/tests/arab_to_roman.aer @@ -1,4 +1,4 @@ -class Main { +class Program { private function num2Roman($num) { $n = intval($num); @@ -15,7 +15,7 @@ class Main { return $result; } - public function __construct() { + public function main() { print(' 7 => ' + $this->num2Roman(7) + "\n"); print(' 9 => ' + $this->num2Roman(9) + "\n"); print(' 11 => ' + $this->num2Roman(11) + "\n"); @@ -28,5 +28,3 @@ class Main { } } - -new Main(); diff --git a/tests/debug_backtrace.aer b/tests/debug_backtrace.aer index b32414d..4c50763 100644 --- a/tests/debug_backtrace.aer +++ b/tests/debug_backtrace.aer @@ -1,6 +1,6 @@ -class Main { +class Program { - function __construct() { + function main() { $this->b($this->a('First A'), $this->a('Second A'), $this->a('Third A')); } @@ -19,5 +19,3 @@ class Main { } } - -new Main(); diff --git a/tests/hello_world.aer b/tests/hello_world.aer index 69830ce..83c13b3 100644 --- a/tests/hello_world.aer +++ b/tests/hello_world.aer @@ -1,9 +1,7 @@ -class Main { +class Program { - public function __construct() { + public function main() { print('Hello world!'); } } - -new Main(); diff --git a/tests/load_module.aer b/tests/load_module.aer index e86be05..d2ad4ef 100644 --- a/tests/load_module.aer +++ b/tests/load_module.aer @@ -1,9 +1,7 @@ -final class Main { - function __construct() { +final class Program { + function main() { var_dump(function_exists('dummy_function')); var_dump(import('dummy')); var_dump(function_exists('dummy_function')); } } - -new Main(); diff --git a/tests/printf_test.aer b/tests/printf_test.aer index 500cab9..e839044 100644 --- a/tests/printf_test.aer +++ b/tests/printf_test.aer @@ -1,11 +1,11 @@ -class Main { +class Program { private $s = 'monkey'; private $t = 'many monkeys'; private $n = 43951789; private $u = -43951789; private $c = 65; - public function __construct() { + public function main() { $this->testMonkey(); $this->testNumbers(); } @@ -36,5 +36,3 @@ class Main { } } - -new Main(); \ No newline at end of file diff --git a/tests/singleton_test.aer b/tests/singleton_test.aer index 3c9da40..03d9ddf 100644 --- a/tests/singleton_test.aer +++ b/tests/singleton_test.aer @@ -22,13 +22,11 @@ final class Test { } } -final class Main { - public function __construct() { +final class Program { + public function main() { $testA = Test::getInstance(); $testA->set(5); $testB = Test::getInstance(); var_dump($testB->get()); } } /* class */ - -new Main(); diff --git a/tests/type_juggle.aer b/tests/type_juggle.aer index 0acbbbd..2dd0ead 100644 --- a/tests/type_juggle.aer +++ b/tests/type_juggle.aer @@ -1,6 +1,6 @@ -class Main { +class Program { - function __construct() { + function main() { $foo = '0'; var_dump($foo); $foo += 2; @@ -23,5 +23,3 @@ class Main { var_dump($foo); } } - -new Main(); diff --git a/tests/unicode_characters.aer b/tests/unicode_characters.aer index bb81caa..d164afe 100644 --- a/tests/unicode_characters.aer +++ b/tests/unicode_characters.aer @@ -47,13 +47,11 @@ class Unicode { } -final class Main { +final class Program { - public function __construct() { + public function main() { $unicode = new Unicode(); var_dump($unicode->unicon("ИфйжБЦ")); } } - -new Main(); diff --git a/tests/utf8_variables.aer b/tests/utf8_variables.aer index 46ae771..ecdeeeb 100644 --- a/tests/utf8_variables.aer +++ b/tests/utf8_variables.aer @@ -1,7 +1,7 @@ -class Main { +class Program { private $概要 = "AerScript Interpreter"; - public function __construct() { + public function main() { $this->ダウンロード(); var_dump($this->概要); var_dump($this->isUTF8('hello')); @@ -39,5 +39,3 @@ class Main { return true; } } - -new Main();