diff --git a/libevmjit/Compiler.cpp b/libevmjit/Compiler.cpp index 92a2b0e0c..d7240a415 100644 --- a/libevmjit/Compiler.cpp +++ b/libevmjit/Compiler.cpp @@ -721,8 +721,8 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti case Instruction::CALLDATALOAD: { - auto index = stack.pop(); - auto value = _ext.calldataload(index); + auto idx = stack.pop(); + auto value = _ext.calldataload(idx); stack.push(value); break; } diff --git a/libevmjit/Ext.cpp b/libevmjit/Ext.cpp index d35aebc68..9b1e0983b 100644 --- a/libevmjit/Ext.cpp +++ b/libevmjit/Ext.cpp @@ -45,7 +45,6 @@ std::array::value> const& getEnvFuncDescs() FuncDesc{"env_log", getFunctionType(Type::Void, {Type::EnvPtr, Type::BytePtr, Type::Size, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr})}, FuncDesc{"env_blockhash", getFunctionType(Type::Void, {Type::EnvPtr, Type::WordPtr, Type::WordPtr})}, FuncDesc{"env_extcode", getFunctionType(Type::BytePtr, {Type::EnvPtr, Type::WordPtr, Type::Size->getPointerTo()})}, - FuncDesc{"ext_calldataload", getFunctionType(Type::Void, {Type::RuntimeDataPtr, Type::WordPtr, Type::WordPtr})}, }}; return descs; @@ -101,12 +100,26 @@ void Ext::sstore(llvm::Value* _index, llvm::Value* _value) createCall(EnvFunc::sstore, {getRuntimeManager().getEnvPtr(), byPtr(_index), byPtr(_value)}); // Uses native endianness } -llvm::Value* Ext::calldataload(llvm::Value* _index) +llvm::Value* Ext::calldataload(llvm::Value* _idx) { auto ret = getArgAlloca(); - createCall(EnvFunc::calldataload, {getRuntimeManager().getDataPtr(), byPtr(_index), ret}); - ret = m_builder.CreateLoad(ret); - return Endianness::toNative(m_builder, ret); + auto result = m_builder.CreateBitCast(ret, Type::BytePtr); + + auto callDataSize = getRuntimeManager().getCallDataSize(); + auto callDataSize64 = m_builder.CreateTrunc(callDataSize, Type::Size); + auto idxValid = m_builder.CreateICmpULT(_idx, callDataSize); + auto idx = m_builder.CreateTrunc(m_builder.CreateSelect(idxValid, _idx, callDataSize), Type::Size, "idx"); + + auto end = m_builder.CreateNUWAdd(idx, m_builder.getInt64(32)); + end = m_builder.CreateSelect(m_builder.CreateICmpULE(end, callDataSize64), end, callDataSize64); + auto copySize = m_builder.CreateNUWSub(end, idx); + auto padSize = m_builder.CreateNUWSub(m_builder.getInt64(32), copySize); + auto dataBegin = m_builder.CreateGEP(Type::Byte, getRuntimeManager().getCallData(), idx); + m_builder.CreateMemCpy(result, dataBegin, copySize, 1); + auto pad = m_builder.CreateGEP(Type::Byte, result, copySize); + m_builder.CreateMemSet(pad, m_builder.getInt8(0), padSize, 1); + + return Endianness::toNative(m_builder, m_builder.CreateLoad(ret)); } llvm::Value* Ext::balance(llvm::Value* _address) diff --git a/libevmjit/Ext.h b/libevmjit/Ext.h index b0048d2e9..760f77df5 100644 --- a/libevmjit/Ext.h +++ b/libevmjit/Ext.h @@ -35,7 +35,6 @@ enum class EnvFunc log, blockhash, extcode, - calldataload, // Helper function, not client Env interface _size }; diff --git a/libevmjit/Stack.cpp b/libevmjit/Stack.cpp index 3a686c766..7cf514dea 100644 --- a/libevmjit/Stack.cpp +++ b/libevmjit/Stack.cpp @@ -175,32 +175,3 @@ void Stack::push(llvm::Value* _value) } } } - -extern "C" -{ - using namespace dev::eth::jit; - - EXPORT void ext_calldataload(RuntimeData* _rtData, i256* _index, byte* o_value) - { - // It asumes all indexes are less than 2^64 - - auto index = _index->a; - if (_index->b || _index->c || _index->d) // if bigger that 2^64 - index = std::numeric_limits::max(); // set max to fill with 0 leter - - auto data = _rtData->callData; - auto size = _rtData->callDataSize; - for (auto i = 0; i < 32; ++i) - { - if (index < size) - { - o_value[i] = data[index]; - ++index; // increment only if in range - } - else - o_value[i] = 0; - } - } - -} // extern "C" -