Two changes come here:
* do not allow two or more classes / interfaces with the same name * fix class_exists() builtin function so that it does not return true if interface is found
This commit is contained in:
parent
63b0f450d3
commit
09451f4042
@ -4046,11 +4046,8 @@ static sxi32 PH7_CompileClassInterface(ph7_gen_state *pGen) {
|
|||||||
}
|
}
|
||||||
pBaseName = &pGen->pIn->sData;
|
pBaseName = &pGen->pIn->sData;
|
||||||
pBase = PH7_VmExtractClass(pGen->pVm, pBaseName->zString, pBaseName->nByte, FALSE, 0);
|
pBase = PH7_VmExtractClass(pGen->pVm, pBaseName->zString, pBaseName->nByte, FALSE, 0);
|
||||||
/* Only interfaces is allowed */
|
/* Only interface is allowed */
|
||||||
while(pBase && (pBase->iFlags & PH7_CLASS_INTERFACE) == 0) {
|
if(pBase == 0 || (pBase->iFlags & PH7_CLASS_INTERFACE) == 0) {
|
||||||
pBase = pBase->pNextName;
|
|
||||||
}
|
|
||||||
if(pBase == 0) {
|
|
||||||
/* Inexistant interface */
|
/* Inexistant interface */
|
||||||
rc = PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "Inexistant base interface '%z'", pBaseName);
|
rc = PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "Inexistant base interface '%z'", pBaseName);
|
||||||
if(rc == SXERR_ABORT) {
|
if(rc == SXERR_ABORT) {
|
||||||
@ -4279,11 +4276,8 @@ static sxi32 GenStateCompileClass(ph7_gen_state *pGen, sxi32 iFlags) {
|
|||||||
pBaseName = &pGen->pIn->sData;
|
pBaseName = &pGen->pIn->sData;
|
||||||
// /* Perform the query */
|
// /* Perform the query */
|
||||||
// pBase = PH7_VmExtractClass(pGen->pVm, pBaseName->zString, pBaseName->nByte, FALSE, 0);
|
// pBase = PH7_VmExtractClass(pGen->pVm, pBaseName->zString, pBaseName->nByte, FALSE, 0);
|
||||||
// /* Interfaces are not allowed */
|
// /* Interface is not allowed */
|
||||||
// while(pBase && (pBase->iFlags & PH7_CLASS_INTERFACE)) {
|
// if(pBase == 0 || (pBase->iFlags & PH7_CLASS_INTERFACE)) {
|
||||||
// pBase = pBase->pNextName;
|
|
||||||
// }
|
|
||||||
// if(pBase == 0) {
|
|
||||||
// /* Inexistant base class */
|
// /* Inexistant base class */
|
||||||
// rc = PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "Inexistant base class '%z'", pBaseName);
|
// rc = PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "Inexistant base class '%z'", pBaseName);
|
||||||
// if(rc == SXERR_ABORT) {
|
// if(rc == SXERR_ABORT) {
|
||||||
@ -4325,10 +4319,7 @@ static sxi32 GenStateCompileClass(ph7_gen_state *pGen, sxi32 iFlags) {
|
|||||||
/* Make sure the interface is already defined */
|
/* Make sure the interface is already defined */
|
||||||
pInterface = PH7_VmExtractClass(pGen->pVm, pIntName->zString, pIntName->nByte, FALSE, 0);
|
pInterface = PH7_VmExtractClass(pGen->pVm, pIntName->zString, pIntName->nByte, FALSE, 0);
|
||||||
/* Only interfaces are allowed */
|
/* Only interfaces are allowed */
|
||||||
while(pInterface && (pInterface->iFlags & PH7_CLASS_INTERFACE) == 0) {
|
if(pInterface == 0 || (pInterface->iFlags & PH7_CLASS_INTERFACE) == 0) {
|
||||||
pInterface = pInterface->pNextName;
|
|
||||||
}
|
|
||||||
if(pInterface == 0) {
|
|
||||||
/* Inexistant interface */
|
/* Inexistant interface */
|
||||||
rc = PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "Inexistant base interface '%z'", pIntName);
|
rc = PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "Inexistant base interface '%z'", pIntName);
|
||||||
if(rc == SXERR_ABORT) {
|
if(rc == SXERR_ABORT) {
|
||||||
|
28
engine/vm.c
28
engine/vm.c
@ -384,13 +384,8 @@ PH7_PRIVATE sxi32 PH7_VmInstallClass(
|
|||||||
/* Check for duplicates */
|
/* Check for duplicates */
|
||||||
pEntry = SyHashGet(&pVm->hClass, (const void *)pName->zString, pName->nByte);
|
pEntry = SyHashGet(&pVm->hClass, (const void *)pName->zString, pName->nByte);
|
||||||
if(pEntry) {
|
if(pEntry) {
|
||||||
ph7_class *pLink = (ph7_class *)pEntry->pUserData;
|
PH7_VmThrowError(&(*pVm), 0, PH7_CTX_ERR, "Cannot declare class, because the name is already in use");
|
||||||
/* Link entry with the same name */
|
|
||||||
pClass->pNextName = pLink;
|
|
||||||
pEntry->pUserData = pClass;
|
|
||||||
return SXRET_OK;
|
|
||||||
}
|
}
|
||||||
pClass->pNextName = 0;
|
|
||||||
/* Perform a simple hashtable insertion */
|
/* Perform a simple hashtable insertion */
|
||||||
rc = SyHashInsert(&pVm->hClass, (const void *)pName->zString, pName->nByte, pClass);
|
rc = SyHashInsert(&pVm->hClass, (const void *)pName->zString, pName->nByte, pClass);
|
||||||
return rc;
|
return rc;
|
||||||
@ -6762,16 +6757,23 @@ static int vm_builtin_method_exists(ph7_context *pCtx, int nArg, ph7_value **apA
|
|||||||
static int vm_builtin_class_exists(ph7_context *pCtx, int nArg, ph7_value **apArg) {
|
static int vm_builtin_class_exists(ph7_context *pCtx, int nArg, ph7_value **apArg) {
|
||||||
int res = 0; /* Assume class does not exists */
|
int res = 0; /* Assume class does not exists */
|
||||||
if(nArg > 0) {
|
if(nArg > 0) {
|
||||||
|
SyHashEntry *pEntry = 0;
|
||||||
const char *zName;
|
const char *zName;
|
||||||
int nLen;
|
int nLen;
|
||||||
/* Extract given name */
|
/* Extract given name */
|
||||||
zName = ph7_value_to_string(apArg[0], &nLen);
|
zName = ph7_value_to_string(apArg[0], &nLen);
|
||||||
/* Perform a hashlookup */
|
/* Perform a hashlookup */
|
||||||
if(nLen > 0 && SyHashGet(&pCtx->pVm->hClass, (const void *)zName, (sxu32)nLen) != 0) {
|
if(nLen > 0) {
|
||||||
|
pEntry = SyHashGet(&pCtx->pVm->hClass, (const void *)zName, (sxu32)nLen);
|
||||||
|
}
|
||||||
|
if(pEntry) {
|
||||||
|
ph7_class *pClass = (ph7_class *)pEntry->pUserData;
|
||||||
|
if((pClass->iFlags & PH7_CLASS_INTERFACE) == 0) {
|
||||||
/* class is available */
|
/* class is available */
|
||||||
res = 1;
|
res = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ph7_result_bool(pCtx, res);
|
ph7_result_bool(pCtx, res);
|
||||||
return PH7_OK;
|
return PH7_OK;
|
||||||
}
|
}
|
||||||
@ -6801,14 +6803,9 @@ static int vm_builtin_interface_exists(ph7_context *pCtx, int nArg, ph7_value **
|
|||||||
}
|
}
|
||||||
if(pEntry) {
|
if(pEntry) {
|
||||||
ph7_class *pClass = (ph7_class *)pEntry->pUserData;
|
ph7_class *pClass = (ph7_class *)pEntry->pUserData;
|
||||||
while(pClass) {
|
|
||||||
if(pClass->iFlags & PH7_CLASS_INTERFACE) {
|
if(pClass->iFlags & PH7_CLASS_INTERFACE) {
|
||||||
/* interface is available */
|
/* interface is available */
|
||||||
res = 1;
|
res = 1;
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Next with the same name */
|
|
||||||
pClass = pClass->pNextName;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11677,18 +11674,13 @@ PH7_PRIVATE ph7_class *PH7_VmExtractClass(
|
|||||||
}
|
}
|
||||||
pClass = (ph7_class *)pEntry->pUserData;
|
pClass = (ph7_class *)pEntry->pUserData;
|
||||||
if(!iLoadable) {
|
if(!iLoadable) {
|
||||||
/* Return the first class seen */
|
/* Return the class absolutely */
|
||||||
return pClass;
|
return pClass;
|
||||||
} else {
|
} else {
|
||||||
/* Check the collision list */
|
|
||||||
while(pClass) {
|
|
||||||
if((pClass->iFlags & (PH7_CLASS_INTERFACE | PH7_CLASS_ABSTRACT)) == 0) {
|
if((pClass->iFlags & (PH7_CLASS_INTERFACE | PH7_CLASS_ABSTRACT)) == 0) {
|
||||||
/* Class is loadable */
|
/* Class is loadable */
|
||||||
return pClass;
|
return pClass;
|
||||||
}
|
}
|
||||||
/* Point to the next entry */
|
|
||||||
pClass = pClass->pNextName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* No such loadable class */
|
/* No such loadable class */
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user