OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / protocol / vm / splice.go
1 package vm
2
3 import "github.com/vapor/math/checked"
4
5 func opCat(vm *virtualMachine) error {
6         err := vm.applyCost(4)
7         if err != nil {
8                 return err
9         }
10         b, err := vm.pop(true)
11         if err != nil {
12                 return err
13         }
14         a, err := vm.pop(true)
15         if err != nil {
16                 return err
17         }
18         lens := int64(len(a) + len(b))
19         err = vm.applyCost(lens)
20         if err != nil {
21                 return err
22         }
23         vm.deferCost(-lens)
24         err = vm.push(append(a, b...), true)
25         if err != nil {
26                 return err
27         }
28         return nil
29 }
30
31 func opSubstr(vm *virtualMachine) error {
32         err := vm.applyCost(4)
33         if err != nil {
34                 return err
35         }
36         size, err := vm.popInt64(true)
37         if err != nil {
38                 return err
39         }
40         if size < 0 {
41                 return ErrBadValue
42         }
43         err = vm.applyCost(size)
44         if err != nil {
45                 return err
46         }
47         vm.deferCost(-size)
48         offset, err := vm.popInt64(true)
49         if err != nil {
50                 return err
51         }
52         if offset < 0 {
53                 return ErrBadValue
54         }
55         str, err := vm.pop(true)
56         if err != nil {
57                 return err
58         }
59         end, ok := checked.AddInt64(offset, size)
60         if !ok || end > int64(len(str)) {
61                 return ErrBadValue
62         }
63         err = vm.push(str[offset:end], true)
64         if err != nil {
65                 return err
66         }
67         return nil
68 }
69
70 func opLeft(vm *virtualMachine) error {
71         err := vm.applyCost(4)
72         if err != nil {
73                 return err
74         }
75         size, err := vm.popInt64(true)
76         if err != nil {
77                 return err
78         }
79         if size < 0 {
80                 return ErrBadValue
81         }
82         err = vm.applyCost(size)
83         if err != nil {
84                 return err
85         }
86         vm.deferCost(-size)
87         str, err := vm.pop(true)
88         if err != nil {
89                 return err
90         }
91         if size > int64(len(str)) {
92                 return ErrBadValue
93         }
94         err = vm.push(str[:size], true)
95         if err != nil {
96                 return err
97         }
98         return nil
99 }
100
101 func opRight(vm *virtualMachine) error {
102         err := vm.applyCost(4)
103         if err != nil {
104                 return err
105         }
106         size, err := vm.popInt64(true)
107         if err != nil {
108                 return err
109         }
110         if size < 0 {
111                 return ErrBadValue
112         }
113         err = vm.applyCost(size)
114         if err != nil {
115                 return err
116         }
117         vm.deferCost(-size)
118         str, err := vm.pop(true)
119         if err != nil {
120                 return err
121         }
122         lstr := int64(len(str))
123         if size > lstr {
124                 return ErrBadValue
125         }
126         err = vm.push(str[lstr-size:], true)
127         if err != nil {
128                 return err
129         }
130         return nil
131 }
132
133 func opSize(vm *virtualMachine) error {
134         err := vm.applyCost(1)
135         if err != nil {
136                 return err
137         }
138         str, err := vm.top()
139         if err != nil {
140                 return err
141         }
142         err = vm.pushInt64(int64(len(str)), true)
143         if err != nil {
144                 return err
145         }
146         return nil
147 }
148
149 func opCatpushdata(vm *virtualMachine) error {
150         err := vm.applyCost(4)
151         if err != nil {
152                 return err
153         }
154         b, err := vm.pop(true)
155         if err != nil {
156                 return err
157         }
158         a, err := vm.pop(true)
159         if err != nil {
160                 return err
161         }
162         lb := len(b)
163         lens := int64(len(a) + lb)
164         err = vm.applyCost(lens)
165         if err != nil {
166                 return err
167         }
168         vm.deferCost(-lens)
169         return vm.push(append(a, PushdataBytes(b)...), true)
170 }