From b9ba1943c442a1e61e0395affe4be82ee0ea5f74 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 25 Oct 2014 15:12:35 +0200 Subject: [PATCH] Latest PoC-7 serpent. --- libserpent/compiler.cpp | 26 ++++++++++++---------- libserpent/opcodes.h | 4 ++-- libserpent/parser.cpp | 2 +- libserpent/rewriter.cpp | 44 +++++++++++--------------------------- libwhisper/Interface.h | 1 + libwhisper/WhisperHost.cpp | 21 ++++++++++++++++++ libwhisper/WhisperHost.h | 17 ++++++++------- 7 files changed, 62 insertions(+), 53 deletions(-) diff --git a/libserpent/compiler.cpp b/libserpent/compiler.cpp index 61b70de05..251c7d9da 100644 --- a/libserpent/compiler.cpp +++ b/libserpent/compiler.cpp @@ -123,9 +123,10 @@ programData opcodeify(Node node, token("$begincode"+symb+".endcode"+symb, m), token("DUP1", m), token("$begincode"+symb, m), sub.code, token("CODECOPY", m), token("$endcode"+symb, m), token("JUMP", m), - token("~begincode"+symb, m), code, token("~endcode"+symb, m) + token("~begincode"+symb, m), code, token("~endcode"+symb, m), + token("JUMPDEST", m) }; - return pd(sub.aux, multiToken(nodelist, 10, m), 1); + return pd(sub.aux, multiToken(nodelist, 11, m), 1); } // Stack variables if (node.val == "with") { @@ -171,9 +172,9 @@ programData opcodeify(Node node, cond.code, token("$endif"+symb, m), token("JUMPI", m), action.code, - token("~endif"+symb, m) + token("~endif"+symb, m), token("JUMPDEST", m) }; - return pd(aux, multiToken(nodelist, 5, m), 0); + return pd(aux, multiToken(nodelist, 6, m), 0); } // 3-part conditional else if (node.val == "if" && node.args.size() == 3) { @@ -190,13 +191,15 @@ programData opcodeify(Node node, if (elsed.outs > outs) elsed.code = popwrap(elsed.code); Node nodelist[] = { ifd.code, - token("NOT", m), token("$else"+symb, m), token("JUMPI", m), + token("NOT", m), + token("$else"+symb, m), token("JUMPI", m), thend.code, - token("$endif"+symb, m), token("JUMP", m), token("~else"+symb, m), + token("$endif"+symb, m), token("JUMP", m), + token("~else"+symb, m), token("JUMPDEST", m), elsed.code, - token("~endif"+symb, m) + token("~endif"+symb, m), token("JUMPDEST", m) }; - return pd(aux, multiToken(nodelist, 10, m), outs); + return pd(aux, multiToken(nodelist, 12, m), outs); } // While (rewritten to this in rewrites) else if (node.val == "until") { @@ -207,13 +210,14 @@ programData opcodeify(Node node, err("Condition of while/until loop has arity 0", m); if (action.outs) action.code = popwrap(action.code); Node nodelist[] = { - token("~beg"+symb, m), + token("~beg"+symb, m), token("JUMPDEST", m), cond.code, token("$end"+symb, m), token("JUMPI", m), action.code, - token("$beg"+symb, m), token("JUMP", m), token("~end"+symb, m) + token("$beg"+symb, m), token("JUMP", m), + token("~end"+symb, m), token("JUMPDEST", m) }; - return pd(aux, multiToken(nodelist, 8, m)); + return pd(aux, multiToken(nodelist, 10, m)); } // Memory allocations else if (node.val == "alloc") { diff --git a/libserpent/opcodes.h b/libserpent/opcodes.h index f55834efa..552364731 100644 --- a/libserpent/opcodes.h +++ b/libserpent/opcodes.h @@ -72,11 +72,11 @@ Mapping mapping[] = { Mapping("PC", 0x5a, 0, 1), Mapping("MSIZE", 0x5b, 0, 1), Mapping("GAS", 0x5c, 0, 1), + Mapping("JUMPDEST", 0x5d, 0, 0), Mapping("CREATE", 0xf0, 3, 1), Mapping("CALL", 0xf1, 7, 1), Mapping("RETURN", 0xf2, 2, 0), - Mapping("POST", 0xf3, 5, 0), - Mapping("CALL_STATELESS", 0xf4, 7, 1), + Mapping("CALL_CODE", 0xf3, 7, 1), Mapping("SUICIDE", 0xff, 1, 0), Mapping("---END---", 0x00, 0, 0), }; diff --git a/libserpent/parser.cpp b/libserpent/parser.cpp index 09fcdfc47..0460c974c 100644 --- a/libserpent/parser.cpp +++ b/libserpent/parser.cpp @@ -155,10 +155,10 @@ Node treefy(std::vector stream) { else if (typ == RPAREN) { std::vector args; while (1) { - if (!oq.size()) err("Bracket without matching", tok.metadata); if (toktype(oq.back()) == LPAREN) break; args.push_back(oq.back()); oq.pop_back(); + if (!oq.size()) err("Bracket without matching", tok.metadata); } oq.pop_back(); args.push_back(oq.back()); diff --git a/libserpent/rewriter.cpp b/libserpent/rewriter.cpp index eeefd2d09..bf6a73828 100644 --- a/libserpent/rewriter.cpp +++ b/libserpent/rewriter.cpp @@ -17,9 +17,7 @@ std::string valid[][3] = { { "alloc", "1", "1" }, { "array", "1", "1" }, { "call", "2", "4" }, - { "call_stateless", "2", "4" }, - { "post", "4", "5" }, - { "postcall", "3", "4" }, + { "call_code", "2", "4" }, { "create", "1", "4" }, { "msg", "4", "6" }, { "msg_stateless", "4", "6" }, @@ -144,22 +142,6 @@ std::string macros[][2] = { "(send $to $value)", "(call (sub (gas) 25) $to $value 0 0 0 0)" }, - { - "(post $gas $to $value $datain $datainsz)", - "(~post $gas $to $value $datain (mul $datainsz 32))" - }, - { - "(post $gas $to $value $datain)", - "(seq (set $1 $datain) (~post $gas $to $value (ref $1) 32))" - }, - { - "(postcall $gas $to $datain)", - "(post $gas $to 0 $datain)", - }, - { - "(postcall $gas $to $datain $datainsz)", - "(post $gas $to 0 $datain $datainsz)", - }, { "(send $gas $to $value)", "(call $gas $to $value 0 0 0 0)" @@ -243,28 +225,28 @@ std::string macros[][2] = { }, // Call stateless and msg stateless { - "(call_stateless $f $dataval)", - "(msg_stateless (sub (gas) 45) $f 0 $dataval)" + "(call_code $f $dataval)", + "(msg_code (sub (gas) 45) $f 0 $dataval)" }, { - "(call_stateless $f $inp $inpsz)", - "(msg_stateless (sub (gas) 25) $f 0 $inp $inpsz)" + "(call_code $f $inp $inpsz)", + "(msg_code (sub (gas) 25) $f 0 $inp $inpsz)" }, { - "(call_stateless $f $inp $inpsz $outsz)", - "(with $1 $outsz (with $2 (alloc (mul 32 (get $1))) (seq (call_stateless (sub (gas) (add 25 (get $1))) $f 0 $inp (mul 32 $inpsz) (get $2) (mul 32 (get $1))) (get $2))))" + "(call_code $f $inp $inpsz $outsz)", + "(with $1 $outsz (with $2 (alloc (mul 32 (get $1))) (seq (call_code (sub (gas) (add 25 (get $1))) $f 0 $inp (mul 32 $inpsz) (get $2) (mul 32 (get $1))) (get $2))))" }, { - "(msg_stateless $gas $to $val $inp $inpsz)", - "(seq (call_stateless $gas $to $val $inp (mul 32 $inpsz) (ref $1) 32) (get $1))" + "(msg_code $gas $to $val $inp $inpsz)", + "(seq (call_code $gas $to $val $inp (mul 32 $inpsz) (ref $1) 32) (get $1))" }, { - "(msg_stateless $gas $to $val $dataval)", - "(seq (set $1 $dataval) (call_stateless $gas $to $val (ref $1) 32 (ref $2) 32) (get $2))" + "(msg_code $gas $to $val $dataval)", + "(seq (set $1 $dataval) (call_code $gas $to $val (ref $1) 32 (ref $2) 32) (get $2))" }, { - "(msg_stateless $gas $to $val $inp $inpsz $outsz)", - "(with $1 (mul 32 $outsz) (with $2 (alloc (get $1)) (call_stateless $gas $to $val $inp (mul 32 $inpsz) (get $2) (get $1)) (get $2)))" + "(msg_code $gas $to $val $inp $inpsz $outsz)", + "(with $1 (mul 32 $outsz) (with $2 (alloc (get $1)) (call_code $gas $to $val $inp (mul 32 $inpsz) (get $2) (get $1)) (get $2)))" }, // Wrappers { diff --git a/libwhisper/Interface.h b/libwhisper/Interface.h index 8bc37ff5e..56b3be599 100644 --- a/libwhisper/Interface.h +++ b/libwhisper/Interface.h @@ -75,6 +75,7 @@ public: virtual void uninstallWatch(unsigned _watchId) = 0; virtual h256s peekWatch(unsigned _watchId) const = 0; virtual h256s checkWatch(unsigned _watchId) = 0; + virtual h256s watchMessages(unsigned _watchId) = 0; virtual Envelope envelope(h256 _m) const = 0; diff --git a/libwhisper/WhisperHost.cpp b/libwhisper/WhisperHost.cpp index b11b4af3a..25c1a06bf 100644 --- a/libwhisper/WhisperHost.cpp +++ b/libwhisper/WhisperHost.cpp @@ -107,6 +107,27 @@ unsigned WhisperHost::installWatch(shh::TopicFilter const& _f) return installWatchOnId(h); } +h256s WhisperHost::watchMessages(unsigned _watchId) +{ + h256s ret; + auto wit = m_watches.find(_watchId); + if (wit == m_watches.end()) + return ret; + TopicFilter f; + { + Guard l(m_filterLock); + auto fit = m_filters.find(wit->second.id); + if (fit == m_filters.end()) + return ret; + f = fit->second.filter; + } + ReadGuard l(x_messages); + for (auto const& m: m_messages) + if (f.matches(m.second)) + ret.push_back(m.first); + return ret; +} + void WhisperHost::uninstallWatch(unsigned _i) { cwatshh << "XXX" << _i; diff --git a/libwhisper/WhisperHost.h b/libwhisper/WhisperHost.h index 2a8789956..9ad859967 100644 --- a/libwhisper/WhisperHost.h +++ b/libwhisper/WhisperHost.h @@ -48,16 +48,17 @@ public: unsigned protocolVersion() const { return 0; } - virtual void inject(Envelope const& _e, WhisperPeer* _from = nullptr); + virtual void inject(Envelope const& _e, WhisperPeer* _from = nullptr) override; using Interface::installWatch; - virtual unsigned installWatch(TopicFilter const& _filter); - virtual unsigned installWatchOnId(h256 _filterId); - virtual void uninstallWatch(unsigned _watchId); - virtual h256s peekWatch(unsigned _watchId) const { dev::Guard l(m_filterLock); try { return m_watches.at(_watchId).changes; } catch (...) { return h256s(); } } - virtual h256s checkWatch(unsigned _watchId) { dev::Guard l(m_filterLock); h256s ret; try { ret = m_watches.at(_watchId).changes; m_watches.at(_watchId).changes.clear(); } catch (...) {} return ret; } - - virtual Envelope envelope(h256 _m) const { try { dev::ReadGuard l(x_messages); return m_messages.at(_m); } catch (...) { return Envelope(); } } + virtual unsigned installWatch(TopicFilter const& _filter) override; + virtual unsigned installWatchOnId(h256 _filterId) override; + virtual void uninstallWatch(unsigned _watchId) override; + virtual h256s peekWatch(unsigned _watchId) const override { dev::Guard l(m_filterLock); try { return m_watches.at(_watchId).changes; } catch (...) { return h256s(); } } + virtual h256s checkWatch(unsigned _watchId) override { dev::Guard l(m_filterLock); h256s ret; try { ret = m_watches.at(_watchId).changes; m_watches.at(_watchId).changes.clear(); } catch (...) {} return ret; } + virtual h256s watchMessages(unsigned _watchId) override; + + virtual Envelope envelope(h256 _m) const override { try { dev::ReadGuard l(x_messages); return m_messages.at(_m); } catch (...) { return Envelope(); } } private: void streamMessage(h256 _m, RLPStream& _s) const;