diff --git a/evmcc/Compiler.cpp b/evmcc/Compiler.cpp index ccdf0b951..39483bc7f 100644 --- a/evmcc/Compiler.cpp +++ b/evmcc/Compiler.cpp @@ -183,7 +183,7 @@ std::unique_ptr Compiler::compile(const dev::bytes& bytecode) BasicBlock* currentBlock = entryBlock; - for (auto pc = bytecode.cbegin(); pc != bytecode.cend(); ++pc) + for (auto pc = bytecode.cbegin(); pc != bytecode.cend() && !finished; ++pc) { using dev::eth::Instruction; @@ -540,6 +540,48 @@ std::unique_ptr Compiler::compile(const dev::bytes& bytecode) break; } + case Instruction::PREVHASH: + { + auto value = ext.prevhash(); + stack.push(value); + break; + } + + case Instruction::COINBASE: + { + auto value = ext.coinbase(); + stack.push(value); + break; + } + + case Instruction::TIMESTAMP: + { + auto value = ext.timestamp(); + stack.push(value); + break; + } + + case Instruction::NUMBER: + { + auto value = ext.number(); + stack.push(value); + break; + } + + case Instruction::DIFFICULTY: + { + auto value = ext.difficulty(); + stack.push(value); + break; + } + + case Instruction::GASLIMIT: + { + auto value = ext.gaslimit(); + stack.push(value); + break; + } + case Instruction::RETURN: { auto index = stack.pop(); diff --git a/evmcc/ExecutionEngine.cpp b/evmcc/ExecutionEngine.cpp index 4d847388e..b9a71827a 100644 --- a/evmcc/ExecutionEngine.cpp +++ b/evmcc/ExecutionEngine.cpp @@ -77,6 +77,12 @@ int ExecutionEngine::run(std::unique_ptr _module) ext->origin = dev::Address(101010101010101010); ext->value = 0xabcd; ext->gasPrice = 1002; + ext->previousBlock.hash = dev::u256(1003); + ext->currentBlock.coinbaseAddress = dev::Address(1004); + ext->currentBlock.timestamp = 1005; + ext->currentBlock.number = 1006; + ext->currentBlock.difficulty = 1007; + ext->currentBlock.gasLimit = 1008; std::string calldata = "Hello the Beautiful World of Ethereum!"; ext->data = calldata; Ext::init(std::move(ext)); diff --git a/evmcc/Ext.cpp b/evmcc/Ext.cpp index 6ae84a286..5690b8ccd 100644 --- a/evmcc/Ext.cpp +++ b/evmcc/Ext.cpp @@ -34,14 +34,20 @@ void Ext::init(std::unique_ptr _ext) g_ext = std::move(_ext); } -struct ExtData +struct ExtData { i256 address; i256 caller; i256 origin; i256 callvalue; - i256 gasprice; i256 calldatasize; + i256 gasprice; + i256 prevhash; + i256 coinbase; + i256 timestamp; + i256 number; + i256 difficulty; + i256 gaslimit; const byte* calldata; }; @@ -55,13 +61,19 @@ Ext::Ext(llvm::IRBuilder<>& _builder, llvm::Module* module) m_args[1] = m_builder.CreateAlloca(i256Ty, nullptr, "ext.value"); Type* elements[] = { - i256Ty, - i256Ty, - i256Ty, - i256Ty, - i256Ty, - i256Ty, - m_builder.getInt8PtrTy() + i256Ty, // i256 address; + i256Ty, // i256 caller; + i256Ty, // i256 origin; + i256Ty, // i256 callvalue; + i256Ty, // i256 calldatasize; + i256Ty, // i256 gasprice; + i256Ty, // i256 prevhash; + i256Ty, // i256 coinbase; + i256Ty, // i256 timestamp; + i256Ty, // i256 number; + i256Ty, // i256 difficulty; + i256Ty, // i256 gaslimit; + //m_builder.getInt8PtrTy() }; auto extDataTy = StructType::create(elements, "ext.Data"); @@ -101,8 +113,14 @@ Value* Ext::address() { return getDataElem(0, "address"); } Value* Ext::caller() { return getDataElem(1, "caller"); } Value* Ext::origin() { return getDataElem(2, "origin"); } Value* Ext::callvalue() { return getDataElem(3, "callvalue"); } -Value* Ext::calldatasize() { return getDataElem(5, "calldatasize"); } -Value* Ext::gasprice() { return getDataElem(4, "gasprice"); } +Value* Ext::calldatasize() { return getDataElem(4, "calldatasize"); } +Value* Ext::gasprice() { return getDataElem(5, "gasprice"); } +Value* Ext::prevhash() { return getDataElem(6, "prevhash"); } +Value* Ext::coinbase() { return getDataElem(7, "coinbase"); } +Value* Ext::timestamp() { return getDataElem(8, "timestamp"); } +Value* Ext::number() { return getDataElem(9, "number"); } +Value* Ext::difficulty() { return getDataElem(10, "difficulty"); } +Value* Ext::gaslimit() { return getDataElem(11, "gaslimit"); } Value* Ext::calldataload(Value* _index) { @@ -135,7 +153,13 @@ EXPORT void ext_init(ExtData* _extData) _extData->callvalue = eth2llvm(g_ext->value); _extData->gasprice = eth2llvm(g_ext->gasPrice); _extData->calldatasize = eth2llvm(g_ext->data.size()); - _extData->calldata = g_ext->data.data(); + _extData->prevhash = eth2llvm(g_ext->previousBlock.hash); + _extData->coinbase = eth2llvm(fromAddress(g_ext->currentBlock.coinbaseAddress)); + _extData->timestamp = eth2llvm(g_ext->currentBlock.timestamp); + _extData->number = eth2llvm(g_ext->currentBlock.number); + _extData->difficulty = eth2llvm(g_ext->currentBlock.difficulty); + _extData->gaslimit = eth2llvm(g_ext->currentBlock.gasLimit); + //_extData->calldata = g_ext->data.data(); } EXPORT void ext_store(i256* _index, i256* _value) diff --git a/evmcc/Ext.h b/evmcc/Ext.h index 138028927..c44e5899b 100644 --- a/evmcc/Ext.h +++ b/evmcc/Ext.h @@ -25,6 +25,12 @@ public: llvm::Value* callvalue(); llvm::Value* calldatasize(); llvm::Value* gasprice(); + llvm::Value* prevhash(); + llvm::Value* coinbase(); + llvm::Value* timestamp(); + llvm::Value* number(); + llvm::Value* difficulty(); + llvm::Value* gaslimit(); llvm::Value* balance(llvm::Value* _address); llvm::Value* calldataload(llvm::Value* _index); diff --git a/evmcc/bytecode/ext_test.evm b/evmcc/bytecode/ext_test.evm index cdd04807f..c4a833296 100644 --- a/evmcc/bytecode/ext_test.evm +++ b/evmcc/bytecode/ext_test.evm @@ -1 +1 @@ -3031333234363a600035602635601335380060016002f2 +3031333234363a40414243444536600035602635601335380060016002f2 diff --git a/evmcc/lll/ext_test.lll b/evmcc/lll/ext_test.lll index b0f3a4adb..85c0b236e 100644 --- a/evmcc/lll/ext_test.lll +++ b/evmcc/lll/ext_test.lll @@ -7,6 +7,13 @@ ORIGIN CALLVALUE CALLDATASIZE GASPRICE +PREVHASH +COINBASE +TIMESTAMP +NUMBER +DIFFICULTY +GASLIMIT +CALLDATASIZE 0 CALLDATALOAD 38