Browse Source

Separate runtime classes

cl-refactor
Paweł Bylica 10 years ago
parent
commit
aa771582a7
  1. 2
      libevmjit/Compiler.cpp
  2. 2
      libevmjit/CompilerHelper.cpp
  3. 2
      libevmjit/GasMeter.cpp
  4. 2
      libevmjit/Memory.cpp
  5. 143
      libevmjit/Runtime.cpp
  6. 61
      libevmjit/Runtime.h
  7. 51
      libevmjit/RuntimeData.h
  8. 159
      libevmjit/RuntimeManager.cpp
  9. 46
      libevmjit/RuntimeManager.h
  10. 1
      libevmjit/Stack.cpp
  11. 4
      libevmjit/Type.cpp

2
libevmjit/Compiler.cpp

@ -22,7 +22,7 @@
#include "Utils.h"
#include "Endianness.h"
#include "Arith256.h"
#include "Runtime.h"
#include "RuntimeManager.h"
namespace dev
{

2
libevmjit/CompilerHelper.cpp

@ -3,7 +3,7 @@
#include <llvm/IR/Function.h>
#include "Runtime.h"
#include "RuntimeManager.h"
namespace dev
{

2
libevmjit/GasMeter.cpp

@ -7,7 +7,7 @@
#include "Type.h"
#include "Ext.h"
#include "Runtime.h"
#include "RuntimeManager.h"
namespace dev
{

2
libevmjit/Memory.cpp

@ -14,7 +14,7 @@
#include "Runtime.h"
#include "GasMeter.h"
#include "Endianness.h"
#include "Runtime.h"
#include "RuntimeManager.h"
namespace dev
{

143
libevmjit/Runtime.cpp

@ -5,9 +5,7 @@
#include <llvm/IR/Function.h>
#include <llvm/IR/IntrinsicInst.h>
#include <libevm/VM.h>
#include "Type.h"
//#include <libevm/VM.h>
namespace dev
{
@ -16,48 +14,6 @@ namespace eth
namespace jit
{
llvm::StructType* RuntimeData::getType()
{
static llvm::StructType* type = nullptr;
if (!type)
{
llvm::Type* elems[] =
{
llvm::ArrayType::get(Type::Word, _size),
Type::BytePtr,
Type::BytePtr,
Type::BytePtr
};
type = llvm::StructType::create(elems, "Runtime");
}
return type;
}
namespace
{
llvm::Twine getName(RuntimeData::Index _index)
{
switch (_index)
{
default: return "data";
case RuntimeData::Gas: return "gas";
case RuntimeData::Address: return "address";
case RuntimeData::Caller: return "caller";
case RuntimeData::Origin: return "origin";
case RuntimeData::CallValue: return "callvalue";
case RuntimeData::CallDataSize: return "calldatasize";
case RuntimeData::GasPrice: return "gasprice";
case RuntimeData::PrevHash: return "prevhash";
case RuntimeData::CoinBase: return "coinbase";
case RuntimeData::TimeStamp: return "timestamp";
case RuntimeData::Number: return "number";
case RuntimeData::Difficulty: return "difficulty";
case RuntimeData::GasLimit: return "gaslimit";
case RuntimeData::CodeSize: return "codesize";
}
}
}
Runtime::Runtime(u256 _gas, ExtVMFace& _ext, jmp_buf _jmpBuf, bool _outputLogs):
m_ext(_ext),
m_outputLogs(_outputLogs)
@ -109,103 +65,6 @@ bool Runtime::outputLogs() const
}
RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder): CompilerHelper(_builder)
{
m_dataPtr = new llvm::GlobalVariable(*getModule(), Type::RuntimePtr, false, llvm::GlobalVariable::PrivateLinkage, llvm::UndefValue::get(Type::RuntimePtr), "rt");
m_longjmp = llvm::Intrinsic::getDeclaration(getModule(), llvm::Intrinsic::longjmp);
// Export data
auto mainFunc = getMainFunction();
llvm::Value* dataPtr = &mainFunc->getArgumentList().back();
m_builder.CreateStore(dataPtr, m_dataPtr);
}
llvm::Value* RuntimeManager::getRuntimePtr()
{
if (auto mainFunc = getMainFunction())
return mainFunc->arg_begin()->getNextNode(); // Runtime is the second parameter of main function
return m_builder.CreateLoad(m_dataPtr, "rt");
}
llvm::Value* RuntimeManager::getPtr(RuntimeData::Index _index)
{
llvm::Value* idxList[] = {m_builder.getInt32(0), m_builder.getInt32(0), m_builder.getInt32(_index)};
return m_builder.CreateInBoundsGEP(getRuntimePtr(), idxList, getName(_index) + "Ptr");
}
llvm::Value* RuntimeManager::get(RuntimeData::Index _index)
{
return m_builder.CreateLoad(getPtr(_index), getName(_index));
}
void RuntimeManager::set(RuntimeData::Index _index, llvm::Value* _value)
{
m_builder.CreateStore(_value, getPtr(_index));
}
void RuntimeManager::registerReturnData(llvm::Value* _offset, llvm::Value* _size)
{
set(RuntimeData::ReturnDataOffset, _offset);
set(RuntimeData::ReturnDataSize, _size);
}
void RuntimeManager::raiseException(ReturnCode _returnCode)
{
m_builder.CreateCall2(m_longjmp, getJmpBuf(), Constant::get(_returnCode));
}
llvm::Value* RuntimeManager::get(Instruction _inst)
{
switch (_inst)
{
default: assert(false); return nullptr;
case Instruction::GAS: return get(RuntimeData::Gas);
case Instruction::ADDRESS: return get(RuntimeData::Address);
case Instruction::CALLER: return get(RuntimeData::Caller);
case Instruction::ORIGIN: return get(RuntimeData::Origin);
case Instruction::CALLVALUE: return get(RuntimeData::CallValue);
case Instruction::CALLDATASIZE: return get(RuntimeData::CallDataSize);
case Instruction::GASPRICE: return get(RuntimeData::GasPrice);
case Instruction::PREVHASH: return get(RuntimeData::PrevHash);
case Instruction::COINBASE: return get(RuntimeData::CoinBase);
case Instruction::TIMESTAMP: return get(RuntimeData::TimeStamp);
case Instruction::NUMBER: return get(RuntimeData::Number);
case Instruction::DIFFICULTY: return get(RuntimeData::Difficulty);
case Instruction::GASLIMIT: return get(RuntimeData::GasLimit);
case Instruction::CODESIZE: return get(RuntimeData::CodeSize);
}
}
llvm::Value* RuntimeManager::getCallData()
{
auto ptr = getBuilder().CreateStructGEP(getRuntimePtr(), 1, "calldataPtr");
return getBuilder().CreateLoad(ptr, "calldata");
}
llvm::Value* RuntimeManager::getCode()
{
auto ptr = getBuilder().CreateStructGEP(getRuntimePtr(), 2, "codePtr");
return getBuilder().CreateLoad(ptr, "code");
}
llvm::Value* RuntimeManager::getJmpBuf()
{
auto ptr = getBuilder().CreateStructGEP(getRuntimePtr(), 3, "jmpbufPtr");
return getBuilder().CreateLoad(ptr, "jmpbuf");
}
llvm::Value* RuntimeManager::getGas()
{
return get(RuntimeData::Gas);
}
void RuntimeManager::setGas(llvm::Value* _gas)
{
llvm::Value* idxList[] = {m_builder.getInt32(0), m_builder.getInt32(0), m_builder.getInt32(RuntimeData::Gas)};
auto ptr = m_builder.CreateInBoundsGEP(getRuntimePtr(), idxList, "gasPtr");
m_builder.CreateStore(_gas, ptr);
}
}
}
}

61
libevmjit/Runtime.h

@ -10,6 +10,7 @@
#include "CompilerHelper.h"
#include "Utils.h"
#include "Type.h"
#include "RuntimeData.h"
#ifdef _MSC_VER
@ -25,39 +26,6 @@ namespace eth
namespace jit
{
struct RuntimeData
{
enum Index: unsigned
{
Gas,
Address,
Caller,
Origin,
CallValue,
CallDataSize,
GasPrice,
PrevHash,
CoinBase,
TimeStamp,
Number,
Difficulty,
GasLimit,
CodeSize,
_size,
ReturnDataOffset = CallValue, // Reuse 2 fields for return data reference
ReturnDataSize = CallDataSize
};
i256 elems[_size];
byte const* callData;
byte const* code;
decltype(&jmp_buf{}[0]) jmpBuf;
static llvm::StructType* getType();
};
using StackImpl = std::vector<i256>;
using MemoryImpl = bytes;
@ -91,33 +59,6 @@ private:
bool m_outputLogs; ///< write LOG statements to console
};
class RuntimeManager: public CompilerHelper
{
public:
RuntimeManager(llvm::IRBuilder<>& _builder);
llvm::Value* getRuntimePtr();
llvm::Value* get(RuntimeData::Index _index);
llvm::Value* get(Instruction _inst);
llvm::Value* getGas(); // TODO: Remove
llvm::Value* getCallData();
llvm::Value* getCode();
void setGas(llvm::Value* _gas);
void registerReturnData(llvm::Value* _index, llvm::Value* _size);
void raiseException(ReturnCode _returnCode);
private:
llvm::Value* getPtr(RuntimeData::Index _index);
void set(RuntimeData::Index _index, llvm::Value* _value);
llvm::Value* getJmpBuf();
llvm::GlobalVariable* m_dataPtr = nullptr;
llvm::Function* m_longjmp = nullptr;
};
}
}
}

