github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/protocol/vm/splice.go (about) 1 package vm 2 3 import "github.com/bytom/bytom/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 }