diff --git a/alethzero/Main.ui b/alethzero/Main.ui
index a9782f8a2..3712ca489 100644
--- a/alethzero/Main.ui
+++ b/alethzero/Main.ui
@@ -1288,7 +1288,8 @@ font-size: 14pt
background: white;
border: 0;
-font-family: Monospace, Ubuntu Mono, Lucida Console, Courier New
+font-family: Monospace, Ubuntu Mono, Lucida Console, Courier New;
+font-size: 12pt
diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp
index a8c024454..d06d0948e 100644
--- a/alethzero/MainWin.cpp
+++ b/alethzero/MainWin.cpp
@@ -118,7 +118,7 @@ Main::Main(QWidget *parent) :
connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved()));
-#if ETH_DEBUG
+#if 0&Ð_DEBUG
m_servers.append("192.168.0.10:30301");
#else
int pocnumber = QString(eth::EthVersion).section('.', 1, 1).toInt();
@@ -985,7 +985,7 @@ void Main::on_data_textChanged()
{
try
{
- m_data = eth::asBytes(compile(src));
+ m_data = compile(src);
for (auto& i: errors)
i = "(LLL " + i + ")";
}
diff --git a/libethcore/TrieDB.h b/libethcore/TrieDB.h
index 023a0dc1d..c6114b95d 100644
--- a/libethcore/TrieDB.h
+++ b/libethcore/TrieDB.h
@@ -42,7 +42,7 @@ extern const h256 c_shaNull;
/**
* @brief Merkle Patricia Tree "Trie": a modifed base-16 Radix tree.
- * This version uses an LDB backend
+ * This version uses an database backend.
* Usage:
* @code
* GenericTrieDB t(&myDB);
@@ -153,6 +153,7 @@ public:
std::string at(bytesConstRef _key) const;
void insert(bytesConstRef _key, bytesConstRef _value);
void remove(bytesConstRef _key);
+ void contains(bytesConstRef _key) { return !at(_key).empty(); }
class iterator
{
@@ -274,6 +275,7 @@ public:
std::string operator[](KeyType _k) const { return at(_k); }
+ bool contains(KeyType _k) const { return GenericTrieDB::contains(bytesConstRef((byte const*)&_k, sizeof(KeyType))); }
std::string at(KeyType _k) const { return GenericTrieDB::at(bytesConstRef((byte const*)&_k, sizeof(KeyType))); }
void insert(KeyType _k, bytesConstRef _value) { GenericTrieDB::insert(bytesConstRef((byte const*)&_k, sizeof(KeyType)), _value); }
void insert(KeyType _k, bytes const& _value) { insert(_k, bytesConstRef(&_value)); }
diff --git a/libethential/CMakeLists.txt b/libethential/CMakeLists.txt
index c81c2c8f1..e247abcd0 100644
--- a/libethential/CMakeLists.txt
+++ b/libethential/CMakeLists.txt
@@ -1,4 +1,5 @@
cmake_policy(SET CMP0015 NEW)
+cmake_policy(SET CMP0022 NEW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
@@ -16,7 +17,6 @@ include_directories(..)
target_link_libraries(${EXECUTABLE} ethential)
target_link_libraries(${EXECUTABLE} gmp)
-
if(${TARGET_PLATFORM} STREQUAL "w64")
include_directories(/usr/x86_64-w64-mingw32/include/cryptopp)
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s)
diff --git a/libethereum/Client.h b/libethereum/Client.h
index cf5235c8c..8683b90f8 100644
--- a/libethereum/Client.h
+++ b/libethereum/Client.h
@@ -140,14 +140,13 @@ public:
BlockChain const& blockChain() const { return m_bc; }
// [NEW API]
-/*
- u256 balanceAt(Address _a, unsigned _age = 1) const;
- u256 countAt(Address _a, unsigned _age = 1) const;
- u256 stateAt(Address _a, u256 _l, unsigned _age = 1) const;
- bytes codeAt(Address _a, unsigned _age = 1) const;
- Transactions transactions(Addresses const& _from, Addresses const& _to, std::vector> const& _stateAlterations, Addresses const& _altered, unsigned _ageFrom = 0, unsigned _ageTo, unsigned _max) const;
-*/
+ u256 balanceAt(Address _a, int _block = -1) const;
+ u256 countAt(Address _a, int _block = -1) const;
+ u256 stateAt(Address _a, u256 _l, int _block = -1) const;
+ bytes codeAt(Address _a, int _block = -1) const;
+ Transactions transactions(Addresses const& _from, Addresses const& _to, std::vector> const& _stateAlterations, Addresses const& _altered, int _blockFrom = 0, int _blockTo = -1, unsigned _max = 10) const;
+
// Misc stuff:
void setClientVersion(std::string const& _name) { m_clientVersion = _name; }
diff --git a/libevm/All.h b/libevm/All.h
new file mode 100644
index 000000000..89c451ef4
--- /dev/null
+++ b/libevm/All.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "ExtVMFace.h"
+#include "FeeStructure.h"
+#include "VM.h"
diff --git a/liblll/Assembly.cpp b/liblll/Assembly.cpp
index 0fa125378..7016b2863 100644
--- a/liblll/Assembly.cpp
+++ b/liblll/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/liblll/Assembly.h b/liblll/Assembly.h
index 3e8a83260..9cd10a820 100644
--- a/liblll/Assembly.h
+++ b/liblll/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/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp
index f0aeb860c..70973aab4 100644
--- a/liblll/CodeFragment.cpp
+++ b/liblll/CodeFragment.cpp
@@ -19,7 +19,6 @@
* @date 2014
*/
-#include "Parser.h"
#include "CodeFragment.h"
#include
@@ -27,12 +26,30 @@
#include
#include
#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 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/liblll/CodeFragment.h b/liblll/CodeFragment.h
index b9d44c030..58e409125 100644
--- a/liblll/CodeFragment.h
+++ b/liblll/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 void error() const { throw T(); }
void constructOperation(sp::utree const& _t, CompilerState& _s);
+ bool m_finalised = false;
Assembly m_asm;
};
diff --git a/liblll/Compiler.cpp b/liblll/Compiler.cpp
index 8400ad955..0faf478d6 100644
--- a/liblll/Compiler.cpp
+++ b/liblll/Compiler.cpp
@@ -36,7 +36,7 @@ bytes eth::compileLLL(string const& _src, bool _opt, vector* _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/liblll/CompilerState.cpp b/liblll/CompilerState.cpp
index 7e990413f..7a6681909 100644
--- a/liblll/CompilerState.cpp
+++ b/liblll/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/liblll/CompilerState.h b/liblll/CompilerState.h
index f8f7ce815..5dcde6147 100644
--- a/liblll/CompilerState.h
+++ b/liblll/CompilerState.h
@@ -48,6 +48,7 @@ struct CompilerState
std::map outers;
std::map, Macro> macros;
std::vector treesToKill;
+ bool usedAlloc = false;
};
}
diff --git a/sc/cmdline.cpp b/sc/cmdline.cpp
index 03e501ea1..e8a0a130c 100644
--- a/sc/cmdline.cpp
+++ b/sc/cmdline.cpp
@@ -10,7 +10,7 @@ int main(int argv, char** argc) {
if (argv == 1) {
std::cerr << "Must provide a command and arguments! Try parse, rewrite, compile, assemble\n";
return 0;
- }
+ }
std::string flag = "";
std::string command = argc[1];
std::string input;