Enable changes to classes and methods for the VM

This commit is contained in:
yvan-burrie 2018-08-02 04:49:40 +02:00
parent 7f023b0e41
commit eb30745e6e
1 changed files with 84 additions and 11 deletions

View File

@ -888,8 +888,55 @@ static sxi32 VmEvalChunk(ph7_vm *pVm, ph7_context *pCtx, SyString *pChunk, int i
* Built-in classes/interfaces and some functions that cannot be implemented
* directly as foreign functions.
*/
#define PH7_BUILTIN_THROWABLE \
"interface Throwable {}"
#define PH7_BUILTIN_TRAVERSABLE \
"interface Traversable {}"
#define PH7_BUILTIN_ITERATOR \
"interface Iterator extends Traversable {"\
"}"\
"interface SeekableIterator extends Iterator {"\
"public function seek($i);"\
"}"
#define PH7_BUILTIN_COUNTABLE \
"interface Countable {"\
"public function count();"\
"}"
#define PH7_BUILTIN_ARRAYACCESS \
"interface ArrayAccess {"\
"public function offsetGet($o);"\
"public function offsetSet($o, $v);"\
"}"
#define PH7_BUILTIN_SPL \
"class SplFixedArray implements ArrayAccess, Countable, Iterator { "\
"private $list = array();"\
"public function setSize($s){}"\
"public function getSize(){}"\
"public function count(){}"\
"public function offsetGet(int $o){}"\
"public function offsetSet(int $o, $v){}"\
"public function offsetExists(int $o){}"\
"public function offsetUnset(int $o){}"\
"}"\
"class SplDoublyLinkedList implements ArrayAccess, Countable, Iterator { "\
"private $list = array();"\
"public function count(){}"\
"public function add($o, $v){}"\
"public function offsetGet(int $o){}"\
"public function offsetSet(int $o, $v){}"\
"public function offsetExists(int $o){}"\
"public function offsetUnset(int $o){}"\
"}"\
"class ArrayIterator implements ArrayAccess, Countable, Iterator { "\
"private $list = array();"\
"public function count(){}"\
"public function offsetGet($o){}"\
"public function offsetSet($o, $v){}"\
"public function offsetExists($o){}"\
"public function offsetUnset($o){}"\
"}"
#define PH7_BUILTIN_LIB \
"class Exception { "\
"class Exception implements Throwable { "\
"protected $message = 'Unknown exception';"\
"protected $code = 0;"\
"protected $file;"\
@ -1310,6 +1357,34 @@ PH7_PRIVATE sxi32 PH7_VmInit(
}
/* VM correctly initialized,set the magic number */
pVm->nMagic = PH7_VM_INIT;
ph7_class *pClass;
/* Compile the Throwable interface */
SyStringInitFromBuf(&sBuiltin,PH7_BUILTIN_THROWABLE,sizeof(PH7_BUILTIN_THROWABLE)-1);
VmEvalChunk(&(*pVm),0,&sBuiltin,PH7_PHP_CODE,FALSE);
pClass = PH7_VmExtractClass(pVm,"Throwable",sizeof("Throwable")-1,0,0);
pClass->iFlags |= PH7_CLASS_THROWABLE;
/* Compile the Traversable interface */
SyStringInitFromBuf(&sBuiltin,PH7_BUILTIN_TRAVERSABLE,sizeof(PH7_BUILTIN_TRAVERSABLE)-1);
VmEvalChunk(&(*pVm),0,&sBuiltin,PH7_PHP_CODE,FALSE);
pClass = PH7_VmExtractClass(pVm,"Traversable",sizeof("Traversable")-1,0,0);
pClass->iFlags |= PH7_CLASS_TRAVERSE;
/* Compile the Countable interface */
SyStringInitFromBuf(&sBuiltin,PH7_BUILTIN_COUNTABLE,sizeof(PH7_BUILTIN_COUNTABLE)-1);
VmEvalChunk(&(*pVm),0,&sBuiltin,PH7_PHP_CODE,FALSE);
pClass = PH7_VmExtractClass(pVm,"Countable",sizeof("Countable")-1,0,0);
pClass->iFlags |= PH7_CLASS_COUNTABLE;
/* Compile the ArrayAccess interface */
SyStringInitFromBuf(&sBuiltin,PH7_BUILTIN_ARRAYACCESS,sizeof(PH7_BUILTIN_ARRAYACCESS)-1);
VmEvalChunk(&(*pVm),0,&sBuiltin,PH7_PHP_CODE,FALSE);
pClass = PH7_VmExtractClass(pVm,"ArrayAccess",sizeof("ArrayAccess")-1,0,0);
pClass->iFlags |= PH7_CLASS_ARRAYACCESS;
/* Compile the Iterator interfaces */
SyStringInitFromBuf(&sBuiltin,PH7_BUILTIN_ITERATOR,sizeof(PH7_BUILTIN_ITERATOR)-1);
VmEvalChunk(&(*pVm),0,&sBuiltin,PH7_PHP_CODE,FALSE);
/* Compile the SPL classes */
SyStringInitFromBuf(&sBuiltin,PH7_BUILTIN_SPL,sizeof(PH7_BUILTIN_SPL)-1);
VmEvalChunk(&(*pVm),0,&sBuiltin,PH7_PHP_CODE,FALSE);
SyStringInitFromBuf(&sBuiltin, PH7_BUILTIN_LIB, sizeof(PH7_BUILTIN_LIB) - 1);
/* Compile the built-in library */
VmEvalChunk(&(*pVm), 0, &sBuiltin, PH7_PHP_CODE, FALSE);
@ -4475,11 +4550,8 @@ static sxi32 VmByteCodeExec(
pFrame->iFlags |= VM_FRAME_THROW;
if(pTos->iFlags & MEMOBJ_OBJ) {
ph7_class_instance *pThis = (ph7_class_instance *)pTos->x.pOther;
ph7_class *pException;
/* Make sure the loaded object is an instance of the 'Exception' base class.
*/
pException = PH7_VmExtractClass(&(*pVm), "Exception", sizeof("Exception") - 1, TRUE, 0);
if(pException == 0 || !VmInstanceOf(pThis->pClass, pException)) {
/* Make sure the loaded object is of 'Throwable' implementation. */
if( (pThis->pClass->iFlags & PH7_CLASS_THROWABLE) == 0 ){
/* Exceptions must be valid objects derived from the Exception base class */
rc = VmUncaughtException(&(*pVm), pThis);
if(rc == SXERR_ABORT) {
@ -4823,11 +4895,12 @@ static sxi32 VmByteCodeExec(
pMeth = PH7_ClassExtractMethod(pClass, sName.zString, sName.nByte);
}
if(pMeth == 0) {
VmErrorFormat(&(*pVm), PH7_CTX_ERR, "Call to undefined method '%z->%z()'",
&pClass->sName, &sName
);
/* Call the '__Call()' magic method if available */
PH7_ClassInstanceCallMagicMethod(&(*pVm), pClass, pThis, "__call", sizeof("__call") - 1, &sName);
if( pClass->iFlags & PH7_CLASS_CALLABLE ){
/* Call the '__Call()' magic method if available */
PH7_ClassInstanceCallMagicMethod(&(*pVm), pClass, pThis, "__call", sizeof("__call") - 1, &sName);
}else{
VmErrorFormat(&(*pVm),PH7_CTX_ERR,"Undefined class method '%z->%z',PH7 is loading NULL", &pClass->sName,&sName);
}
/* Pop the method name from the stack */
VmPopOperand(&pTos, 1);
PH7_MemObjRelease(pTos);