diff --git a/evmcc/Compiler.cpp b/evmcc/Compiler.cpp index 91bc692eb..720570277 100644 --- a/evmcc/Compiler.cpp +++ b/evmcc/Compiler.cpp @@ -8,6 +8,7 @@ #include "Memory.h" #include "Ext.h" +#include "GasMeter.h" namespace evmcc { @@ -182,6 +183,7 @@ std::unique_ptr Compiler::compile(const dev::bytes& bytecode) // Init runtime structures. auto memory = Memory(builder, module.get()); auto ext = Ext(builder, module.get()); + GasMeter gasMeter(builder, module.get()); // Jump to first instruction builder.CreateBr(basicBlocks.begin()->second); @@ -195,6 +197,8 @@ std::unique_ptr Compiler::compile(const dev::bytes& bytecode) for (auto currentPC = basicBlock.begin(); currentPC != basicBlock.end(); ++currentPC) { auto inst = static_cast(bytecode[currentPC]); + gasMeter.check(inst); + switch (inst) { diff --git a/evmcc/GasMeter.cpp b/evmcc/GasMeter.cpp index 3687cfed3..af08d13b7 100644 --- a/evmcc/GasMeter.cpp +++ b/evmcc/GasMeter.cpp @@ -1,6 +1,9 @@ #include "GasMeter.h" +#include +#include + #include #include @@ -9,7 +12,7 @@ namespace evmcc using namespace dev::eth; // We should move all the JIT code into dev::eth namespace -namespace +namespace // Helper functions { uint64_t getStepCost(dev::eth::Instruction inst) // TODO: Add this function to FeeSructure @@ -46,4 +49,21 @@ uint64_t getStepCost(dev::eth::Instruction inst) // TODO: Add this function to F } +GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module): + m_builder(_builder) +{ + m_gas = new llvm::GlobalVariable(*_module, m_builder.getIntNTy(256), false, llvm::GlobalVariable::PrivateLinkage, llvm::UndefValue::get(m_builder.getIntNTy(256)), "gas"); + m_gas->setUnnamedAddr(true); // Address is not important + + //llvm::Function::Create() +} + +void GasMeter::check(Instruction _inst) +{ + auto stepCost = getStepCost(_inst); + auto before = m_builder.CreateLoad(m_gas, "gas.before"); + auto after = m_builder.CreateSub(before, m_builder.getIntN(256, stepCost)); + m_builder.CreateStore(after, m_gas); +} + } \ No newline at end of file diff --git a/evmcc/GasMeter.h b/evmcc/GasMeter.h index c234a4ab6..f50438c9a 100644 --- a/evmcc/GasMeter.h +++ b/evmcc/GasMeter.h @@ -1,9 +1,26 @@ #pragma once +#include + #include 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; +}; + } \ No newline at end of file