diff --git a/evmcc/Compiler.cpp b/evmcc/Compiler.cpp index 00f2fb00b..0bbcafafb 100644 --- a/evmcc/Compiler.cpp +++ b/evmcc/Compiler.cpp @@ -263,6 +263,13 @@ std::unique_ptr Compiler::compile(const dev::bytes& bytecode) break; } + case Instruction::ADDRESS: + { + auto value = ext.address(); + stack.push(value); + break; + } + } } diff --git a/evmcc/ExecutionEngine.cpp b/evmcc/ExecutionEngine.cpp index 3b3205af4..2b305e04a 100644 --- a/evmcc/ExecutionEngine.cpp +++ b/evmcc/ExecutionEngine.cpp @@ -69,6 +69,7 @@ int ExecutionEngine::run(std::unique_ptr _module) exec->finalizeObject(); auto ext = std::make_unique(); + ext->myAddress = dev::Address(1122334455667788); Ext::init(std::move(ext)); auto entryFunc = module->getFunction("main"); diff --git a/evmcc/Ext.cpp b/evmcc/Ext.cpp index 35606f67f..c6658f80c 100644 --- a/evmcc/Ext.cpp +++ b/evmcc/Ext.cpp @@ -19,6 +19,12 @@ using Linkage = llvm::GlobalValue::LinkageTypes; namespace evmcc { +// TODO: Copy of dev::eth::fromAddress in VM.h +inline dev::u256 fromAddress(dev::Address _a) +{ + return (dev::u160)_a; +} + std::unique_ptr g_ext; void Ext::init(std::unique_ptr _ext) @@ -26,17 +32,45 @@ void Ext::init(std::unique_ptr _ext) g_ext = std::move(_ext); } +struct ExtData +{ + i256 address; + i256 caller; + i256 origin; + i256 callvalue; + i256 gasprice; + i256 calldatasize; + const byte* calldata; +}; + Ext::Ext(llvm::IRBuilder<>& _builder) : m_builder(_builder) { auto module = m_builder.GetInsertBlock()->getParent()->getParent(); auto&& ctx = _builder.getContext(); - m_args[0] = m_builder.CreateAlloca(m_builder.getIntNTy(256), nullptr, "ext.index"); - m_args[1] = m_builder.CreateAlloca(m_builder.getIntNTy(256), nullptr, "ext.value"); - - m_store = Function::Create(TypeBuilder*, i<256>*), true>::get(ctx), Linkage::ExternalLinkage, "ext_store", module); + auto i256Ty = m_builder.getIntNTy(256); + m_args[0] = m_builder.CreateAlloca(i256Ty, nullptr, "ext.index"); + m_args[1] = m_builder.CreateAlloca(i256Ty, nullptr, "ext.value"); + + Type* elements[] = { + i256Ty, + i256Ty, + i256Ty, + i256Ty, + i256Ty, + i256Ty, + m_builder.getInt8PtrTy() + }; + auto extDataTy = StructType::create(elements, "ext.Data"); + + m_data = m_builder.CreateAlloca(extDataTy, nullptr, "ext.data"); + + m_init = Function::Create(FunctionType::get(m_builder.getVoidTy(), extDataTy->getPointerTo(), false), Linkage::ExternalLinkage, "ext_init", module); + m_store = Function::Create(TypeBuilder*, i<256>*), true>::get(ctx), Linkage::ExternalLinkage, "ext_store", module); m_setStore = Function::Create(TypeBuilder*, i<256>*), true>::get(ctx), Linkage::ExternalLinkage, "ext_setStore", module); + + m_builder.CreateCall(m_init, m_data); } llvm::Value* Ext::store(llvm::Value* _index) @@ -53,9 +87,26 @@ void Ext::setStore(llvm::Value* _index, llvm::Value* _value) m_builder.CreateCall(m_setStore, m_args); } +Value* Ext::address() +{ + auto valuePtr = m_builder.CreateStructGEP(m_data, 0); + return m_builder.CreateLoad(valuePtr); +} + extern "C" { +EXPORT void ext_init(ExtData* _extData) +{ + _extData->address = eth2llvm(fromAddress(g_ext->myAddress)); + _extData->caller = eth2llvm(fromAddress(g_ext->caller)); + _extData->origin = eth2llvm(fromAddress(g_ext->origin)); + _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(); +} + EXPORT void ext_store(i256* _index, i256* _value) { auto index = llvm2eth(*_index); diff --git a/evmcc/Ext.h b/evmcc/Ext.h index 4de1c6645..f1e6ccc66 100644 --- a/evmcc/Ext.h +++ b/evmcc/Ext.h @@ -19,10 +19,14 @@ public: llvm::Value* store(llvm::Value* _index); void setStore(llvm::Value* _index, llvm::Value* _value); + llvm::Value* address(); + private: llvm::IRBuilder<>& m_builder; llvm::Value* m_args[2]; + llvm::Value* m_data; + llvm::Function* m_init; llvm::Function* m_store; llvm::Function* m_setStore; }; diff --git a/evmcc/bytecode/ext_test.evm b/evmcc/bytecode/ext_test.evm new file mode 100644 index 000000000..64bb6b746 --- /dev/null +++ b/evmcc/bytecode/ext_test.evm @@ -0,0 +1 @@ +30 diff --git a/evmcc/lll/ext_test.lll b/evmcc/lll/ext_test.lll new file mode 100644 index 000000000..627f6f96e --- /dev/null +++ b/evmcc/lll/ext_test.lll @@ -0,0 +1,4 @@ + +(asm +ADDRESS +) \ No newline at end of file