Browse Source

Better eth <-> jit integer conversions.

cl-refactor
Paweł Bylica 10 years ago
parent
commit
b56cef3b1e
  1. 14
      include/evmjit/JIT.h
  2. 16
      libevmjit-cpp/Env.cpp
  3. 18
      libevmjit-cpp/JitVM.cpp
  4. 27
      libevmjit-cpp/Utils.h

14
include/evmjit/JIT.h

@ -35,21 +35,13 @@ inline bool operator==(h256 _h1, h256 _h2)
/// Representation of 256-bit value binary compatible with LLVM i256
struct i256
{
uint64_t a = 0;
uint64_t b = 0;
uint64_t c = 0;
uint64_t d = 0;
uint64_t words[4] = {0,};
i256() = default;
i256(h256 _h)
{
a = _h.words[0];
b = _h.words[1];
c = _h.words[2];
d = _h.words[3];
}
i256(h256 _h) { *this = *reinterpret_cast<i256*>(&_h); }
};
// TODO: Merge with ExecutionContext
struct RuntimeData
{
enum Index

16
libevmjit-cpp/Env.cpp

@ -20,15 +20,15 @@ extern "C"
EXPORT void env_sload(ExtVMFace* _env, i256* _index, i256* o_value)
{
auto index = llvm2eth(*_index);
auto index = jit2eth(*_index);
auto value = _env->store(index); // Interface uses native endianness
*o_value = eth2llvm(value);
*o_value = eth2jit(value);
}
EXPORT void env_sstore(ExtVMFace* _env, i256* _index, i256* _value)
{
auto index = llvm2eth(*_index);
auto value = llvm2eth(*_value);
auto index = jit2eth(*_index);
auto value = jit2eth(*_value);
if (value == 0 && _env->store(index) != 0) // If delete
_env->sub.refunds += c_sstoreRefundGas; // Increase refund counter
@ -39,17 +39,17 @@ extern "C"
EXPORT void env_balance(ExtVMFace* _env, h256* _address, i256* o_value)
{
auto u = _env->balance(right160(*_address));
*o_value = eth2llvm(u);
*o_value = eth2jit(u);
}
EXPORT void env_blockhash(ExtVMFace* _env, i256* _number, h256* o_hash)
{
*o_hash = _env->blockhash(llvm2eth(*_number));
*o_hash = _env->blockhash(jit2eth(*_number));
}
EXPORT void env_create(ExtVMFace* _env, int64_t* io_gas, i256* _endowment, byte* _initBeg, uint64_t _initSize, h256* o_address)
{
auto endowment = llvm2eth(*_endowment);
auto endowment = jit2eth(*_endowment);
if (_env->balance(_env->myAddress) >= endowment && _env->depth < 1024)
{
u256 gas = *io_gas;
@ -63,7 +63,7 @@ extern "C"
EXPORT bool env_call(ExtVMFace* _env, int64_t* io_gas, int64_t _callGas, h256* _receiveAddress, i256* _value, byte* _inBeg, uint64_t _inSize, byte* _outBeg, uint64_t _outSize, h256* _codeAddress)
{
auto value = llvm2eth(*_value);
auto value = jit2eth(*_value);
auto receiveAddress = right160(*_receiveAddress);
auto codeAddress = right160(*_codeAddress);
const auto isCall = receiveAddress == codeAddress; // OPT: The same address pointer can be used if not CODECALL

18
libevmjit-cpp/JitVM.cpp

@ -39,25 +39,25 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _step)
m_data.gasPrice = static_cast<decltype(m_data.gasPrice)>(_ext.gasPrice);
m_data.callData = _ext.data.data();
m_data.callDataSize = _ext.data.size();
m_data.address = eth2llvm(fromAddress(_ext.myAddress));
m_data.caller = eth2llvm(fromAddress(_ext.caller));
m_data.origin = eth2llvm(fromAddress(_ext.origin));
m_data.callValue = eth2llvm(_ext.value);
m_data.coinBase = eth2llvm(fromAddress(_ext.currentBlock.coinbaseAddress));
m_data.difficulty = eth2llvm(_ext.currentBlock.difficulty);
m_data.gasLimit = eth2llvm(_ext.currentBlock.gasLimit);
m_data.address = eth2jit(fromAddress(_ext.myAddress));
m_data.caller = eth2jit(fromAddress(_ext.caller));
m_data.origin = eth2jit(fromAddress(_ext.origin));
m_data.callValue = eth2jit(_ext.value);
m_data.coinBase = eth2jit(fromAddress(_ext.currentBlock.coinbaseAddress));
m_data.difficulty = eth2jit(_ext.currentBlock.difficulty);
m_data.gasLimit = eth2jit(_ext.currentBlock.gasLimit);
m_data.number = static_cast<decltype(m_data.number)>(_ext.currentBlock.number);
m_data.timestamp = static_cast<decltype(m_data.timestamp)>(_ext.currentBlock.timestamp);
m_data.code = _ext.code.data();
m_data.codeSize = _ext.code.size();
m_data.codeHash = eth2llvm(sha3(_ext.code));
m_data.codeHash = eth2jit(sha3(_ext.code));
m_context.init(m_data, reinterpret_cast<evmjit::Env*>(&_ext));
auto exitCode = evmjit::JIT::exec(m_context);
switch (exitCode)
{
case evmjit::ReturnCode::Suicide:
_ext.suicide(right160(llvm2eth(m_data.address)));
_ext.suicide(right160(jit2eth(m_data.address)));
break;
case evmjit::ReturnCode::BadJumpDestination:

27
libevmjit-cpp/Utils.h

@ -7,34 +7,35 @@ namespace dev
namespace eth
{
inline u256 llvm2eth(evmjit::i256 _i)
/// Converts EVM JIT representation of 256-bit integer to eth type dev::u256.
inline u256 jit2eth(evmjit::i256 _i)
{
u256 u = 0;
u |= _i.d;
u256 u = _i.words[3];
u <<= 64;
u |= _i.c;
u |= _i.words[2];
u <<= 64;
u |= _i.b;
u |= _i.words[1];
u <<= 64;
u |= _i.a;
u |= _i.words[0];
return u;
}
inline evmjit::i256 eth2llvm(u256 _u)
/// Converts eth type dev::u256 to EVM JIT representation of 256-bit integer.
inline evmjit::i256 eth2jit(u256 _u)
{
evmjit::i256 i;
u256 mask = 0xFFFFFFFFFFFFFFFF;
i.a = static_cast<uint64_t>(_u & mask);
i.words[0] = static_cast<uint64_t>(_u);
_u >>= 64;
i.b = static_cast<uint64_t>(_u & mask);
i.words[1] = static_cast<uint64_t>(_u);
_u >>= 64;
i.c = static_cast<uint64_t>(_u & mask);
i.words[2] = static_cast<uint64_t>(_u);
_u >>= 64;
i.d = static_cast<uint64_t>(_u & mask);
i.words[3] = static_cast<uint64_t>(_u);
return i;
}
inline evmjit::h256 eth2llvm(h256 _u)
/// Converts eth type dev::h256 to EVM JIT representation of 256-bit hash value.
inline evmjit::h256 eth2jit(h256 _u)
{
/// Just directly copies memory
return *(evmjit::h256*)&_u;

Loading…
Cancel
Save