Several changes:

* small code cleanup
 * implement new structure for storing information about class inheritance
 * implement PH7_NewClassInfo()
 * make a use of smaller ph7_class_info instead of ph7_class, to reduce memory usage
This commit is contained in:
2018-07-27 21:05:54 +02:00
parent e47eef7d97
commit caf9126f0b
4 changed files with 51 additions and 8 deletions

View File

@@ -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");

View File

@@ -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.

View File

@@ -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) {