mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 03:10:48 +00:00
Implementing RETURN and STOP instructions
This commit is contained in:
parent
b9cda13a9a
commit
748ee0fe8d
5 changed files with 63 additions and 17 deletions
|
|
@ -49,7 +49,10 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
IRBuilder<> builder(context);
|
||||
|
||||
// Create main function
|
||||
auto mainFuncType = FunctionType::get(llvm::Type::getInt32Ty(context), false);
|
||||
const auto i32Ty = builder.getInt32Ty();
|
||||
Type* retTypeElems[] = {i32Ty, i32Ty};
|
||||
auto retType = StructType::create(retTypeElems, "MemRef", true);
|
||||
auto mainFuncType = FunctionType::get(builder.getInt64Ty(), false);
|
||||
auto mainFunc = Function::Create(mainFuncType, Function::ExternalLinkage, "main", module.get());
|
||||
|
||||
auto entryBlock = BasicBlock::Create(context, "entry", mainFunc);
|
||||
|
|
@ -61,7 +64,9 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
|
||||
auto ext = Ext(builder);
|
||||
|
||||
for (auto pc = bytecode.cbegin(); pc != bytecode.cend(); ++pc)
|
||||
auto userRet = false;
|
||||
auto finished = false;
|
||||
for (auto pc = bytecode.cbegin(); pc != bytecode.cend() && !finished; ++pc)
|
||||
{
|
||||
using dev::eth::Instruction;
|
||||
|
||||
|
|
@ -313,10 +318,47 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
break;
|
||||
}
|
||||
|
||||
case Instruction::CODESIZE:
|
||||
{
|
||||
auto value = builder.getIntN(256, bytecode.size());
|
||||
stack.push(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case Instruction::RETURN:
|
||||
{
|
||||
auto index = stack.pop();
|
||||
auto size = stack.pop();
|
||||
|
||||
// MCJIT does not support returning structs
|
||||
//auto index32 = builder.CreateTrunc(index, i32Ty, "index32");
|
||||
//auto size32 = builder.CreateTrunc(size, i32Ty, "size32");
|
||||
//auto ret = builder.CreateInsertValue(UndefValue::get(retType), index32, 0, "ret");
|
||||
//ret = builder.CreateInsertValue(ret, size32, 1, "ret");
|
||||
|
||||
auto ret = builder.CreateTrunc(index, builder.getInt64Ty());
|
||||
ret = builder.CreateShl(ret, 32);
|
||||
size = builder.CreateTrunc(size, i32Ty);
|
||||
size = builder.CreateZExt(size, builder.getInt64Ty());
|
||||
ret = builder.CreateOr(ret, size);
|
||||
|
||||
builder.CreateRet(ret);
|
||||
finished = true;
|
||||
userRet = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case Instruction::STOP:
|
||||
{
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
builder.CreateRet(ConstantInt::get(Type::getInt32Ty(context), 0));
|
||||
if (!userRet)
|
||||
builder.CreateRet(builder.getInt64(0));
|
||||
|
||||
return module;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,8 +86,14 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
|
|||
}
|
||||
|
||||
auto result = exec->runFunction(entryFunc, {});
|
||||
auto intResult = result.IntVal.getZExtValue();
|
||||
return intResult;
|
||||
if (auto intResult = result.IntVal.getZExtValue())
|
||||
{
|
||||
auto index = intResult >> 32;
|
||||
auto size = 0xFFFFFFFF & intResult;
|
||||
// TODO: Get the data from memory
|
||||
return 10;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include <libdevcore/Common.h>
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define EXPORT __declspec(dllexport)
|
||||
#else
|
||||
|
|
@ -19,15 +21,6 @@
|
|||
namespace evmcc
|
||||
{
|
||||
|
||||
struct i256
|
||||
{
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
uint64_t c;
|
||||
uint64_t d;
|
||||
};
|
||||
static_assert(sizeof(i256) == 32, "Wrong i256 size");
|
||||
|
||||
using MemoryImpl = dev::bytes;
|
||||
|
||||
|
||||
|
|
@ -102,7 +95,7 @@ extern "C"
|
|||
{
|
||||
using namespace evmcc;
|
||||
|
||||
EXPORT MemoryImpl* evmccrt_memory;
|
||||
static MemoryImpl* evmccrt_memory;
|
||||
|
||||
EXPORT void evmccrt_memory_create(void)
|
||||
{
|
||||
|
|
@ -121,7 +114,7 @@ EXPORT void* evmccrt_memory_require(uint64_t _size)
|
|||
if (evmccrt_memory->size() < _size)
|
||||
evmccrt_memory->resize(_size);
|
||||
|
||||
return &(*evmccrt_memory)[0];
|
||||
return evmccrt_memory->data();
|
||||
}
|
||||
|
||||
EXPORT void evmccrt_memory_dump(uint64_t _begin, uint64_t _end)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
30333234363a600035602635601335
|
||||
30333234363a600035602635601335380060016002f2
|
||||
|
|
|
|||
|
|
@ -12,4 +12,9 @@ CALLDATALOAD
|
|||
CALLDATALOAD
|
||||
19
|
||||
CALLDATALOAD
|
||||
CODESIZE
|
||||
STOP
|
||||
1
|
||||
2
|
||||
RETURN
|
||||
)
|
||||
Loading…
Reference in a new issue