aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGav Wood <i@gavwood.com>2014-07-01 06:16:01 +0800
committerGav Wood <i@gavwood.com>2014-07-01 06:16:01 +0800
commit3174a5e0c6072004159326f000c0e1dfe6703b00 (patch)
tree34d20ebc891413a5b16d92ddfa2c7e2e19c99f39
parente65c3ff17de66cfd7d80ef78abba09c6ecf35ded (diff)
downloaddexon-solidity-3174a5e0c6072004159326f000c0e1dfe6703b00.tar.gz
dexon-solidity-3174a5e0c6072004159326f000c0e1dfe6703b00.tar.zst
dexon-solidity-3174a5e0c6072004159326f000c0e1dfe6703b00.zip
Fixed problem with alloc.
-rw-r--r--Assembly.cpp5
-rw-r--r--Assembly.h2
-rw-r--r--CodeFragment.cpp39
-rw-r--r--CodeFragment.h7
-rw-r--r--Compiler.cpp4
-rw-r--r--CompilerState.cpp3
-rw-r--r--CompilerState.h1
7 files changed, 53 insertions, 8 deletions
diff --git a/Assembly.cpp b/Assembly.cpp
index 0fa12537..7016b286 100644
--- a/Assembly.cpp
+++ b/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/Assembly.h b/Assembly.h
index 3e8a8326..9cd10a82 100644
--- a/Assembly.h
+++ b/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/CodeFragment.cpp b/CodeFragment.cpp
index f0aeb860..70973aab 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -19,7 +19,6 @@
* @date 2014
*/
-#include "Parser.h"
#include "CodeFragment.h"
#include <boost/algorithm/string.hpp>
@@ -27,12 +26,30 @@
#include <libethential/Log.h>
#include <libevmface/Instruction.h>
#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<CodeFragment> 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/CodeFragment.h b/CodeFragment.h
index b9d44c03..58e40912 100644
--- a/CodeFragment.h
+++ b/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 <class T> void error() const { throw T(); }
void constructOperation(sp::utree const& _t, CompilerState& _s);
+ bool m_finalised = false;
Assembly m_asm;
};
diff --git a/Compiler.cpp b/Compiler.cpp
index 8400ad95..0faf478d 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -36,7 +36,7 @@ bytes eth::compileLLL(string const& _src, bool _opt, vector<string>* _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/CompilerState.cpp b/CompilerState.cpp
index 7e990413..7a668190 100644
--- a/CompilerState.cpp
+++ b/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/CompilerState.h b/CompilerState.h
index f8f7ce81..5dcde614 100644
--- a/CompilerState.h
+++ b/CompilerState.h
@@ -48,6 +48,7 @@ struct CompilerState
std::map<std::string, CodeFragment> outers;
std::map<std::pair<std::string, unsigned>, Macro> macros;
std::vector<boost::spirit::utree> treesToKill;
+ bool usedAlloc = false;
};
}