51
libevmjit/RuntimeData.h

@ -0,0 +1,51 @@
#pragma once
#include <csetjmp>
#include "Utils.h"
namespace dev
{
namespace eth
{
namespace jit
{
using jmpBufRef = decltype(&jmp_buf{}[0]);
struct RuntimeData
{
enum Index
{
Gas,
Address,
Caller,
Origin,
CallValue,
CallDataSize,
GasPrice,
PrevHash,
CoinBase,
TimeStamp,
Number,
Difficulty,
GasLimit,
CodeSize,
_size,
ReturnDataOffset = CallValue, // Reuse 2 fields for return data reference
ReturnDataSize = CallDataSize
};
i256 elems[_size];
byte const* callData;
byte const* code;
jmpBufRef jmpBuf;
};
}
}
}

159
libevmjit/RuntimeManager.cpp

@ -0,0 +1,159 @@
#include "RuntimeManager.h"
#include <llvm/IR/GlobalVariable.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/IntrinsicInst.h>
#include "RuntimeData.h"
#include "Instruction.h"
namespace dev
{
namespace eth
{
namespace jit
{
llvm::StructType* RuntimeManager::getRuntimeDataType()
{
static llvm::StructType* type = nullptr;
if (!type)
{
llvm::Type* elems[] =
{
llvm::ArrayType::get(Type::Word, RuntimeData::_size),
Type::BytePtr,
Type::BytePtr,
Type::BytePtr
};
type = llvm::StructType::create(elems, "Runtime");
}
return type;
}
namespace
{
llvm::Twine getName(RuntimeData::Index _index)
{
switch (_index)
{
default: return "data";
case RuntimeData::Gas: return "gas";
case RuntimeData::Address: return "address";
case RuntimeData::Caller: return "caller";
case RuntimeData::Origin: return "origin";
case RuntimeData::CallValue: return "callvalue";
case RuntimeData::CallDataSize: return "calldatasize";
case RuntimeData::GasPrice: return "gasprice";
case RuntimeData::PrevHash: return "prevhash";
case RuntimeData::CoinBase: return "coinbase";
case RuntimeData::TimeStamp: return "timestamp";
case RuntimeData::Number: return "number";
case RuntimeData::Difficulty: return "difficulty";
case RuntimeData::GasLimit: return "gaslimit";
case RuntimeData::CodeSize: return "codesize";
}
}
}
RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder): CompilerHelper(_builder)
{
m_dataPtr = new llvm::GlobalVariable(*getModule(), Type::RuntimePtr, false, llvm::GlobalVariable::PrivateLinkage, llvm::UndefValue::get(Type::RuntimePtr), "rt");
m_longjmp = llvm::Intrinsic::getDeclaration(getModule(), llvm::Intrinsic::longjmp);
// Export data
auto mainFunc = getMainFunction();
llvm::Value* dataPtr = &mainFunc->getArgumentList().back();
m_builder.CreateStore(dataPtr, m_dataPtr);
}
llvm::Value* RuntimeManager::getRuntimePtr()
{
if (auto mainFunc = getMainFunction())
return mainFunc->arg_begin()->getNextNode(); // Runtime is the second parameter of main function
return m_builder.CreateLoad(m_dataPtr, "rt");
}
llvm::Value* RuntimeManager::getPtr(RuntimeData::Index _index)
{
llvm::Value* idxList[] = {m_builder.getInt32(0), m_builder.getInt32(0), m_builder.getInt32(_index)};
return m_builder.CreateInBoundsGEP(getRuntimePtr(), idxList, getName(_index) + "Ptr");
}
llvm::Value* RuntimeManager::get(RuntimeData::Index _index)
{
return m_builder.CreateLoad(getPtr(_index), getName(_index));
}
void RuntimeManager::set(RuntimeData::Index _index, llvm::Value* _value)
{
m_builder.CreateStore(_value, getPtr(_index));
}
void RuntimeManager::registerReturnData(llvm::Value* _offset, llvm::Value* _size)
{
set(RuntimeData::ReturnDataOffset, _offset);
set(RuntimeData::ReturnDataSize, _size);
}
void RuntimeManager::raiseException(ReturnCode _returnCode)
{
m_builder.CreateCall2(m_longjmp, getJmpBuf(), Constant::get(_returnCode));
}
llvm::Value* RuntimeManager::get(Instruction _inst)
{
switch (_inst)
{
default: assert(false); return nullptr;
case Instruction::GAS: return get(RuntimeData::Gas);
case Instruction::ADDRESS: return get(RuntimeData::Address);
case Instruction::CALLER: return get(RuntimeData::Caller);
case Instruction::ORIGIN: return get(RuntimeData::Origin);
case Instruction::CALLVALUE: return get(RuntimeData::CallValue);
case Instruction::CALLDATASIZE: return get(RuntimeData::CallDataSize);
case Instruction::GASPRICE: return get(RuntimeData::GasPrice);
case Instruction::PREVHASH: return get(RuntimeData::PrevHash);
case Instruction::COINBASE: return get(RuntimeData::CoinBase);
case Instruction::TIMESTAMP: return get(RuntimeData::TimeStamp);
case Instruction::NUMBER: return get(RuntimeData::Number);
case Instruction::DIFFICULTY: return get(RuntimeData::Difficulty);
case Instruction::GASLIMIT: return get(RuntimeData::GasLimit);
case Instruction::CODESIZE: return get(RuntimeData::CodeSize);
}
}
llvm::Value* RuntimeManager::getCallData()
{
auto ptr = getBuilder().CreateStructGEP(getRuntimePtr(), 1, "calldataPtr");
return getBuilder().CreateLoad(ptr, "calldata");
}
llvm::Value* RuntimeManager::getCode()
{
auto ptr = getBuilder().CreateStructGEP(getRuntimePtr(), 2, "codePtr");
return getBuilder().CreateLoad(ptr, "code");
}
llvm::Value* RuntimeManager::getJmpBuf()
{
auto ptr = getBuilder().CreateStructGEP(getRuntimePtr(), 3, "jmpbufPtr");
return getBuilder().CreateLoad(ptr, "jmpbuf");
}
llvm::Value* RuntimeManager::getGas()
{
return get(RuntimeData::Gas);
}
void RuntimeManager::setGas(llvm::Value* _gas)
{
llvm::Value* idxList[] = {m_builder.getInt32(0), m_builder.getInt32(0), m_builder.getInt32(RuntimeData::Gas)};
auto ptr = m_builder.CreateInBoundsGEP(getRuntimePtr(), idxList, "gasPtr");
m_builder.CreateStore(_gas, ptr);
}
}
}
}

