diff --git a/engine/compiler.c b/engine/compiler.c index 5bfa1ff..2b33b60 100644 --- a/engine/compiler.c +++ b/engine/compiler.c @@ -2557,7 +2557,7 @@ static sxi32 PH7_CompileVar(ph7_gen_state *pGen) { } void *p3 = (void *) zDup; /* Emit OP_LOAD instruction */ - PH7_VmEmitInstr(pGen->pVm, pGen->pIn->nLine, PH7_OP_LOAD, 0, nType, p3, 0); + PH7_VmEmitInstr(pGen->pVm, pGen->pIn->nLine, PH7_OP_DECLARE, 0, nType, p3, 0); /* Check if we have an expression to compile */ if(pGen->pIn < pGen->pEnd && (pGen->pIn[2].nType & PH7_TK_EQUAL)) { /* Compile the expression */ diff --git a/engine/vm.c b/engine/vm.c index 6a67477..02c553e 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -2395,6 +2395,39 @@ static sxi32 VmByteCodeExec( break; } /* + * DECLARE: * P2 P3 + * + * Create a variable where it's name is taken from the top of the stack or + * from the P3 operand. It takes a variable type from P2 operand. + */ + case PH7_OP_DECLARE: { + ph7_value *pObj; + SyString sName; + SyStringInitFromBuf(&sName, pInstr->p3, SyStrlen((const char *)pInstr->p3)); + /* Reserve a room for the target object */ + pTos++; + /* Create a new variable */ + pObj = VmCreateMemObj(&(*pVm), &sName, FALSE); + if(!pObj) { + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, + "Redeclaration of ā€˜$%zā€™ variable", &sName); + } + if(pInstr->iP2 & MEMOBJ_MIXED && (pInstr->iP2 & MEMOBJ_HASHMAP) == 0) { + pObj->iFlags = MEMOBJ_MIXED | MEMOBJ_VOID; + } else { + if(pInstr->iP2 & MEMOBJ_HASHMAP) { + ph7_hashmap *pMap; + pMap = PH7_NewHashmap(&(*pVm), 0, 0); + if(pMap == 0) { + PH7_VmMemoryError(&(*pVm)); + } + pObj->x.pOther = pMap; + } + MemObjSetType(pObj, pInstr->iP2); + } + pTos->nIdx = SXU32_HIGH; /* Mark as constant */ + break; + } /* * LOADC P1 P2 * * * Load a constant [i.e: PHP_EOL,PHP_OS,__TIME__,...] indexed at P2 in the constant pool. @@ -5369,6 +5402,9 @@ static const char *VmInstrToString(sxi32 nOp) { case PH7_OP_HALT: zOp = "HALT"; break; + case PH7_OP_DECLARE: + zOp = "DECLARE"; + break; case PH7_OP_LOAD: zOp = "LOAD"; break; diff --git a/include/ph7int.h b/include/ph7int.h index 112a289..82272a6 100644 --- a/include/ph7int.h +++ b/include/ph7int.h @@ -1389,6 +1389,7 @@ enum iErrCode { enum ph7_vm_op { PH7_OP_DONE = 1, /* Done */ PH7_OP_HALT, /* Halt */ + PH7_OP_DECLARE, /* Declare a variable */ PH7_OP_LOAD, /* Load memory object */ PH7_OP_LOADC, /* Load constant */ PH7_OP_LOAD_IDX, /* Load array entry */