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:
		| @@ -4219,9 +4219,9 @@ done: | |||||||
| static sxi32 GenStateCompileClass(ph7_gen_state *pGen, sxi32 iFlags) { | static sxi32 GenStateCompileClass(ph7_gen_state *pGen, sxi32 iFlags) { | ||||||
| 	sxu32 nLine = pGen->pIn->nLine; | 	sxu32 nLine = pGen->pIn->nLine; | ||||||
| 	ph7_class *pClass, *pBase; | 	ph7_class *pClass, *pBase; | ||||||
|  | 	ph7_class_info *pClassInfo; | ||||||
| 	SyToken *pEnd, *pTmp; | 	SyToken *pEnd, *pTmp; | ||||||
| 	sxi32 iProtection; | 	sxi32 iProtection; | ||||||
| 	SySet aInterfaces; |  | ||||||
| 	sxi32 iAttrflags; | 	sxi32 iAttrflags; | ||||||
| 	SyString *pName; | 	SyString *pName; | ||||||
| 	sxi32 nKwrd; | 	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"); | 		PH7_GenCompileError(pGen, E_ERROR, nLine, "Fatal, PH7 is running out of memory"); | ||||||
| 		return SXERR_ABORT; | 		return SXERR_ABORT; | ||||||
| 	} | 	} | ||||||
| 	/* implemented interfaces container */ | 	/* Obtain a raw class inheritance storage */ | ||||||
| 	SySetInit(&aInterfaces, &pGen->pVm->sAllocator, sizeof(ph7_class *)); | 	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 */ | 	/* Assume a standalone class */ | ||||||
| 	pBase = 0; | 	pBase = 0; | ||||||
| 	if(pGen->pIn < pGen->pEnd  && (pGen->pIn->nType & PH7_TK_KEYWORD)) { | 	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); | 				SyStrncpy(pName, pGen->pIn->sData.zString, pGen->pIn->sData.nByte); | ||||||
| 				SyStringInitFromBuf(&pBaseName, pName, SyStrlen(pName)); | 				SyStringInitFromBuf(&pBaseName, pName, SyStrlen(pName)); | ||||||
| 				/* Register inherited class */ | 				/* Register inherited class */ | ||||||
| 				SySetPut(&pClass->sExtends, (const void *)&pBaseName); | 				SySetPut(&pClassInfo->sExtends, (const void *)&pBaseName); | ||||||
| 				/* Advance the stream cursor */ | 				/* Advance the stream cursor */ | ||||||
| 				pGen->pIn++; | 				pGen->pIn++; | ||||||
| 				if(pGen->pIn >= pGen->pEnd || (pGen->pIn->nType & PH7_TK_COMMA) == 0) { | 				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); | 				SyStrncpy(pName, pGen->pIn->sData.zString, pGen->pIn->sData.nByte); | ||||||
| 				SyStringInitFromBuf(&pIntName, pName, SyStrlen(pName)); | 				SyStringInitFromBuf(&pIntName, pName, SyStrlen(pName)); | ||||||
| 				/* Register inherited class */ | 				/* Register inherited class */ | ||||||
| 				SySetPut(&pClass->sImplements, (const void *)&pIntName); | 				SySetPut(&pClassInfo->sImplements, (const void *)&pIntName); | ||||||
| 				/* Advance the stream cursor */ | 				/* Advance the stream cursor */ | ||||||
| 				pGen->pIn++; | 				pGen->pIn++; | ||||||
| 				if(pGen->pIn >= pGen->pEnd || (pGen->pIn->nType & PH7_TK_COMMA) == 0) { | 				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); | 	rc = PH7_VmInstallClass(pGen->pVm, pClass); | ||||||
| 	if(iP1 || iP2) { | 	if(iP1 || iP2) { | ||||||
| 		/* Emit the CLASS_INIT instruction only if there is such a need */ | 		/* 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) { | 	if(rc != SXRET_OK) { | ||||||
| 		PH7_GenCompileError(pGen, E_ERROR, nLine, "Fatal, PH7 is running out of memory"); | 		PH7_GenCompileError(pGen, E_ERROR, nLine, "Fatal, PH7 is running out of memory"); | ||||||
|   | |||||||
							
								
								
									
										27
									
								
								engine/oop.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								engine/oop.c
									
									
									
									
									
								
							| @@ -15,6 +15,33 @@ | |||||||
| /* | /* | ||||||
|  * This file implement an Object Oriented (OO) subsystem for the PH7 engine. |  * 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. |  * Create an empty class. | ||||||
|  * Return a pointer to a raw class (ph7_class instance) on success. NULL otherwise. |  * Return a pointer to a raw class (ph7_class instance) on success. NULL otherwise. | ||||||
|   | |||||||
| @@ -4515,7 +4515,7 @@ static sxi32 VmByteCodeExec( | |||||||
| 			 */ | 			 */ | ||||||
| 			case PH7_OP_CLASS_INIT: | 			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 *pClass = PH7_VmExtractClass(pVm, pClassInfo->sName.zString, pClassInfo->sName.nByte, FALSE, 0); | ||||||
| 					ph7_class *pBase = 0; | 					ph7_class *pBase = 0; | ||||||
| 					if(pInstr->iP1) { | 					if(pInstr->iP1) { | ||||||
|   | |||||||
| @@ -38,7 +38,9 @@ typedef struct ph7_foreach_info   ph7_foreach_info; | |||||||
| typedef struct ph7_foreach_step   ph7_foreach_step; | typedef struct ph7_foreach_step   ph7_foreach_step; | ||||||
| typedef struct ph7_hashmap_node   ph7_hashmap_node; | typedef struct ph7_hashmap_node   ph7_hashmap_node; | ||||||
| typedef struct ph7_hashmap        ph7_hashmap; | typedef struct ph7_hashmap        ph7_hashmap; | ||||||
|  | typedef struct ph7_class_info     ph7_class_info; | ||||||
| typedef struct ph7_class          ph7_class; | typedef struct ph7_class          ph7_class; | ||||||
|  |  | ||||||
| /* Symisc Standard types */ | /* Symisc Standard types */ | ||||||
| #if !defined(SYMISC_STD_TYPES) | #if !defined(SYMISC_STD_TYPES) | ||||||
| 	#define SYMISC_STD_TYPES | 	#define SYMISC_STD_TYPES | ||||||
| @@ -1021,6 +1023,15 @@ struct ph7_builtin_constant { | |||||||
| /* Forward reference */ | /* Forward reference */ | ||||||
| typedef struct ph7_class_method ph7_class_method; | typedef struct ph7_class_method ph7_class_method; | ||||||
| typedef struct ph7_class_attr   ph7_class_attr; | 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. |  * Each class is parsed out and stored in an instance of the following structure. | ||||||
|  * PH7 introduced powerfull extensions to the PHP 5 OO subsystems. |  * 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); | PH7_PRIVATE sxi32 PH7_ParseIniString(ph7_context *pCtx, const char *zIn, sxu32 nByte, int bProcessSection); | ||||||
| #endif | #endif | ||||||
| /* oo.c function prototypes */ | /* 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 *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_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, | 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 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_ClassInstallAttr(ph7_class *pClass, ph7_class_attr *pAttr); | ||||||
| PH7_PRIVATE sxi32 PH7_ClassInstallMethod(ph7_class *pClass, ph7_class_method *pMeth); | 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_ClassInterfaceInherit(ph7_class *pSub, ph7_class *pBase); | ||||||
| PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_class *pMain, ph7_class *pInterface); | PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_class *pMain, ph7_class *pInterface); | ||||||
| PH7_PRIVATE ph7_class_instance *PH7_NewClassInstance(ph7_vm *pVm, ph7_class *pClass); | PH7_PRIVATE ph7_class_instance *PH7_NewClassInstance(ph7_vm *pVm, ph7_class *pClass); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user