mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 19:56:44 +00:00
parent
11bf67b2d8
commit
07f6bbffe5
13 changed files with 49 additions and 51 deletions
|
|
@ -30,7 +30,7 @@ Compiler::Compiler()
|
||||||
Type::init(llvm::getGlobalContext());
|
Type::init(llvm::getGlobalContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::createBasicBlocks(const dev::bytes& bytecode)
|
void Compiler::createBasicBlocks(const bytes& bytecode)
|
||||||
{
|
{
|
||||||
std::set<ProgramCounter> splitPoints; // Sorted collections of instruction indices where basic blocks start/end
|
std::set<ProgramCounter> splitPoints; // Sorted collections of instruction indices where basic blocks start/end
|
||||||
splitPoints.insert(0); // First basic block
|
splitPoints.insert(0); // First basic block
|
||||||
|
|
@ -41,8 +41,6 @@ void Compiler::createBasicBlocks(const dev::bytes& bytecode)
|
||||||
|
|
||||||
for (auto curr = bytecode.cbegin(); curr != bytecode.cend(); ++curr)
|
for (auto curr = bytecode.cbegin(); curr != bytecode.cend(); ++curr)
|
||||||
{
|
{
|
||||||
using dev::eth::Instruction;
|
|
||||||
|
|
||||||
ProgramCounter currentPC = curr - bytecode.cbegin();
|
ProgramCounter currentPC = curr - bytecode.cbegin();
|
||||||
validJumpTargets[currentPC] = 1;
|
validJumpTargets[currentPC] = 1;
|
||||||
|
|
||||||
|
|
@ -62,7 +60,7 @@ void Compiler::createBasicBlocks(const dev::bytes& bytecode)
|
||||||
if (nextInst == Instruction::JUMP || nextInst == Instruction::JUMPI)
|
if (nextInst == Instruction::JUMP || nextInst == Instruction::JUMPI)
|
||||||
{
|
{
|
||||||
// Compute target PC of the jump.
|
// Compute target PC of the jump.
|
||||||
dev::u256 val = 0;
|
u256 val = 0;
|
||||||
for (auto iter = curr + 1; iter < next; ++iter)
|
for (auto iter = curr + 1; iter < next; ++iter)
|
||||||
{
|
{
|
||||||
val <<= 8;
|
val <<= 8;
|
||||||
|
|
@ -153,7 +151,7 @@ void Compiler::createBasicBlocks(const dev::bytes& bytecode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
||||||
{
|
{
|
||||||
auto& context = llvm::getGlobalContext();
|
auto& context = llvm::getGlobalContext();
|
||||||
auto module = std::make_unique<llvm::Module>("main", context);
|
auto module = std::make_unique<llvm::Module>("main", context);
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,11 @@ public:
|
||||||
|
|
||||||
Compiler();
|
Compiler();
|
||||||
|
|
||||||
std::unique_ptr<llvm::Module> compile(const dev::bytes& bytecode);
|
std::unique_ptr<llvm::Module> compile(const bytes& bytecode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void createBasicBlocks(const dev::bytes& bytecode);
|
void createBasicBlocks(const bytes& bytecode);
|
||||||
|
|
||||||
void linkBasicBlocks();
|
void linkBasicBlocks();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,14 +81,14 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
|
||||||
exec->finalizeObject();
|
exec->finalizeObject();
|
||||||
|
|
||||||
// Create fake ExtVM interface
|
// Create fake ExtVM interface
|
||||||
auto ext = std::make_unique<dev::eth::ExtVMFace>();
|
auto ext = std::make_unique<ExtVMFace>();
|
||||||
ext->myAddress = dev::Address(1122334455667788);
|
ext->myAddress = Address(1122334455667788);
|
||||||
ext->caller = dev::Address(0xfacefacefaceface);
|
ext->caller = Address(0xfacefacefaceface);
|
||||||
ext->origin = dev::Address(101010101010101010);
|
ext->origin = Address(101010101010101010);
|
||||||
ext->value = 0xabcd;
|
ext->value = 0xabcd;
|
||||||
ext->gasPrice = 1002;
|
ext->gasPrice = 1002;
|
||||||
ext->previousBlock.hash = dev::u256(1003);
|
ext->previousBlock.hash = u256(1003);
|
||||||
ext->currentBlock.coinbaseAddress = dev::Address(1004);
|
ext->currentBlock.coinbaseAddress = Address(1004);
|
||||||
ext->currentBlock.timestamp = 1005;
|
ext->currentBlock.timestamp = 1005;
|
||||||
ext->currentBlock.number = 1006;
|
ext->currentBlock.number = 1006;
|
||||||
ext->currentBlock.difficulty = 1007;
|
ext->currentBlock.difficulty = 1007;
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,10 @@ namespace eth
|
||||||
namespace jit
|
namespace jit
|
||||||
{
|
{
|
||||||
|
|
||||||
// TODO: Copy of dev::eth::fromAddress in VM.h
|
// TODO: Copy of fromAddress in VM.h
|
||||||
inline dev::u256 fromAddress(dev::Address _a)
|
inline u256 fromAddress(Address _a)
|
||||||
{
|
{
|
||||||
return (dev::u160)_a;
|
return (u160)_a;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ExtData
|
struct ExtData
|
||||||
|
|
@ -288,13 +288,13 @@ EXPORT void ext_calldataload(i256* _index, i256* _value)
|
||||||
|
|
||||||
EXPORT void ext_balance(h256* _address, i256* _value)
|
EXPORT void ext_balance(h256* _address, i256* _value)
|
||||||
{
|
{
|
||||||
auto u = Runtime::getExt().balance(dev::right160(*_address));
|
auto u = Runtime::getExt().balance(right160(*_address));
|
||||||
*_value = eth2llvm(u);
|
*_value = eth2llvm(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void ext_suicide(h256* _address)
|
EXPORT void ext_suicide(h256* _address)
|
||||||
{
|
{
|
||||||
Runtime::getExt().suicide(dev::right160(*_address));
|
Runtime::getExt().suicide(right160(*_address));
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void ext_create(i256* _endowment, i256* _initOff, i256* _initSize, h256* _address)
|
EXPORT void ext_create(i256* _endowment, i256* _initOff, i256* _initSize, h256* _address)
|
||||||
|
|
@ -308,8 +308,8 @@ EXPORT void ext_create(i256* _endowment, i256* _initOff, i256* _initSize, h256*
|
||||||
u256 gas; // TODO: Handle gas
|
u256 gas; // TODO: Handle gas
|
||||||
auto initOff = static_cast<size_t>(llvm2eth(*_initOff));
|
auto initOff = static_cast<size_t>(llvm2eth(*_initOff));
|
||||||
auto initSize = static_cast<size_t>(llvm2eth(*_initSize));
|
auto initSize = static_cast<size_t>(llvm2eth(*_initSize));
|
||||||
auto&& initRef = dev::bytesConstRef(Runtime::getMemory().data() + initOff, initSize);
|
auto&& initRef = bytesConstRef(Runtime::getMemory().data() + initOff, initSize);
|
||||||
auto&& onOp = dev::bytesConstRef(); // TODO: Handle that thing
|
auto&& onOp = bytesConstRef(); // TODO: Handle that thing
|
||||||
h256 address = ext.create(endowment, &gas, initRef, onOp);
|
h256 address = ext.create(endowment, &gas, initRef, onOp);
|
||||||
*_address = address;
|
*_address = address;
|
||||||
}
|
}
|
||||||
|
|
@ -329,15 +329,15 @@ EXPORT void ext_call(i256* _gas, h256* _receiveAddress, i256* _value, i256* _inO
|
||||||
if (ext.balance(ext.myAddress) >= value)
|
if (ext.balance(ext.myAddress) >= value)
|
||||||
{
|
{
|
||||||
ext.subBalance(value);
|
ext.subBalance(value);
|
||||||
auto receiveAddress = dev::right160(*_receiveAddress);
|
auto receiveAddress = right160(*_receiveAddress);
|
||||||
auto inOff = static_cast<size_t>(llvm2eth(*_inOff));
|
auto inOff = static_cast<size_t>(llvm2eth(*_inOff));
|
||||||
auto inSize = static_cast<size_t>(llvm2eth(*_inSize));
|
auto inSize = static_cast<size_t>(llvm2eth(*_inSize));
|
||||||
auto outOff = static_cast<size_t>(llvm2eth(*_outOff));
|
auto outOff = static_cast<size_t>(llvm2eth(*_outOff));
|
||||||
auto outSize = static_cast<size_t>(llvm2eth(*_outSize));
|
auto outSize = static_cast<size_t>(llvm2eth(*_outSize));
|
||||||
auto&& inRef = dev::bytesConstRef(Runtime::getMemory().data() + inOff, inSize);
|
auto&& inRef = bytesConstRef(Runtime::getMemory().data() + inOff, inSize);
|
||||||
auto&& outRef = dev::bytesConstRef(Runtime::getMemory().data() + outOff, outSize);
|
auto&& outRef = bytesConstRef(Runtime::getMemory().data() + outOff, outSize);
|
||||||
dev::eth::OnOpFunc onOp{}; // TODO: Handle that thing
|
OnOpFunc onOp{}; // TODO: Handle that thing
|
||||||
auto codeAddress = dev::right160(*_codeAddress);
|
auto codeAddress = right160(*_codeAddress);
|
||||||
ret = ext.call(receiveAddress, value, inRef, &gas, outRef, onOp, {}, codeAddress);
|
ret = ext.call(receiveAddress, value, inRef, &gas, outRef, onOp, {}, codeAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -349,23 +349,23 @@ EXPORT void ext_sha3(i256* _inOff, i256* _inSize, i256* _ret)
|
||||||
{
|
{
|
||||||
auto inOff = static_cast<size_t>(llvm2eth(*_inOff));
|
auto inOff = static_cast<size_t>(llvm2eth(*_inOff));
|
||||||
auto inSize = static_cast<size_t>(llvm2eth(*_inSize));
|
auto inSize = static_cast<size_t>(llvm2eth(*_inSize));
|
||||||
auto dataRef = dev::bytesConstRef(Runtime::getMemory().data() + inOff, inSize);
|
auto dataRef = bytesConstRef(Runtime::getMemory().data() + inOff, inSize);
|
||||||
auto hash = dev::eth::sha3(dataRef);
|
auto hash = sha3(dataRef);
|
||||||
*_ret = *reinterpret_cast<i256*>(&hash);
|
*_ret = *reinterpret_cast<i256*>(&hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void ext_exp(i256* _left, i256* _right, i256* _ret)
|
EXPORT void ext_exp(i256* _left, i256* _right, i256* _ret)
|
||||||
{
|
{
|
||||||
dev::bigint left = llvm2eth(*_left);
|
bigint left = llvm2eth(*_left);
|
||||||
dev::bigint right = llvm2eth(*_right);
|
bigint right = llvm2eth(*_right);
|
||||||
auto ret = static_cast<u256>(boost::multiprecision::powm(left, right, dev::bigint(2) << 256));
|
auto ret = static_cast<u256>(boost::multiprecision::powm(left, right, bigint(2) << 256));
|
||||||
*_ret = eth2llvm(ret);
|
*_ret = eth2llvm(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT unsigned char* ext_codeAt(h256* _addr256)
|
EXPORT unsigned char* ext_codeAt(h256* _addr256)
|
||||||
{
|
{
|
||||||
auto&& ext = Runtime::getExt();
|
auto&& ext = Runtime::getExt();
|
||||||
auto addr = dev::right160(*_addr256);
|
auto addr = right160(*_addr256);
|
||||||
auto& code = ext.codeAt(addr);
|
auto& code = ext.codeAt(addr);
|
||||||
return const_cast<unsigned char*>(code.data());
|
return const_cast<unsigned char*>(code.data());
|
||||||
}
|
}
|
||||||
|
|
@ -373,7 +373,7 @@ EXPORT unsigned char* ext_codeAt(h256* _addr256)
|
||||||
EXPORT void ext_codesizeAt(h256* _addr256, i256* _ret)
|
EXPORT void ext_codesizeAt(h256* _addr256, i256* _ret)
|
||||||
{
|
{
|
||||||
auto&& ext = Runtime::getExt();
|
auto&& ext = Runtime::getExt();
|
||||||
auto addr = dev::right160(*_addr256);
|
auto addr = right160(*_addr256);
|
||||||
auto& code = ext.codeAt(addr);
|
auto& code = ext.codeAt(addr);
|
||||||
*_ret = eth2llvm(u256(code.size()));
|
*_ret = eth2llvm(u256(code.size()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class Ext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Ext(llvm::IRBuilder<>& _builder, llvm::Module* module);
|
Ext(llvm::IRBuilder<>& _builder, llvm::Module* module);
|
||||||
static void init(std::unique_ptr<dev::eth::ExtVMFace> _ext);
|
static void init(std::unique_ptr<ExtVMFace> _ext);
|
||||||
|
|
||||||
llvm::Value* store(llvm::Value* _index);
|
llvm::Value* store(llvm::Value* _index);
|
||||||
void setStore(llvm::Value* _index, llvm::Value* _value);
|
void setStore(llvm::Value* _index, llvm::Value* _value);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ namespace jit
|
||||||
namespace // Helper functions
|
namespace // Helper functions
|
||||||
{
|
{
|
||||||
|
|
||||||
uint64_t getStepCost(dev::eth::Instruction inst) // TODO: Add this function to FeeSructure (pull request submitted)
|
uint64_t getStepCost(Instruction inst) // TODO: Add this function to FeeSructure (pull request submitted)
|
||||||
{
|
{
|
||||||
switch (inst)
|
switch (inst)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ public:
|
||||||
void operator=(GasMeter) = delete;
|
void operator=(GasMeter) = delete;
|
||||||
|
|
||||||
/// Count step cost of instruction
|
/// Count step cost of instruction
|
||||||
void count(dev::eth::Instruction _inst);
|
void count(Instruction _inst);
|
||||||
|
|
||||||
/// Calculate & count gas cost for SSTORE instruction
|
/// Calculate & count gas cost for SSTORE instruction
|
||||||
void countSStore(class Ext& _ext, llvm::Value* _index, llvm::Value* _newValue);
|
void countSStore(class Ext& _ext, llvm::Value* _index, llvm::Value* _newValue);
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ public:
|
||||||
void require(llvm::Value* _offset, llvm::Value* _size);
|
void require(llvm::Value* _offset, llvm::Value* _size);
|
||||||
|
|
||||||
void registerReturnData(llvm::Value* _index, llvm::Value* _size);
|
void registerReturnData(llvm::Value* _index, llvm::Value* _size);
|
||||||
static dev::bytesConstRef getReturnData();
|
static bytesConstRef getReturnData();
|
||||||
|
|
||||||
void dump(uint64_t _begin, uint64_t _end = 0);
|
void dump(uint64_t _begin, uint64_t _end = 0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ extern "C"
|
||||||
EXPORT i256 gas;
|
EXPORT i256 gas;
|
||||||
}
|
}
|
||||||
|
|
||||||
Runtime::Runtime(dev::u256 _gas, std::unique_ptr<dev::eth::ExtVMFace> _ext):
|
Runtime::Runtime(u256 _gas, std::unique_ptr<ExtVMFace> _ext):
|
||||||
m_ext(std::move(_ext))
|
m_ext(std::move(_ext))
|
||||||
{
|
{
|
||||||
assert(!g_runtime);
|
assert(!g_runtime);
|
||||||
|
|
@ -42,12 +42,12 @@ MemoryImpl& Runtime::getMemory()
|
||||||
return g_runtime->m_memory;
|
return g_runtime->m_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev::eth::ExtVMFace& Runtime::getExt()
|
ExtVMFace& Runtime::getExt()
|
||||||
{
|
{
|
||||||
return *g_runtime->m_ext;
|
return *g_runtime->m_ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev::u256 Runtime::getGas()
|
u256 Runtime::getGas()
|
||||||
{
|
{
|
||||||
return llvm2eth(gas);
|
return llvm2eth(gas);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,12 @@ namespace jit
|
||||||
{
|
{
|
||||||
|
|
||||||
using StackImpl = std::vector<i256>;
|
using StackImpl = std::vector<i256>;
|
||||||
using MemoryImpl = dev::bytes;
|
using MemoryImpl = bytes;
|
||||||
|
|
||||||
class Runtime
|
class Runtime
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Runtime(dev::u256 _gas, std::unique_ptr<dev::eth::ExtVMFace> _ext);
|
Runtime(u256 _gas, std::unique_ptr<ExtVMFace> _ext);
|
||||||
~Runtime();
|
~Runtime();
|
||||||
|
|
||||||
Runtime(const Runtime&) = delete;
|
Runtime(const Runtime&) = delete;
|
||||||
|
|
@ -35,13 +35,13 @@ public:
|
||||||
|
|
||||||
static StackImpl& getStack();
|
static StackImpl& getStack();
|
||||||
static MemoryImpl& getMemory();
|
static MemoryImpl& getMemory();
|
||||||
static dev::eth::ExtVMFace& getExt();
|
static ExtVMFace& getExt();
|
||||||
static dev::u256 getGas();
|
static u256 getGas();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StackImpl m_stack;
|
StackImpl m_stack;
|
||||||
MemoryImpl m_memory;
|
MemoryImpl m_memory;
|
||||||
std::unique_ptr<dev::eth::ExtVMFace> m_ext;
|
std::unique_ptr<ExtVMFace> m_ext;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ namespace eth
|
||||||
namespace jit
|
namespace jit
|
||||||
{
|
{
|
||||||
|
|
||||||
dev::u256 llvm2eth(i256 _i)
|
u256 llvm2eth(i256 _i)
|
||||||
{
|
{
|
||||||
dev::u256 u = 0;
|
u256 u = 0;
|
||||||
u |= _i.d;
|
u |= _i.d;
|
||||||
u <<= 64;
|
u <<= 64;
|
||||||
u |= _i.c;
|
u |= _i.c;
|
||||||
|
|
@ -21,10 +21,10 @@ dev::u256 llvm2eth(i256 _i)
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
i256 eth2llvm(dev::u256 _u)
|
i256 eth2llvm(u256 _u)
|
||||||
{
|
{
|
||||||
i256 i;
|
i256 i;
|
||||||
dev::u256 mask = 0xFFFFFFFFFFFFFFFF;
|
u256 mask = 0xFFFFFFFFFFFFFFFF;
|
||||||
i.a = static_cast<uint64_t>(_u & mask);
|
i.a = static_cast<uint64_t>(_u & mask);
|
||||||
_u >>= 64;
|
_u >>= 64;
|
||||||
i.b = static_cast<uint64_t>(_u & mask);
|
i.b = static_cast<uint64_t>(_u & mask);
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ struct i256
|
||||||
};
|
};
|
||||||
static_assert(sizeof(i256) == 32, "Wrong i265 size");
|
static_assert(sizeof(i256) == 32, "Wrong i265 size");
|
||||||
|
|
||||||
dev::u256 llvm2eth(i256);
|
u256 llvm2eth(i256);
|
||||||
i256 eth2llvm(dev::u256);
|
i256 eth2llvm(u256);
|
||||||
|
|
||||||
struct InsertPointGuard
|
struct InsertPointGuard
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
if (opt_show_bytes)
|
if (opt_show_bytes)
|
||||||
{
|
{
|
||||||
std::cout << dev::memDump(bytecode) << std::endl;
|
std::cout << memDump(bytecode) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_dissassemble)
|
if (opt_dissassemble)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue