+++ /dev/null
-package vm
-
-import (
- "bytes"
-)
-
-func opInvert(vm *virtualMachine) error {
- err := vm.applyCost(1)
- if err != nil {
- return err
- }
- top, err := vm.top()
- if err != nil {
- return err
- }
- err = vm.applyCost(int64(len(top)))
- if err != nil {
- return err
- }
- // Could rewrite top in place but maybe it's a shared data
- // structure?
- newTop := make([]byte, 0, len(top))
- for _, b := range top {
- newTop = append(newTop, ^b)
- }
- vm.dataStack[len(vm.dataStack)-1] = newTop
- return nil
-}
-
-func opAnd(vm *virtualMachine) error {
- err := vm.applyCost(1)
- if err != nil {
- return err
- }
- b, err := vm.pop(true)
- if err != nil {
- return err
- }
- a, err := vm.pop(true)
- if err != nil {
- return err
- }
- min, max := len(a), len(b)
- if min > max {
- min, max = max, min
- }
- err = vm.applyCost(int64(min))
- if err != nil {
- return err
- }
- res := make([]byte, 0, min)
- for i := 0; i < min; i++ {
- res = append(res, a[i]&b[i])
- }
- return vm.push(res, true)
-}
-
-func opOr(vm *virtualMachine) error {
- return doOr(vm, false)
-}
-
-func opXor(vm *virtualMachine) error {
- return doOr(vm, true)
-}
-
-func doOr(vm *virtualMachine, xor bool) error {
- err := vm.applyCost(1)
- if err != nil {
- return err
- }
- b, err := vm.pop(true)
- if err != nil {
- return err
- }
- a, err := vm.pop(true)
- if err != nil {
- return err
- }
- min, max := len(a), len(b)
- if min > max {
- min, max = max, min
- }
- err = vm.applyCost(int64(max))
- if err != nil {
- return err
- }
- res := make([]byte, 0, max)
- for i := 0; i < max; i++ {
- var aByte, bByte, resByte byte
- if i >= len(a) {
- aByte = 0
- } else {
- aByte = a[i]
- }
- if i >= len(b) {
- bByte = 0
- } else {
- bByte = b[i]
- }
- if xor {
- resByte = aByte ^ bByte
- } else {
- resByte = aByte | bByte
- }
-
- res = append(res, resByte)
- }
- return vm.push(res, true)
-}
-
-func opEqual(vm *virtualMachine) error {
- res, err := doEqual(vm)
- if err != nil {
- return err
- }
- return vm.pushBool(res, true)
-}
-
-func opEqualVerify(vm *virtualMachine) error {
- res, err := doEqual(vm)
- if err != nil {
- return err
- }
- if res {
- return nil
- }
- return ErrVerifyFailed
-}
-
-func doEqual(vm *virtualMachine) (bool, error) {
- err := vm.applyCost(1)
- if err != nil {
- return false, err
- }
- b, err := vm.pop(true)
- if err != nil {
- return false, err
- }
- a, err := vm.pop(true)
- if err != nil {
- return false, err
- }
- min, max := len(a), len(b)
- if min > max {
- min, max = max, min
- }
- err = vm.applyCost(int64(min))
- if err != nil {
- return false, err
- }
- return bytes.Equal(a, b), nil
-}