From 53002a7425a2097efaf60d0bfafc4246417909b2 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 26 May 2014 12:12:22 +0200 Subject: [PATCH] Assembler. Debug trace stuff. --- libethereum/State.cpp | 21 ++++++++++++---- libethereum/State.h | 1 + liblll/Assembly.cpp | 53 +++++++++++++++++++++++++++++++++++++++++ liblll/Assembly.h | 13 +++++++--- liblll/CodeFragment.cpp | 25 ------------------- liblll/CodeFragment.h | 2 -- liblll/Parser.cpp | 25 +++++++++++++++++++ liblll/Parser.h | 1 + 8 files changed, 107 insertions(+), 34 deletions(-) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index db17f599e..fa70dde24 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -35,6 +35,8 @@ using namespace std; using namespace eth; +#define ctrace clog(StateTrace) + Overlay State::openDB(std::string _path, bool _killExisting) { if (_path.empty()) @@ -883,11 +885,13 @@ u256 State::execute(bytesConstRef _rlp) commit(); // get an updated hash #endif +#if ETH_PARANOIA if (!isTrieGood()) { cwarn << "BAD TRIE before execution begins."; throw InvalidTrie(); } +#endif State old(*this); auto h = rootHash(); @@ -895,8 +899,10 @@ u256 State::execute(bytesConstRef _rlp) Executive e(*this); e.setup(_rlp); - cnote << "Executing" << e.t() << "on" << h; - cnote << toHex(e.t().rlp(true)); +#if ETH_PARANOIA + ctrace << "Executing" << e.t() << "on" << h; + ctrace << toHex(e.t().rlp(true)); +#endif u256 startGasUsed = gasUsed(); if (startGasUsed + e.t().gas > m_currentBlock.gasLimit) @@ -905,22 +911,29 @@ u256 State::execute(bytesConstRef _rlp) e.go(); e.finalize(); +#if ETH_PARANOIA + ctrace << "Ready for commit;"; + ctrace << old.diff(*this); +#endif + commit(); +#if ETH_PARANOIA if (e.t().receiveAddress) { EnforceRefs r(m_db, true); assert(!storageRoot(e.t().receiveAddress) || m_db.lookup(storageRoot(e.t().receiveAddress)).size()); } - cnote << "Executed; now" << rootHash(); - cnote << old.diff(*this); + ctrace << "Executed; now" << rootHash(); + ctrace << old.diff(*this); if (!isTrieGood()) { cwarn << "BAD TRIE immediately after execution."; throw InvalidTrie(); } +#endif // TODO: CHECK TRIE after level DB flush to make sure exactly the same. diff --git a/libethereum/State.h b/libethereum/State.h index cbad244b3..eac800447 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -43,6 +43,7 @@ namespace eth class BlockChain; struct StateChat: public LogChannel { static const char* name() { return "=S="; } static const int verbosity = 4; }; +struct StateTrace: public LogChannel { static const char* name() { return "=S="; } static const int verbosity = 7; }; struct TransactionReceipt { diff --git a/liblll/Assembly.cpp b/liblll/Assembly.cpp index e69de29bb..317a92fc8 100644 --- a/liblll/Assembly.cpp +++ b/liblll/Assembly.cpp @@ -0,0 +1,53 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Assembly.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Assembly.h" + +#include + +using namespace std; +using namespace eth; + +void Assembly::append(Assembly const& _a) +{ + for (AssemblyItem i: _a.m_items) + { + if (i.type() == Tag || i.type() == PushTag) + i.m_data += m_usedTags; + m_items.push_back(i); + } + for (auto const& i: _a.m_data) + m_data.insert(i); +} + +ostream& Assembly::streamOut(ostream& _out) const +{ + for (auto const& i: m_items) + { + } + return _out; +} + +bytes Assembly::assemble() const +{ + bytes ret; + return ret; +} diff --git a/liblll/Assembly.h b/liblll/Assembly.h index 28d2974bb..cbce3ca82 100644 --- a/liblll/Assembly.h +++ b/liblll/Assembly.h @@ -21,6 +21,7 @@ #pragma once +#include #include #include #include "Exceptions.h" @@ -30,23 +31,24 @@ namespace eth enum AssemblyItemType { Operation, Push, PushString, PushTag, Tag, PushData }; +class Assembly; + class AssemblyItem { + friend class Assembly; + public: AssemblyItem(u256 _push): m_type(Push), m_data(_push) {} - AssemblyItem(std::string const& _push): m_type(PushString), m_pushString(_push) {} AssemblyItem(AssemblyItemType _type, AssemblyItem const& _tag): m_type(_type), m_data(_tag.m_data) { assert(_type == PushTag); assert(_tag.m_type == Tag); } AssemblyItem(Instruction _i): m_type(Operation), m_data((byte)_i) {} AssemblyItem(AssemblyItemType _type, u256 _data): m_type(_type), m_data(_data) {} AssemblyItemType type() const { return m_type; } u256 data() const { return m_data; } - std::string const& pushString() const { return m_pushString; } private: AssemblyItemType m_type; u256 m_data; - std::string m_pushString; }; class Assembly @@ -54,8 +56,13 @@ class Assembly public: AssemblyItem newTag() { return AssemblyItem(Tag, m_usedTags++); } AssemblyItem newData(bytes const& _data) { auto h = sha3(_data); m_data[h] = _data; return AssemblyItem(PushData, h); } + AssemblyItem newPushString(std::string const& _data) { auto b = asBytes(_data); auto h = sha3(b); m_data[h] = b; return AssemblyItem(PushString, h); } + + void append(AssemblyItem const& _i) { m_items.push_back(_i); } + bytes assemble() const; void append(Assembly const& _a); + std::ostream& streamOut(std::ostream& _out) const; private: u256 m_usedTags = 0; diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp index cc76c432a..c4b7ae0bb 100644 --- a/liblll/CodeFragment.cpp +++ b/liblll/CodeFragment.cpp @@ -34,31 +34,6 @@ namespace qi = boost::spirit::qi; namespace px = boost::phoenix; namespace sp = boost::spirit; -void eth::debugOutAST(ostream& _out, sp::utree const& _this) -{ - switch (_this.which()) - { - case sp::utree_type::list_type: - switch (_this.tag()) - { - case 0: _out << "( "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << ")"; break; - case 1: _out << "@ "; debugOutAST(_out, _this.front()); break; - case 2: _out << "@@ "; debugOutAST(_out, _this.front()); break; - case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break; - case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break; - case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break; - default:; - } - - break; - case sp::utree_type::int_type: _out << _this.get(); break; - case sp::utree_type::string_type: _out << "\"" << _this.get, sp::utree_type::string_type>>() << "\""; break; - case sp::utree_type::symbol_type: _out << _this.get, sp::utree_type::symbol_type>>(); break; - case sp::utree_type::any_type: _out << *_this.get(); break; - default: _out << "nil"; - } -} - void CodeFragment::appendFragment(CodeFragment const& _f) { m_locs.reserve(m_locs.size() + _f.m_locs.size()); diff --git a/liblll/CodeFragment.h b/liblll/CodeFragment.h index cee7da3b3..9f312cda9 100644 --- a/liblll/CodeFragment.h +++ b/liblll/CodeFragment.h @@ -32,8 +32,6 @@ namespace sp = boost::spirit; namespace eth { -void debugOutAST(std::ostream& _out, sp::utree const& _this); - class CompilerState; class CodeFragment diff --git a/liblll/Parser.cpp b/liblll/Parser.cpp index 2a0146a60..10d2188a4 100644 --- a/liblll/Parser.cpp +++ b/liblll/Parser.cpp @@ -42,6 +42,31 @@ void eth::killBigints(sp::utree const& _this) } } +void eth::debugOutAST(ostream& _out, sp::utree const& _this) +{ + switch (_this.which()) + { + case sp::utree_type::list_type: + switch (_this.tag()) + { + case 0: _out << "( "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << ")"; break; + case 1: _out << "@ "; debugOutAST(_out, _this.front()); break; + case 2: _out << "@@ "; debugOutAST(_out, _this.front()); break; + case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break; + case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break; + case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break; + default:; + } + + break; + case sp::utree_type::int_type: _out << _this.get(); break; + case sp::utree_type::string_type: _out << "\"" << _this.get, sp::utree_type::string_type>>() << "\""; break; + case sp::utree_type::symbol_type: _out << _this.get, sp::utree_type::symbol_type>>(); break; + case sp::utree_type::any_type: _out << *_this.get(); break; + default: _out << "nil"; + } +} + void eth::parseTreeLLL(string const& _s, sp::utree& o_out) { using qi::ascii::space; diff --git a/liblll/Parser.h b/liblll/Parser.h index 3b2756576..059ffe6a2 100644 --- a/liblll/Parser.h +++ b/liblll/Parser.h @@ -33,6 +33,7 @@ namespace eth void killBigints(sp::utree const& _this); void parseTreeLLL(std::string const& _s, sp::utree& o_out); +void debugOutAST(std::ostream& _out, sp::utree const& _this); }