Browse Source

Merge branch 'develop-evmcc' of github.com:imapp-pl/ethereum into develop-evmcc

Conflicts:
	libevmjit/Compiler.cpp
cl-refactor
artur-zawlocki 10 years ago
parent
commit
937fbaa56a
  1. 1
      evmcc/test/mem/mstore1.evm
  2. 6
      evmcc/test/mem/mstore1.lll
  3. 9
      libevmjit/Compiler.cpp
  4. 3
      libevmjit/Endianness.cpp
  5. 7
      libevmjit/Endianness.h
  6. 13
      libevmjit/ExecutionEngine.cpp
  7. 2
      libevmjit/Ext.cpp
  8. 18
      libevmjit/GasMeter.cpp
  9. 6
      libevmjit/Memory.cpp

1
evmcc/test/mem/mstore1.evm

@ -0,0 +1 @@
6001600054

6
evmcc/test/mem/mstore1.lll

@ -0,0 +1,6 @@
(asm ;; []
1
0
MSTORE ;; [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]
)

9
libevmjit/Compiler.cpp

@ -34,16 +34,18 @@ Compiler::Compiler():
void Compiler::createBasicBlocks(bytesConstRef bytecode)
{
std::set<ProgramCounter> splitPoints; // Sorted collections of instruction indices where basic blocks start/end
splitPoints.insert(0); // First basic block
std::map<ProgramCounter, ProgramCounter> directJumpTargets;
std::vector<ProgramCounter> indirectJumpTargets;
boost::dynamic_bitset<> validJumpTargets(bytecode.size());
boost::dynamic_bitset<> validJumpTargets(std::max(bytecode.size(), size_t(1)));
splitPoints.insert(0); // First basic block
validJumpTargets[0] = true;
for (auto curr = bytecode.begin(); curr != bytecode.end(); ++curr)
{
ProgramCounter currentPC = curr - bytecode.begin();
validJumpTargets[currentPC] = 1;
validJumpTargets[currentPC] = true;
auto inst = static_cast<Instruction>(*curr);
switch (inst)
@ -473,6 +475,7 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
memory.require(inOff, inSize);
auto hash = ext.sha3(inOff, inSize);
stack.push(hash);
break;
}
case Instruction::POP:

3
libevmjit/Endianness.cpp

@ -12,9 +12,10 @@ namespace eth
namespace jit
{
llvm::Value* Endianness::toBE(llvm::IRBuilder<>& _builder, llvm::Value* _word)
llvm::Value* Endianness::bswap(llvm::IRBuilder<>& _builder, llvm::Value* _word)
{
// TODO: Native is Little Endian
assert(_word->getType() == Type::i256);
auto bswap = llvm::Intrinsic::getDeclaration(_builder.GetInsertBlock()->getParent()->getParent(), llvm::Intrinsic::bswap, Type::i256);
return _builder.CreateCall(bswap, _word);
}

7
libevmjit/Endianness.h

@ -14,7 +14,12 @@ class Endianness
{
public:
static llvm::Value* toBE(llvm::IRBuilder<>& _builder, llvm::Value* _word);
static llvm::Value* toBE(llvm::IRBuilder<>& _builder, llvm::Value* _word) { return bswap(_builder, _word); }
static llvm::Value* toNative(llvm::IRBuilder<>& _builder, llvm::Value* _word) { return bswap(_builder, _word); }
private:
static llvm::Value* bswap(llvm::IRBuilder<>& _builder, llvm::Value* _word);
};
}

13
libevmjit/ExecutionEngine.cpp

@ -70,13 +70,7 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, u256& _gas, ExtV
auto exec = std::unique_ptr<llvm::ExecutionEngine>(builder.create());
if (!exec)
{
if (!errorMsg.empty())
std::cerr << "error creating EE: " << errorMsg << std::endl;
else
std::cerr << "unknown error creating llvm::ExecutionEngine" << std::endl;
exit(1);
}
BOOST_THROW_EXCEPTION(Exception() << errinfo_comment(errorMsg));
_module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module
exec->finalizeObject();
@ -106,10 +100,7 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, u256& _gas, ExtV
auto entryFunc = module->getFunction("main");
if (!entryFunc)
{
std::cerr << "main function not found\n";
exit(1);
}
BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("main function not found"));
ReturnCode returnCode;
std::jmp_buf buf;

