Browse Source

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

Conflicts:
	libevmjit/Compiler.cpp
cl-refactor
artur-zawlocki 11 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) void Compiler::createBasicBlocks(bytesConstRef bytecode)
{ {
std::set<ProgramCounter> splitPoints; // Sorted collections of instruction indices where basic blocks start/end 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::map<ProgramCounter, ProgramCounter> directJumpTargets;
std::vector<ProgramCounter> indirectJumpTargets; 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) for (auto curr = bytecode.begin(); curr != bytecode.end(); ++curr)
{ {
ProgramCounter currentPC = curr - bytecode.begin(); ProgramCounter currentPC = curr - bytecode.begin();
validJumpTargets[currentPC] = 1; validJumpTargets[currentPC] = true;
auto inst = static_cast<Instruction>(*curr); auto inst = static_cast<Instruction>(*curr);
switch (inst) switch (inst)
@ -473,6 +475,7 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
memory.require(inOff, inSize); memory.require(inOff, inSize);
auto hash = ext.sha3(inOff, inSize); auto hash = ext.sha3(inOff, inSize);
stack.push(hash); stack.push(hash);
break;
} }
case Instruction::POP: case Instruction::POP:

3
libevmjit/Endianness.cpp

@ -12,9 +12,10 @@ namespace eth
namespace jit 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 // TODO: Native is Little Endian
assert(_word->getType() == Type::i256);
auto bswap = llvm::Intrinsic::getDeclaration(_builder.GetInsertBlock()->getParent()->getParent(), llvm::Intrinsic::bswap, Type::i256); auto bswap = llvm::Intrinsic::getDeclaration(_builder.GetInsertBlock()->getParent()->getParent(), llvm::Intrinsic::bswap, Type::i256);
return _builder.CreateCall(bswap, _word); return _builder.CreateCall(bswap, _word);
} }

7
libevmjit/Endianness.h

@ -14,7 +14,12 @@ class Endianness
{ {
public: 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()); auto exec = std::unique_ptr<llvm::ExecutionEngine>(builder.create());
if (!exec) if (!exec)
{ BOOST_THROW_EXCEPTION(Exception() << errinfo_comment(errorMsg));
if (!errorMsg.empty())
std::cerr << "error creating EE: " << errorMsg << std::endl;
else
std::cerr << "unknown error creating llvm::ExecutionEngine" << std::endl;
exit(1);
}
_module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module _module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module
exec->finalizeObject(); exec->finalizeObject();
@ -106,10 +100,7 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, u256& _gas, ExtV
auto entryFunc = module->getFunction("main"); auto entryFunc = module->getFunction("main");
if (!entryFunc) if (!entryFunc)
{ BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("main function not found"));
std::cerr << "main function not found\n";
exit(1);
}
ReturnCode returnCode; ReturnCode returnCode;
std::jmp_buf buf; 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 initOff = static_cast<size_t>(llvm2eth(*_initOff));
auto initSize = static_cast<size_t>(llvm2eth(*_initSize)); auto initSize = static_cast<size_t>(llvm2eth(*_initSize));
auto&& initRef = bytesConstRef(Runtime::getMemory().data() + initOff, 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); h256 address = ext.create(endowment, &gas, initRef, onOp);
*_address = address; *_address = address;
} }

18
libevmjit/GasMeter.cpp

@ -30,26 +30,26 @@ uint64_t getStepCost(Instruction inst) // TODO: Add this function to FeeSructure
return 0; return 0;
case Instruction::SSTORE: case Instruction::SSTORE:
return static_cast<uint64_t>(FeeStructure::c_sstoreGas); return static_cast<uint64_t>(c_sstoreGas);
case Instruction::SLOAD: case Instruction::SLOAD:
return static_cast<uint64_t>(FeeStructure::c_sloadGas); return static_cast<uint64_t>(c_sloadGas);
case Instruction::SHA3: case Instruction::SHA3:
return static_cast<uint64_t>(FeeStructure::c_sha3Gas); return static_cast<uint64_t>(c_sha3Gas);
case Instruction::BALANCE: case Instruction::BALANCE:
return static_cast<uint64_t>(FeeStructure::c_sha3Gas); return static_cast<uint64_t>(c_sha3Gas);
case Instruction::CALL: case Instruction::CALL:
case Instruction::CALLCODE: case Instruction::CALLCODE:
return static_cast<uint64_t>(FeeStructure::c_callGas); return static_cast<uint64_t>(c_callGas);
case Instruction::CREATE: case Instruction::CREATE:
return static_cast<uint64_t>(FeeStructure::c_createGas); return static_cast<uint64_t>(c_createGas);
default: // Assumes instruction code is valid 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 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 // [ADD] if oldValue == 0 and newValue != 0 => 2*cost
// [DEL] if oldValue != 0 and newValue == 0 => 0 // [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) void GasMeter::checkMemory(llvm::Value* _additionalMemoryInWords, llvm::IRBuilder<>& _builder)
{ {
// Memory uses other builder, but that can be changes later // 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); _builder.CreateCall(m_gasCheckFunc, cost);
} }

6
libevmjit/Memory.cpp

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

Loading…
Cancel
Save