Browse Source
Conflicts: evmjit/libevmjit/Arith256.cpp evmjit/libevmjit/ExecutionEngine.cpp evmjit/libevmjit/Runtime.hcl-refactor
Paweł Bylica
10 years ago
35 changed files with 341 additions and 290 deletions
@ -1,47 +1,51 @@ |
|||
#include "CompilerHelper.h" |
|||
#include "RuntimeManager.h" |
|||
#include <llvm/IR/Module.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
namespace jit |
|||
{ |
|||
|
|||
CompilerHelper::CompilerHelper(llvm::IRBuilder<>& _builder) : |
|||
m_builder(_builder) |
|||
{} |
|||
|
|||
llvm::Module* CompilerHelper::getModule() |
|||
{ |
|||
assert(m_builder.GetInsertBlock()); |
|||
assert(m_builder.GetInsertBlock()->getParent()); // BB must be in a function
|
|||
return m_builder.GetInsertBlock()->getParent()->getParent(); |
|||
} |
|||
|
|||
llvm::Function* CompilerHelper::getMainFunction() |
|||
{ |
|||
// TODO: Rename or change semantics of getMainFunction() function
|
|||
assert(m_builder.GetInsertBlock()); |
|||
auto mainFunc = m_builder.GetInsertBlock()->getParent(); |
|||
assert(mainFunc); |
|||
if (mainFunc == &mainFunc->getParent()->getFunctionList().front()) // Main function is the first one in module
|
|||
return mainFunc; |
|||
return nullptr; |
|||
} |
|||
|
|||
llvm::CallInst* CompilerHelper::createCall(llvm::Function* _func, std::initializer_list<llvm::Value*> const& _args) |
|||
{ |
|||
return getBuilder().CreateCall(_func, {_args.begin(), _args.size()}); |
|||
} |
|||
|
|||
|
|||
RuntimeHelper::RuntimeHelper(RuntimeManager& _runtimeManager): |
|||
CompilerHelper(_runtimeManager.getBuilder()), |
|||
m_runtimeManager(_runtimeManager) |
|||
{} |
|||
|
|||
} |
|||
} |
|||
} |
|||
#include "CompilerHelper.h" |
|||
|
|||
#include "preprocessor/llvm_includes_start.h" |
|||
#include <llvm/IR/Module.h> |
|||
#include "preprocessor/llvm_includes_end.h" |
|||
|
|||
#include "RuntimeManager.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
namespace jit |
|||
{ |
|||
|
|||
CompilerHelper::CompilerHelper(llvm::IRBuilder<>& _builder) : |
|||
m_builder(_builder) |
|||
{} |
|||
|
|||
llvm::Module* CompilerHelper::getModule() |
|||
{ |
|||
assert(m_builder.GetInsertBlock()); |
|||
assert(m_builder.GetInsertBlock()->getParent()); // BB must be in a function
|
|||
return m_builder.GetInsertBlock()->getParent()->getParent(); |
|||
} |
|||
|
|||
llvm::Function* CompilerHelper::getMainFunction() |
|||
{ |
|||
// TODO: Rename or change semantics of getMainFunction() function
|
|||
assert(m_builder.GetInsertBlock()); |
|||
auto mainFunc = m_builder.GetInsertBlock()->getParent(); |
|||
assert(mainFunc); |
|||
if (mainFunc == &mainFunc->getParent()->getFunctionList().front()) // Main function is the first one in module
|
|||
return mainFunc; |
|||
return nullptr; |
|||
} |
|||
|
|||
llvm::CallInst* CompilerHelper::createCall(llvm::Function* _func, std::initializer_list<llvm::Value*> const& _args) |
|||
{ |
|||
return getBuilder().CreateCall(_func, {_args.begin(), _args.size()}); |
|||
} |
|||
|
|||
|
|||
RuntimeHelper::RuntimeHelper(RuntimeManager& _runtimeManager): |
|||
CompilerHelper(_runtimeManager.getBuilder()), |
|||
m_runtimeManager(_runtimeManager) |
|||
{} |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
@ -1,79 +1,79 @@ |
|||
#pragma once |
|||
#pragma once |
|||
|
|||
#include "preprocessor/llvm_includes_start.h" |
|||
#include "preprocessor/llvm_includes_start.h" |
|||
#include <llvm/IR/IRBuilder.h> |
|||
#include "preprocessor/llvm_includes_end.h" |
|||
|
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
namespace jit |
|||
{ |
|||
class RuntimeManager; |
|||
|
|||
/// Base class for compiler helpers like Memory, GasMeter, etc.
|
|||
class CompilerHelper |
|||
{ |
|||
protected: |
|||
CompilerHelper(llvm::IRBuilder<>& _builder); |
|||
|
|||
CompilerHelper(const CompilerHelper&) = delete; |
|||
CompilerHelper& operator=(CompilerHelper) = delete; |
|||
|
|||
/// Reference to the IR module being compiled
|
|||
llvm::Module* getModule(); |
|||
|
|||
/// Reference to the main module function
|
|||
llvm::Function* getMainFunction(); |
|||
|
|||
/// Reference to parent compiler IR builder
|
|||
llvm::IRBuilder<>& m_builder; |
|||
llvm::IRBuilder<>& getBuilder() { return m_builder; } |
|||
|
|||
llvm::CallInst* createCall(llvm::Function* _func, std::initializer_list<llvm::Value*> const& _args); |
|||
|
|||
friend class RuntimeHelper; |
|||
}; |
|||
|
|||
|
|||
/// Compiler helper that depends on runtime data
|
|||
class RuntimeHelper : public CompilerHelper |
|||
{ |
|||
protected: |
|||
RuntimeHelper(RuntimeManager& _runtimeManager); |
|||
|
|||
RuntimeManager& getRuntimeManager() { return m_runtimeManager; } |
|||
|
|||
private: |
|||
RuntimeManager& m_runtimeManager; |
|||
}; |
|||
|
|||
|
|||
/// Saves the insert point of the IR builder and restores it when destructed
|
|||
struct InsertPointGuard |
|||
{ |
|||
InsertPointGuard(llvm::IRBuilder<>& _builder) : |
|||
m_builder(_builder), |
|||
m_insertBB(m_builder.GetInsertBlock()), |
|||
m_insertPt(m_builder.GetInsertPoint()) |
|||
{} |
|||
|
|||
InsertPointGuard(const InsertPointGuard&) = delete; |
|||
void operator=(InsertPointGuard) = delete; |
|||
|
|||
~InsertPointGuard() |
|||
{ |
|||
m_builder.SetInsertPoint(m_insertBB, m_insertPt); |
|||
} |
|||
|
|||
private: |
|||
llvm::IRBuilder<>& m_builder; |
|||
llvm::BasicBlock* m_insertBB; |
|||
llvm::BasicBlock::iterator m_insertPt; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
} |
|||
#include "preprocessor/llvm_includes_end.h" |
|||
|
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
namespace jit |
|||
{ |
|||
class RuntimeManager; |
|||
|
|||
/// Base class for compiler helpers like Memory, GasMeter, etc.
|
|||
class CompilerHelper |
|||
{ |
|||
protected: |
|||
CompilerHelper(llvm::IRBuilder<>& _builder); |
|||
|
|||
CompilerHelper(const CompilerHelper&) = delete; |
|||
CompilerHelper& operator=(CompilerHelper) = delete; |
|||
|
|||
/// Reference to the IR module being compiled
|
|||
llvm::Module* getModule(); |
|||
|
|||
/// Reference to the main module function
|
|||
llvm::Function* getMainFunction(); |
|||
|
|||
/// Reference to parent compiler IR builder
|
|||
llvm::IRBuilder<>& m_builder; |
|||
llvm::IRBuilder<>& getBuilder() { return m_builder; } |
|||
|
|||
llvm::CallInst* createCall(llvm::Function* _func, std::initializer_list<llvm::Value*> const& _args); |
|||
|
|||
friend class RuntimeHelper; |
|||
}; |
|||
|
|||
|
|||
/// Compiler helper that depends on runtime data
|
|||
class RuntimeHelper : public CompilerHelper |
|||
{ |
|||
protected: |
|||
RuntimeHelper(RuntimeManager& _runtimeManager); |
|||
|
|||
RuntimeManager& getRuntimeManager() { return m_runtimeManager; } |
|||
|
|||
private: |
|||
RuntimeManager& m_runtimeManager; |
|||
}; |
|||
|
|||
|
|||
/// Saves the insert point of the IR builder and restores it when destructed
|
|||
struct InsertPointGuard |
|||
{ |
|||
InsertPointGuard(llvm::IRBuilder<>& _builder) : |
|||
m_builder(_builder), |
|||
m_insertBB(m_builder.GetInsertBlock()), |
|||
m_insertPt(m_builder.GetInsertPoint()) |
|||
{} |
|||
|
|||
InsertPointGuard(const InsertPointGuard&) = delete; |
|||
void operator=(InsertPointGuard) = delete; |
|||
|
|||
~InsertPointGuard() |
|||
{ |
|||
m_builder.SetInsertPoint(m_insertBB, m_insertPt); |
|||
} |
|||
|
|||
private: |
|||
llvm::IRBuilder<>& m_builder; |
|||
llvm::BasicBlock* m_insertBB; |
|||
llvm::BasicBlock::iterator m_insertPt; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
@ -1,38 +1,39 @@ |
|||
#include "Endianness.h" |
|||
#include "Type.h" |
|||
|
|||
#include "preprocessor/llvm_includes_start.h" |
|||
#include <llvm/IR/IntrinsicInst.h> |
|||
#include "preprocessor/llvm_includes_end.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
namespace jit |
|||
{ |
|||
|
|||
llvm::Value* Endianness::bswapIfLE(llvm::IRBuilder<>& _builder, llvm::Value* _word) |
|||
{ |
|||
union tester |
|||
{ |
|||
unsigned int x; |
|||
unsigned char isLE; |
|||
}; |
|||
|
|||
if (tester{1}.isLE) |
|||
{ |
|||
// FIXME: Disabled because of problems with BYTE
|
|||
//if (auto constant = llvm::dyn_cast<llvm::ConstantInt>(_word))
|
|||
// return _builder.getInt(constant->getValue().byteSwap());
|
|||
|
|||
// OPT: Cache func declaration?
|
|||
auto bswapFunc = llvm::Intrinsic::getDeclaration(_builder.GetInsertBlock()->getParent()->getParent(), llvm::Intrinsic::bswap, Type::Word); |
|||
return _builder.CreateCall(bswapFunc, _word); |
|||
} |
|||
return _word; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
#include "Endianness.h" |
|||
|
|||
#include "preprocessor/llvm_includes_start.h" |
|||
#include <llvm/IR/IntrinsicInst.h> |
|||
#include "preprocessor/llvm_includes_end.h" |
|||
|
|||
#include "Type.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
namespace jit |
|||
{ |
|||
|
|||
llvm::Value* Endianness::bswapIfLE(llvm::IRBuilder<>& _builder, llvm::Value* _word) |
|||
{ |
|||
union tester |
|||
{ |
|||
unsigned int x; |
|||
unsigned char isLE; |
|||
}; |
|||
|
|||
if (tester{1}.isLE) |
|||
{ |
|||
// FIXME: Disabled because of problems with BYTE
|
|||
//if (auto constant = llvm::dyn_cast<llvm::ConstantInt>(_word))
|
|||
// return _builder.getInt(constant->getValue().byteSwap());
|
|||
|
|||
// OPT: Cache func declaration?
|
|||
auto bswapFunc = llvm::Intrinsic::getDeclaration(_builder.GetInsertBlock()->getParent()->getParent(), llvm::Intrinsic::bswap, Type::Word); |
|||
return _builder.CreateCall(bswapFunc, _word); |
|||
} |
|||
return _word; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
@ -1,25 +1,25 @@ |
|||
#pragma once |
|||
|
|||
#include "preprocessor/llvm_includes_start.h" |
|||
#include <llvm/IR/IRBuilder.h> |
|||
#include "preprocessor/llvm_includes_end.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
namespace jit |
|||
{ |
|||
|
|||
struct Endianness |
|||
{ |
|||
static llvm::Value* toBE(llvm::IRBuilder<>& _builder, llvm::Value* _word) { return bswapIfLE(_builder, _word); } |
|||
static llvm::Value* toNative(llvm::IRBuilder<>& _builder, llvm::Value* _word) { return bswapIfLE(_builder, _word); } |
|||
|
|||
private: |
|||
static llvm::Value* bswapIfLE(llvm::IRBuilder<>& _builder, llvm::Value* _word); |
|||
}; |
|||
|
|||
} |
|||
} |
|||
} |
|||
#pragma once |
|||
|
|||
#include "preprocessor/llvm_includes_start.h" |
|||
#include <llvm/IR/IRBuilder.h> |
|||
#include "preprocessor/llvm_includes_end.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
namespace jit |
|||
{ |
|||
|
|||
struct Endianness |
|||
{ |
|||
static llvm::Value* toBE(llvm::IRBuilder<>& _builder, llvm::Value* _word) { return bswapIfLE(_builder, _word); } |
|||
static llvm::Value* toNative(llvm::IRBuilder<>& _builder, llvm::Value* _word) { return bswapIfLE(_builder, _word); } |
|||
|
|||
private: |
|||
static llvm::Value* bswapIfLE(llvm::IRBuilder<>& _builder, llvm::Value* _word); |
|||
}; |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
@ -1,39 +1,40 @@ |
|||
#pragma once |
|||
#include "RuntimeData.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
namespace jit |
|||
{ |
|||
|
|||
using StackImpl = std::vector<i256>; |
|||
using MemoryImpl = bytes; |
|||
|
|||
class Runtime |
|||
{ |
|||
public: |
|||
Runtime(RuntimeData* _data, Env* _env); |
|||
|
|||
Runtime(const Runtime&) = delete; |
|||
Runtime& operator=(const Runtime&) = delete; |
|||
|
|||
StackImpl& getStack() { return m_stack; } |
|||
MemoryImpl& getMemory() { return m_memory; } |
|||
|
|||
bytes_ref getReturnData() const; |
|||
|
|||
private: |
|||
RuntimeData& m_data; ///< Pointer to data. Expected by compiled contract.
|
|||
Env& m_env; ///< Pointer to environment proxy. Expected by compiled contract.
|
|||
void* m_currJmpBuf = nullptr; ///< Pointer to jump buffer. Expected by compiled contract.
|
|||
byte* m_memoryData = nullptr; |
|||
i256 m_memorySize; |
|||
StackImpl m_stack; |
|||
MemoryImpl m_memory; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
} |
|||
#pragma once |
|||
|
|||
#include "RuntimeData.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
namespace jit |
|||
{ |
|||
|
|||
using StackImpl = std::vector<i256>; |
|||
using MemoryImpl = bytes; |
|||
|
|||
class Runtime |
|||
{ |
|||
public: |
|||
Runtime(RuntimeData* _data, Env* _env); |
|||
|
|||
Runtime(const Runtime&) = delete; |
|||
Runtime& operator=(const Runtime&) = delete; |
|||
|
|||
StackImpl& getStack() { return m_stack; } |
|||
MemoryImpl& getMemory() { return m_memory; } |
|||
|
|||
bytes_ref getReturnData() const; |
|||
|
|||
private: |
|||
RuntimeData& m_data; ///< Pointer to data. Expected by compiled contract.
|
|||
Env& m_env; ///< Pointer to environment proxy. Expected by compiled contract.
|
|||
void* m_currJmpBuf = nullptr; ///< Pointer to jump buffer. Expected by compiled contract.
|
|||
byte* m_memoryData = nullptr; |
|||
i256 m_memorySize; |
|||
StackImpl m_stack; |
|||
MemoryImpl m_memory; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
@ -1,3 +1,5 @@ |
|||
|
|||
#pragma warning(pop) |
|||
#pragma GCC diagnostic pop |
|||
#if defined(_MSC_VER) |
|||
#pragma warning(pop) |
|||
#else |
|||
#pragma GCC diagnostic pop |
|||
#endif |
|||
|
@ -1,5 +1,8 @@ |
|||
|
|||
#pragma warning(push) |
|||
#pragma warning(disable: 4267 4244 4800) |
|||
#pragma GCC diagnostic push |
|||
#pragma GCC diagnostic ignored "-Wunused-parameter" |
|||
#if defined(_MSC_VER) |
|||
#pragma warning(push) |
|||
#pragma warning(disable: 4267 4244 4800) |
|||
#else |
|||
#pragma GCC diagnostic push |
|||
#pragma GCC diagnostic ignored "-Wunused-parameter" |
|||
#pragma GCC diagnostic ignored "-Wconversion" |
|||
#endif |
|||
|
Loading…
Reference in new issue