diff --git a/engine/compiler.c b/engine/compiler.c index 84db7f3..d5b5e1d 100644 --- a/engine/compiler.c +++ b/engine/compiler.c @@ -4219,9 +4219,9 @@ done: static sxi32 GenStateCompileClass(ph7_gen_state *pGen, sxi32 iFlags) { sxu32 nLine = pGen->pIn->nLine; ph7_class *pClass, *pBase; + ph7_class_info *pClassInfo; SyToken *pEnd, *pTmp; sxi32 iProtection; - SySet aInterfaces; sxi32 iAttrflags; SyString *pName; sxi32 nKwrd; @@ -4253,8 +4253,12 @@ static sxi32 GenStateCompileClass(ph7_gen_state *pGen, sxi32 iFlags) { PH7_GenCompileError(pGen, E_ERROR, nLine, "Fatal, PH7 is running out of memory"); return SXERR_ABORT; } - /* implemented interfaces container */ - SySetInit(&aInterfaces, &pGen->pVm->sAllocator, sizeof(ph7_class *)); + /* Obtain a raw class inheritance storage */ + pClassInfo = PH7_NewClassInfo(pGen->pVm, pName); + if(pClassInfo == 0) { + PH7_GenCompileError(pGen, E_ERROR, nLine, "Fatal, PH7 is running out of memory"); + return SXERR_ABORT; + } /* Assume a standalone class */ pBase = 0; if(pGen->pIn < pGen->pEnd && (pGen->pIn->nType & PH7_TK_KEYWORD)) { @@ -4280,7 +4284,7 @@ static sxi32 GenStateCompileClass(ph7_gen_state *pGen, sxi32 iFlags) { SyStrncpy(pName, pGen->pIn->sData.zString, pGen->pIn->sData.nByte); SyStringInitFromBuf(&pBaseName, pName, SyStrlen(pName)); /* Register inherited class */ - SySetPut(&pClass->sExtends, (const void *)&pBaseName); + SySetPut(&pClassInfo->sExtends, (const void *)&pBaseName); /* Advance the stream cursor */ pGen->pIn++; if(pGen->pIn >= pGen->pEnd || (pGen->pIn->nType & PH7_TK_COMMA) == 0) { @@ -4314,7 +4318,7 @@ static sxi32 GenStateCompileClass(ph7_gen_state *pGen, sxi32 iFlags) { SyStrncpy(pName, pGen->pIn->sData.zString, pGen->pIn->sData.nByte); SyStringInitFromBuf(&pIntName, pName, SyStrlen(pName)); /* Register inherited class */ - SySetPut(&pClass->sImplements, (const void *)&pIntName); + SySetPut(&pClassInfo->sImplements, (const void *)&pIntName); /* Advance the stream cursor */ pGen->pIn++; if(pGen->pIn >= pGen->pEnd || (pGen->pIn->nType & PH7_TK_COMMA) == 0) { @@ -4565,7 +4569,7 @@ static sxi32 GenStateCompileClass(ph7_gen_state *pGen, sxi32 iFlags) { rc = PH7_VmInstallClass(pGen->pVm, pClass); if(iP1 || iP2) { /* Emit the CLASS_INIT instruction only if there is such a need */ - PH7_VmEmitInstr(pGen->pVm, PH7_OP_CLASS_INIT, iP1, iP2, pClass, 0); + PH7_VmEmitInstr(pGen->pVm, PH7_OP_CLASS_INIT, iP1, iP2, pClassInfo, 0); } if(rc != SXRET_OK) { PH7_GenCompileError(pGen, E_ERROR, nLine, "Fatal, PH7 is running out of memory"); diff --git a/engine/oop.c b/engine/oop.c index 478edc2..6762b0f 100644 --- a/engine/oop.c +++ b/engine/oop.c @@ -15,6 +15,33 @@ /* * This file implement an Object Oriented (OO) subsystem for the PH7 engine. */ +/* + * Create an empty class inheritance storage. + * Return a pointer to a storage (ph7_class_info instance) on success. NULL otherwise. + */ +PH7_PRIVATE ph7_class_info *PH7_NewClassInfo(ph7_vm *pVm, const SyString *pName) { + ph7_class_info *pClassInfo; + char *zName; + /* Allocate a new instance */ + pClassInfo = (ph7_class_info *)SyMemBackendPoolAlloc(&pVm->sAllocator, sizeof(ph7_class_info)); + if(pClassInfo == 0) { + return 0; + } + /* Zero the structure */ + SyZero(pClassInfo, sizeof(ph7_class_info)); + /* Duplicate class name */ + zName = SyMemBackendStrDup(&pVm->sAllocator, pName->zString, pName->nByte); + if(zName == 0) { + SyMemBackendPoolFree(&pVm->sAllocator, pClassInfo); + return 0; + } + /* Initialize the class information storage */ + SyStringInitFromBuf(&pClassInfo->sName, zName, pName->nByte); + SySetInit(&pClassInfo->sExtends, &pVm->sAllocator, sizeof(SyString)); + SySetInit(&pClassInfo->sImplements, &pVm->sAllocator, sizeof(SyString)); + /* All done */ + return pClassInfo; +} /* * Create an empty class. * Return a pointer to a raw class (ph7_class instance) on success. NULL otherwise. diff --git a/engine/vm.c b/engine/vm.c index df1ee90..f3b1751 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -4515,7 +4515,7 @@ static sxi32 VmByteCodeExec( */ case PH7_OP_CLASS_INIT: { - ph7_class *pClassInfo = (ph7_class *)pInstr->p3; + ph7_class_info *pClassInfo = (ph7_class_info *)pInstr->p3; ph7_class *pClass = PH7_VmExtractClass(pVm, pClassInfo->sName.zString, pClassInfo->sName.nByte, FALSE, 0); ph7_class *pBase = 0; if(pInstr->iP1) { diff --git a/include/ph7int.h b/include/ph7int.h index 215d53f..8160e27 100644 --- a/include/ph7int.h +++ b/include/ph7int.h @@ -38,7 +38,9 @@ typedef struct ph7_foreach_info ph7_foreach_info; typedef struct ph7_foreach_step ph7_foreach_step; typedef struct ph7_hashmap_node ph7_hashmap_node; typedef struct ph7_hashmap ph7_hashmap; +typedef struct ph7_class_info ph7_class_info; typedef struct ph7_class ph7_class; + /* Symisc Standard types */ #if !defined(SYMISC_STD_TYPES) #define SYMISC_STD_TYPES @@ -1021,6 +1023,15 @@ struct ph7_builtin_constant { /* Forward reference */ typedef struct ph7_class_method ph7_class_method; typedef struct ph7_class_attr ph7_class_attr; +/* + * Information about class/interface inheritance and interface implementation + * is stored in an instance of the following structure. + */ +struct ph7_class_info { + SyString sName; /* Class full qualified name */ + SySet sExtends; /* List of inherited classes / interfaces */ + SySet sImplements; /* List of implemented interfaces */ +}; /* * Each class is parsed out and stored in an instance of the following structure. * PH7 introduced powerfull extensions to the PHP 5 OO subsystems. @@ -1693,6 +1704,7 @@ PH7_PRIVATE sxi32 PH7_StripTagsFromString(ph7_context *pCtx, const char *zIn, in PH7_PRIVATE sxi32 PH7_ParseIniString(ph7_context *pCtx, const char *zIn, sxu32 nByte, int bProcessSection); #endif /* oo.c function prototypes */ +PH7_PRIVATE ph7_class_info *PH7_NewClassInfo(ph7_vm *pVm, const SyString *pName); PH7_PRIVATE ph7_class *PH7_NewRawClass(ph7_vm *pVm, const SyString *pName, sxu32 nLine); PH7_PRIVATE ph7_class_attr *PH7_NewClassAttr(ph7_vm *pVm, const SyString *pName, sxu32 nLine, sxi32 iProtection, sxi32 iFlags); PH7_PRIVATE ph7_class_method *PH7_NewClassMethod(ph7_vm *pVm, ph7_class *pClass, const SyString *pName, sxu32 nLine, @@ -1701,7 +1713,7 @@ PH7_PRIVATE ph7_class_method *PH7_ClassExtractMethod(ph7_class *pClass, const ch PH7_PRIVATE ph7_class_attr *PH7_ClassExtractAttribute(ph7_class *pClass, const char *zName, sxu32 nByte); PH7_PRIVATE sxi32 PH7_ClassInstallAttr(ph7_class *pClass, ph7_class_attr *pAttr); PH7_PRIVATE sxi32 PH7_ClassInstallMethod(ph7_class *pClass, ph7_class_method *pMeth); -PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_class *pSub, ph7_class *pBase); +PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_vm *pVm, ph7_class *pSub, ph7_class *pBase); PH7_PRIVATE sxi32 PH7_ClassInterfaceInherit(ph7_class *pSub, ph7_class *pBase); PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_class *pMain, ph7_class *pInterface); PH7_PRIVATE ph7_class_instance *PH7_NewClassInstance(ph7_vm *pVm, ph7_class *pClass);