Browse Source

Latest PoC-7 serpent.

cl-refactor
Gav Wood 10 years ago
parent
commit
b9ba1943c4
  1. 26
      libserpent/compiler.cpp
  2. 4
      libserpent/opcodes.h
  3. 2
      libserpent/parser.cpp
  4. 44
      libserpent/rewriter.cpp
  5. 1
      libwhisper/Interface.h
  6. 21
      libwhisper/WhisperHost.cpp
  7. 17
      libwhisper/WhisperHost.h

26
libserpent/compiler.cpp

@ -123,9 +123,10 @@ programData opcodeify(Node node,
token("$begincode"+symb+".endcode"+symb, m), token("DUP1", m), token("$begincode"+symb+".endcode"+symb, m), token("DUP1", m),
token("$begincode"+symb, m), sub.code, token("CODECOPY", m), token("$begincode"+symb, m), sub.code, token("CODECOPY", m),
token("$endcode"+symb, m), token("JUMP", 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 // Stack variables
if (node.val == "with") { if (node.val == "with") {
@ -171,9 +172,9 @@ programData opcodeify(Node node,
cond.code, cond.code,
token("$endif"+symb, m), token("JUMPI", m), token("$endif"+symb, m), token("JUMPI", m),
action.code, 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 // 3-part conditional
else if (node.val == "if" && node.args.size() == 3) { 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); if (elsed.outs > outs) elsed.code = popwrap(elsed.code);
Node nodelist[] = { Node nodelist[] = {
ifd.code, ifd.code,
token("NOT", m), token("$else"+symb, m), token("JUMPI", m), token("NOT", m),
token("$else"+symb, m), token("JUMPI", m),
thend.code, 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, 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) // While (rewritten to this in rewrites)
else if (node.val == "until") { else if (node.val == "until") {
@ -207,13 +210,14 @@ programData opcodeify(Node node,
err("Condition of while/until loop has arity 0", m); err("Condition of while/until loop has arity 0", m);
if (action.outs) action.code = popwrap(action.code); if (action.outs) action.code = popwrap(action.code);
Node nodelist[] = { Node nodelist[] = {
token("~beg"+symb, m), token("~beg"+symb, m), token("JUMPDEST", m),
cond.code, cond.code,
token("$end"+symb, m), token("JUMPI", m), token("$end"+symb, m), token("JUMPI", m),
action.code, 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 // Memory allocations
else if (node.val == "alloc") { else if (node.val == "alloc") {

4
libserpent/opcodes.h

@ -72,11 +72,11 @@ Mapping mapping[] = {
Mapping("PC", 0x5a, 0, 1), Mapping("PC", 0x5a, 0, 1),
Mapping("MSIZE", 0x5b, 0, 1), Mapping("MSIZE", 0x5b, 0, 1),
Mapping("GAS", 0x5c, 0, 1), Mapping("GAS", 0x5c, 0, 1),
Mapping("JUMPDEST", 0x5d, 0, 0),
Mapping("CREATE", 0xf0, 3, 1), Mapping("CREATE", 0xf0, 3, 1),
Mapping("CALL", 0xf1, 7, 1), Mapping("CALL", 0xf1, 7, 1),
Mapping("RETURN", 0xf2, 2, 0), Mapping("RETURN", 0xf2, 2, 0),
Mapping("POST", 0xf3, 5, 0), Mapping("CALL_CODE", 0xf3, 7, 1),
Mapping("CALL_STATELESS", 0xf4, 7, 1),
Mapping("SUICIDE", 0xff, 1, 0), Mapping("SUICIDE", 0xff, 1, 0),
Mapping("---END---", 0x00, 0, 0), Mapping("---END---", 0x00, 0, 0),
}; };

2
libserpent/parser.cpp

@ -155,10 +155,10 @@ Node treefy(std::vector<Node> stream) {
else if (typ == RPAREN) { else if (typ == RPAREN) {
std::vector<Node> args; std::vector<Node> args;
while (1) { while (1) {
if (!oq.size()) err("Bracket without matching", tok.metadata);
if (toktype(oq.back()) == LPAREN) break; if (toktype(oq.back()) == LPAREN) break;
args.push_back(oq.back()); args.push_back(oq.back());
oq.pop_back(); oq.pop_back();
if (!oq.size()) err("Bracket without matching", tok.metadata);
} }
oq.pop_back(); oq.pop_back();
args.push_back(oq.back()); args.push_back(oq.back());

44
libserpent/rewriter.cpp

@ -17,9 +17,7 @@ std::string valid[][3] = {
{ "alloc", "1", "1" }, { "alloc", "1", "1" },
{ "array", "1", "1" }, { "array", "1", "1" },
{ "call", "2", "4" }, { "call", "2", "4" },
{ "call_stateless", "2", "4" }, { "call_code", "2", "4" },
{ "post", "4", "5" },
{ "postcall", "3", "4" },
{ "create", "1", "4" }, { "create", "1", "4" },
{ "msg", "4", "6" }, { "msg", "4", "6" },
{ "msg_stateless", "4", "6" }, { "msg_stateless", "4", "6" },
@ -144,22 +142,6 @@ std::string macros[][2] = {
"(send $to $value)", "(send $to $value)",
"(call (sub (gas) 25) $to $value 0 0 0 0)" "(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)", "(send $gas $to $value)",
"(call $gas $to $value 0 0 0 0)" "(call $gas $to $value 0 0 0 0)"
@ -243,28 +225,28 @@ std::string macros[][2] = {
}, },
// Call stateless and msg stateless // Call stateless and msg stateless
{ {
"(call_stateless $f $dataval)", "(call_code $f $dataval)",
"(msg_stateless (sub (gas) 45) $f 0 $dataval)" "(msg_code (sub (gas) 45) $f 0 $dataval)"
}, },
{ {
"(call_stateless $f $inp $inpsz)", "(call_code $f $inp $inpsz)",
"(msg_stateless (sub (gas) 25) $f 0 $inp $inpsz)" "(msg_code (sub (gas) 25) $f 0 $inp $inpsz)"
}, },
{ {
"(call_stateless $f $inp $inpsz $outsz)", "(call_code $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))))" "(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)", "(msg_code $gas $to $val $inp $inpsz)",
"(seq (call_stateless $gas $to $val $inp (mul 32 $inpsz) (ref $1) 32) (get $1))" "(seq (call_code $gas $to $val $inp (mul 32 $inpsz) (ref $1) 32) (get $1))"
}, },
{ {
"(msg_stateless $gas $to $val $dataval)", "(msg_code $gas $to $val $dataval)",
"(seq (set $1 $dataval) (call_stateless $gas $to $val (ref $1) 32 (ref $2) 32) (get $2))" "(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)", "(msg_code $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)))" "(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 // Wrappers
{ {

1
libwhisper/Interface.h

@ -75,6 +75,7 @@ public:
virtual void uninstallWatch(unsigned _watchId) = 0; virtual void uninstallWatch(unsigned _watchId) = 0;
virtual h256s peekWatch(unsigned _watchId) const = 0; virtual h256s peekWatch(unsigned _watchId) const = 0;
virtual h256s checkWatch(unsigned _watchId) = 0; virtual h256s checkWatch(unsigned _watchId) = 0;
virtual h256s watchMessages(unsigned _watchId) = 0;
virtual Envelope envelope(h256 _m) const = 0; virtual Envelope envelope(h256 _m) const = 0;

21
libwhisper/WhisperHost.cpp

@ -107,6 +107,27 @@ unsigned WhisperHost::installWatch(shh::TopicFilter const& _f)
return installWatchOnId(h); 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) void WhisperHost::uninstallWatch(unsigned _i)
{ {
cwatshh << "XXX" << _i; cwatshh << "XXX" << _i;

17
libwhisper/WhisperHost.h

@ -48,16 +48,17 @@ public:
unsigned protocolVersion() const { return 0; } 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; using Interface::installWatch;
virtual unsigned installWatch(TopicFilter const& _filter); virtual unsigned installWatch(TopicFilter const& _filter) override;
virtual unsigned installWatchOnId(h256 _filterId); virtual unsigned installWatchOnId(h256 _filterId) override;
virtual void uninstallWatch(unsigned _watchId); virtual void uninstallWatch(unsigned _watchId) override;
virtual h256s peekWatch(unsigned _watchId) const { dev::Guard l(m_filterLock); try { return m_watches.at(_watchId).changes; } catch (...) { return h256s(); } } 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) { 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 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 { try { dev::ReadGuard l(x_messages); return m_messages.at(_m); } catch (...) { return Envelope(); } }
virtual Envelope envelope(h256 _m) const override { try { dev::ReadGuard l(x_messages); return m_messages.at(_m); } catch (...) { return Envelope(); } }
private: private:
void streamMessage(h256 _m, RLPStream& _s) const; void streamMessage(h256 _m, RLPStream& _s) const;

Loading…
Cancel
Save