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  }