diff --git a/alethzero/Main.ui b/alethzero/Main.ui index a9782f8a2..3712ca489 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -1288,7 +1288,8 @@ font-size: 14pt background: white; border: 0; -font-family: Monospace, Ubuntu Mono, Lucida Console, Courier New +font-family: Monospace, Ubuntu Mono, Lucida Console, Courier New; +font-size: 12pt diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index a8c024454..d06d0948e 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -118,7 +118,7 @@ Main::Main(QWidget *parent) : connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); -#if ETH_DEBUG +#if 0&Ð_DEBUG m_servers.append("192.168.0.10:30301"); #else int pocnumber = QString(eth::EthVersion).section('.', 1, 1).toInt(); @@ -985,7 +985,7 @@ void Main::on_data_textChanged() { try { - m_data = eth::asBytes(compile(src)); + m_data = compile(src); for (auto& i: errors) i = "(LLL " + i + ")"; } diff --git a/libethcore/TrieDB.h b/libethcore/TrieDB.h index 023a0dc1d..c6114b95d 100644 --- a/libethcore/TrieDB.h +++ b/libethcore/TrieDB.h @@ -42,7 +42,7 @@ extern const h256 c_shaNull; /** * @brief Merkle Patricia Tree "Trie": a modifed base-16 Radix tree. - * This version uses an LDB backend + * This version uses an database backend. * Usage: * @code * GenericTrieDB t(&myDB); @@ -153,6 +153,7 @@ public: std::string at(bytesConstRef _key) const; void insert(bytesConstRef _key, bytesConstRef _value); void remove(bytesConstRef _key); + void contains(bytesConstRef _key) { return !at(_key).empty(); } class iterator { @@ -274,6 +275,7 @@ public: std::string operator[](KeyType _k) const { return at(_k); } + bool contains(KeyType _k) const { return GenericTrieDB::contains(bytesConstRef((byte const*)&_k, sizeof(KeyType))); } std::string at(KeyType _k) const { return GenericTrieDB::at(bytesConstRef((byte const*)&_k, sizeof(KeyType))); } void insert(KeyType _k, bytesConstRef _value) { GenericTrieDB::insert(bytesConstRef((byte const*)&_k, sizeof(KeyType)), _value); } void insert(KeyType _k, bytes const& _value) { insert(_k, bytesConstRef(&_value)); } diff --git a/libethential/CMakeLists.txt b/libethential/CMakeLists.txt index c81c2c8f1..e247abcd0 100644 --- a/libethential/CMakeLists.txt +++ b/libethential/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_policy(SET CMP0015 NEW) +cmake_policy(SET CMP0022 NEW) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") @@ -16,7 +17,6 @@ include_directories(..) target_link_libraries(${EXECUTABLE} ethential) target_link_libraries(${EXECUTABLE} gmp) - if(${TARGET_PLATFORM} STREQUAL "w64") include_directories(/usr/x86_64-w64-mingw32/include/cryptopp) target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) diff --git a/libethereum/Client.h b/libethereum/Client.h index cf5235c8c..8683b90f8 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -140,14 +140,13 @@ public: BlockChain const& blockChain() const { return m_bc; } // [NEW API] -/* - u256 balanceAt(Address _a, unsigned _age = 1) const; - u256 countAt(Address _a, unsigned _age = 1) const; - u256 stateAt(Address _a, u256 _l, unsigned _age = 1) const; - bytes codeAt(Address _a, unsigned _age = 1) const; - Transactions transactions(Addresses const& _from, Addresses const& _to, std::vector> const& _stateAlterations, Addresses const& _altered, unsigned _ageFrom = 0, unsigned _ageTo, unsigned _max) const; -*/ + u256 balanceAt(Address _a, int _block = -1) const; + u256 countAt(Address _a, int _block = -1) const; + u256 stateAt(Address _a, u256 _l, int _block = -1) const; + bytes codeAt(Address _a, int _block = -1) const; + Transactions transactions(Addresses const& _from, Addresses const& _to, std::vector> const& _stateAlterations, Addresses const& _altered, int _blockFrom = 0, int _blockTo = -1, unsigned _max = 10) const; + // Misc stuff: void setClientVersion(std::string const& _name) { m_clientVersion = _name; } diff --git a/libevm/All.h b/libevm/All.h new file mode 100644 index 000000000..89c451ef4 --- /dev/null +++ b/libevm/All.h @@ -0,0 +1,5 @@ +#pragma once + +#include "ExtVMFace.h" +#include "FeeStructure.h" +#include "VM.h" diff --git a/liblll/Assembly.cpp b/liblll/Assembly.cpp index 0fa125378..7016b2863 100644 --- a/liblll/Assembly.cpp +++ b/liblll/Assembly.cpp @@ -176,6 +176,11 @@ AssemblyItem const& Assembly::append(AssemblyItem const& _i) return back(); } +void Assembly::injectStart(AssemblyItem const& _i) +{ + m_items.insert(m_items.begin(), _i); +} + inline bool matches(AssemblyItemsConstRef _a, AssemblyItemsConstRef _b) { if (_a.size() != _b.size()) diff --git a/liblll/Assembly.h b/liblll/Assembly.h index 3e8a83260..9cd10a820 100644 --- a/liblll/Assembly.h +++ b/liblll/Assembly.h @@ -98,6 +98,8 @@ public: void popTo(int _deposit) { while (m_deposit > _deposit) append(Instruction::POP); } + void injectStart(AssemblyItem const& _i); + std::string out() const { std::stringstream ret; streamOut(ret); return ret.str(); } int deposit() const { return m_deposit; } bytes assemble() const; diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp index f0aeb860c..70973aab4 100644 --- a/liblll/CodeFragment.cpp +++ b/liblll/CodeFragment.cpp @@ -19,7 +19,6 @@ * @date 2014 */ -#include "Parser.h" #include "CodeFragment.h" #include @@ -27,12 +26,30 @@ #include #include #include "CompilerState.h" +#include "Parser.h" using namespace std; using namespace eth; namespace qi = boost::spirit::qi; namespace px = boost::phoenix; namespace sp = boost::spirit; +void CodeFragment::finalise(CompilerState const& _cs) +{ + if (_cs.usedAlloc && _cs.vars.size() && !m_finalised) + { + m_finalised = true; + m_asm.injectStart(Instruction::MSTORE8); + m_asm.injectStart((u256)((_cs.vars.size() + 2) * 32) - 1); + m_asm.injectStart((u256)1); + } +} + +bytes CodeFragment::code(CompilerState const& _cs) +{ + finalise(_cs); + return m_asm.assemble(); +} + CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM) { /* cdebug << "CodeFragment. Locals:"; @@ -317,6 +334,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) vector code; CompilerState ns = _s; ns.vars.clear(); + ns.usedAlloc = false; int c = _t.tag() ? 1 : 0; for (auto const& i: _t) if (c++) @@ -456,13 +474,30 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) m_asm.appendJump(begin); m_asm << end.tag(); } + else if (us == "ALLOC") + { + requireSize(1); + requireDeposit(0, 1); + + m_asm.append(Instruction::MEMSIZE); + m_asm.append(u256(0)); + m_asm.append(u256(1)); + m_asm.append(code[0].m_asm, 1); + m_asm.append(Instruction::MEMSIZE); + m_asm.append(Instruction::ADD); + m_asm.append(Instruction::SUB); + m_asm.append(Instruction::MSTORE8); + + _s.usedAlloc = true; + } else if (us == "LLL") { requireMinSize(2); requireMaxSize(3); requireDeposit(1, 1); - bytes const& subcode = code[0].code(); + code[0].optimise(); + bytes subcode = code[0].code(ns); m_asm.append((u256)subcode.size()); m_asm.append(Instruction::DUP); diff --git a/liblll/CodeFragment.h b/liblll/CodeFragment.h index b9d44c030..58e409125 100644 --- a/liblll/CodeFragment.h +++ b/liblll/CodeFragment.h @@ -43,18 +43,21 @@ public: static CodeFragment compile(std::string const& _src, CompilerState& _s); /// Consolidates data and compiles code. - bytes code() const { return m_asm.assemble(); } + bytes code(CompilerState const& _cs); /// Consolidates data and compiles code. - std::string assembly() const { return m_asm.out(); } + std::string assembly(CompilerState const& _cs) { finalise(_cs); return m_asm.out(); } /// Optimise the code. Best do this just before calling code() or assembly(). void optimise() { m_asm.optimise(); } private: + void finalise(CompilerState const& _cs); + template void error() const { throw T(); } void constructOperation(sp::utree const& _t, CompilerState& _s); + bool m_finalised = false; Assembly m_asm; }; diff --git a/liblll/Compiler.cpp b/liblll/Compiler.cpp index 8400ad955..0faf478d6 100644 --- a/liblll/Compiler.cpp +++ b/liblll/Compiler.cpp @@ -36,7 +36,7 @@ bytes eth::compileLLL(string const& _src, bool _opt, vector* _errors) auto f = CodeFragment::compile(_src, cs); if (_opt) f.optimise(); - bytes ret = f.code(); + bytes ret = f.code(cs); for (auto i: cs.treesToKill) killBigints(i); return ret; @@ -63,7 +63,7 @@ std::string eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector auto f = CodeFragment::compile(_src, cs); if (_opt) f.optimise(); - string ret = f.assembly(); + string ret = f.assembly(cs); for (auto i: cs.treesToKill) killBigints(i); return ret; diff --git a/liblll/CompilerState.cpp b/liblll/CompilerState.cpp index 7e990413f..7a6681909 100644 --- a/liblll/CompilerState.cpp +++ b/liblll/CompilerState.cpp @@ -52,8 +52,7 @@ void CompilerState::populateStandard() "(def 'regname (name) { [0]:name (call (- (gas) 21) namereg 0 0 32 0 0) })" "(def 'send (to value) (call (- (gas) 21) to value 0 0 0 0))" "(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))" - "(def 'alloc (len) (asm msize 0 1 len msize add sub mstore8))" - "(def 'msg (gaslimit to value data datasize outsize) { [32]:outsize [0]:(alloc @32) (call gaslimit to value data datasize @0 @32) @0 })" + "(def 'msg (gaslimit to value data datasize outsize) { (set x outsize) (set y (alloc @32)) (call gaslimit to value data datasize @0 @32) @0 })" "(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })" "(def 'msg (gaslimit to value data) { [0]:data (msg gaslimit to value 0 32) })" "(def 'msg (to value data) { [0]:data (msg 0 to value 0 32) })" diff --git a/liblll/CompilerState.h b/liblll/CompilerState.h index f8f7ce815..5dcde6147 100644 --- a/liblll/CompilerState.h +++ b/liblll/CompilerState.h @@ -48,6 +48,7 @@ struct CompilerState std::map outers; std::map, Macro> macros; std::vector treesToKill; + bool usedAlloc = false; }; } diff --git a/sc/cmdline.cpp b/sc/cmdline.cpp index 03e501ea1..e8a0a130c 100644 --- a/sc/cmdline.cpp +++ b/sc/cmdline.cpp @@ -10,7 +10,7 @@ int main(int argv, char** argc) { if (argv == 1) { std::cerr << "Must provide a command and arguments! Try parse, rewrite, compile, assemble\n"; return 0; - } + } std::string flag = ""; std::string command = argc[1]; std::string input;