From aaef03396c917c560bb4d89c9871174b30013469 Mon Sep 17 00:00:00 2001 From: belliash Date: Tue, 2 Apr 2019 19:44:09 +0200 Subject: [PATCH] Implement PH7_MemObjSafeStore(). --- engine/memobj.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ include/ph7int.h | 1 + 2 files changed, 53 insertions(+) diff --git a/engine/memobj.c b/engine/memobj.c index cfd0bb6..92a3adc 100644 --- a/engine/memobj.c +++ b/engine/memobj.c @@ -381,6 +381,58 @@ PH7_PRIVATE sxi32 PH7_CheckVarCompat(ph7_value *pObj, int nType) { } return SXERR_NOMATCH; } +/* + * Duplicate safely the contents of a ph7_value if source and + * destination are of the compatible data types. + */ +PH7_PRIVATE sxi32 PH7_MemObjSafeStore(ph7_value *pSrc, ph7_value *pDest) { + if(pDest->iFlags == pSrc->iFlags) { + PH7_MemObjStore(pSrc, pDest); + } else if(pDest->iFlags & MEMOBJ_MIXED) { + if(pDest->iFlags & MEMOBJ_HASHMAP) { + /* mixed[] */ + if(pSrc->iFlags & MEMOBJ_HASHMAP) { + PH7_MemObjStore(pSrc, pDest); + pDest->iFlags |= MEMOBJ_MIXED; + } else if(pSrc->iFlags & MEMOBJ_NULL) { + /* Temporarily do no allow to assign a NULL value to array */ + return SXERR_NOMATCH; + } else { + return SXERR_NOMATCH; + } + } else { + /* mixed */ + if(pSrc->iFlags == MEMOBJ_NULL) { + MemObjSetType(pDest, MEMOBJ_MIXED | MEMOBJ_VOID); + } else if((pSrc->iFlags & MEMOBJ_HASHMAP) == 0) { + PH7_MemObjStore(pSrc, pDest); + pDest->iFlags |= MEMOBJ_MIXED; + } else { + return SXERR_NOMATCH; + } + } + } else if((pDest->iFlags & MEMOBJ_HASHMAP)) { + /* [] */ + if(pSrc->iFlags & MEMOBJ_NULL) { + /* Temporarily do no allow to assign a NULL value to array */ + return SXERR_NOMATCH; + } else if(pSrc->iFlags & MEMOBJ_HASHMAP) { + if(PH7_HashmapCast(pSrc, pDest->iFlags ^ MEMOBJ_HASHMAP) != SXRET_OK) { + return SXERR_NOMATCH; + } + PH7_MemObjStore(pSrc, pDest); + } else { + return SXERR_NOMATCH; + } + } else if(PH7_CheckVarCompat(pSrc, pDest->iFlags) == SXRET_OK) { + ProcMemObjCast xCast = PH7_MemObjCastMethod(pDest->iFlags); + xCast(pSrc); + PH7_MemObjStore(pSrc, pDest); + } else { + return SXERR_NOMATCH; + } + return SXRET_OK; +} /* * Convert a ph7_value to type integer.Invalidate any prior representations. */ diff --git a/include/ph7int.h b/include/ph7int.h index c19263e..269bf8a 100644 --- a/include/ph7int.h +++ b/include/ph7int.h @@ -1650,6 +1650,7 @@ PH7_PRIVATE sxi32 PH7_MemObjToBool(ph7_value *pObj); PH7_PRIVATE sxi32 PH7_MemObjToCallback(ph7_value *pObj); PH7_PRIVATE sxi32 PH7_MemObjToResource(ph7_value *pObj); PH7_PRIVATE sxi32 PH7_CheckVarCompat(ph7_value *pObj, int nType); +PH7_PRIVATE sxi32 PH7_MemObjSafeStore(ph7_value *pSrc, ph7_value *pDest); PH7_PRIVATE sxi64 PH7_TokenValueToInt64(SyString *pData); /* lex.c function prototypes */ PH7_PRIVATE sxi32 PH7_TokenizeRawText(const char *zInput, sxu32 nLen, SySet *pOut);