Implement deterministic int64 wrapping arithmetic
This commit is contained in:
+1
-1
@@ -1259,7 +1259,7 @@ PH7_PRIVATE sxi32 PH7_MemObjAdd(ph7_value *pObj1, ph7_value *pObj2, int bAddStor
|
||||
sxi64 a, b;
|
||||
a = pObj1->x.iVal;
|
||||
b = pObj2->x.iVal;
|
||||
pObj1->x.iVal = a + b;
|
||||
pObj1->x.iVal = PH7_Int64Add(a, b);
|
||||
MemObjSetType(pObj1, MEMOBJ_INT);
|
||||
}
|
||||
} else {
|
||||
|
||||
+38
-22
@@ -3775,7 +3775,7 @@ Resume:
|
||||
if(pObj->nType & MEMOBJ_REAL) {
|
||||
pObj->x.rVal++;
|
||||
} else {
|
||||
pObj->x.iVal++;
|
||||
pObj->x.iVal = PH7_Int64Add(pObj->x.iVal, 1);
|
||||
}
|
||||
if(pInstr->iP1) {
|
||||
/* Pre-increment */
|
||||
@@ -3788,7 +3788,7 @@ Resume:
|
||||
if(pTos->nType & MEMOBJ_REAL) {
|
||||
pTos->x.rVal++;
|
||||
} else {
|
||||
pTos->x.iVal++;
|
||||
pTos->x.iVal = PH7_Int64Add(pTos->x.iVal, 1);
|
||||
MemObjSetType(pTos, MEMOBJ_INT);
|
||||
}
|
||||
}
|
||||
@@ -3816,7 +3816,7 @@ Resume:
|
||||
if(pObj->nType & MEMOBJ_REAL) {
|
||||
pObj->x.rVal--;
|
||||
} else {
|
||||
pObj->x.iVal--;
|
||||
pObj->x.iVal = PH7_Int64Sub(pObj->x.iVal, 1);
|
||||
}
|
||||
if(pInstr->iP1) {
|
||||
/* Pre-decrement */
|
||||
@@ -3829,7 +3829,7 @@ Resume:
|
||||
if(pTos->nType & MEMOBJ_REAL) {
|
||||
pTos->x.rVal--;
|
||||
} else {
|
||||
pTos->x.iVal--;
|
||||
pTos->x.iVal = PH7_Int64Sub(pTos->x.iVal, 1);
|
||||
MemObjSetType(pTos, MEMOBJ_INT);
|
||||
}
|
||||
}
|
||||
@@ -3854,7 +3854,7 @@ Resume:
|
||||
pTos->x.rVal = -pTos->x.rVal;
|
||||
}
|
||||
if(pTos->nType & MEMOBJ_INT) {
|
||||
pTos->x.iVal = -pTos->x.iVal;
|
||||
pTos->x.iVal = PH7_Int64Neg(pTos->x.iVal);
|
||||
}
|
||||
break;
|
||||
/*
|
||||
@@ -3905,7 +3905,7 @@ Resume:
|
||||
if((pTos->nType & MEMOBJ_INT) == 0) {
|
||||
PH7_MemObjToInteger(pTos);
|
||||
}
|
||||
pTos->x.iVal = ~pTos->x.iVal;
|
||||
pTos->x.iVal = PH7_Int64FromUnsigned(~(sxu64)pTos->x.iVal);
|
||||
break;
|
||||
/* OP_MUL * * *
|
||||
* OP_MUL_STORE * * *
|
||||
@@ -3944,7 +3944,7 @@ Resume:
|
||||
sxi64 a, b, r;
|
||||
a = pNos->x.iVal;
|
||||
b = pTos->x.iVal;
|
||||
r = a * b;
|
||||
r = PH7_Int64Mul(a, b);
|
||||
/* Push the result */
|
||||
pNos->x.iVal = r;
|
||||
MemObjSetType(pNos, MEMOBJ_INT);
|
||||
@@ -4000,7 +4000,23 @@ Resume:
|
||||
sxi64 a, b, r;
|
||||
a = pNos->x.iVal;
|
||||
b = pTos->x.iVal;
|
||||
r = (sxi64)pow((double)b, (double)a);
|
||||
/* The parser emits the exponent before the base. */
|
||||
if(a < 0) {
|
||||
if(b == 0) {
|
||||
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Division by zero");
|
||||
}
|
||||
r = b == 1 ? 1 : b == -1 ? ((sxu64)a & 1 ? -1 : 1) : 0;
|
||||
} else {
|
||||
sxu64 base = (sxu64)b, exponent = (sxu64)a, result = 1;
|
||||
while(exponent != 0) {
|
||||
if(exponent & 1) {
|
||||
result *= base;
|
||||
}
|
||||
base *= base;
|
||||
exponent >>= 1;
|
||||
}
|
||||
r = PH7_Int64FromUnsigned(result);
|
||||
}
|
||||
/* Push the result */
|
||||
pNos->x.iVal = r;
|
||||
MemObjSetType(pNos, MEMOBJ_INT);
|
||||
@@ -4131,7 +4147,7 @@ Resume:
|
||||
sxi64 a, b, r;
|
||||
a = pNos->x.iVal;
|
||||
b = pTos->x.iVal;
|
||||
r = a - b;
|
||||
r = PH7_Int64Sub(a, b);
|
||||
/* Push the result */
|
||||
pNos->x.iVal = r;
|
||||
MemObjSetType(pNos, MEMOBJ_INT);
|
||||
@@ -4172,7 +4188,7 @@ Resume:
|
||||
sxi64 a, b, r;
|
||||
a = pTos->x.iVal;
|
||||
b = pNos->x.iVal;
|
||||
r = a - b;
|
||||
r = PH7_Int64Sub(a, b);
|
||||
/* Push the result */
|
||||
pNos->x.iVal = r;
|
||||
MemObjSetType(pNos, MEMOBJ_INT);
|
||||
@@ -4217,7 +4233,7 @@ Resume:
|
||||
if(b == 0) {
|
||||
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Division by zero %qd%%0", a);
|
||||
} else {
|
||||
r = a % b;
|
||||
r = b == -1 ? 0 : a % b;
|
||||
}
|
||||
/* Push the result */
|
||||
pNos->x.iVal = r;
|
||||
@@ -4256,7 +4272,7 @@ Resume:
|
||||
if(b == 0) {
|
||||
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Division by zero %qd%%0", a);
|
||||
} else {
|
||||
r = a % b;
|
||||
r = b == -1 ? 0 : a % b;
|
||||
}
|
||||
/* Push the result */
|
||||
pNos->x.iVal = r;
|
||||
@@ -4392,16 +4408,16 @@ Resume:
|
||||
switch(pInstr->iOp) {
|
||||
case PH7_OP_BOR_STORE:
|
||||
case PH7_OP_BOR:
|
||||
r = a | b;
|
||||
r = PH7_Int64FromUnsigned((sxu64)a | (sxu64)b);
|
||||
break;
|
||||
case PH7_OP_BXOR_STORE:
|
||||
case PH7_OP_BXOR:
|
||||
r = a ^ b;
|
||||
r = PH7_Int64FromUnsigned((sxu64)a ^ (sxu64)b);
|
||||
break;
|
||||
case PH7_OP_BAND_STORE:
|
||||
case PH7_OP_BAND:
|
||||
default:
|
||||
r = a & b;
|
||||
r = PH7_Int64FromUnsigned((sxu64)a & (sxu64)b);
|
||||
break;
|
||||
}
|
||||
/* Push the result */
|
||||
@@ -4450,16 +4466,16 @@ Resume:
|
||||
switch(pInstr->iOp) {
|
||||
case PH7_OP_BOR_STORE:
|
||||
case PH7_OP_BOR:
|
||||
r = a | b;
|
||||
r = PH7_Int64FromUnsigned((sxu64)a | (sxu64)b);
|
||||
break;
|
||||
case PH7_OP_BXOR_STORE:
|
||||
case PH7_OP_BXOR:
|
||||
r = a ^ b;
|
||||
r = PH7_Int64FromUnsigned((sxu64)a ^ (sxu64)b);
|
||||
break;
|
||||
case PH7_OP_BAND_STORE:
|
||||
case PH7_OP_BAND:
|
||||
default:
|
||||
r = a & b;
|
||||
r = PH7_Int64FromUnsigned((sxu64)a & (sxu64)b);
|
||||
break;
|
||||
}
|
||||
/* Push the result */
|
||||
@@ -4506,9 +4522,9 @@ Resume:
|
||||
a = pNos->x.iVal;
|
||||
b = (sxi32)pTos->x.iVal;
|
||||
if(pInstr->iOp == PH7_OP_SHL) {
|
||||
r = a << b;
|
||||
r = PH7_Int64FromUnsigned((sxu64)a << b);
|
||||
} else {
|
||||
r = a >> b;
|
||||
r = PH7_Int64ShiftRight(a, b);
|
||||
}
|
||||
/* Push the result */
|
||||
pNos->x.iVal = r;
|
||||
@@ -4550,9 +4566,9 @@ Resume:
|
||||
a = pTos->x.iVal;
|
||||
b = (sxi32)pNos->x.iVal;
|
||||
if(pInstr->iOp == PH7_OP_SHL_STORE) {
|
||||
r = a << b;
|
||||
r = PH7_Int64FromUnsigned((sxu64)a << b);
|
||||
} else {
|
||||
r = a >> b;
|
||||
r = PH7_Int64ShiftRight(a, b);
|
||||
}
|
||||
/* Push the result */
|
||||
pNos->x.iVal = r;
|
||||
|
||||
Reference in New Issue
Block a user