artur-zawlocki
10 years ago
7 changed files with 202 additions and 71 deletions
@ -0,0 +1,79 @@ |
|||
|
|||
#include "GasMeter.h" |
|||
|
|||
#include <llvm/IR/GlobalVariable.h> |
|||
#include <llvm/IR/Function.h> |
|||
|
|||
#include <libevmface/Instruction.h> |
|||
#include <libevm/FeeStructure.h> |
|||
|
|||
#include "Type.h" |
|||
|
|||
namespace evmcc |
|||
{ |
|||
|
|||
using namespace dev::eth; // We should move all the JIT code into dev::eth namespace
|
|||
|
|||
namespace // Helper functions
|
|||
{ |
|||
|
|||
uint64_t getStepCost(dev::eth::Instruction inst) // TODO: Add this function to FeeSructure
|
|||
{ |
|||
switch (inst) |
|||
{ |
|||
case Instruction::STOP: |
|||
case Instruction::SUICIDE: |
|||
return 0; |
|||
|
|||
case Instruction::SSTORE: |
|||
return static_cast<uint64_t>(c_sstoreGas); |
|||
|
|||
case Instruction::SLOAD: |
|||
return static_cast<uint64_t>(c_sloadGas); |
|||
|
|||
case Instruction::SHA3: |
|||
return static_cast<uint64_t>(c_sha3Gas); |
|||
|
|||
case Instruction::BALANCE: |
|||
return static_cast<uint64_t>(c_sha3Gas); |
|||
|
|||
case Instruction::CALL: |
|||
case Instruction::CALLCODE: |
|||
return static_cast<uint64_t>(c_callGas); |
|||
|
|||
case Instruction::CREATE: |
|||
return static_cast<uint64_t>(c_createGas); |
|||
|
|||
default: // Assumes instruction code is valid
|
|||
return static_cast<uint64_t>(c_stepGas);; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module): |
|||
m_builder(_builder) |
|||
{ |
|||
m_gas = new llvm::GlobalVariable(*_module, Type::i256, false, llvm::GlobalVariable::PrivateLinkage, llvm::UndefValue::get(Type::i256), "gas"); |
|||
m_gas->setUnnamedAddr(true); // Address is not important
|
|||
|
|||
auto pt = m_builder.GetInsertPoint(); |
|||
auto bb = m_builder.GetInsertBlock(); |
|||
m_gasCheckFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "gas.check", _module); |
|||
auto gasCheckBB = llvm::BasicBlock::Create(_builder.getContext(), {}, m_gasCheckFunc); |
|||
m_builder.SetInsertPoint(gasCheckBB); |
|||
llvm::Value* cost = m_gasCheckFunc->arg_begin(); |
|||
llvm::Value* gas = m_builder.CreateLoad(m_gas); |
|||
gas = m_builder.CreateSub(gas, cost); |
|||
m_builder.CreateStore(gas, m_gas); |
|||
m_builder.CreateRetVoid(); |
|||
m_builder.SetInsertPoint(bb, pt); |
|||
} |
|||
|
|||
void GasMeter::check(Instruction _inst) |
|||
{ |
|||
auto stepCost = getStepCost(_inst); |
|||
m_builder.CreateCall(m_gasCheckFunc, m_builder.getIntN(256, stepCost)); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,27 @@ |
|||
|
|||
#pragma once |
|||
|
|||
#include <llvm/IR/IRBuilder.h> |
|||
|
|||
#include <libevmface/Instruction.h> |
|||
|
|||
namespace evmcc |
|||
{ |
|||
|
|||
class GasMeter |
|||
{ |
|||
public: |
|||
GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* module); |
|||
|
|||
GasMeter(const GasMeter&) = delete; |
|||
void operator=(GasMeter) = delete; |
|||
|
|||
void check(dev::eth::Instruction _inst); |
|||
|
|||
private: |
|||
llvm::IRBuilder<>& m_builder; |
|||
llvm::GlobalVariable* m_gas; |
|||
llvm::Function* m_gasCheckFunc; |
|||
}; |
|||
|
|||
} |
@ -0,0 +1,20 @@ |
|||
|
|||
#include "Type.h" |
|||
|
|||
#include <llvm/IR/DerivedTypes.h> |
|||
|
|||
namespace evmcc |
|||
{ |
|||
|
|||
llvm::IntegerType* Type::i256; |
|||
llvm::IntegerType* Type::lowPrecision; |
|||
llvm::Type* Type::Void; |
|||
|
|||
void Type::init(llvm::LLVMContext& _context) |
|||
{ |
|||
i256 = llvm::Type::getIntNTy(_context, 256); |
|||
lowPrecision = llvm::Type::getInt64Ty(_context); |
|||
Void = llvm::Type::getVoidTy(_context); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,22 @@ |
|||
|
|||
#pragma once |
|||
|
|||
#include <llvm/IR/Type.h> |
|||
|
|||
namespace evmcc |
|||
{ |
|||
|
|||
struct Type |
|||
{ |
|||
static llvm::IntegerType* i256; |
|||
|
|||
/// Type for doing low precision arithmetics where 256-bit precision is not supported by native target
|
|||
/// @TODO: Use 64-bit for now. In 128-bit compiler-rt library functions are required
|
|||
static llvm::IntegerType* lowPrecision; |
|||
|
|||
static llvm::Type* Void; |
|||
|
|||
static void init(llvm::LLVMContext& _context); |
|||
}; |
|||
|
|||
} |
Loading…
Reference in new issue