From b56cef3b1e69cf506bc9da085caea7c42d044e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 18 May 2015 14:35:32 +0200 Subject: [PATCH] Better eth <-> jit integer conversions. --- include/evmjit/JIT.h | 14 +++----------- libevmjit-cpp/Env.cpp | 16 ++++++++-------- libevmjit-cpp/JitVM.cpp | 18 +++++++++--------- libevmjit-cpp/Utils.h | 27 ++++++++++++++------------- 4 files changed, 34 insertions(+), 41 deletions(-) diff --git a/include/evmjit/JIT.h b/include/evmjit/JIT.h index cbf0e6e78..c12637a25 100644 --- a/include/evmjit/JIT.h +++ b/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(&_h); } }; +// TODO: Merge with ExecutionContext struct RuntimeData { enum Index diff --git a/libevmjit-cpp/Env.cpp b/libevmjit-cpp/Env.cpp index 366f5704a..b2382b8ba 100644 --- a/libevmjit-cpp/Env.cpp +++ b/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 diff --git a/libevmjit-cpp/JitVM.cpp b/libevmjit-cpp/JitVM.cpp index e9559026a..3bdbc37b8 100644 --- a/libevmjit-cpp/JitVM.cpp +++ b/libevmjit-cpp/JitVM.cpp @@ -39,25 +39,25 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _step) m_data.gasPrice = static_cast(_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(_ext.currentBlock.number); m_data.timestamp = static_cast(_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(&_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: diff --git a/libevmjit-cpp/Utils.h b/libevmjit-cpp/Utils.h index d52861fcc..ebb6ad97d 100644 --- a/libevmjit-cpp/Utils.h +++ b/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(_u & mask); + i.words[0] = static_cast(_u); _u >>= 64; - i.b = static_cast(_u & mask); + i.words[1] = static_cast(_u); _u >>= 64; - i.c = static_cast(_u & mask); + i.words[2] = static_cast(_u); _u >>= 64; - i.d = static_cast(_u & mask); + i.words[3] = static_cast(_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;