mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 19:30:44 +00:00
Merge branch 'develop-evmcc' of github.com:imapp-pl/ethereum into develop-evmcc
This commit is contained in:
commit
a1a195bce3
9 changed files with 137 additions and 102 deletions
|
|
@ -400,9 +400,9 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
/*
|
/*
|
||||||
if (byteNum < 32) - use select
|
if (byteNum < 32) - use select
|
||||||
{
|
{
|
||||||
value <<= byteNum*8
|
value <<= byteNum*8
|
||||||
value >>= 31*8
|
value >>= 31*8
|
||||||
push value
|
push value
|
||||||
}
|
}
|
||||||
else push 0
|
else push 0
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,7 @@
|
||||||
#include <llvm/Support/PrettyStackTrace.h>
|
#include <llvm/Support/PrettyStackTrace.h>
|
||||||
#include <llvm/Support/Host.h>
|
#include <llvm/Support/Host.h>
|
||||||
|
|
||||||
#include "Ext.h"
|
#include "Runtime.h"
|
||||||
#include "Memory.h"
|
|
||||||
|
|
||||||
namespace evmcc
|
namespace evmcc
|
||||||
{
|
{
|
||||||
|
|
@ -69,8 +68,7 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
|
||||||
_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();
|
||||||
|
|
||||||
auto&& memory = Memory::init();
|
// Create fake ExtVM interface
|
||||||
|
|
||||||
auto ext = std::make_unique<dev::eth::ExtVMFace>();
|
auto ext = std::make_unique<dev::eth::ExtVMFace>();
|
||||||
ext->myAddress = dev::Address(1122334455667788);
|
ext->myAddress = dev::Address(1122334455667788);
|
||||||
ext->caller = dev::Address(0xfacefacefaceface);
|
ext->caller = dev::Address(0xfacefacefaceface);
|
||||||
|
|
@ -85,7 +83,9 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
|
||||||
ext->currentBlock.gasLimit = 1008;
|
ext->currentBlock.gasLimit = 1008;
|
||||||
std::string calldata = "Hello the Beautiful World of Ethereum!";
|
std::string calldata = "Hello the Beautiful World of Ethereum!";
|
||||||
ext->data = calldata;
|
ext->data = calldata;
|
||||||
Ext::init(std::move(ext));
|
|
||||||
|
// Init runtime
|
||||||
|
Runtime runtime(std::move(ext));
|
||||||
|
|
||||||
auto entryFunc = module->getFunction("main");
|
auto entryFunc = module->getFunction("main");
|
||||||
if (!entryFunc)
|
if (!entryFunc)
|
||||||
|
|
@ -101,7 +101,7 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
|
||||||
auto size = 0xFFFFFFFF & intResult;
|
auto size = 0xFFFFFFFF & intResult;
|
||||||
|
|
||||||
std::cout << "RETURN [ ";
|
std::cout << "RETURN [ ";
|
||||||
for (dev::bytes::const_iterator it = memory.cbegin() + index, end = it + size; it != end; ++it)
|
for (dev::bytes::const_iterator it = Runtime::getMemory().cbegin() + index, end = it + size; it != end; ++it)
|
||||||
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)*it << " ";
|
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)*it << " ";
|
||||||
std::cout << "]";
|
std::cout << "]";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
#include <llvm/IR/TypeBuilder.h>
|
#include <llvm/IR/TypeBuilder.h>
|
||||||
#include <llvm/IR/IntrinsicInst.h>
|
#include <llvm/IR/IntrinsicInst.h>
|
||||||
|
|
||||||
#include "Utils.h"
|
#include "Runtime.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define EXPORT __declspec(dllexport)
|
#define EXPORT __declspec(dllexport)
|
||||||
|
|
@ -27,13 +27,6 @@ inline dev::u256 fromAddress(dev::Address _a)
|
||||||
return (dev::u160)_a;
|
return (dev::u160)_a;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<dev::eth::ExtVMFace> g_ext;
|
|
||||||
|
|
||||||
void Ext::init(std::unique_ptr<dev::eth::ExtVMFace> _ext)
|
|
||||||
{
|
|
||||||
g_ext = std::move(_ext);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ExtData
|
struct ExtData
|
||||||
{
|
{
|
||||||
i256 address;
|
i256 address;
|
||||||
|
|
@ -147,25 +140,26 @@ extern "C"
|
||||||
|
|
||||||
EXPORT void ext_init(ExtData* _extData)
|
EXPORT void ext_init(ExtData* _extData)
|
||||||
{
|
{
|
||||||
_extData->address = eth2llvm(fromAddress(g_ext->myAddress));
|
auto&& ext = Runtime::getExt();
|
||||||
_extData->caller = eth2llvm(fromAddress(g_ext->caller));
|
_extData->address = eth2llvm(fromAddress(ext.myAddress));
|
||||||
_extData->origin = eth2llvm(fromAddress(g_ext->origin));
|
_extData->caller = eth2llvm(fromAddress(ext.caller));
|
||||||
_extData->callvalue = eth2llvm(g_ext->value);
|
_extData->origin = eth2llvm(fromAddress(ext.origin));
|
||||||
_extData->gasprice = eth2llvm(g_ext->gasPrice);
|
_extData->callvalue = eth2llvm(ext.value);
|
||||||
_extData->calldatasize = eth2llvm(g_ext->data.size());
|
_extData->gasprice = eth2llvm(ext.gasPrice);
|
||||||
_extData->prevhash = eth2llvm(g_ext->previousBlock.hash);
|
_extData->calldatasize = eth2llvm(ext.data.size());
|
||||||
_extData->coinbase = eth2llvm(fromAddress(g_ext->currentBlock.coinbaseAddress));
|
_extData->prevhash = eth2llvm(ext.previousBlock.hash);
|
||||||
_extData->timestamp = eth2llvm(g_ext->currentBlock.timestamp);
|
_extData->coinbase = eth2llvm(fromAddress(ext.currentBlock.coinbaseAddress));
|
||||||
_extData->number = eth2llvm(g_ext->currentBlock.number);
|
_extData->timestamp = eth2llvm(ext.currentBlock.timestamp);
|
||||||
_extData->difficulty = eth2llvm(g_ext->currentBlock.difficulty);
|
_extData->number = eth2llvm(ext.currentBlock.number);
|
||||||
_extData->gaslimit = eth2llvm(g_ext->currentBlock.gasLimit);
|
_extData->difficulty = eth2llvm(ext.currentBlock.difficulty);
|
||||||
//_extData->calldata = g_ext->data.data();
|
_extData->gaslimit = eth2llvm(ext.currentBlock.gasLimit);
|
||||||
|
//_extData->calldata = ext.data.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void ext_store(i256* _index, i256* _value)
|
EXPORT void ext_store(i256* _index, i256* _value)
|
||||||
{
|
{
|
||||||
auto index = llvm2eth(*_index);
|
auto index = llvm2eth(*_index);
|
||||||
auto value = g_ext->store(index);
|
auto value = Runtime::getExt().store(index);
|
||||||
*_value = eth2llvm(value);
|
*_value = eth2llvm(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -173,7 +167,7 @@ EXPORT void ext_setStore(i256* _index, i256* _value)
|
||||||
{
|
{
|
||||||
auto index = llvm2eth(*_index);
|
auto index = llvm2eth(*_index);
|
||||||
auto value = llvm2eth(*_value);
|
auto value = llvm2eth(*_value);
|
||||||
g_ext->setStore(index, value);
|
Runtime::getExt().setStore(index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void ext_calldataload(i256* _index, i256* _value)
|
EXPORT void ext_calldataload(i256* _index, i256* _value)
|
||||||
|
|
@ -182,13 +176,13 @@ EXPORT void ext_calldataload(i256* _index, i256* _value)
|
||||||
assert(index + 31 > index); // TODO: Handle large index
|
assert(index + 31 > index); // TODO: Handle large index
|
||||||
auto b = reinterpret_cast<byte*>(_value);
|
auto b = reinterpret_cast<byte*>(_value);
|
||||||
for (size_t i = index, j = 31; i <= index + 31; ++i, --j)
|
for (size_t i = index, j = 31; i <= index + 31; ++i, --j)
|
||||||
b[j] = i < g_ext->data.size() ? g_ext->data[i] : 0;
|
b[j] = i < Runtime::getExt().data.size() ? Runtime::getExt().data[i] : 0;
|
||||||
// TODO: It all can be done by adding padding to data or by using min() algorithm without branch
|
// TODO: It all can be done by adding padding to data or by using min() algorithm without branch
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void ext_balance(h256* _address, i256* _value)
|
EXPORT void ext_balance(h256* _address, i256* _value)
|
||||||
{
|
{
|
||||||
auto u = g_ext->balance(dev::right160(*_address));
|
auto u = Runtime::getExt().balance(dev::right160(*_address));
|
||||||
*_value = eth2llvm(u);
|
*_value = eth2llvm(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <libdevcore/Common.h>
|
#include <libdevcore/Common.h>
|
||||||
|
|
||||||
#include "Utils.h"
|
#include "Runtime.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define EXPORT __declspec(dllexport)
|
#define EXPORT __declspec(dllexport)
|
||||||
|
|
@ -21,11 +21,6 @@
|
||||||
namespace evmcc
|
namespace evmcc
|
||||||
{
|
{
|
||||||
|
|
||||||
using MemoryImpl = dev::bytes;
|
|
||||||
|
|
||||||
static MemoryImpl* evmccrt_memory;
|
|
||||||
|
|
||||||
|
|
||||||
Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* module)
|
Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* module)
|
||||||
: m_builder(_builder)
|
: m_builder(_builder)
|
||||||
{
|
{
|
||||||
|
|
@ -48,15 +43,6 @@ Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* module)
|
||||||
"evmccrt_memory_dump", module);
|
"evmccrt_memory_dump", module);
|
||||||
}
|
}
|
||||||
|
|
||||||
const dev::bytes& Memory::init()
|
|
||||||
{
|
|
||||||
evmccrt_memory = new MemoryImpl();
|
|
||||||
std::cerr << "MEMORY: create(), initial size = " << evmccrt_memory->size()
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
return *evmccrt_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
llvm::Value* Memory::loadWord(llvm::Value* _addr)
|
llvm::Value* Memory::loadWord(llvm::Value* _addr)
|
||||||
{
|
{
|
||||||
|
|
@ -132,29 +118,30 @@ extern "C"
|
||||||
EXPORT uint8_t* evmccrt_memory_require(uint64_t _index)
|
EXPORT uint8_t* evmccrt_memory_require(uint64_t _index)
|
||||||
{
|
{
|
||||||
uint64_t requiredSize = (_index / 32 + 1) * 32;
|
uint64_t requiredSize = (_index / 32 + 1) * 32;
|
||||||
|
auto&& memory = Runtime::getMemory();
|
||||||
|
|
||||||
if (evmccrt_memory->size() < requiredSize)
|
if (memory.size() < requiredSize)
|
||||||
{
|
{
|
||||||
std::cerr << "MEMORY: current size: " << std::dec
|
std::cerr << "MEMORY: current size: " << std::dec
|
||||||
<< evmccrt_memory->size() << " bytes, required size: "
|
<< memory.size() << " bytes, required size: "
|
||||||
<< requiredSize << " bytes"
|
<< requiredSize << " bytes"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
evmccrt_memory->resize(requiredSize);
|
memory.resize(requiredSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return evmccrt_memory->data();
|
return memory.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT uint64_t evmccrt_memory_size()
|
EXPORT uint64_t evmccrt_memory_size()
|
||||||
{
|
{
|
||||||
return evmccrt_memory->size() / 32;
|
return Runtime::getMemory().size() / 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void evmccrt_memory_dump(uint64_t _begin, uint64_t _end)
|
EXPORT void evmccrt_memory_dump(uint64_t _begin, uint64_t _end)
|
||||||
{
|
{
|
||||||
if (_end == 0)
|
if (_end == 0)
|
||||||
_end = evmccrt_memory->size();
|
_end = Runtime::getMemory().size();
|
||||||
|
|
||||||
std::cerr << "MEMORY: active size: " << std::dec
|
std::cerr << "MEMORY: active size: " << std::dec
|
||||||
<< evmccrt_memory_size() << " words\n";
|
<< evmccrt_memory_size() << " words\n";
|
||||||
|
|
@ -169,7 +156,7 @@ EXPORT void evmccrt_memory_dump(uint64_t _begin, uint64_t _end)
|
||||||
if ((i - _begin) % 16 == 0)
|
if ((i - _begin) % 16 == 0)
|
||||||
std::cerr << '\n' << std::dec << i << ": ";
|
std::cerr << '\n' << std::dec << i << ": ";
|
||||||
|
|
||||||
uint8_t b = (*evmccrt_memory)[i];
|
auto b = Runtime::getMemory()[i];
|
||||||
std::cerr << std::hex << std::setw(2) << static_cast<int>(b) << ' ';
|
std::cerr << std::hex << std::setw(2) << static_cast<int>(b) << ' ';
|
||||||
}
|
}
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ class Memory
|
||||||
public:
|
public:
|
||||||
Memory(llvm::IRBuilder<>& _builder, llvm::Module* module);
|
Memory(llvm::IRBuilder<>& _builder, llvm::Module* module);
|
||||||
|
|
||||||
static const dev::bytes& init();
|
|
||||||
|
|
||||||
llvm::Value* loadWord(llvm::Value* _addr);
|
llvm::Value* loadWord(llvm::Value* _addr);
|
||||||
void storeWord(llvm::Value* _addr, llvm::Value* _word);
|
void storeWord(llvm::Value* _addr, llvm::Value* _word);
|
||||||
void storeByte(llvm::Value* _addr, llvm::Value* _byte);
|
void storeByte(llvm::Value* _addr, llvm::Value* _byte);
|
||||||
|
|
|
||||||
36
evmcc/Runtime.cpp
Normal file
36
evmcc/Runtime.cpp
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
|
||||||
|
#include "Runtime.h"
|
||||||
|
|
||||||
|
namespace evmcc
|
||||||
|
{
|
||||||
|
|
||||||
|
static Runtime* g_runtime;
|
||||||
|
|
||||||
|
Runtime::Runtime(std::unique_ptr<dev::eth::ExtVMFace> _ext)
|
||||||
|
: m_ext(std::move(_ext))
|
||||||
|
{
|
||||||
|
assert(!g_runtime);
|
||||||
|
g_runtime = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Runtime::~Runtime()
|
||||||
|
{
|
||||||
|
g_runtime = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
StackImpl& Runtime::getStack()
|
||||||
|
{
|
||||||
|
return g_runtime->m_stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryImpl& Runtime::getMemory()
|
||||||
|
{
|
||||||
|
return g_runtime->m_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev::eth::ExtVMFace& Runtime::getExt()
|
||||||
|
{
|
||||||
|
return *g_runtime->m_ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
35
evmcc/Runtime.h
Normal file
35
evmcc/Runtime.h
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <libevm/ExtVMFace.h>
|
||||||
|
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
namespace evmcc
|
||||||
|
{
|
||||||
|
|
||||||
|
using StackImpl = std::vector<i256>;
|
||||||
|
using MemoryImpl = dev::bytes;
|
||||||
|
|
||||||
|
class Runtime
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Runtime(std::unique_ptr<dev::eth::ExtVMFace> _ext);
|
||||||
|
~Runtime();
|
||||||
|
|
||||||
|
Runtime(const Runtime&) = delete;
|
||||||
|
void operator=(const Runtime&) = delete;
|
||||||
|
|
||||||
|
static StackImpl& getStack();
|
||||||
|
static MemoryImpl& getMemory();
|
||||||
|
static dev::eth::ExtVMFace& getExt();
|
||||||
|
|
||||||
|
private:
|
||||||
|
StackImpl m_stack;
|
||||||
|
MemoryImpl m_memory;
|
||||||
|
std::unique_ptr<dev::eth::ExtVMFace> m_ext;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include <llvm/IR/Function.h>
|
#include <llvm/IR/Function.h>
|
||||||
|
|
||||||
#include "Utils.h"
|
#include "Runtime.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define EXPORT __declspec(dllexport)
|
#define EXPORT __declspec(dllexport)
|
||||||
|
|
@ -20,9 +20,6 @@
|
||||||
namespace evmcc
|
namespace evmcc
|
||||||
{
|
{
|
||||||
|
|
||||||
using StackImpl = std::vector<i256>;
|
|
||||||
|
|
||||||
|
|
||||||
Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
|
Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
|
||||||
: m_builder(_builder)
|
: m_builder(_builder)
|
||||||
{
|
{
|
||||||
|
|
@ -32,18 +29,14 @@ Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
|
||||||
auto i256PtrTy = i256Ty->getPointerTo();
|
auto i256PtrTy = i256Ty->getPointerTo();
|
||||||
auto voidTy = m_builder.getVoidTy();
|
auto voidTy = m_builder.getVoidTy();
|
||||||
|
|
||||||
auto stackCreate = llvm::Function::Create(llvm::FunctionType::get(stackPtrTy, false),
|
auto funcType = llvm::FunctionType::get(voidTy, i256PtrTy, false);
|
||||||
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_create", _module);
|
|
||||||
|
|
||||||
llvm::Type* argsTypes[] = {stackPtrTy, i256PtrTy};
|
|
||||||
auto funcType = llvm::FunctionType::get(voidTy, argsTypes, false);
|
|
||||||
m_stackPush = llvm::Function::Create(funcType,
|
m_stackPush = llvm::Function::Create(funcType,
|
||||||
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_push", _module);
|
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_push", _module);
|
||||||
|
|
||||||
m_stackPop = llvm::Function::Create(funcType,
|
m_stackPop = llvm::Function::Create(funcType,
|
||||||
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_pop", _module);
|
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_pop", _module);
|
||||||
|
|
||||||
llvm::Type* getArgsTypes[] = {stackPtrTy, m_builder.getInt32Ty(), i256PtrTy};
|
llvm::Type* getArgsTypes[] = {m_builder.getInt32Ty(), i256PtrTy};
|
||||||
auto getFuncType = llvm::FunctionType::get(voidTy, getArgsTypes, false);
|
auto getFuncType = llvm::FunctionType::get(voidTy, getArgsTypes, false);
|
||||||
m_stackGet = llvm::Function::Create(getFuncType,
|
m_stackGet = llvm::Function::Create(getFuncType,
|
||||||
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_get", _module);
|
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_get", _module);
|
||||||
|
|
@ -51,37 +44,36 @@ Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
|
||||||
m_stackSet = llvm::Function::Create(getFuncType,
|
m_stackSet = llvm::Function::Create(getFuncType,
|
||||||
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_set", _module);
|
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_set", _module);
|
||||||
|
|
||||||
m_args[0] = m_builder.CreateCall(stackCreate, "stack.ptr");
|
m_stackVal = m_builder.CreateAlloca(i256Ty, nullptr, "stack.val");
|
||||||
m_args[1] = m_builder.CreateAlloca(i256Ty, nullptr, "stack.val");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Stack::push(llvm::Value* _value)
|
void Stack::push(llvm::Value* _value)
|
||||||
{
|
{
|
||||||
m_builder.CreateStore(_value, m_args[1]); // copy value to memory
|
m_builder.CreateStore(_value, m_stackVal); // copy value to memory
|
||||||
m_builder.CreateCall(m_stackPush, m_args);
|
m_builder.CreateCall(m_stackPush, m_stackVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
llvm::Value* Stack::pop()
|
llvm::Value* Stack::pop()
|
||||||
{
|
{
|
||||||
m_builder.CreateCall(m_stackPop, m_args);
|
m_builder.CreateCall(m_stackPop, m_stackVal);
|
||||||
return m_builder.CreateLoad(m_args[1]);
|
return m_builder.CreateLoad(m_stackVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
llvm::Value* Stack::get(uint32_t _index)
|
llvm::Value* Stack::get(uint32_t _index)
|
||||||
{
|
{
|
||||||
llvm::Value* args[] = {m_args[0], m_builder.getInt32(_index), m_args[1]};
|
llvm::Value* args[] = {m_builder.getInt32(_index), m_stackVal};
|
||||||
m_builder.CreateCall(m_stackGet, args);
|
m_builder.CreateCall(m_stackGet, args);
|
||||||
return m_builder.CreateLoad(m_args[1]);
|
return m_builder.CreateLoad(m_stackVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Stack::set(uint32_t _index, llvm::Value* _value)
|
void Stack::set(uint32_t _index, llvm::Value* _value)
|
||||||
{
|
{
|
||||||
m_builder.CreateStore(_value, m_args[1]); // copy value to memory
|
m_builder.CreateStore(_value, m_stackVal); // copy value to memory
|
||||||
llvm::Value* args[] = {m_args[0], m_builder.getInt32(_index), m_args[1]};
|
llvm::Value* args[] = {m_builder.getInt32(_index), m_stackVal};
|
||||||
m_builder.CreateCall(m_stackSet, args);
|
m_builder.CreateCall(m_stackSet, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,41 +105,34 @@ extern "C"
|
||||||
{
|
{
|
||||||
using namespace evmcc;
|
using namespace evmcc;
|
||||||
|
|
||||||
EXPORT void* evmccrt_stack_create()
|
EXPORT void evmccrt_stack_push(i256* _word)
|
||||||
{
|
{
|
||||||
auto stack = new StackImpl;
|
//debugStack("push", *_word);
|
||||||
std::cerr << "STACK create\n";
|
Runtime::getStack().push_back(*_word);
|
||||||
return stack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void evmccrt_stack_push(StackImpl* _stack, i256* _word)
|
EXPORT void evmccrt_stack_pop(i256* _outWord)
|
||||||
{
|
{
|
||||||
debugStack("push", *_word);
|
assert(!Runtime::getStack().empty());
|
||||||
_stack->push_back(*_word);
|
auto word = &Runtime::getStack().back();
|
||||||
}
|
//debugStack("pop", *word);
|
||||||
|
Runtime::getStack().pop_back();
|
||||||
EXPORT void evmccrt_stack_pop(StackImpl* _stack, i256* _outWord)
|
|
||||||
{
|
|
||||||
assert(!_stack->empty());
|
|
||||||
auto word = &_stack->back();
|
|
||||||
debugStack("pop", *word);
|
|
||||||
_stack->pop_back();
|
|
||||||
*_outWord = *word;
|
*_outWord = *word;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void evmccrt_stack_get(StackImpl* _stack, uint32_t _index, i256* _outWord)
|
EXPORT void evmccrt_stack_get(uint32_t _index, i256* _outWord)
|
||||||
{
|
{
|
||||||
assert(_index < _stack->size());
|
assert(_index < Runtime::getStack().size());
|
||||||
auto word = _stack->rbegin() + _index;
|
auto word = Runtime::getStack().rbegin() + _index;
|
||||||
debugStack("get", *word, _index);
|
//debugStack("get", *word, _index);
|
||||||
*_outWord = *word;
|
*_outWord = *word;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void evmccrt_stack_set(StackImpl* _stack, uint32_t _index, i256* _word)
|
EXPORT void evmccrt_stack_set(uint32_t _index, i256* _word)
|
||||||
{
|
{
|
||||||
assert(_index < _stack->size());
|
assert(_index < Runtime::getStack().size());
|
||||||
*(_stack->rbegin() + _index) = *_word;
|
*(Runtime::getStack().rbegin() + _index) = *_word;
|
||||||
debugStack("set", *_word, _index);
|
//debugStack("set", *_word, _index);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
llvm::IRBuilder<>& m_builder;
|
llvm::IRBuilder<>& m_builder;
|
||||||
llvm::Value* m_args[2];
|
llvm::Value* m_stackVal;
|
||||||
llvm::Function* m_stackPush;
|
llvm::Function* m_stackPush;
|
||||||
llvm::Function* m_stackPop;
|
llvm::Function* m_stackPop;
|
||||||
llvm::Function* m_stackGet;
|
llvm::Function* m_stackGet;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue