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)
184 y, err := vm.popInt64(true)
188 x, err := vm.popInt64(true)
192 res, ok := checked.SubInt64(x, y)
196 return vm.pushInt64(res, true)
199 func opMul(vm *virtualMachine) error {
200 err := vm.applyCost(8)
204 y, err := vm.popInt64(true)
208 x, err := vm.popInt64(true)
212 res, ok := checked.MulInt64(x, y)
216 return vm.pushInt64(res, true)
219 func opDiv(vm *virtualMachine) error {
220 err := vm.applyCost(8)
224 y, err := vm.popInt64(true)
228 x, err := vm.popInt64(true)
235 res, ok := checked.DivInt64(x, y)
239 return vm.pushInt64(res, true)
242 func opMod(vm *virtualMachine) error {
243 err := vm.applyCost(8)
247 y, err := vm.popInt64(true)
251 x, err := vm.popInt64(true)
259 res, ok := checked.ModInt64(x, y)
264 // Go's modulus operator produces the wrong result for mixed-sign
266 if res != 0 && (x >= 0) != (y >= 0) {
270 return vm.pushInt64(res, true)
273 func opLshift(vm *virtualMachine) error {
274 err := vm.applyCost(8)
278 y, err := vm.popInt64(true)
285 x, err := vm.popInt64(true)
289 if x == 0 || y == 0 {
290 return vm.pushInt64(x, true)
293 res, ok := checked.LshiftInt64(x, y)
298 return vm.pushInt64(res, true)
301 func opRshift(vm *virtualMachine) error {
302 err := vm.applyCost(8)
306 y, err := vm.popInt64(true)
310 x, err := vm.popInt64(true)
317 return vm.pushInt64(x>>uint64(y), true)
320 func opBoolAnd(vm *virtualMachine) error {
321 err := vm.applyCost(2)
325 b, err := vm.pop(true)
329 a, err := vm.pop(true)
333 return vm.pushBool(AsBool(a) && AsBool(b), true)
336 func opBoolOr(vm *virtualMachine) error {
337 err := vm.applyCost(2)
341 b, err := vm.pop(true)
345 a, err := vm.pop(true)
349 return vm.pushBool(AsBool(a) || AsBool(b), true)
361 func opNumEqual(vm *virtualMachine) error {
362 return doNumCompare(vm, cmpEqual)
365 func opNumEqualVerify(vm *virtualMachine) error {
366 err := vm.applyCost(2)
370 y, err := vm.popInt64(true)
374 x, err := vm.popInt64(true)
381 return ErrVerifyFailed
384 func opNumNotEqual(vm *virtualMachine) error {
385 return doNumCompare(vm, cmpNotEqual)
388 func opLessThan(vm *virtualMachine) error {
389 return doNumCompare(vm, cmpLess)
392 func opGreaterThan(vm *virtualMachine) error {
393 return doNumCompare(vm, cmpGreater)
396 func opLessThanOrEqual(vm *virtualMachine) error {
397 return doNumCompare(vm, cmpLessEqual)
400 func opGreaterThanOrEqual(vm *virtualMachine) error {
401 return doNumCompare(vm, cmpGreaterEqual)
404 func doNumCompare(vm *virtualMachine, op int) error {
405 err := vm.applyCost(2)
409 y, err := vm.popBigInt(true)
413 x, err := vm.popBigInt(true)
425 case cmpGreaterEqual:
432 return vm.pushBool(res, true)
435 func opMin(vm *virtualMachine) error {
436 err := vm.applyCost(2)
440 y, err := vm.popInt64(true)
444 x, err := vm.popInt64(true)
451 return vm.pushInt64(x, true)
454 func opMax(vm *virtualMachine) error {
455 err := vm.applyCost(2)
459 y, err := vm.popInt64(true)
463 x, err := vm.popInt64(true)
470 return vm.pushInt64(x, true)
473 func opWithin(vm *virtualMachine) error {
474 err := vm.applyCost(4)
478 max, err := vm.popInt64(true)
482 min, err := vm.popInt64(true)
486 x, err := vm.popInt64(true)
490 return vm.pushBool(x >= min && x < max, true)