From 174ecb2a38879e79a0cfb10176c3d6371cf0f312 Mon Sep 17 00:00:00 2001 From: belliash Date: Fri, 23 Nov 2018 09:19:37 +0100 Subject: [PATCH] Initial support for void type. --- engine/api.c | 17 +++++++++++++++++ engine/lexer.c | 4 +++- engine/memobj.c | 44 +++++++++++++++++++++++++++++++++++++------- engine/parser.c | 1 + engine/vm.c | 13 +++++++++++++ include/ph7int.h | 1 + 6 files changed, 72 insertions(+), 8 deletions(-) diff --git a/engine/api.c b/engine/api.c index b6005b5..b48f024 100644 --- a/engine/api.c +++ b/engine/api.c @@ -1796,6 +1796,16 @@ int ph7_value_double(ph7_value *pVal, double Value) { MemObjSetType(pVal, MEMOBJ_REAL); return PH7_OK; } +/* + * [CAPIREF: ph7_value_void()] + * Please refer to the official documentation for function purpose and expected parameters. + */ +int ph7_value_void(ph7_value *pVal) { + /* Invalidate any prior representation */ + PH7_MemObjRelease(pVal); + MemObjSetType(pVal, MEMOBJ_VOID); + return PH7_OK; +} /* * [CAPIREF: ph7_value_string()] * Please refer to the official documentation for function purpose and expected parameters. @@ -1882,6 +1892,13 @@ int ph7_value_is_float(ph7_value *pVal) { int ph7_value_is_bool(ph7_value *pVal) { return (pVal->iFlags & MEMOBJ_BOOL) ? TRUE : FALSE; } +/* + * [CAPIREF: ph7_value_is_void()] + * Please refer to the official documentation for function purpose and expected parameters. + */ +int ph7_value_is_void(ph7_value *pVal) { + return (pVal->iFlags & MEMOBJ_VOID) ? TRUE : FALSE; +} /* * [CAPIREF: ph7_value_is_string()] * Please refer to the official documentation for function purpose and expected parameters. diff --git a/engine/lexer.c b/engine/lexer.c index 668ac8c..30ac00c 100644 --- a/engine/lexer.c +++ b/engine/lexer.c @@ -225,7 +225,7 @@ static sxi32 TokenizeAerScript(SyStream *pStream, SyToken *pToken, void *pUserDa pTmp = (SyToken *)SySetPeek(pTokSet); if(pTmp->nType & PH7_TK_KEYWORD) { sxi32 nID = SX_PTR_TO_INT(pTmp->pUserData); - if((sxu32)nID & (PH7_KEYWORD_ARRAY | PH7_KEYWORD_INT | PH7_KEYWORD_FLOAT | PH7_KEYWORD_STRING | PH7_KEYWORD_OBJECT | PH7_KEYWORD_BOOL)) { + if((sxu32)nID & (PH7_KEYWORD_ARRAY | PH7_KEYWORD_INT | PH7_KEYWORD_FLOAT | PH7_KEYWORD_STRING | PH7_KEYWORD_OBJECT | PH7_KEYWORD_BOOL | PH7_KEYWORD_VOID)) { pTmp = (SyToken *)SySetAt(pTokSet, pTokSet->nUsed - 2); if(pTmp->nType & PH7_TK_LPAREN) { /* Merge the three tokens '(' 'TYPE' ')' into a single one */ @@ -240,6 +240,8 @@ static sxi32 TokenizeAerScript(SyStream *pStream, SyToken *pToken, void *pUserDa zTypeCast = "(array)"; } else if(nID & PH7_KEYWORD_OBJECT) { zTypeCast = "(object)"; + } else if(nID & PH7_KEYWORD_VOID) { + zTypeCast = "(void)"; } /* Reflect the change */ pToken->nType = PH7_TK_OP; diff --git a/engine/memobj.c b/engine/memobj.c index a677ecf..c3988ab 100644 --- a/engine/memobj.c +++ b/engine/memobj.c @@ -137,7 +137,7 @@ static sxi64 MemObjIntValue(ph7_value *pObj) { return pObj->x.iVal; } else if(iFlags & MEMOBJ_STRING) { return MemObjStringToInt(&(*pObj)); - } else if(iFlags & MEMOBJ_NULL) { + } else if(iFlags & (MEMOBJ_NULL | MEMOBJ_VOID)) { return 0; } else if(iFlags & MEMOBJ_HASHMAP) { ph7_hashmap *pMap = (ph7_hashmap *)pObj->x.pOther; @@ -192,7 +192,7 @@ static ph7_real MemObjRealValue(ph7_value *pObj) { SyStrToReal(sString.zString, sString.nByte, (void *)&rVal, 0); } return rVal; - } else if(iFlags & MEMOBJ_NULL) { + } else if(iFlags & (MEMOBJ_NULL | MEMOBJ_VOID)) { return 0.0; } else if(iFlags & MEMOBJ_HASHMAP) { /* Return the total number of entries in the hashmap */ @@ -303,7 +303,7 @@ static sxi32 MemObjBooleanValue(ph7_value *pObj) { } return zIn >= zEnd ? 0 : 1; } - } else if(iFlags & MEMOBJ_NULL) { + } else if(iFlags & (MEMOBJ_NULL | MEMOBJ_VOID)) { return 0; } else if(iFlags & MEMOBJ_HASHMAP) { ph7_hashmap *pMap = (ph7_hashmap *)pObj->x.pOther; @@ -374,6 +374,16 @@ PH7_PRIVATE sxi32 PH7_MemObjToBool(ph7_value *pObj) { } return SXRET_OK; } +/* + * Convert a ph7_value to type void.Invalidate any prior representations. + */ +PH7_PRIVATE sxi32 PH7_MemObjToVoid(ph7_value *pObj) { + if((pObj->iFlags & MEMOBJ_VOID) == 0) { +// PH7_MemObjRelease(pObj); + MemObjSetType(pObj, MEMOBJ_VOID); + } + return SXRET_OK; +} /* * Convert a ph7_value to type string.Prior representations are NOT invalidated. */ @@ -512,6 +522,8 @@ PH7_PRIVATE ProcMemObjCast PH7_MemObjCastMethod(sxi32 iFlags) { return PH7_MemObjToHashmap; } else if(iFlags & MEMOBJ_OBJ) { return PH7_MemObjToObject; + } else if(iFlags & MEMOBJ_VOID) { + return PH7_MemObjToVoid; } /* NULL cast */ return PH7_MemObjToNull; @@ -524,7 +536,7 @@ PH7_PRIVATE ProcMemObjCast PH7_MemObjCastMethod(sxi32 iFlags) { PH7_PRIVATE sxi32 PH7_MemObjIsNumeric(ph7_value *pObj) { if(pObj->iFlags & (MEMOBJ_BOOL | MEMOBJ_INT | MEMOBJ_REAL)) { return TRUE; - } else if(pObj->iFlags & (MEMOBJ_NULL | MEMOBJ_HASHMAP | MEMOBJ_OBJ | MEMOBJ_RES)) { + } else if(pObj->iFlags & (MEMOBJ_NULL | MEMOBJ_HASHMAP | MEMOBJ_OBJ | MEMOBJ_RES | MEMOBJ_VOID)) { return FALSE; } else if(pObj->iFlags & MEMOBJ_STRING) { SyString sStr; @@ -554,7 +566,7 @@ PH7_PRIVATE sxi32 PH7_MemObjIsNumeric(ph7_value *pObj) { * OBJECT VALUE MUST NOT BE MODIFIED. */ PH7_PRIVATE sxi32 PH7_MemObjIsEmpty(ph7_value *pObj) { - if(pObj->iFlags & MEMOBJ_NULL) { + if(pObj->iFlags & (MEMOBJ_NULL | MEMOBJ_VOID)) { return TRUE; } else if(pObj->iFlags & MEMOBJ_INT) { return pObj->x.iVal == 0 ? TRUE : FALSE; @@ -596,8 +608,8 @@ PH7_PRIVATE sxi32 PH7_MemObjIsEmpty(ph7_value *pObj) { */ PH7_PRIVATE sxi32 PH7_MemObjToNumeric(ph7_value *pObj) { if(pObj->iFlags & (MEMOBJ_INT | MEMOBJ_REAL | MEMOBJ_BOOL | MEMOBJ_NULL)) { - if(pObj->iFlags & (MEMOBJ_BOOL | MEMOBJ_NULL)) { - if(pObj->iFlags & MEMOBJ_NULL) { + if(pObj->iFlags & (MEMOBJ_BOOL | MEMOBJ_NULL | MEMOBJ_VOID)) { + if(pObj->iFlags & (MEMOBJ_NULL | MEMOBJ_VOID)) { pObj->x.iVal = 0; } MemObjSetType(pObj, MEMOBJ_INT); @@ -691,6 +703,18 @@ PH7_PRIVATE sxi32 PH7_MemObjInitFromReal(ph7_vm *pVm, ph7_value *pObj, ph7_real return SXRET_OK; } /* + * Initialize a ph7_value to the void type. + */ +PH7_PRIVATE sxi32 PH7_MemObjInitFromVoid(ph7_vm *pVm, ph7_value *pObj, ph7_real rVal) { + /* Zero the structure */ + SyZero(pObj, sizeof(ph7_value)); + /* Initialize fields */ + pObj->pVm = pVm; + SyBlobInit(&pObj->sBlob, &pVm->sAllocator); + /* Set the desired type */ + pObj->iFlags = MEMOBJ_VOID; + return SXRET_OK; +}/* * Initialize a ph7_value to the array type. */ PH7_PRIVATE sxi32 PH7_MemObjInitFromArray(ph7_vm *pVm, ph7_value *pObj, ph7_hashmap *pArray) { @@ -1139,6 +1163,8 @@ PH7_PRIVATE const char *PH7_MemObjTypeDump(ph7_value *pVal) { zType = "array(bool, "; } else if(pVal->iFlags & MEMOBJ_RES) { zType = "array(resource, "; + } else if(pVal->iFlags & MEMOBJ_VOID) { + zType = "array(void, "; } } else if(pVal->iFlags & MEMOBJ_OBJ) { zType = "object"; @@ -1152,6 +1178,8 @@ PH7_PRIVATE const char *PH7_MemObjTypeDump(ph7_value *pVal) { zType = "bool"; } else if(pVal->iFlags & MEMOBJ_RES) { zType = "resource"; + } else if(pVal->iFlags & MEMOBJ_VOID) { + zType = "void"; } } return zType; @@ -1192,6 +1220,8 @@ PH7_PRIVATE sxi32 PH7_MemObjDump( } else if(pObj->iFlags & MEMOBJ_OBJ) { /* Dump class instance attributes */ rc = PH7_ClassInstanceDump(&(*pOut), (ph7_class_instance *)pObj->x.pOther, ShowType, nTab + 1, nDepth + 1); + } else if(pObj->iFlags & MEMOBJ_VOID) { + SyBlobAppend(&(*pOut), "NULL", sizeof("NULL")); } else { SyBlob *pContents = &pObj->sBlob; /* Get a printable representation of the contents */ diff --git a/engine/parser.c b/engine/parser.c index 40708d0..c410525 100644 --- a/engine/parser.c +++ b/engine/parser.c @@ -182,6 +182,7 @@ static const ph7_expr_op aOpTable[] = { { {"(float)", sizeof("(float)") - 1 }, EXPR_OP_TYPECAST, 4, EXPR_OP_ASSOC_RIGHT, PH7_OP_CVT_REAL }, { {"(array)", sizeof("(array)") - 1 }, EXPR_OP_TYPECAST, 4, EXPR_OP_ASSOC_RIGHT, PH7_OP_CVT_ARRAY}, { {"(object)", sizeof("(object)") - 1}, EXPR_OP_TYPECAST, 4, EXPR_OP_ASSOC_RIGHT, PH7_OP_CVT_OBJ }, + { {"(void)", sizeof("(void)") - 1 }, EXPR_OP_TYPECAST, 4, EXPR_OP_ASSOC_RIGHT, PH7_OP_CVT_VOID }, /* Binary operators */ /* Precedence 7,left-associative */ { {"instanceof", sizeof("instanceof") - 1}, EXPR_OP_INSTOF, 7, EXPR_OP_NON_ASSOC, PH7_OP_IS_A}, diff --git a/engine/vm.c b/engine/vm.c index a643eeb..de50e7b 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -2266,6 +2266,19 @@ static sxi32 VmByteCodeExec( PH7_MemObjToObject(pTos); } break; + /* + * CVT_VOID: * * * + * + * Force the top of the stack to be a void type. + */ + case PH7_OP_CVT_VOID: +#ifdef UNTRUST + if(pTos < pStack) { + goto Abort; + } +#endif + PH7_MemObjToVoid(pTos); + break; /* * ERR_CTRL * * * * diff --git a/include/ph7int.h b/include/ph7int.h index 50b115d..2f6e5e1 100644 --- a/include/ph7int.h +++ b/include/ph7int.h @@ -1457,6 +1457,7 @@ enum ph7_vm_op { PH7_OP_CVT_NULL, /* NULL cast */ PH7_OP_CVT_ARRAY, /* Array cast */ PH7_OP_CVT_OBJ, /* Object cast */ + PH7_OP_CVT_VOID, /* Void cast */ PH7_OP_CLASS_INIT, /* Class init */ PH7_OP_INTERFACE_INIT,/* Interface init */ PH7_OP_FOREACH_INIT, /* For each init */