Get rid of dirty references. Return a reference & pass-by reference are still working.
The build was successful. Details

This commit is contained in:
Rafal Kupiec 2019-03-29 22:55:49 +01:00
parent a7137316f7
commit 3f205c19ce
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
7 changed files with 55 additions and 563 deletions

View File

@ -794,7 +794,6 @@ static sxi32 PH7_GenStateArrayNodeValidator(ph7_gen_state *pGen, ph7_expr_node *
PH7_PRIVATE sxi32 PH7_CompileArray(ph7_gen_state *pGen, sxi32 iCompileFlag) { PH7_PRIVATE sxi32 PH7_CompileArray(ph7_gen_state *pGen, sxi32 iCompileFlag) {
sxi32(*xValidator)(ph7_gen_state *, ph7_expr_node *); /* Expression tree validator callback */ sxi32(*xValidator)(ph7_gen_state *, ph7_expr_node *); /* Expression tree validator callback */
SyToken *pKey, *pCur; SyToken *pKey, *pCur;
sxi32 iEmitRef = 0;
sxi32 nPair = 0; sxi32 nPair = 0;
sxi32 iNest; sxi32 iNest;
sxi32 rc; sxi32 rc;
@ -862,31 +861,12 @@ PH7_PRIVATE sxi32 PH7_CompileArray(ph7_gen_state *pGen, sxi32 iCompileFlag) {
/* No available key,load NULL */ /* No available key,load NULL */
PH7_VmEmitInstr(pGen->pVm, 0, PH7_OP_LOADC, 0, 0 /* nil index */, 0, 0); PH7_VmEmitInstr(pGen->pVm, 0, PH7_OP_LOADC, 0, 0 /* nil index */, 0, 0);
} }
if(pCur->nType & PH7_TK_AMPER /*'&'*/) {
/* Insertion by reference, [i.e: $a = array(&$x);] */
xValidator = PH7_GenStateArrayNodeValidator; /* Only variable are allowed */
iEmitRef = 1;
pCur++; /* Jump the '&' token */
if(pCur >= pGen->pIn) {
/* Missing value */
rc = PH7_GenCompileError(&(*pGen), E_ERROR, pCur->nLine, "array(): Missing referenced variable");
if(rc == SXERR_ABORT) {
return SXERR_ABORT;
}
return SXRET_OK;
}
}
/* Compile indice value */ /* Compile indice value */
rc = PH7_GenStateCompileArrayEntry(&(*pGen), pCur, pGen->pIn, EXPR_FLAG_RDONLY_LOAD/*Do not create the variable if non-existent*/, xValidator); rc = PH7_GenStateCompileArrayEntry(&(*pGen), pCur, pGen->pIn, EXPR_FLAG_RDONLY_LOAD/*Do not create the variable if non-existent*/, xValidator);
if(rc == SXERR_ABORT) { if(rc == SXERR_ABORT) {
return SXERR_ABORT; return SXERR_ABORT;
} }
if(iEmitRef) {
/* Emit the load reference instruction */
PH7_VmEmitInstr(pGen->pVm, 0, PH7_OP_LOAD_REF, 0, 0, 0, 0);
}
xValidator = 0; xValidator = 0;
iEmitRef = 0;
nPair++; nPair++;
} }
/* Emit the load map instruction */ /* Emit the load map instruction */
@ -5073,21 +5053,6 @@ static sxi32 PH7_GenStateEmitExprCode(
(void)PH7_VmPopInstr(pGen->pVm); (void)PH7_VmPopInstr(pGen->pVm);
} }
} }
} else if(iVmOp == PH7_OP_STORE_REF) {
pInstr = PH7_VmPopInstr(pGen->pVm);
if(pInstr) {
if(pInstr->iOp == PH7_OP_LOAD_IDX) {
/* Array insertion by reference [i.e: $pArray[] =& $some_var; ]
* We have to convert the STORE_REF instruction into STORE_IDX_REF
*/
iVmOp = PH7_OP_STORE_IDX_REF;
iP1 = pInstr->iP1;
iP2 = pInstr->iP2;
p3 = pInstr->p3;
} else {
p3 = pInstr->p3;
}
}
} }
} }
if(iVmOp > 0) { if(iVmOp > 0) {

View File

@ -16,10 +16,6 @@
/* Allowed node types */ /* Allowed node types */
#define HASHMAP_INT_NODE 1 /* Node with an int [i.e: 64-bit integer] key */ #define HASHMAP_INT_NODE 1 /* Node with an int [i.e: 64-bit integer] key */
#define HASHMAP_BLOB_NODE 2 /* Node with a string/BLOB key */ #define HASHMAP_BLOB_NODE 2 /* Node with a string/BLOB key */
/* Node control flags */
#define HASHMAP_NODE_FOREIGN_OBJ 0x001 /* Node hold a reference to a foreign ph7_value
* [i.e: array(&var)/$a[] =& $var ]
*/
/* /*
* Default hash function for int [i.e; 64-bit integer] keys. * Default hash function for int [i.e; 64-bit integer] keys.
*/ */
@ -193,9 +189,7 @@ PH7_PRIVATE void PH7_HashmapUnlinkNode(ph7_hashmap_node *pNode, int bRestore) {
/* Remove the ph7_value associated with this node from the reference table */ /* Remove the ph7_value associated with this node from the reference table */
PH7_VmRefObjRemove(pVm, pNode->nValIdx, 0, pNode); PH7_VmRefObjRemove(pVm, pNode->nValIdx, 0, pNode);
/* Restore to the freelist */ /* Restore to the freelist */
if((pNode->iFlags & HASHMAP_NODE_FOREIGN_OBJ) == 0) { PH7_VmUnsetMemObj(pVm, pNode->nValIdx, FALSE);
PH7_VmUnsetMemObj(pVm, pNode->nValIdx, FALSE);
}
} }
if(pNode->iType == HASHMAP_BLOB_NODE) { if(pNode->iType == HASHMAP_BLOB_NODE) {
SyBlobRelease(&pNode->xKey.sKey); SyBlobRelease(&pNode->xKey.sKey);
@ -271,26 +265,22 @@ static sxi32 HashmapGrowBucket(ph7_hashmap *pMap) {
* Insert a 64-bit integer key and it's associated value (if any) in the given * Insert a 64-bit integer key and it's associated value (if any) in the given
* hashmap. * hashmap.
*/ */
static sxi32 HashmapInsertIntKey(ph7_hashmap *pMap, sxi64 iKey, ph7_value *pValue, sxu32 nRefIdx, int isForeign) { static sxi32 HashmapInsertIntKey(ph7_hashmap *pMap, sxi64 iKey, ph7_value *pValue, sxu32 nRefIdx) {
ph7_hashmap_node *pNode; ph7_hashmap_node *pNode;
sxu32 nIdx; sxu32 nIdx;
sxu32 nHash; sxu32 nHash;
sxi32 rc; sxi32 rc;
if(!isForeign) { ph7_value *pObj;
ph7_value *pObj; /* Reserve a ph7_value for the value */
/* Reserve a ph7_value for the value */ pObj = PH7_ReserveMemObj(pMap->pVm);
pObj = PH7_ReserveMemObj(pMap->pVm); if(pObj == 0) {
if(pObj == 0) { return SXERR_MEM;
return SXERR_MEM;
}
if(pValue) {
/* Duplicate the value */
PH7_MemObjStore(pValue, pObj);
}
nIdx = pObj->nIdx;
} else {
nIdx = nRefIdx;
} }
if(pValue) {
/* Duplicate the value */
PH7_MemObjStore(pValue, pObj);
}
nIdx = pObj->nIdx;
/* Hash the key */ /* Hash the key */
nHash = pMap->xIntHash(iKey); nHash = pMap->xIntHash(iKey);
/* Allocate a new int node */ /* Allocate a new int node */
@ -298,10 +288,6 @@ static sxi32 HashmapInsertIntKey(ph7_hashmap *pMap, sxi64 iKey, ph7_value *pValu
if(pNode == 0) { if(pNode == 0) {
return SXERR_MEM; return SXERR_MEM;
} }
if(isForeign) {
/* Mark as a foregin entry */
pNode->iFlags |= HASHMAP_NODE_FOREIGN_OBJ;
}
/* Make sure the bucket is big enough to hold the new entry */ /* Make sure the bucket is big enough to hold the new entry */
rc = HashmapGrowBucket(&(*pMap)); rc = HashmapGrowBucket(&(*pMap));
if(rc != SXRET_OK) { if(rc != SXRET_OK) {
@ -319,26 +305,22 @@ static sxi32 HashmapInsertIntKey(ph7_hashmap *pMap, sxi64 iKey, ph7_value *pValu
* Insert a BLOB key and it's associated value (if any) in the given * Insert a BLOB key and it's associated value (if any) in the given
* hashmap. * hashmap.
*/ */
static sxi32 HashmapInsertBlobKey(ph7_hashmap *pMap, const void *pKey, sxu32 nKeyLen, ph7_value *pValue, sxu32 nRefIdx, int isForeign) { static sxi32 HashmapInsertBlobKey(ph7_hashmap *pMap, const void *pKey, sxu32 nKeyLen, ph7_value *pValue, sxu32 nRefIdx) {
ph7_hashmap_node *pNode; ph7_hashmap_node *pNode;
sxu32 nHash; sxu32 nHash;
sxu32 nIdx; sxu32 nIdx;
sxi32 rc; sxi32 rc;
if(!isForeign) { ph7_value *pObj;
ph7_value *pObj; /* Reserve a ph7_value for the value */
/* Reserve a ph7_value for the value */ pObj = PH7_ReserveMemObj(pMap->pVm);
pObj = PH7_ReserveMemObj(pMap->pVm); if(pObj == 0) {
if(pObj == 0) { return SXERR_MEM;
return SXERR_MEM;
}
if(pValue) {
/* Duplicate the value */
PH7_MemObjStore(pValue, pObj);
}
nIdx = pObj->nIdx;
} else {
nIdx = nRefIdx;
} }
if(pValue) {
/* Duplicate the value */
PH7_MemObjStore(pValue, pObj);
}
nIdx = pObj->nIdx;
/* Hash the key */ /* Hash the key */
nHash = pMap->xBlobHash(pKey, nKeyLen); nHash = pMap->xBlobHash(pKey, nKeyLen);
/* Allocate a new blob node */ /* Allocate a new blob node */
@ -346,10 +328,6 @@ static sxi32 HashmapInsertBlobKey(ph7_hashmap *pMap, const void *pKey, sxu32 nKe
if(pNode == 0) { if(pNode == 0) {
return SXERR_MEM; return SXERR_MEM;
} }
if(isForeign) {
/* Mark as a foregin entry */
pNode->iFlags |= HASHMAP_NODE_FOREIGN_OBJ;
}
/* Make sure the bucket is big enough to hold the new entry */ /* Make sure the bucket is big enough to hold the new entry */
rc = HashmapGrowBucket(&(*pMap)); rc = HashmapGrowBucket(&(*pMap));
if(rc != SXRET_OK) { if(rc != SXRET_OK) {
@ -553,7 +531,7 @@ static sxi32 HashmapInsert(
return SXRET_OK; return SXRET_OK;
} }
/* Perform a blob-key insertion */ /* Perform a blob-key insertion */
rc = HashmapInsertBlobKey(&(*pMap), SyBlobData(&pKey->sBlob), SyBlobLength(&pKey->sBlob), &(*pVal), 0, FALSE); rc = HashmapInsertBlobKey(&(*pMap), SyBlobData(&pKey->sBlob), SyBlobLength(&pKey->sBlob), &(*pVal), 0);
return rc; return rc;
} }
IntKey: IntKey:
@ -577,7 +555,7 @@ IntKey:
return SXRET_OK; return SXRET_OK;
} }
/* Perform a 64-bit-int-key insertion */ /* Perform a 64-bit-int-key insertion */
rc = HashmapInsertIntKey(&(*pMap), pKey->x.iVal, &(*pVal), 0, FALSE); rc = HashmapInsertIntKey(&(*pMap), pKey->x.iVal, &(*pVal), 0);
if(rc == SXRET_OK) { if(rc == SXRET_OK) {
if(pKey->x.iVal >= pMap->iNextIdx) { if(pKey->x.iVal >= pMap->iNextIdx) {
/* Increment the automatic index */ /* Increment the automatic index */
@ -590,102 +568,7 @@ IntKey:
} }
} else { } else {
/* Assign an automatic index */ /* Assign an automatic index */
rc = HashmapInsertIntKey(&(*pMap), pMap->iNextIdx, &(*pVal), 0, FALSE); rc = HashmapInsertIntKey(&(*pMap), pMap->iNextIdx, &(*pVal), 0);
if(rc == SXRET_OK) {
++pMap->iNextIdx;
}
}
/* Insertion result */
return rc;
}
/*
* Insert a given key and it's associated value (foreign index) in the given
* hashmap.
* This is insertion by reference so be careful to mark the node
* with the HASHMAP_NODE_FOREIGN_OBJ flag being set.
* The insertion by reference is triggered when the following
* expression is encountered.
* $var = 10;
* $a = array(&var);
* OR
* $a[] =& $var;
* That is,$var is a foreign ph7_value and the $a array have no control
* over it's contents.
* Note that the node that hold the foreign ph7_value is automatically
* removed when the foreign ph7_value is unset.
* Example:
* $var = 10;
* $a[] =& $var;
* echo count($a).PHP_EOL; //1
* //Unset the foreign ph7_value now
* unset($var);
* echo count($a); //0
* Note that this is a PH7 eXtension.
* Refer to the official documentation for more information.
* If a node with the given key already exists in the database
* then this function overwrite the old value.
*/
static sxi32 HashmapInsertByRef(
ph7_hashmap *pMap, /* Target hashmap */
ph7_value *pKey, /* Lookup key */
sxu32 nRefIdx /* Foreign ph7_value index */
) {
ph7_hashmap_node *pNode = 0;
sxi32 rc = SXRET_OK;
if(pKey && pKey->iFlags & (MEMOBJ_STRING | MEMOBJ_HASHMAP | MEMOBJ_OBJ | MEMOBJ_RES)) {
if((pKey->iFlags & MEMOBJ_STRING) == 0) {
/* Force a string cast */
PH7_MemObjToString(&(*pKey));
}
if(SyBlobLength(&pKey->sBlob) < 1 || HashmapIsIntKey(&pKey->sBlob)) {
if(SyBlobLength(&pKey->sBlob) < 1) {
/* Automatic index assign */
pKey = 0;
}
goto IntKey;
}
if(SXRET_OK == HashmapLookupBlobKey(&(*pMap), SyBlobData(&pKey->sBlob),
SyBlobLength(&pKey->sBlob), &pNode)) {
/* Overwrite */
PH7_VmRefObjRemove(pMap->pVm, pNode->nValIdx, 0, pNode);
pNode->nValIdx = nRefIdx;
/* Install in the reference table */
PH7_VmRefObjInstall(pMap->pVm, nRefIdx, 0, pNode, 0);
return SXRET_OK;
}
/* Perform a blob-key insertion */
rc = HashmapInsertBlobKey(&(*pMap), SyBlobData(&pKey->sBlob), SyBlobLength(&pKey->sBlob), 0, nRefIdx, TRUE);
return rc;
}
IntKey:
if(pKey) {
if((pKey->iFlags & MEMOBJ_INT) == 0) {
/* Force an integer cast */
PH7_MemObjToInteger(pKey);
}
if(SXRET_OK == HashmapLookupIntKey(&(*pMap), pKey->x.iVal, &pNode)) {
/* Overwrite */
PH7_VmRefObjRemove(pMap->pVm, pNode->nValIdx, 0, pNode);
pNode->nValIdx = nRefIdx;
/* Install in the reference table */
PH7_VmRefObjInstall(pMap->pVm, nRefIdx, 0, pNode, 0);
return SXRET_OK;
}
/* Perform a 64-bit-int-key insertion */
rc = HashmapInsertIntKey(&(*pMap), pKey->x.iVal, 0, nRefIdx, TRUE);
if(rc == SXRET_OK) {
if(pKey->x.iVal >= pMap->iNextIdx) {
/* Increment the automatic index */
pMap->iNextIdx = pKey->x.iVal + 1;
/* Make sure the automatic index is not reserved */
while(SXRET_OK == HashmapLookupIntKey(&(*pMap), pMap->iNextIdx, 0)) {
pMap->iNextIdx++;
}
}
}
} else {
/* Assign an automatic index */
rc = HashmapInsertIntKey(&(*pMap), pMap->iNextIdx, 0, nRefIdx, TRUE);
if(rc == SXRET_OK) { if(rc == SXRET_OK) {
++pMap->iNextIdx; ++pMap->iNextIdx;
} }
@ -693,6 +576,7 @@ IntKey:
/* Insertion result */ /* Insertion result */
return rc; return rc;
} }
/* /*
* Extract node value. * Extract node value.
*/ */
@ -722,12 +606,12 @@ static sxi32 HashmapInsertNode(ph7_hashmap *pMap, ph7_hashmap_node *pNode, int b
/* Assign an automatic index */ /* Assign an automatic index */
rc = HashmapInsert(&(*pMap), 0, pObj); rc = HashmapInsert(&(*pMap), 0, pObj);
} else { } else {
rc = HashmapInsertIntKey(&(*pMap), pNode->xKey.iKey, pObj, 0, FALSE); rc = HashmapInsertIntKey(&(*pMap), pNode->xKey.iKey, pObj, 0);
} }
} else { } else {
/* Blob key */ /* Blob key */
rc = HashmapInsertBlobKey(&(*pMap), SyBlobData(&pNode->xKey.sKey), rc = HashmapInsertBlobKey(&(*pMap), SyBlobData(&pNode->xKey.sKey),
SyBlobLength(&pNode->xKey.sKey), pObj, 0, FALSE); SyBlobLength(&pNode->xKey.sKey), pObj, 0);
} }
return rc; return rc;
} }
@ -821,8 +705,8 @@ static int HashmapFindValue(
pVal = HashmapExtractNodeValue(pEntry); pVal = HashmapExtractNodeValue(pEntry);
if(pVal) { if(pVal) {
if((pVal->iFlags | pNeedle->iFlags) & MEMOBJ_NULL) { if((pVal->iFlags | pNeedle->iFlags) & MEMOBJ_NULL) {
sxi32 iF1 = pVal->iFlags & ~MEMOBJ_AUX; sxi32 iF1 = pVal->iFlags;
sxi32 iF2 = pNeedle->iFlags & ~MEMOBJ_AUX; sxi32 iF2 = pNeedle->iFlags;
if(iF1 == iF2) { if(iF1 == iF2) {
/* NULL values are equals */ /* NULL values are equals */
if(ppNode) { if(ppNode) {
@ -1144,7 +1028,7 @@ PH7_PRIVATE sxi32 PH7_HashmapDup(ph7_hashmap *pSrc, ph7_hashmap *pDest) {
PH7_MemObjRelease(&sKey); PH7_MemObjRelease(&sKey);
} else { } else {
/* Int key insertion */ /* Int key insertion */
rc = HashmapInsertIntKey(&(*pDest), pEntry->xKey.iKey, pVal, 0, FALSE); rc = HashmapInsertIntKey(&(*pDest), pEntry->xKey.iKey, pVal, 0);
} }
if(rc != SXRET_OK) { if(rc != SXRET_OK) {
return rc; return rc;
@ -1214,7 +1098,7 @@ PH7_PRIVATE sxi32 PH7_HashmapUnion(ph7_hashmap *pLeft, ph7_hashmap *pRight) {
if(pObj) { if(pObj) {
/* Perform the insertion */ /* Perform the insertion */
rc = HashmapInsertBlobKey(&(*pLeft), SyBlobData(&pEntry->xKey.sKey), SyBlobLength(&pEntry->xKey.sKey), rc = HashmapInsertBlobKey(&(*pLeft), SyBlobData(&pEntry->xKey.sKey), SyBlobLength(&pEntry->xKey.sKey),
pObj, 0, FALSE); pObj, 0);
if(rc != SXRET_OK) { if(rc != SXRET_OK) {
return rc; return rc;
} }
@ -1226,7 +1110,7 @@ PH7_PRIVATE sxi32 PH7_HashmapUnion(ph7_hashmap *pLeft, ph7_hashmap *pRight) {
pObj = HashmapExtractNodeValue(pEntry); pObj = HashmapExtractNodeValue(pEntry);
if(pObj) { if(pObj) {
/* Perform the insertion */ /* Perform the insertion */
rc = HashmapInsertIntKey(&(*pLeft), pEntry->xKey.iKey, pObj, 0, FALSE); rc = HashmapInsertIntKey(&(*pLeft), pEntry->xKey.iKey, pObj, 0);
if(rc != SXRET_OK) { if(rc != SXRET_OK) {
return rc; return rc;
} }
@ -1345,10 +1229,8 @@ PH7_PRIVATE sxi32 PH7_HashmapRelease(ph7_hashmap *pMap, int FreeDS) {
pNext = pEntry->pPrev; /* Reverse link */ pNext = pEntry->pPrev; /* Reverse link */
/* Remove the reference from the foreign table */ /* Remove the reference from the foreign table */
PH7_VmRefObjRemove(pVm, pEntry->nValIdx, 0, pEntry); PH7_VmRefObjRemove(pVm, pEntry->nValIdx, 0, pEntry);
if((pEntry->iFlags & HASHMAP_NODE_FOREIGN_OBJ) == 0) { /* Restore the ph7_value to the free list */
/* Restore the ph7_value to the free list */ PH7_VmUnsetMemObj(pVm, pEntry->nValIdx, FALSE);
PH7_VmUnsetMemObj(pVm, pEntry->nValIdx, FALSE);
}
/* Release the node */ /* Release the node */
if(pEntry->iType == HASHMAP_BLOB_NODE) { if(pEntry->iType == HASHMAP_BLOB_NODE) {
SyBlobRelease(&pEntry->xKey.sKey); SyBlobRelease(&pEntry->xKey.sKey);
@ -1419,40 +1301,7 @@ PH7_PRIVATE sxi32 PH7_HashmapInsert(
) { ) {
return HashmapInsert(&(*pMap), &(*pKey), &(*pVal)); return HashmapInsert(&(*pMap), &(*pKey), &(*pVal));
} }
/*
* Insert a given key and it's associated value (foreign index) in the given
* hashmap.
* This is insertion by reference so be careful to mark the node
* with the HASHMAP_NODE_FOREIGN_OBJ flag being set.
* The insertion by reference is triggered when the following
* expression is encountered.
* $var = 10;
* $a = array(&var);
* OR
* $a[] =& $var;
* That is,$var is a foreign ph7_value and the $a array have no control
* over it's contents.
* Note that the node that hold the foreign ph7_value is automatically
* removed when the foreign ph7_value is unset.
* Example:
* $var = 10;
* $a[] =& $var;
* echo count($a).PHP_EOL; //1
* //Unset the foreign ph7_value now
* unset($var);
* echo count($a); //0
* Note that this is a PH7 eXtension.
* Refer to the official documentation for more information.
* If a node with the given key already exists in the database
* then this function overwrite the old value.
*/
PH7_PRIVATE sxi32 PH7_HashmapInsertByRef(
ph7_hashmap *pMap, /* Target hashmap */
ph7_value *pKey, /* Lookup key */
sxu32 nRefIdx /* Foreign ph7_value index */
) {
return HashmapInsertByRef(&(*pMap), &(*pKey), nRefIdx);
}
/* /*
* Reset the node cursor of a given hashmap. * Reset the node cursor of a given hashmap.
*/ */
@ -5500,7 +5349,6 @@ PH7_PRIVATE sxi32 PH7_HashmapDump(SyBlob *pOut, ph7_hashmap *pMap, int ShowType,
ph7_hashmap_node *pEntry; ph7_hashmap_node *pEntry;
ph7_value *pObj; ph7_value *pObj;
sxu32 n = 0; sxu32 n = 0;
int isRef;
sxi32 rc; sxi32 rc;
int i; int i;
if(nDepth > 31) { if(nDepth > 31) {
@ -5547,13 +5395,8 @@ PH7_PRIVATE sxi32 PH7_HashmapDump(SyBlob *pOut, ph7_hashmap *pMap, int ShowType,
#endif #endif
/* Dump node value */ /* Dump node value */
pObj = HashmapExtractNodeValue(pEntry); pObj = HashmapExtractNodeValue(pEntry);
isRef = 0;
if(pObj) { if(pObj) {
if(pEntry->iFlags & HASHMAP_NODE_FOREIGN_OBJ) { rc = PH7_MemObjDump(&(*pOut), pObj, ShowType, nTab + 1, nDepth);
/* Referenced object */
isRef = 1;
}
rc = PH7_MemObjDump(&(*pOut), pObj, ShowType, nTab + 1, nDepth, isRef);
if(rc == SXERR_LIMIT) { if(rc == SXERR_LIMIT) {
break; break;
} }

View File

@ -812,7 +812,6 @@ PH7_PRIVATE sxi32 PH7_MemObjStore(ph7_value *pSrc, ph7_value *pDest) {
pObj = (ph7_class_instance *)pDest->x.pOther; pObj = (ph7_class_instance *)pDest->x.pOther;
} }
SyMemcpy((const void *) & (*pSrc), &(*pDest), sizeof(ph7_value) - (sizeof(ph7_vm *) + sizeof(SyBlob) + sizeof(sxu32))); SyMemcpy((const void *) & (*pSrc), &(*pDest), sizeof(ph7_value) - (sizeof(ph7_vm *) + sizeof(SyBlob) + sizeof(sxu32)));
pDest->iFlags &= ~MEMOBJ_AUX;
rc = SXRET_OK; rc = SXRET_OK;
if(SyBlobLength(&pSrc->sBlob) > 0) { if(SyBlobLength(&pSrc->sBlob) > 0) {
SyBlobReset(&pDest->sBlob); SyBlobReset(&pDest->sBlob);
@ -931,8 +930,8 @@ PH7_PRIVATE sxi32 PH7_MemObjCmp(ph7_value *pObj1, ph7_value *pObj2, int bStrict,
if(bStrict) { if(bStrict) {
sxi32 iF1, iF2; sxi32 iF1, iF2;
/* Strict comparisons with === */ /* Strict comparisons with === */
iF1 = pObj1->iFlags & ~MEMOBJ_AUX; iF1 = pObj1->iFlags;
iF2 = pObj2->iFlags & ~MEMOBJ_AUX; iF2 = pObj2->iFlags;
if(iF1 != iF2) { if(iF1 != iF2) {
/* Not of the same type */ /* Not of the same type */
return 1; return 1;
@ -1206,8 +1205,7 @@ PH7_PRIVATE sxi32 PH7_MemObjDump(
ph7_value *pObj, /* Dump this */ ph7_value *pObj, /* Dump this */
int ShowType, /* TRUE to output value type */ int ShowType, /* TRUE to output value type */
int nTab, /* # of Whitespace to insert */ int nTab, /* # of Whitespace to insert */
int nDepth, /* Nesting level */ int nDepth /* Nesting level */
int isRef /* TRUE if referenced object */
) { ) {
sxi32 rc = SXRET_OK; sxi32 rc = SXRET_OK;
const char *zType; const char *zType;
@ -1216,9 +1214,6 @@ PH7_PRIVATE sxi32 PH7_MemObjDump(
SyBlobAppend(&(*pOut), " ", sizeof(char)); SyBlobAppend(&(*pOut), " ", sizeof(char));
} }
if(ShowType) { if(ShowType) {
if(isRef) {
SyBlobAppend(&(*pOut), "&", sizeof(char));
}
/* Get value type first */ /* Get value type first */
zType = PH7_MemObjTypeDump(pObj); zType = PH7_MemObjTypeDump(pObj);
SyBlobAppend(&(*pOut), zType, SyStrlen(zType)); SyBlobAppend(&(*pOut), zType, SyStrlen(zType));

View File

@ -929,7 +929,7 @@ PH7_PRIVATE sxi32 PH7_ClassInstanceDump(SyBlob *pOut, ph7_class_instance *pThis,
#else #else
SyBlobAppend(&(*pOut), "\n", sizeof(char)); SyBlobAppend(&(*pOut), "\n", sizeof(char));
#endif #endif
rc = PH7_MemObjDump(&(*pOut), pValue, ShowType, nTab + 1, nDepth, 0); rc = PH7_MemObjDump(&(*pOut), pValue, ShowType, nTab + 1, nDepth);
if(rc == SXERR_LIMIT) { if(rc == SXERR_LIMIT) {
break; break;
} }

View File

@ -209,8 +209,6 @@ static const ph7_expr_op aOpTable[] = {
{ {"!==", sizeof(char) * 3}, EXPR_OP_TNE, 11, EXPR_OP_NON_ASSOC, PH7_OP_TNE}, { {"!==", sizeof(char) * 3}, EXPR_OP_TNE, 11, EXPR_OP_NON_ASSOC, PH7_OP_TNE},
/* Precedence 12,left-associative */ /* Precedence 12,left-associative */
{ {"&", sizeof(char)}, EXPR_OP_BAND, 12, EXPR_OP_ASSOC_LEFT, PH7_OP_BAND}, { {"&", sizeof(char)}, EXPR_OP_BAND, 12, EXPR_OP_ASSOC_LEFT, PH7_OP_BAND},
/* Precedence 12,left-associative */
{ {"=&", sizeof(char) * 2}, EXPR_OP_REF, 12, EXPR_OP_ASSOC_LEFT, PH7_OP_STORE_REF},
/* Binary operators */ /* Binary operators */
/* Precedence 13,left-associative */ /* Precedence 13,left-associative */
{ {"^", sizeof(char)}, EXPR_OP_XOR, 13, EXPR_OP_ASSOC_LEFT, PH7_OP_BXOR}, { {"^", sizeof(char)}, EXPR_OP_XOR, 13, EXPR_OP_ASSOC_LEFT, PH7_OP_BXOR},
@ -859,13 +857,6 @@ static sxi32 ExprProcessFuncArguments(ph7_gen_state *pGen, ph7_expr_node *pOp, p
iCur++; iCur++;
} }
if(iCur > iNode) { if(iCur > iNode) {
if(apNode[iNode] && (apNode[iNode]->pStart->nType & PH7_TK_AMPER /*'&'*/) && ((iCur - iNode) == 2)
&& apNode[iNode + 1]->xCode == PH7_CompileVariable) {
PH7_GenCompileError(&(*pGen), E_WARNING, apNode[iNode]->pStart->nLine,
"call-time pass-by-reference is deprecated");
ExprFreeTree(&(*pGen), apNode[iNode]);
apNode[iNode] = 0;
}
ExprMakeTree(&(*pGen), &apNode[iNode], iCur - iNode); ExprMakeTree(&(*pGen), &apNode[iNode], iCur - iNode);
if(apNode[iNode]) { if(apNode[iNode]) {
/* Put a pointer to the root of the tree in the arguments set */ /* Put a pointer to the root of the tree in the arguments set */

View File

@ -1324,24 +1324,6 @@ PH7_PRIVATE ph7_value *PH7_ReserveMemObj(ph7_vm *pVm) {
pObj->nIdx = nIdx; pObj->nIdx = nIdx;
return pObj; return pObj;
} }
/*
* Insert an entry by reference (not copy) in the given hashmap.
*/
static sxi32 VmHashmapRefInsert(
ph7_hashmap *pMap, /* Target hashmap */
const char *zKey, /* Entry key */
sxu32 nByte, /* Key length */
sxu32 nRefIdx /* Entry index in the object pool */
) {
ph7_value sKey;
sxi32 rc;
PH7_MemObjInitFromString(pMap->pVm, &sKey, 0);
PH7_MemObjStringAppend(&sKey, zKey, nByte);
/* Perform the insertion */
rc = PH7_HashmapInsertByRef(&(*pMap), &sKey, nRefIdx);
PH7_MemObjRelease(&sKey);
return rc;
}
/* /*
* Extract a variable value from the top active VM frame. * Extract a variable value from the top active VM frame.
* Return a pointer to the variable value on success. * Return a pointer to the variable value on success.
@ -2492,26 +2474,14 @@ static sxi32 VmByteCodeExec(
iFlags = pEntry[1].iFlags; /* Save the type of value */ iFlags = pEntry[1].iFlags; /* Save the type of value */
/* Perform the insertion */ /* Perform the insertion */
while(pEntry < pTos) { while(pEntry < pTos) {
if(pEntry[1].iFlags & MEMOBJ_REFERENCE) { /* Standard insertion */
/* Insertion by reference */ PH7_HashmapInsert(pMap,
PH7_HashmapInsertByRef(pMap, (pEntry->iFlags & MEMOBJ_NULL) ? 0 /* Automatic index assign */ : pEntry,
(pEntry->iFlags & MEMOBJ_NULL) ? 0 /* Automatic index assign */ : pEntry, &pEntry[1]
(sxu32)pEntry[1].x.iVal );
);
} else {
/* Standard insertion */
PH7_HashmapInsert(pMap,
(pEntry->iFlags & MEMOBJ_NULL) ? 0 /* Automatic index assign */ : pEntry,
&pEntry[1]
);
}
/* Set the proper type of array */ /* Set the proper type of array */
if((iFlags & MEMOBJ_MIXED) == 0) { if((iFlags & MEMOBJ_MIXED) == 0) {
if(pEntry[1].iFlags & MEMOBJ_REFERENCE) { pFlags = pEntry[1].iFlags;
pFlags = pEntry[1].iFlags ^ MEMOBJ_REFERENCE;
} else {
pFlags = pEntry[1].iFlags;
}
if(iFlags != pFlags && iFlags != (pFlags ^ MEMOBJ_HASHMAP)) { if(iFlags != pFlags && iFlags != (pFlags ^ MEMOBJ_HASHMAP)) {
iFlags = MEMOBJ_MIXED; iFlags = MEMOBJ_MIXED;
} }
@ -2801,12 +2771,10 @@ static sxi32 VmByteCodeExec(
} }
/* /*
* STORE_IDX: P1 * P3 * STORE_IDX: P1 * P3
* STORE_IDX_R: P1 * P3
* *
* Perfrom a store operation an a hashmap entry. * Perfrom a store operation an a hashmap entry.
*/ */
case PH7_OP_STORE_IDX: case PH7_OP_STORE_IDX: {
case PH7_OP_STORE_IDX_REF: {
ph7_hashmap *pMap = 0; /* cc warning */ ph7_hashmap *pMap = 0; /* cc warning */
ph7_value *pKey; ph7_value *pKey;
sxu32 nIdx; sxu32 nIdx;
@ -2836,7 +2804,7 @@ static sxi32 VmByteCodeExec(
break; break;
} }
/* Phase#1: Load the array */ /* Phase#1: Load the array */
if((pObj->iFlags & MEMOBJ_STRING) && (pInstr->iOp != PH7_OP_STORE_IDX_REF)) { if(pObj->iFlags & MEMOBJ_STRING) {
VmPopOperand(&pTos, 1); VmPopOperand(&pTos, 1);
if((pTos->iFlags & MEMOBJ_STRING) == 0) { if((pTos->iFlags & MEMOBJ_STRING) == 0) {
/* Force a string cast */ /* Force a string cast */
@ -2880,12 +2848,7 @@ static sxi32 VmByteCodeExec(
} }
VmPopOperand(&pTos, 1); VmPopOperand(&pTos, 1);
/* Phase#2: Perform the insertion */ /* Phase#2: Perform the insertion */
if(pInstr->iOp == PH7_OP_STORE_IDX_REF && pTos->nIdx != SXU32_HIGH) { PH7_HashmapInsert(pMap, pKey, pTos);
/* Insertion by reference */
PH7_HashmapInsertByRef(pMap, pKey, pTos->nIdx);
} else {
PH7_HashmapInsert(pMap, pKey, pTos);
}
if(pKey) { if(pKey) {
PH7_MemObjRelease(pKey); PH7_MemObjRelease(pKey);
} }
@ -3958,96 +3921,6 @@ static sxi32 VmByteCodeExec(
} }
break; break;
} }
/*
* OP_LOAD_REF * * *
* Push the index of a referenced object on the stack.
*/
case PH7_OP_LOAD_REF: {
sxu32 nIdx;
#ifdef UNTRUST
if(pTos < pStack) {
goto Abort;
}
#endif
/* Extract memory object index */
nIdx = pTos->nIdx;
if(nIdx != SXU32_HIGH /* Not a constant */) {
/* Nullify the object */
PH7_MemObjRelease(pTos);
/* Mark as constant and store the index on the top of the stack */
pTos->x.iVal = (sxi64)nIdx;
pTos->nIdx = SXU32_HIGH;
pTos->iFlags = MEMOBJ_INT | MEMOBJ_REFERENCE;
}
break;
}
/*
* OP_STORE_REF * * P3
* Perform an assignment operation by reference.
*/
case PH7_OP_STORE_REF: {
SyString sName = { 0, 0 };
SyHashEntry *pEntry;
sxu32 nIdx;
#ifdef UNTRUST
if(pTos < pStack) {
goto Abort;
}
#endif
if(pInstr->p3 == 0) {
char *zName;
/* Take the variable name from the Next on the stack */
if((pTos->iFlags & MEMOBJ_STRING) == 0) {
/* Force a string cast */
PH7_MemObjToString(pTos);
}
if(SyBlobLength(&pTos->sBlob) > 0) {
zName = SyMemBackendStrDup(&pVm->sAllocator,
(const char *)SyBlobData(&pTos->sBlob), SyBlobLength(&pTos->sBlob));
if(zName) {
SyStringInitFromBuf(&sName, zName, SyBlobLength(&pTos->sBlob));
}
}
PH7_MemObjRelease(pTos);
pTos--;
} else {
SyStringInitFromBuf(&sName, pInstr->p3, SyStrlen((const char *)pInstr->p3));
}
nIdx = pTos->nIdx;
if(nIdx == SXU32_HIGH) {
if((pTos->iFlags & (MEMOBJ_OBJ | MEMOBJ_HASHMAP | MEMOBJ_RES)) == 0) {
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR,
"Reference operator require a variable not a constant as it's right operand");
} else {
ph7_value *pObj;
/* Extract the desired variable and if not available dynamically create it */
pObj = VmExtractMemObj(&(*pVm), &sName, FALSE, TRUE);
if(pObj == 0) {
PH7_VmMemoryError(&(*pVm));
}
/* Perform the store operation */
PH7_MemObjStore(pTos, pObj);
pTos->nIdx = pObj->nIdx;
}
} else if(sName.nByte > 0) {
VmFrame *pFrame = pVm->pFrame;
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
/* Safely ignore the exception frame */
pFrame = pFrame->pParent;
}
/* Query the local frame */
pEntry = SyHashGet(&pFrame->hVar, (const void *)sName.zString, sName.nByte);
if(pEntry) {
rc = SyHashInsert(&pFrame->hVar, (const void *)sName.zString, sName.nByte, SX_INT_TO_PTR(nIdx));
if(rc == SXRET_OK) {
PH7_VmRefObjInstall(&(*pVm), nIdx, SyHashLastEntry(&pFrame->hVar), 0, 0);
}
} else {
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Referenced variable name '%z' does not exists", &sName);
}
}
break;
}
/* /*
* OP_LOAD_EXCEPTION * P2 P3 * OP_LOAD_EXCEPTION * P2 P3
* Push an exception in the corresponding container so that * Push an exception in the corresponding container so that
@ -5668,9 +5541,6 @@ static const char *VmInstrToString(sxi32 nOp) {
case PH7_OP_STORE_IDX: case PH7_OP_STORE_IDX:
zOp = "STORE_IDX"; zOp = "STORE_IDX";
break; break;
case PH7_OP_STORE_IDX_REF:
zOp = "STORE_IDX_R";
break;
case PH7_OP_PULL: case PH7_OP_PULL:
zOp = "PULL"; zOp = "PULL";
break; break;
@ -5734,12 +5604,6 @@ static const char *VmInstrToString(sxi32 nOp) {
case PH7_OP_CONSUME: case PH7_OP_CONSUME:
zOp = "CONSUME"; zOp = "CONSUME";
break; break;
case PH7_OP_LOAD_REF:
zOp = "LOAD_REF";
break;
case PH7_OP_STORE_REF:
zOp = "STORE_REF";
break;
case PH7_OP_MEMBER: case PH7_OP_MEMBER:
zOp = "MEMBER"; zOp = "MEMBER";
break; break;
@ -5812,163 +5676,6 @@ PH7_PRIVATE void PH7_VmExpandConstantValue(ph7_value *pVal, void *pUserData) {
* Status: * Status:
* Stable. * Stable.
*/ */
/*
* int func_num_args(void)
* Returns the number of arguments passed to the function.
* Parameters
* None.
* Return
* Total number of arguments passed into the current user-defined function
* or -1 if called from the globe scope.
*/
static int vm_builtin_func_num_args(ph7_context *pCtx, int nArg, ph7_value **apArg) {
VmFrame *pFrame;
ph7_vm *pVm;
/* Point to the target VM */
pVm = pCtx->pVm;
/* Current frame */
pFrame = pVm->pFrame;
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
/* Safely ignore the exception frame */
pFrame = pFrame->pParent;
}
if(pFrame->pParent == 0) {
SXUNUSED(nArg);
SXUNUSED(apArg);
/* Global frame,return -1 */
ph7_result_int(pCtx, -1);
return SXRET_OK;
}
/* Total number of arguments passed to the enclosing function */
nArg = (int)SySetUsed(&pFrame->sArg);
ph7_result_int(pCtx, nArg);
return SXRET_OK;
}
/*
* value func_get_arg(int $arg_num)
* Return an item from the argument list.
* Parameters
* Argument number(index start from zero).
* Return
* Returns the specified argument or FALSE on error.
*/
static int vm_builtin_func_get_arg(ph7_context *pCtx, int nArg, ph7_value **apArg) {
ph7_value *pObj = 0;
VmSlot *pSlot = 0;
VmFrame *pFrame;
ph7_vm *pVm;
/* Point to the target VM */
pVm = pCtx->pVm;
/* Current frame */
pFrame = pVm->pFrame;
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
/* Safely ignore the exception frame */
pFrame = pFrame->pParent;
}
/* Extract the desired index */
nArg = ph7_value_to_int(apArg[0]);
if(nArg < 0 || nArg >= (int)SySetUsed(&pFrame->sArg)) {
/* Invalid index,return FALSE */
ph7_result_bool(pCtx, 0);
return SXRET_OK;
}
/* Extract the desired argument */
if((pSlot = (VmSlot *)SySetAt(&pFrame->sArg, (sxu32)nArg)) != 0) {
if((pObj = (ph7_value *)SySetAt(&pVm->aMemObj, pSlot->nIdx)) != 0) {
/* Return the desired argument */
ph7_result_value(pCtx, (ph7_value *)pObj);
} else {
/* No such argument,return false */
ph7_result_bool(pCtx, 0);
}
} else {
/* CAN'T HAPPEN */
ph7_result_bool(pCtx, 0);
}
return SXRET_OK;
}
/*
* array func_get_args_byref(void)
* Returns an array comprising a function's argument list.
* Parameters
* None.
* Return
* Returns an array in which each element is a POINTER to the corresponding
* member of the current user-defined function's argument list.
* Otherwise FALSE is returned on failure.
* NOTE:
* Arguments are returned to the array by reference.
*/
static int vm_builtin_func_get_args_byref(ph7_context *pCtx, int nArg, ph7_value **apArg) {
ph7_value *pArray;
VmFrame *pFrame;
VmSlot *aSlot;
sxu32 n;
/* Point to the current frame */
pFrame = pCtx->pVm->pFrame;
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
/* Safely ignore the exception frame */
pFrame = pFrame->pParent;
}
/* Create a new array */
pArray = ph7_context_new_array(pCtx);
if(pArray == 0) {
SXUNUSED(nArg); /* cc warning */
SXUNUSED(apArg);
ph7_result_bool(pCtx, 0);
return SXRET_OK;
}
/* Start filling the array with the given arguments (Pass by reference) */
aSlot = (VmSlot *)SySetBasePtr(&pFrame->sArg);
for(n = 0; n < SySetUsed(&pFrame->sArg) ; n++) {
PH7_HashmapInsertByRef((ph7_hashmap *)pArray->x.pOther, 0/*Automatic index assign*/, aSlot[n].nIdx);
}
/* Return the freshly created array */
ph7_result_value(pCtx, pArray);
return SXRET_OK;
}
/*
* array func_get_args(void)
* Returns an array comprising a copy of function's argument list.
* Parameters
* None.
* Return
* Returns an array in which each element is a copy of the corresponding
* member of the current user-defined function's argument list.
* Otherwise FALSE is returned on failure.
*/
static int vm_builtin_func_get_args(ph7_context *pCtx, int nArg, ph7_value **apArg) {
ph7_value *pObj = 0;
ph7_value *pArray;
VmFrame *pFrame;
VmSlot *aSlot;
sxu32 n;
/* Point to the current frame */
pFrame = pCtx->pVm->pFrame;
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
/* Safely ignore the exception frame */
pFrame = pFrame->pParent;
}
/* Create a new array */
pArray = ph7_context_new_array(pCtx);
if(pArray == 0) {
SXUNUSED(nArg); /* cc warning */
SXUNUSED(apArg);
ph7_result_bool(pCtx, 0);
return SXRET_OK;
}
/* Start filling the array with the given arguments */
aSlot = (VmSlot *)SySetBasePtr(&pFrame->sArg);
for(n = 0; n < SySetUsed(&pFrame->sArg) ; n++) {
pObj = (ph7_value *)SySetAt(&pCtx->pVm->aMemObj, aSlot[n].nIdx);
if(pObj) {
ph7_array_add_elem(pArray, 0/* Automatic index assign*/, pObj);
}
}
/* Return the freshly created array */
ph7_result_value(pCtx, pArray);
return SXRET_OK;
}
/* /*
* bool function_exists(string $name) * bool function_exists(string $name)
* Return TRUE if the given function has been defined. * Return TRUE if the given function has been defined.
@ -8491,7 +8198,7 @@ static int vm_builtin_var_dump(ph7_context *pCtx, int nArg, ph7_value **apArg) {
/* Reset the working buffer */ /* Reset the working buffer */
SyBlobReset(&sDump); SyBlobReset(&sDump);
/* Dump the given expression */ /* Dump the given expression */
PH7_MemObjDump(&sDump, pObj, TRUE, 0, 0, 0); PH7_MemObjDump(&sDump, pObj, TRUE, 0, 0);
/* Output */ /* Output */
if(SyBlobLength(&sDump) > 0) { if(SyBlobLength(&sDump) > 0) {
ph7_context_output(pCtx, (const char *)SyBlobData(&sDump), (int)SyBlobLength(&sDump)); ph7_context_output(pCtx, (const char *)SyBlobData(&sDump), (int)SyBlobLength(&sDump));
@ -8527,7 +8234,7 @@ static int vm_builtin_print_r(ph7_context *pCtx, int nArg, ph7_value **apArg) {
ret_string = ph7_value_to_bool(apArg[1]); ret_string = ph7_value_to_bool(apArg[1]);
} }
/* Generate dump */ /* Generate dump */
PH7_MemObjDump(&sDump, apArg[0], FALSE, 0, 0, 0); PH7_MemObjDump(&sDump, apArg[0], FALSE, 0, 0);
if(!ret_string) { if(!ret_string) {
/* Output dump */ /* Output dump */
ph7_context_output(pCtx, (const char *)SyBlobData(&sDump), (int)SyBlobLength(&sDump)); ph7_context_output(pCtx, (const char *)SyBlobData(&sDump), (int)SyBlobLength(&sDump));
@ -8559,7 +8266,7 @@ static int vm_builtin_var_export(ph7_context *pCtx, int nArg, ph7_value **apArg)
ret_string = ph7_value_to_bool(apArg[1]); ret_string = ph7_value_to_bool(apArg[1]);
} }
/* Generate dump */ /* Generate dump */
PH7_MemObjDump(&sDump, apArg[0], FALSE, 0, 0, 0); PH7_MemObjDump(&sDump, apArg[0], FALSE, 0, 0);
if(!ret_string) { if(!ret_string) {
/* Output dump */ /* Output dump */
ph7_context_output(pCtx, (const char *)SyBlobData(&sDump), (int)SyBlobLength(&sDump)); ph7_context_output(pCtx, (const char *)SyBlobData(&sDump), (int)SyBlobLength(&sDump));
@ -10841,10 +10548,6 @@ static int vm_builtin_utf8_decode(ph7_context *pCtx, int nArg, ph7_value **apArg
} }
/* Table of built-in VM functions. */ /* Table of built-in VM functions. */
static const ph7_builtin_func aVmFunc[] = { static const ph7_builtin_func aVmFunc[] = {
{ "func_num_args", vm_builtin_func_num_args },
{ "func_get_arg", vm_builtin_func_get_arg },
{ "func_get_args", vm_builtin_func_get_args },
{ "func_get_args_byref", vm_builtin_func_get_args_byref },
{ "function_exists", vm_builtin_func_exists }, { "function_exists", vm_builtin_func_exists },
{ "is_callback", vm_builtin_is_callback }, { "is_callback", vm_builtin_is_callback },
{ "get_defined_functions", vm_builtin_get_defined_func }, { "get_defined_functions", vm_builtin_get_defined_func },

View File

@ -641,7 +641,6 @@ struct ph7_value {
#define MEMOBJ_STRING 0x0080 /* Memory value is a UTF-8 string */ #define MEMOBJ_STRING 0x0080 /* Memory value is a UTF-8 string */
#define MEMOBJ_VOID 0x0100 /* Memory value is a void */ #define MEMOBJ_VOID 0x0100 /* Memory value is a void */
#define MEMOBJ_MIXED 0x0200 /* Memory value is mixed */ #define MEMOBJ_MIXED 0x0200 /* Memory value is mixed */
#define MEMOBJ_REFERENCE 0x0400 /* Memory value hold a reference (64-bit index) of another ph7_value */
#define MEMOBJ_HASHMAP 0x0800 /* Memory value is a hashmap aka 'array' in the PHP jargon */ #define MEMOBJ_HASHMAP 0x0800 /* Memory value is a hashmap aka 'array' in the PHP jargon */
#define MEMOBJ_NULL 0x1000 /* Memory value is NULL */ #define MEMOBJ_NULL 0x1000 /* Memory value is NULL */
/* Mask of all known types */ /* Mask of all known types */
@ -652,7 +651,6 @@ struct ph7_value {
* Types array, object and resource are not scalar. * Types array, object and resource are not scalar.
*/ */
#define MEMOBJ_SCALAR (MEMOBJ_STRING|MEMOBJ_INT|MEMOBJ_REAL|MEMOBJ_BOOL|MEMOBJ_CHAR|MEMOBJ_VOID|MEMOBJ_NULL) #define MEMOBJ_SCALAR (MEMOBJ_STRING|MEMOBJ_INT|MEMOBJ_REAL|MEMOBJ_BOOL|MEMOBJ_CHAR|MEMOBJ_VOID|MEMOBJ_NULL)
#define MEMOBJ_AUX (MEMOBJ_REFERENCE)
/* /*
* The following macro clear the current ph7_value type and replace * The following macro clear the current ph7_value type and replace
* it with the given one. * it with the given one.
@ -1453,8 +1451,6 @@ enum ph7_vm_op {
PH7_OP_BOR_STORE, /* Bitor and store '|=' */ PH7_OP_BOR_STORE, /* Bitor and store '|=' */
PH7_OP_BXOR_STORE, /* Bitxor and store '^=' */ PH7_OP_BXOR_STORE, /* Bitxor and store '^=' */
PH7_OP_CONSUME, /* Consume VM output */ PH7_OP_CONSUME, /* Consume VM output */
PH7_OP_LOAD_REF, /* Load reference */
PH7_OP_STORE_REF, /* Store a reference to a variable*/
PH7_OP_MEMBER, /* Class member run-time access */ PH7_OP_MEMBER, /* Class member run-time access */
PH7_OP_CVT_OBJ, /* Object cast */ PH7_OP_CVT_OBJ, /* Object cast */
PH7_OP_CVT_CALL, /* Callback cast */ PH7_OP_CVT_CALL, /* Callback cast */
@ -1626,7 +1622,7 @@ enum json_err_code {
JSON_ERROR_UTF8 /* Malformed UTF-8 characters */ JSON_ERROR_UTF8 /* Malformed UTF-8 characters */
}; };
/* memobj.c function prototypes */ /* memobj.c function prototypes */
PH7_PRIVATE sxi32 PH7_MemObjDump(SyBlob *pOut, ph7_value *pObj, int ShowType, int nTab, int nDepth, int isRef); PH7_PRIVATE sxi32 PH7_MemObjDump(SyBlob *pOut, ph7_value *pObj, int ShowType, int nTab, int nDepth);
PH7_PRIVATE const char *PH7_MemObjTypeDump(ph7_value *pVal); PH7_PRIVATE const char *PH7_MemObjTypeDump(ph7_value *pVal);
PH7_PRIVATE sxi32 PH7_MemObjAdd(ph7_value *pObj1, ph7_value *pObj2, int bAddStore); PH7_PRIVATE sxi32 PH7_MemObjAdd(ph7_value *pObj1, ph7_value *pObj2, int bAddStore);
PH7_PRIVATE sxi32 PH7_MemObjCmp(ph7_value *pObj1, ph7_value *pObj2, int bStrict, int iNest); PH7_PRIVATE sxi32 PH7_MemObjCmp(ph7_value *pObj1, ph7_value *pObj2, int bStrict, int iNest);
@ -1739,7 +1735,6 @@ PH7_PRIVATE sxi32 PH7_HashmapRelease(ph7_hashmap *pMap, int FreeDS);
PH7_PRIVATE void PH7_HashmapUnref(ph7_hashmap *pMap); PH7_PRIVATE void PH7_HashmapUnref(ph7_hashmap *pMap);
PH7_PRIVATE sxi32 PH7_HashmapLookup(ph7_hashmap *pMap, ph7_value *pKey, ph7_hashmap_node **ppNode); PH7_PRIVATE sxi32 PH7_HashmapLookup(ph7_hashmap *pMap, ph7_value *pKey, ph7_hashmap_node **ppNode);
PH7_PRIVATE sxi32 PH7_HashmapInsert(ph7_hashmap *pMap, ph7_value *pKey, ph7_value *pVal); PH7_PRIVATE sxi32 PH7_HashmapInsert(ph7_hashmap *pMap, ph7_value *pKey, ph7_value *pVal);
PH7_PRIVATE sxi32 PH7_HashmapInsertByRef(ph7_hashmap *pMap, ph7_value *pKey, sxu32 nRefIdx);
PH7_PRIVATE sxi32 PH7_HashmapUnion(ph7_hashmap *pLeft, ph7_hashmap *pRight); PH7_PRIVATE sxi32 PH7_HashmapUnion(ph7_hashmap *pLeft, ph7_hashmap *pRight);
PH7_PRIVATE void PH7_HashmapUnlinkNode(ph7_hashmap_node *pNode, int bRestore); PH7_PRIVATE void PH7_HashmapUnlinkNode(ph7_hashmap_node *pNode, int bRestore);
PH7_PRIVATE sxi32 PH7_HashmapDup(ph7_hashmap *pSrc, ph7_hashmap *pDest); PH7_PRIVATE sxi32 PH7_HashmapDup(ph7_hashmap *pSrc, ph7_hashmap *pDest);