code: func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, error) {
  	if contract.CodeAddr != nil {
  		precompiles := PrecompiledContractsHomestead
  		if evm.ChainConfig().IsByzantium(evm.BlockNumber) {
  			precompiles = PrecompiledContractsByzantium
  		}
  		if p := precompiles[*contract.CodeAddr]; p != nil {
  			return RunPrecompiledContract(p, input, contract)
  		}
  	}
  	for _, interpreter := range evm.interpreters {
  		if interpreter.CanRun(contract.Code) {
  			if evm.interpreter != interpreter {
  				// Ensure that the interpreter pointer is set back
  				// to its current value upon return.
  				defer func(i Interpreter) {
  					evm.interpreter = i
  				}(evm.interpreter)
  				evm.interpreter = interpreter
  			}
  			return interpreter.Run(contract, input, readOnly)
  		}
  	}
  	return nil, ErrNoCompatibleInterpreter
  }
docs: // run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter.