This commit is contained in:
+25
-7
@@ -55,6 +55,19 @@ struct SyhttpHeader {
|
|||||||
#define HTTP_PROTO_11 2 /* HTTP/1.1 */
|
#define HTTP_PROTO_11 2 /* HTTP/1.1 */
|
||||||
#define HTTP_PROTO_20 3 /* HTTP/2.0 */
|
#define HTTP_PROTO_20 3 /* HTTP/2.0 */
|
||||||
static void VmScopeRecord(ph7_vm *pVm, const SyString *pName, sxi32 bConst);
|
static void VmScopeRecord(ph7_vm *pVm, const SyString *pName, sxi32 bConst);
|
||||||
|
/* Lookup visible local names across auxiliary frames, never caller invocations.
|
||||||
|
* Scope exit removes names from these tables without releasing retained storage. */
|
||||||
|
static SyHashEntry *VmLookupLocal(VmFrame *pFrame, const SyString *pName, sxi32 bConst) {
|
||||||
|
for(;;) {
|
||||||
|
SyHashEntry *pEntry = SyHashGet(bConst ? &pFrame->hConst : &pFrame->hVar,
|
||||||
|
pName->zString, pName->nByte);
|
||||||
|
if(pEntry || pFrame->pParent == 0 ||
|
||||||
|
(pFrame->iFlags & (VM_FRAME_LOOP | VM_FRAME_EXCEPTION | VM_FRAME_CATCH | VM_FRAME_FINALLY)) == 0) {
|
||||||
|
return pEntry;
|
||||||
|
}
|
||||||
|
pFrame = pFrame->pParent;
|
||||||
|
}
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Register a constant and it's associated expansion callback so that
|
* Register a constant and it's associated expansion callback so that
|
||||||
* it can be expanded from the target PHP program.
|
* it can be expanded from the target PHP program.
|
||||||
@@ -88,6 +101,9 @@ PH7_PRIVATE sxi32 PH7_VmRegisterConstant(
|
|||||||
pFrame = pFrame->pParent;
|
pFrame = pFrame->pParent;
|
||||||
}
|
}
|
||||||
pCollection = &pFrame->hConst;
|
pCollection = &pFrame->hConst;
|
||||||
|
if(VmLookupLocal(pFrame, pName, TRUE)) {
|
||||||
|
return SXERR_EXISTS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pEntry = SyHashGet(pCollection, (const void *)pName->zString, pName->nByte);
|
pEntry = SyHashGet(pCollection, (const void *)pName->zString, pName->nByte);
|
||||||
if(pEntry) {
|
if(pEntry) {
|
||||||
@@ -2262,8 +2278,8 @@ static ph7_value *VmCreateMemObj(
|
|||||||
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
|
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
|
||||||
pFrame = pFrame->pParent;
|
pFrame = pFrame->pParent;
|
||||||
}
|
}
|
||||||
/* Query the top active frame */
|
/* Auxiliary frames do not permit shadowing a visible local. */
|
||||||
pEntry = SyHashGet(&pFrame->hVar, (const void *)pName->zString, pName->nByte);
|
pEntry = VmLookupLocal(pFrame, pName, FALSE);
|
||||||
if(pEntry) {
|
if(pEntry) {
|
||||||
/* Variable already exists */
|
/* Variable already exists */
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3293,7 +3309,7 @@ Resume:
|
|||||||
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
|
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
|
||||||
pFrame = pFrame->pParent;
|
pFrame = pFrame->pParent;
|
||||||
}
|
}
|
||||||
if(SyHashGet(&pFrame->hVar, pStatic->sName.zString, pStatic->sName.nByte)) {
|
if(VmLookupLocal(pFrame, &pStatic->sName, FALSE)) {
|
||||||
PH7_VmThrowError(pVm, PH7_CTX_ERR, "Redeclaration of ‘$%z’ variable", &pStatic->sName);
|
PH7_VmThrowError(pVm, PH7_CTX_ERR, "Redeclaration of ‘$%z’ variable", &pStatic->sName);
|
||||||
}
|
}
|
||||||
if(pStatic->nIdx == SXU32_HIGH) {
|
if(pStatic->nIdx == SXU32_HIGH) {
|
||||||
@@ -3440,7 +3456,7 @@ Resume:
|
|||||||
/* Candidate for expansion via user defined callbacks */
|
/* Candidate for expansion via user defined callbacks */
|
||||||
for(;;) {
|
for(;;) {
|
||||||
pEntry = SyHashGet(&pFrame->hConst, SyBlobData(&pObj->sBlob), SyBlobLength(&pObj->sBlob));
|
pEntry = SyHashGet(&pFrame->hConst, SyBlobData(&pObj->sBlob), SyBlobLength(&pObj->sBlob));
|
||||||
if(pEntry == 0 && pFrame->iFlags & VM_FRAME_LOOP && pFrame->pParent) {
|
if(pEntry == 0 && pFrame->iFlags & (VM_FRAME_LOOP | VM_FRAME_EXCEPTION | VM_FRAME_CATCH | VM_FRAME_FINALLY) && pFrame->pParent) {
|
||||||
pFrame = pFrame->pParent;
|
pFrame = pFrame->pParent;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@@ -9335,13 +9351,15 @@ static sxi32 VmExecExceptionBlock(ph7_vm *pVm, ph7_exception *pException,
|
|||||||
rc = VmEnterFrame(pVm, 0, 0, &pFrame);
|
rc = VmEnterFrame(pVm, 0, 0, &pFrame);
|
||||||
if(rc == SXRET_OK) {
|
if(rc == SXRET_OK) {
|
||||||
if(pCatch) {
|
if(pCatch) {
|
||||||
ph7_value *pObj = VmCreateMemObj(pVm, &pCatch->sThis, FALSE);
|
ph7_value *pObj;
|
||||||
pFrame->iFlags |= VM_FRAME_CATCH;
|
pFrame->iFlags |= VM_FRAME_CATCH;
|
||||||
if(pObj) {
|
pObj = VmCreateMemObj(pVm, &pCatch->sThis, FALSE);
|
||||||
|
if(pObj == 0) {
|
||||||
|
PH7_VmThrowError(pVm, PH7_CTX_ERR, "Redeclaration of ‘$%z’ variable", &pCatch->sThis);
|
||||||
|
}
|
||||||
pThis->iRef++;
|
pThis->iRef++;
|
||||||
pObj->x.pOther = pThis;
|
pObj->x.pOther = pThis;
|
||||||
MemObjSetType(pObj, MEMOBJ_OBJ);
|
MemObjSetType(pObj, MEMOBJ_OBJ);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
pFrame->iFlags |= VM_FRAME_FINALLY;
|
pFrame->iFlags |= VM_FRAME_FINALLY;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user