46
libevmjit/RuntimeManager.h

@ -0,0 +1,46 @@
#pragma once
#include "CompilerHelper.h"
#include "Type.h"
#include "RuntimeData.h"
#include "Instruction.h"
namespace dev
{
namespace eth
{
namespace jit
{
class RuntimeManager: public CompilerHelper
{
public:
RuntimeManager(llvm::IRBuilder<>& _builder);
llvm::Value* getRuntimePtr();
llvm::Value* get(RuntimeData::Index _index);
llvm::Value* get(Instruction _inst);
llvm::Value* getGas(); // TODO: Remove
llvm::Value* getCallData();
llvm::Value* getCode();
void setGas(llvm::Value* _gas);
void registerReturnData(llvm::Value* _index, llvm::Value* _size);
void raiseException(ReturnCode _returnCode);
static llvm::StructType* getRuntimeDataType();
private:
llvm::Value* getPtr(RuntimeData::Index _index);
void set(RuntimeData::Index _index, llvm::Value* _value);
llvm::Value* getJmpBuf();
llvm::GlobalVariable* m_dataPtr = nullptr;
llvm::Function* m_longjmp = nullptr;
};
}
}
}

1
libevmjit/Stack.cpp

@ -1,4 +1,5 @@
#include "Stack.h"
#include "RuntimeManager.h"
#include "Runtime.h"
#include "Type.h"

4
libevmjit/Type.cpp

@ -3,7 +3,7 @@
#include <llvm/IR/DerivedTypes.h>
#include "Runtime.h"
#include "RuntimeManager.h"
namespace dev
{
@ -33,7 +33,7 @@ void Type::init(llvm::LLVMContext& _context)
BytePtr = Byte->getPointerTo();
Void = llvm::Type::getVoidTy(_context);
MainReturn = llvm::Type::getInt32Ty(_context);
RuntimePtr = RuntimeData::getType()->getPointerTo();
RuntimePtr = RuntimeManager::getRuntimeDataType()->getPointerTo();
}
llvm::ConstantInt* Constant::get(int64_t _n)

Loading…
Cancel
Save