6 "github.com/holiman/uint256"
8 "github.com/bytom/bytom/math/checked"
11 func op1Add(vm *virtualMachine) error {
12 err := vm.applyCost(2)
17 n, err := vm.popBigInt(true)
22 num, ok := checked.NewUInt256("1")
27 if num.Add(n, num); num.Sign() < 0 {
31 return vm.pushBigInt(num, true)
34 func op1Sub(vm *virtualMachine) error {
35 err := vm.applyCost(2)
40 n, err := vm.popBigInt(true)
45 num, ok := checked.NewUInt256("1")
50 if num.Sub(n, num); num.Sign() < 0 {
54 return vm.pushBigInt(num, true)
57 func op2Mul(vm *virtualMachine) error {
58 err := vm.applyCost(2)
63 n, err := vm.popBigInt(true)
68 num, ok := checked.NewUInt256("2")
73 if num.Mul(n, num); num.Sign() < 0 {
77 return vm.pushBigInt(num, true)
80 func op2Div(vm *virtualMachine) error {
81 err := vm.applyCost(2)
86 n, err := vm.popBigInt(true)
91 return vm.pushBigInt(n.Rsh(n,1), true)
94 func opNegate(vm *virtualMachine) error {
95 err := vm.applyCost(2)
99 n, err := vm.popInt64(true)
103 res, ok := checked.NegateInt64(n)
107 return vm.pushInt64(res, true)
110 func opAbs(vm *virtualMachine) error {
111 err := vm.applyCost(2)
115 n, err := vm.popInt64(true)
119 if n == math.MinInt64 {
125 return vm.pushInt64(n, true)
128 func opNot(vm *virtualMachine) error {
129 err := vm.applyCost(2)
134 n, err := vm.popBigInt(true)
139 return vm.pushBool(n.Cmp(uint256.NewInt()) == 0, true)
142 func op0NotEqual(vm *virtualMachine) error {
143 err := vm.applyCost(2)
148 n, err := vm.popBigInt(true)
153 return vm.pushBool(n.Cmp(uint256.NewInt()) != 0, true)
156 func opAdd(vm *virtualMachine) error {
157 err := vm.applyCost(2)
162 y, err := vm.popBigInt(true)
167 x, err := vm.popBigInt(true)
172 if x.Add(x, y); x.Sign() < 0 {
176 return vm.pushBigInt(x, true)
179 func opSub(vm *virtualMachine) error {
180 err := vm.applyCost(2)
185 y, err := vm.popBigInt(true)
190 x, err := vm.popBigInt(true)
195 if x.Sub(x, y); x.Sign() < 0 {
199 return vm.pushBigInt(x, true)
202 func opMul(vm *virtualMachine) error {
203 err := vm.applyCost(8)
208 y, err := vm.popBigInt(true)
213 x, err := vm.popBigInt(true)
218 if overflow := x.MulOverflow(x, y); overflow || x.Sign() < 0 {
222 return vm.pushBigInt(x, true)
225 func opDiv(vm *virtualMachine) error {
226 err := vm.applyCost(8)
231 y, err := vm.popBigInt(true)
236 x, err := vm.popBigInt(true)
245 return vm.pushBigInt(x.Div(x, y), true)
248 func opMod(vm *virtualMachine) error {
249 err := vm.applyCost(8)
253 y, err := vm.popInt64(true)
257 x, err := vm.popInt64(true)
265 res, ok := checked.ModInt64(x, y)
270 // Go's modulus operator produces the wrong result for mixed-sign
272 if res != 0 && (x >= 0) != (y >= 0) {
276 return vm.pushInt64(res, true)
279 func opLshift(vm *virtualMachine) error {
280 err := vm.applyCost(8)
284 y, err := vm.popInt64(true)
291 x, err := vm.popInt64(true)
295 if x == 0 || y == 0 {
296 return vm.pushInt64(x, true)
299 res, ok := checked.LshiftInt64(x, y)
304 return vm.pushInt64(res, true)
307 func opRshift(vm *virtualMachine) error {
308 err := vm.applyCost(8)
312 y, err := vm.popInt64(true)
316 x, err := vm.popInt64(true)
323 return vm.pushInt64(x>>uint64(y), true)
326 func opBoolAnd(vm *virtualMachine) error {
327 err := vm.applyCost(2)
331 b, err := vm.pop(true)
335 a, err := vm.pop(true)
339 return vm.pushBool(AsBool(a) && AsBool(b), true)
342 func opBoolOr(vm *virtualMachine) error {
343 err := vm.applyCost(2)
347 b, err := vm.pop(true)
351 a, err := vm.pop(true)
355 return vm.pushBool(AsBool(a) || AsBool(b), true)
367 func opNumEqual(vm *virtualMachine) error {
368 return doNumCompare(vm, cmpEqual)
371 func opNumEqualVerify(vm *virtualMachine) error {
372 err := vm.applyCost(2)
376 y, err := vm.popInt64(true)
380 x, err := vm.popInt64(true)
387 return ErrVerifyFailed
390 func opNumNotEqual(vm *virtualMachine) error {
391 return doNumCompare(vm, cmpNotEqual)
394 func opLessThan(vm *virtualMachine) error {
395 return doNumCompare(vm, cmpLess)
398 func opGreaterThan(vm *virtualMachine) error {
399 return doNumCompare(vm, cmpGreater)
402 func opLessThanOrEqual(vm *virtualMachine) error {
403 return doNumCompare(vm, cmpLessEqual)
406 func opGreaterThanOrEqual(vm *virtualMachine) error {
407 return doNumCompare(vm, cmpGreaterEqual)
410 func doNumCompare(vm *virtualMachine, op int) error {
411 err := vm.applyCost(2)
415 y, err := vm.popBigInt(true)
419 x, err := vm.popBigInt(true)
431 case cmpGreaterEqual:
438 return vm.pushBool(res, true)
441 func opMin(vm *virtualMachine) error {
442 err := vm.applyCost(2)
446 y, err := vm.popInt64(true)
450 x, err := vm.popInt64(true)
457 return vm.pushInt64(x, true)
460 func opMax(vm *virtualMachine) error {
461 err := vm.applyCost(2)
465 y, err := vm.popInt64(true)
469 x, err := vm.popInt64(true)
476 return vm.pushInt64(x, true)
479 func opWithin(vm *virtualMachine) error {
480 err := vm.applyCost(4)
484 max, err := vm.popInt64(true)
488 min, err := vm.popInt64(true)
492 x, err := vm.popInt64(true)
496 return vm.pushBool(x >= min && x < max, true)