github.com/MetalBlockchain/subnet-evm@v0.4.9/core/vm/common.go (about) 1 // (c) 2019-2020, Ava Labs, Inc. 2 // 3 // This file is a derived work, based on the go-ethereum library whose original 4 // notices appear below. 5 // 6 // It is distributed under a license compatible with the licensing terms of the 7 // original code from which it is derived. 8 // 9 // Much love to the original authors for their work. 10 // ********** 11 // Copyright 2014 The go-ethereum Authors 12 // This file is part of the go-ethereum library. 13 // 14 // The go-ethereum library is free software: you can redistribute it and/or modify 15 // it under the terms of the GNU Lesser General Public License as published by 16 // the Free Software Foundation, either version 3 of the License, or 17 // (at your option) any later version. 18 // 19 // The go-ethereum library is distributed in the hope that it will be useful, 20 // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 // GNU Lesser General Public License for more details. 23 // 24 // You should have received a copy of the GNU Lesser General Public License 25 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 26 27 package vm 28 29 import ( 30 "github.com/ethereum/go-ethereum/common" 31 "github.com/ethereum/go-ethereum/common/math" 32 "github.com/holiman/uint256" 33 ) 34 35 // calcMemSize64 calculates the required memory size, and returns 36 // the size and whether the result overflowed uint64 37 func calcMemSize64(off, l *uint256.Int) (uint64, bool) { 38 if !l.IsUint64() { 39 return 0, true 40 } 41 return calcMemSize64WithUint(off, l.Uint64()) 42 } 43 44 // calcMemSize64WithUint calculates the required memory size, and returns 45 // the size and whether the result overflowed uint64 46 // Identical to calcMemSize64, but length is a uint64 47 func calcMemSize64WithUint(off *uint256.Int, length64 uint64) (uint64, bool) { 48 // if length is zero, memsize is always zero, regardless of offset 49 if length64 == 0 { 50 return 0, false 51 } 52 // Check that offset doesn't overflow 53 offset64, overflow := off.Uint64WithOverflow() 54 if overflow { 55 return 0, true 56 } 57 val := offset64 + length64 58 // if value < either of it's parts, then it overflowed 59 return val, val < offset64 60 } 61 62 // getData returns a slice from the data based on the start and size and pads 63 // up to size with zero's. This function is overflow safe. 64 func getData(data []byte, start uint64, size uint64) []byte { 65 length := uint64(len(data)) 66 if start > length { 67 start = length 68 } 69 end := start + size 70 if end > length { 71 end = length 72 } 73 return common.RightPadBytes(data[start:end], int(size)) 74 } 75 76 // toWordSize returns the ceiled word size required for memory expansion. 77 func toWordSize(size uint64) uint64 { 78 if size > math.MaxUint64-31 { 79 return math.MaxUint64/32 + 1 80 } 81 82 return (size + 31) / 32 83 } 84 85 func allZero(b []byte) bool { 86 for _, byte := range b { 87 if byte != 0 { 88 return false 89 } 90 } 91 return true 92 }