From 9300373c5077738ec9d799f2f7af9deb6e213c57 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 10 Mar 2014 10:59:19 -0700 Subject: [PATCH] Call and multi in LLL. --- libethereum/BlockChain.cpp | 2 +- libethereum/Instruction.cpp | 70 ++++++++++++++++++++++++++++++++----- libethereum/State.cpp | 1 + 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 644c5e2d9..d29a8c6d8 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -221,7 +221,7 @@ void BlockChain::import(bytes const& _block, Overlay const& _db) // cnote << "Parent " << bi.parentHash << " has " << details(bi.parentHash).children.size() << " children."; - // This might be the new last block... + // This might be the new best block... if (td > details(m_lastBlockHash).totalDifficulty) { m_lastBlockHash = newHash; diff --git a/libethereum/Instruction.cpp b/libethereum/Instruction.cpp index 24410da24..141c8bd77 100644 --- a/libethereum/Instruction.cpp +++ b/libethereum/Instruction.cpp @@ -283,10 +283,11 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s for (int i = 0; i < 2; ++i) { int o = compileLispFragment(d, e, _quiet, codes[i], locs[i]); - if (o == -1) + if (o == -1 || (i == 0 && o != 1)) return false; - for (int i = 0; i < o; ++i) - o_code.push_back(Instruction::POP); // pop additional items off stack for the previous item (final item's returns get left on). + if (i == 1) + for (int j = 0; j < o; ++j) + codes[i].push_back(Instruction::POP); // pop additional items off stack for the previous item (final item's returns get left on). } if (compileLispFragment(d, e, _quiet, codes[2], locs[2]) != -1) return false; @@ -320,10 +321,11 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s for (int i = 0; i < 2; ++i) { int o = compileLispFragment(d, e, _quiet, codes[i], locs[i]); - if (o == -1) + if (o == -1 || (i == 0 && o != 1)) return false; - for (int i = 0; i < o; ++i) - o_code.push_back(Instruction::POP); // pop additional items off stack for the previous item (final item's returns get left on). + if (i == 1) + for (int j = 0; j < o; ++j) + codes[i].push_back(Instruction::POP); // pop additional items off stack for the previous item (final item's returns get left on). } if (compileLispFragment(d, e, _quiet, codes[2], locs[2]) != -1) return false; @@ -374,6 +376,58 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s break; } } + else if (t == "CALL") + { + if (exec) + { + vector>> codes(1); + int totalArgs = 0; + while (d != e) + { + int o = compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second); + if (o < 1) + break; + codes.push_back(pair>()); + totalArgs += o; + } + if (totalArgs < 2) + { + cwarn << "Expected at least 2 arguments to CALL; got" << totalArgs << "."; + break; + } + + unsigned datan = codes.size() - 3; + unsigned i = 0; + for (auto it = codes.rbegin(); it != codes.rend(); ++it, ++i) + { + appendCode(o_code, o_locs, it->first, it->second); + if (i == datan) + { + o_code.push_back(Instruction::PUSH); + o_code.push_back(datan); + } + } + o_code.push_back(Instruction::MKTX); + outs = 0; + } + } + else if (t == "MULTI") + { + while (d != e) + { + u256s codes; + vector locs; + outs = 0; + int o; + if ((o = compileLispFragment(d, e, _quiet, codes, locs)) > -1) + { + outs += o; + appendCode(o_code, o_locs, codes, locs); + } + else + break; + } + } else if (t == "AND") { vector codes; @@ -501,9 +555,9 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s totalArgs += o; } int ea = c_instructionInfo.at(it->second).args; - if (totalArgs != ea || (ea < 0 && totalArgs < -ea)) + if ((ea >= 0 && totalArgs != ea) || (ea < 0 && totalArgs < -ea)) { - cwarn << "Expected " << (ea < 0 ? "at least" : "exactly") << abs(ea) << "arguments to binary operator" << t << "; got" << totalArgs << "."; + cwarn << "Expected " << (ea < 0 ? "at least" : "exactly") << abs(ea) << "arguments to operation" << t << "; got" << totalArgs << "."; break; } diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 4e710cb1d..0fb544844 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -368,6 +368,7 @@ u256 State::playback(bytesConstRef _block, BlockInfo const& _grandParent, bool _ u256 tdIncrease = m_currentBlock.difficulty; // Check uncles & apply their rewards to state. + // TODO: Check for uniqueness of uncles. Addresses rewarded; for (auto const& i: RLP(_block)[2]) {