2
libevmjit/Ext.cpp

@ -310,7 +310,7 @@ EXPORT void ext_create(i256* _endowment, i256* _initOff, i256* _initSize, h256*
auto initOff = static_cast<size_t>(llvm2eth(*_initOff));
auto initSize = static_cast<size_t>(llvm2eth(*_initSize));
auto&& initRef = bytesConstRef(Runtime::getMemory().data() + initOff, initSize);
auto&& onOp = bytesConstRef(); // TODO: Handle that thing
OnOpFunc onOp{}; // TODO: Handle that thing
h256 address = ext.create(endowment, &gas, initRef, onOp);
*_address = address;
}

18
libevmjit/GasMeter.cpp

@ -30,26 +30,26 @@ uint64_t getStepCost(Instruction inst) // TODO: Add this function to FeeSructure
return 0;
case Instruction::SSTORE:
return static_cast<uint64_t>(FeeStructure::c_sstoreGas);
return static_cast<uint64_t>(c_sstoreGas);
case Instruction::SLOAD:
return static_cast<uint64_t>(FeeStructure::c_sloadGas);
return static_cast<uint64_t>(c_sloadGas);
case Instruction::SHA3:
return static_cast<uint64_t>(FeeStructure::c_sha3Gas);
return static_cast<uint64_t>(c_sha3Gas);
case Instruction::BALANCE:
return static_cast<uint64_t>(FeeStructure::c_sha3Gas);
return static_cast<uint64_t>(c_sha3Gas);
case Instruction::CALL:
case Instruction::CALLCODE:
return static_cast<uint64_t>(FeeStructure::c_callGas);
return static_cast<uint64_t>(c_callGas);
case Instruction::CREATE:
return static_cast<uint64_t>(FeeStructure::c_createGas);
return static_cast<uint64_t>(c_createGas);
default: // Assumes instruction code is valid
return static_cast<uint64_t>(FeeStructure::c_stepGas);
return static_cast<uint64_t>(c_stepGas);
}
}
@ -134,7 +134,7 @@ void GasMeter::countSStore(Ext& _ext, llvm::Value* _index, llvm::Value* _newValu
{
assert(!m_checkCall); // Everything should've been commited before
static const auto sstoreCost = static_cast<uint64_t>(FeeStructure::c_sstoreGas);
static const auto sstoreCost = static_cast<uint64_t>(c_sstoreGas);
// [ADD] if oldValue == 0 and newValue != 0 => 2*cost
// [DEL] if oldValue != 0 and newValue == 0 => 0
@ -187,7 +187,7 @@ void GasMeter::commitCostBlock(llvm::Value* _additionalCost)
void GasMeter::checkMemory(llvm::Value* _additionalMemoryInWords, llvm::IRBuilder<>& _builder)
{
// Memory uses other builder, but that can be changes later
auto cost = _builder.CreateMul(_additionalMemoryInWords, Constant::get(static_cast<uint64_t>(FeeStructure::c_memoryGas)), "memcost");
auto cost = _builder.CreateMul(_additionalMemoryInWords, Constant::get(static_cast<uint64_t>(c_memoryGas)), "memcost");
_builder.CreateCall(m_gasCheckFunc, cost);
}

6
libevmjit/Memory.cpp

@ -14,6 +14,7 @@
#include "Type.h"
#include "Runtime.h"
#include "GasMeter.h"
#include "Endianness.h"
namespace dev
{
@ -117,12 +118,15 @@ llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, GasMet
{
llvm::Value* value = ++func->arg_begin();
value->setName("value");
if (isWord)
value = Endianness::toBE(m_builder, value);
m_builder.CreateStore(value, ptr);
m_builder.CreateRetVoid();
}
else
{
auto ret = m_builder.CreateLoad(ptr);
llvm::Value* ret = m_builder.CreateLoad(ptr);
ret = Endianness::toNative(m_builder, ret);
m_builder.CreateRet(ret);
}

Loading…
Cancel
Save