OSDN Git Service

Hulk did something
[bytom/vapor.git] / protocol / vm / bitwise.go
1 package vm
2
3 import "bytes"
4
5 func opInvert(vm *virtualMachine) error {
6         err := vm.applyCost(1)
7         if err != nil {
8                 return err
9         }
10         top, err := vm.top()
11         if err != nil {
12                 return err
13         }
14         err = vm.applyCost(int64(len(top)))
15         if err != nil {
16                 return err
17         }
18         // Could rewrite top in place but maybe it's a shared data
19         // structure?
20         newTop := make([]byte, 0, len(top))
21         for _, b := range top {
22                 newTop = append(newTop, ^b)
23         }
24         vm.dataStack[len(vm.dataStack)-1] = newTop
25         return nil
26 }
27
28 func opAnd(vm *virtualMachine) error {
29         err := vm.applyCost(1)
30         if err != nil {
31                 return err
32         }
33         b, err := vm.pop(true)
34         if err != nil {
35                 return err
36         }
37         a, err := vm.pop(true)
38         if err != nil {
39                 return err
40         }
41         min, max := len(a), len(b)
42         if min > max {
43                 min, max = max, min
44         }
45         err = vm.applyCost(int64(min))
46         if err != nil {
47                 return err
48         }
49         res := make([]byte, 0, min)
50         for i := 0; i < min; i++ {
51                 res = append(res, a[i]&b[i])
52         }
53         return vm.push(res, true)
54 }
55
56 func opOr(vm *virtualMachine) error {
57         return doOr(vm, false)
58 }
59
60 func opXor(vm *virtualMachine) error {
61         return doOr(vm, true)
62 }
63
64 func doOr(vm *virtualMachine, xor bool) error {
65         err := vm.applyCost(1)
66         if err != nil {
67                 return err
68         }
69         b, err := vm.pop(true)
70         if err != nil {
71                 return err
72         }
73         a, err := vm.pop(true)
74         if err != nil {
75                 return err
76         }
77         min, max := len(a), len(b)
78         if min > max {
79                 min, max = max, min
80         }
81         err = vm.applyCost(int64(max))
82         if err != nil {
83                 return err
84         }
85         res := make([]byte, 0, max)
86         for i := 0; i < max; i++ {
87                 var aByte, bByte, resByte byte
88                 if i >= len(a) {
89                         aByte = 0
90                 } else {
91                         aByte = a[i]
92                 }
93                 if i >= len(b) {
94                         bByte = 0
95                 } else {
96                         bByte = b[i]
97                 }
98                 if xor {
99                         resByte = aByte ^ bByte
100                 } else {
101                         resByte = aByte | bByte
102                 }
103
104                 res = append(res, resByte)
105         }
106         return vm.push(res, true)
107 }
108
109 func opEqual(vm *virtualMachine) error {
110         res, err := doEqual(vm)
111         if err != nil {
112                 return err
113         }
114         return vm.pushBool(res, true)
115 }
116
117 func opEqualVerify(vm *virtualMachine) error {
118         res, err := doEqual(vm)
119         if err != nil {
120                 return err
121         }
122         if res {
123                 return nil
124         }
125         return ErrVerifyFailed
126 }
127
128 func doEqual(vm *virtualMachine) (bool, error) {
129         err := vm.applyCost(1)
130         if err != nil {
131                 return false, err
132         }
133         b, err := vm.pop(true)
134         if err != nil {
135                 return false, err
136         }
137         a, err := vm.pop(true)
138         if err != nil {
139                 return false, err
140         }
141         min, max := len(a), len(b)
142         if min > max {
143                 min, max = max, min
144         }
145         err = vm.applyCost(int64(min))
146         if err != nil {
147                 return false, err
148         }
149         return bytes.Equal(a, b), nil
150 }