github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/execution/evm/code.go (about)

     1  package evm
     2  
     3  import (
     4  	"github.com/hyperledger/burrow/acm"
     5  	"github.com/hyperledger/burrow/execution/evm/asm"
     6  	"github.com/tmthrgd/go-bitset"
     7  )
     8  
     9  type Code struct {
    10  	Bytecode     acm.Bytecode
    11  	OpcodeBitset bitset.Bitset
    12  }
    13  
    14  // Build a Code object that includes analysis of which symbols are opcodes versus push data
    15  func NewCode(code []byte) *Code {
    16  	return &Code{
    17  		Bytecode:     code,
    18  		OpcodeBitset: opcodeBitset(code),
    19  	}
    20  }
    21  
    22  func (code *Code) Length() uint64 {
    23  	if code == nil {
    24  		return 0
    25  	}
    26  	return uint64(len(code.Bytecode))
    27  }
    28  
    29  func (code *Code) GetBytecode() acm.Bytecode {
    30  	if code == nil {
    31  		return nil
    32  	}
    33  	return code.Bytecode
    34  }
    35  
    36  func (code *Code) IsOpcode(indexOfSymbolInCode uint64) bool {
    37  	if code == nil || indexOfSymbolInCode >= uint64(code.OpcodeBitset.Len()) {
    38  		return false
    39  	}
    40  	return code.OpcodeBitset.IsSet(uint(indexOfSymbolInCode))
    41  }
    42  
    43  func (code *Code) IsPushData(indexOfSymbolInCode uint64) bool {
    44  	return !code.IsOpcode(indexOfSymbolInCode)
    45  }
    46  
    47  func (code *Code) GetSymbol(n uint64) asm.OpCode {
    48  	if code.Length() <= n {
    49  		return asm.STOP
    50  	} else {
    51  		return asm.OpCode(code.Bytecode[n])
    52  	}
    53  }
    54  
    55  // If code[i] is an opcode (rather than PUSH data) then bitset.IsSet(i) will be true
    56  func opcodeBitset(code []byte) bitset.Bitset {
    57  	bs := bitset.New(uint(len(code)))
    58  	for i := 0; i < len(code); i++ {
    59  		bs.Set(uint(i))
    60  		symbol := asm.OpCode(code[i])
    61  		if symbol >= asm.PUSH1 && symbol <= asm.PUSH32 {
    62  			i += int(symbol - asm.PUSH1 + 1)
    63  		}
    64  	}
    65  	return bs
    66  }