aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/grammar.txt5
-rw-r--r--docs/solidity-by-example.rst8
-rw-r--r--libdevcore/Assertions.h34
-rw-r--r--libdevcore/Common.h2
-rw-r--r--libdevcore/CommonIO.cpp23
-rw-r--r--libdevcore/Exceptions.h4
-rw-r--r--libdevcore/debugbreak.h128
-rw-r--r--libevmasm/Assembly.cpp16
-rw-r--r--libevmasm/Assembly.h13
-rw-r--r--libjulia/backends/evm/EVMAssembly.cpp2
-rw-r--r--libjulia/backends/evm/EVMCodeTransform.cpp2
-rw-r--r--liblll/CodeFragment.cpp27
-rw-r--r--liblll/CompilerState.cpp10
-rw-r--r--libsolidity/ast/AST.cpp2
-rw-r--r--libsolidity/ast/AST.h1
-rw-r--r--libsolidity/ast/ASTJsonConverter.cpp1
-rw-r--r--libsolidity/ast/ASTJsonConverter.h1
-rw-r--r--libsolidity/ast/Types.cpp1
-rw-r--r--libsolidity/codegen/ArrayUtils.cpp2
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp1
-rw-r--r--libsolidity/codegen/ExpressionCompiler.h2
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.cpp1
-rw-r--r--libsolidity/inlineasm/AsmPrinter.cpp2
-rw-r--r--libsolidity/inlineasm/AsmScopeFiller.cpp2
-rw-r--r--libsolidity/interface/CompilerStack.cpp10
-rw-r--r--libsolidity/interface/CompilerStack.h10
-rw-r--r--libsolidity/interface/Exceptions.cpp1
-rw-r--r--libsolidity/interface/Exceptions.h11
-rw-r--r--libsolidity/interface/StandardCompiler.cpp10
-rw-r--r--libsolidity/interface/Utils.h45
-rw-r--r--libsolidity/interface/Version.cpp2
-rw-r--r--libsolidity/parsing/DocStringParser.cpp2
-rw-r--r--libsolidity/parsing/Scanner.cpp2
-rw-r--r--libsolidity/parsing/Token.h1
-rwxr-xr-xscripts/bytecodecompare/prepare_report.py2
-rw-r--r--scripts/bytecodecompare/storebytecode.bat7
-rw-r--r--solc/CommandLineInterface.cpp7
-rw-r--r--solc/jsonCompiler.cpp2
-rw-r--r--test/liblll/EndToEndTest.cpp126
39 files changed, 225 insertions, 303 deletions
diff --git a/docs/grammar.txt b/docs/grammar.txt
index 09e492f3..b38b7ffa 100644
--- a/docs/grammar.txt
+++ b/docs/grammar.txt
@@ -88,7 +88,6 @@ Expression =
| Expression '||' Expression
| Expression '?' Expression ':' Expression
| Expression ('=' | '|=' | '^=' | '&=' | '<<=' | '>>=' | '+=' | '-=' | '*=' | '/=' | '%=') Expression
- | Expression? (',' Expression)
| PrimaryExpression
PrimaryExpression = Identifier
@@ -96,6 +95,7 @@ PrimaryExpression = Identifier
| NumberLiteral
| HexLiteral
| StringLiteral
+ | TupleExpression
| ElementaryTypeNameExpression
ExpressionList = Expression ( ',' Expression )*
@@ -120,6 +120,9 @@ Identifier = [a-zA-Z_$] [a-zA-Z_$0-9]*
HexNumber = '0x' [0-9a-fA-F]+
DecimalNumber = [0-9]+
+TupleExpression = '(' ( Expression ( ',' Expression )* )? ')'
+ | '[' ( Expression ( ',' Expression )* )? ']'
+
ElementaryTypeNameExpression = ElementaryTypeName
ElementaryTypeName = 'address' | 'bool' | 'string' | 'var'
diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst
index 993e2c18..450b0286 100644
--- a/docs/solidity-by-example.rst
+++ b/docs/solidity-by-example.rst
@@ -94,7 +94,7 @@ of votes.
// called incorrectly. But watch out, this
// will currently also consume all provided gas
// (this is planned to change in the future).
- require((msg.sender == chairperson) && !voters[voter].voted);
+ require((msg.sender == chairperson) && !voters[voter].voted && (voters[voter].weight == 0));
voters[voter].weight = 1;
}
@@ -165,7 +165,7 @@ of votes.
}
}
}
-
+
// Calls winningProposal() function to get the index
// of the winner contained in the proposals array and then
// returns the name of the winner
@@ -273,7 +273,7 @@ activate themselves.
// If the bid is not higher, send the
// money back.
require(msg.value > highestBid);
-
+
if (highestBidder != 0) {
// Sending back the money by simply using
// highestBidder.send(highestBid) is a security risk
@@ -296,7 +296,7 @@ activate themselves.
// before `send` returns.
pendingReturns[msg.sender] = 0;
- if (!msg.sender.send(amount)) {
+ if (!msg.sender.send(amount)) {
// No need to call throw here, just reset the amount owing
pendingReturns[msg.sender] = amount;
return false;
diff --git a/libdevcore/Assertions.h b/libdevcore/Assertions.h
index e54b9d55..729ffb05 100644
--- a/libdevcore/Assertions.h
+++ b/libdevcore/Assertions.h
@@ -25,7 +25,6 @@
#pragma once
#include "Exceptions.h"
-#include "debugbreak.h"
namespace dev
{
@@ -38,37 +37,6 @@ namespace dev
#define ETH_FUNC __func__
#endif
-#define asserts(A) ::dev::assertAux(A, #A, __LINE__, __FILE__, ETH_FUNC)
-#define assertsEqual(A, B) ::dev::assertEqualAux(A, B, #A, #B, __LINE__, __FILE__, ETH_FUNC)
-
-inline bool assertAux(bool _a, char const* _aStr, unsigned _line, char const* _file, char const* _func)
-{
- bool ret = _a;
- if (!ret)
- {
- std::cerr << "Assertion failed:" << _aStr << " [func=" << _func << ", line=" << _line << ", file=" << _file << "]" << std::endl;
-#if ETH_DEBUG
- debug_break();
-#endif
- }
- return !ret;
-}
-
-template<class A, class B>
-inline bool assertEqualAux(A const& _a, B const& _b, char const* _aStr, char const* _bStr, unsigned _line, char const* _file, char const* _func)
-{
- bool ret = _a == _b;
- if (!ret)
- {
- std::cerr << "Assertion failed: " << _aStr << " == " << _bStr << " [func=" << _func << ", line=" << _line << ", file=" << _file << "]" << std::endl;
- std::cerr << " Fail equality: " << _a << "==" << _b << std::endl;
-#if ETH_DEBUG
- debug_break();
-#endif
- }
- return !ret;
-}
-
/// Assertion that throws an exception containing the given description if it is not met.
/// Use it as assertThrow(1 == 1, ExceptionType, "Mathematics is wrong.");
/// Do NOT supply an exception object as the second parameter.
@@ -86,6 +54,4 @@ inline bool assertEqualAux(A const& _a, B const& _b, char const* _aStr, char con
} \
while (false)
-using errinfo_comment = boost::error_info<struct tag_comment, std::string>;
-
}
diff --git a/libdevcore/Common.h b/libdevcore/Common.h
index dc981ff6..c5b09a80 100644
--- a/libdevcore/Common.h
+++ b/libdevcore/Common.h
@@ -76,8 +76,6 @@ using byte = uint8_t;
#define DEV_QUOTED_HELPER(s) #s
#define DEV_QUOTED(s) DEV_QUOTED_HELPER(s)
-#define DEV_IGNORE_EXCEPTIONS(X) try { X; } catch (...) {}
-
namespace dev
{
diff --git a/libdevcore/CommonIO.cpp b/libdevcore/CommonIO.cpp
index 8dbcb00a..52829455 100644
--- a/libdevcore/CommonIO.cpp
+++ b/libdevcore/CommonIO.cpp
@@ -30,11 +30,11 @@
#include <termios.h>
#endif
#include <boost/filesystem.hpp>
-#include "Exceptions.h"
+#include "Assertions.h"
+
using namespace std;
using namespace dev;
-
template <typename _T>
inline _T contentsGeneric(std::string const& _file)
{
@@ -78,13 +78,24 @@ void dev::writeFile(std::string const& _file, bytesConstRef _data, bool _writeDe
if (!fs::exists(p.parent_path()))
{
fs::create_directories(p.parent_path());
- DEV_IGNORE_EXCEPTIONS(fs::permissions(p.parent_path(), fs::owner_all));
+ try
+ {
+ fs::permissions(p.parent_path(), fs::owner_all);
+ }
+ catch (...)
+ {
+ }
}
ofstream s(_file, ios::trunc | ios::binary);
s.write(reinterpret_cast<char const*>(_data.data()), _data.size());
- if (!s)
- BOOST_THROW_EXCEPTION(FileError() << errinfo_comment("Could not write to file: " + _file));
- DEV_IGNORE_EXCEPTIONS(fs::permissions(_file, fs::owner_read|fs::owner_write));
+ assertThrow(s, FileError, "Could not write to file: " + _file);
+ try
+ {
+ fs::permissions(_file, fs::owner_read|fs::owner_write);
+ }
+ catch (...)
+ {
+ }
}
}
diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h
index 37cdbed9..4817e9e3 100644
--- a/libdevcore/Exceptions.h
+++ b/libdevcore/Exceptions.h
@@ -56,9 +56,5 @@ DEV_SIMPLE_EXCEPTION(FileError);
// error information to be added to exceptions
using errinfo_invalidSymbol = boost::error_info<struct tag_invalidSymbol, char>;
using errinfo_comment = boost::error_info<struct tag_comment, std::string>;
-using errinfo_required = boost::error_info<struct tag_required, bigint>;
-using errinfo_got = boost::error_info<struct tag_got, bigint>;
-using errinfo_required_h256 = boost::error_info<struct tag_required_h256, h256>;
-using errinfo_got_h256 = boost::error_info<struct tag_get_h256, h256>;
}
diff --git a/libdevcore/debugbreak.h b/libdevcore/debugbreak.h
deleted file mode 100644
index f8838a5f..00000000
--- a/libdevcore/debugbreak.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Copyright (c) 2013, Scott Tsai
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DEBUG_BREAK_H
-#define DEBUG_BREAK_H
-
-#if defined(_MSC_VER) || defined(__MINGW32__)
-
-#define debug_break __debugbreak
-
-#else
-
-#include <signal.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
- /* gcc optimizers consider code after __builtin_trap() dead.
- * Making __builtin_trap() unsuitable for breaking into the debugger */
- DEBUG_BREAK_PREFER_BUILTIN_TRAP_TO_SIGTRAP = 0,
-};
-
-#if defined(__i386__) || defined(__x86_64__)
-enum { HAVE_TRAP_INSTRUCTION = 1, };
-__attribute__((gnu_inline, always_inline))
-static void __inline__ trap_instruction(void)
-{
- __asm__ volatile("int $0x03");
-}
-#elif defined(__thumb__)
-enum { HAVE_TRAP_INSTRUCTION = 1, };
-/* FIXME: handle __THUMB_INTERWORK__ */
-__attribute__((gnu_inline, always_inline))
-static void __inline__ trap_instruction(void)
-{
- /* See 'arm-linux-tdep.c' in GDB source.
- * Both instruction sequences below works. */
-#if 1
- /* 'eabi_linux_thumb_le_breakpoint' */
- __asm__ volatile(".inst 0xde01");
-#else
- /* 'eabi_linux_thumb2_le_breakpoint' */
- __asm__ volatile(".inst.w 0xf7f0a000");
-#endif
-
- /* Known problem:
- * After a breakpoint hit, can't stepi, step, or continue in GDB.
- * 'step' stuck on the same instruction.
- *
- * Workaround: a new GDB command,
- * 'debugbreak-step' is defined in debugbreak-gdb.py
- * that does:
- * (gdb) set $instruction_len = 2
- * (gdb) tbreak *($pc + $instruction_len)
- * (gdb) jump *($pc + $instruction_len)
- */
-}
-#elif defined(__arm__) && !defined(__thumb__)
-enum { HAVE_TRAP_INSTRUCTION = 1, };
-__attribute__((gnu_inline, always_inline))
-static void __inline__ trap_instruction(void)
-{
- /* See 'arm-linux-tdep.c' in GDB source,
- * 'eabi_linux_arm_le_breakpoint' */
- __asm__ volatile(".inst 0xe7f001f0");
- /* Has same known problem and workaround
- * as Thumb mode */
-}
-#elif defined(ETH_EMSCRIPTEN)
-enum { HAVE_TRAP_INSTRUCTION = 1, };
-__attribute__((gnu_inline, always_inline))
-static void __inline__ trap_instruction(void)
-{
- asm("debugger");
-}
-#else
-enum { HAVE_TRAP_INSTRUCTION = 0, };
-#endif
-
-__attribute__((gnu_inline, always_inline))
-static void __inline__ debug_break(void)
-{
- if (HAVE_TRAP_INSTRUCTION) {
- trap_instruction();
- } else if (DEBUG_BREAK_PREFER_BUILTIN_TRAP_TO_SIGTRAP) {
- /* raises SIGILL on Linux x86{,-64}, to continue in gdb:
- * (gdb) handle SIGILL stop nopass
- * */
- __builtin_trap();
- } else {
- raise(SIGTRAP);
- }
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-#endif
diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp
index 92a4c2a4..27199b7b 100644
--- a/libevmasm/Assembly.cpp
+++ b/libevmasm/Assembly.cpp
@@ -55,21 +55,15 @@ void Assembly::append(Assembly const& _a)
m_subs += _a.m_subs;
for (auto const& lib: _a.m_libraries)
m_libraries.insert(lib);
-
- assert(!_a.m_baseDeposit);
- assert(!_a.m_totalDeposit);
}
void Assembly::append(Assembly const& _a, int _deposit)
{
- if (_deposit > _a.m_deposit)
- BOOST_THROW_EXCEPTION(InvalidDeposit());
- else
- {
- append(_a);
- while (_deposit++ < _a.m_deposit)
- append(Instruction::POP);
- }
+ assertThrow(_deposit <= _a.m_deposit, InvalidDeposit, "");
+
+ append(_a);
+ while (_deposit++ < _a.m_deposit)
+ append(Instruction::POP);
}
unsigned Assembly::bytesRequired(unsigned subTagSize) const
diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h
index 13d82e1a..0d40abcf 100644
--- a/libevmasm/Assembly.h
+++ b/libevmasm/Assembly.h
@@ -85,16 +85,10 @@ public:
AssemblyItem const& back() const { return m_items.back(); }
std::string backString() const { return m_items.size() && m_items.back().type() == PushString ? m_strings.at((h256)m_items.back().data()) : std::string(); }
- void onePath() { if (asserts(!m_totalDeposit && !m_baseDeposit)) BOOST_THROW_EXCEPTION(InvalidDeposit()); m_baseDeposit = m_deposit; m_totalDeposit = INT_MAX; }
- void otherPath() { donePath(); m_totalDeposit = m_deposit; m_deposit = m_baseDeposit; }
- void donePaths() { donePath(); m_totalDeposit = m_baseDeposit = 0; }
- void ignored() { m_baseDeposit = m_deposit; }
- void endIgnored() { m_deposit = m_baseDeposit; m_baseDeposit = 0; }
-
void injectStart(AssemblyItem const& _i);
int deposit() const { return m_deposit; }
- void adjustDeposit(int _adjustment) { m_deposit += _adjustment; if (asserts(m_deposit >= 0)) BOOST_THROW_EXCEPTION(InvalidDeposit()); }
- void setDeposit(int _deposit) { m_deposit = _deposit; if (asserts(m_deposit >= 0)) BOOST_THROW_EXCEPTION(InvalidDeposit()); }
+ void adjustDeposit(int _adjustment) { m_deposit += _adjustment; assertThrow(m_deposit >= 0, InvalidDeposit, ""); }
+ void setDeposit(int _deposit) { m_deposit = _deposit; assertThrow(m_deposit >= 0, InvalidDeposit, ""); }
/// Changes the source location used for each appended item.
void setSourceLocation(SourceLocation const& _location) { m_currentSourceLocation = _location; }
@@ -121,7 +115,6 @@ protected:
/// returns the replaced tags.
std::map<u256, u256> optimiseInternal(bool _enable, bool _isCreation, size_t _runs);
- void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) BOOST_THROW_EXCEPTION(InvalidDeposit()); }
unsigned bytesRequired(unsigned subTagSize) const;
private:
@@ -144,8 +137,6 @@ protected:
mutable std::vector<size_t> m_tagPositionsInBytecode;
int m_deposit = 0;
- int m_baseDeposit = 0;
- int m_totalDeposit = 0;
SourceLocation m_currentSourceLocation;
};
diff --git a/libjulia/backends/evm/EVMAssembly.cpp b/libjulia/backends/evm/EVMAssembly.cpp
index daca2393..7ec26957 100644
--- a/libjulia/backends/evm/EVMAssembly.cpp
+++ b/libjulia/backends/evm/EVMAssembly.cpp
@@ -22,7 +22,7 @@
#include <libevmasm/Instruction.h>
-#include <libsolidity/interface/Utils.h>
+#include <libsolidity/interface/Exceptions.h>
using namespace std;
using namespace dev;
diff --git a/libjulia/backends/evm/EVMCodeTransform.cpp b/libjulia/backends/evm/EVMCodeTransform.cpp
index b231ecec..8f12bc25 100644
--- a/libjulia/backends/evm/EVMCodeTransform.cpp
+++ b/libjulia/backends/evm/EVMCodeTransform.cpp
@@ -23,7 +23,7 @@
#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/interface/Utils.h>
+#include <libsolidity/interface/Exceptions.h>
#include <boost/range/adaptor/reversed.hpp>
diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp
index 9f37bc65..1329ec9b 100644
--- a/liblll/CodeFragment.cpp
+++ b/liblll/CodeFragment.cpp
@@ -192,7 +192,13 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
{
if (_t.size() != 2)
error<IncorrectParameterCount>();
- m_asm.append(CodeFragment::compile(contentsString(firstAsString()), _s).m_asm);
+ string fileName = firstAsString();
+ if (fileName.empty())
+ error<InvalidName>("Empty file name provided");
+ string contents = contentsString(fileName);
+ if (contents.empty())
+ error<InvalidName>(std::string("File not found (or empty): ") + fileName);
+ m_asm.append(CodeFragment::compile(contents, _s).m_asm);
}
else if (us == "SET")
{
@@ -439,15 +445,21 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
int minDep = min(code[1].m_asm.deposit(), code[2].m_asm.deposit());
m_asm.append(code[0].m_asm);
- auto pos = m_asm.appendJumpI();
- m_asm.onePath();
+ auto mainBranch = m_asm.appendJumpI();
+
+ /// The else branch.
+ int startDeposit = m_asm.deposit();
m_asm.append(code[2].m_asm, minDep);
auto end = m_asm.appendJump();
- m_asm.otherPath();
- m_asm << pos.tag();
+ int deposit = m_asm.deposit();
+ m_asm.setDeposit(startDeposit);
+
+ /// The main branch.
+ m_asm << mainBranch.tag();
m_asm.append(code[1].m_asm, minDep);
m_asm << end.tag();
- m_asm.donePaths();
+ if (m_asm.deposit() != deposit)
+ error<InvalidDeposit>();
}
else if (us == "WHEN" || us == "UNLESS")
{
@@ -458,11 +470,8 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
if (us == "WHEN")
m_asm.append(Instruction::ISZERO);
auto end = m_asm.appendJumpI();
- m_asm.onePath();
- m_asm.otherPath();
m_asm.append(code[1].m_asm, 0);
m_asm << end.tag();
- m_asm.donePaths();
}
else if (us == "WHILE" || us == "UNTIL")
{
diff --git a/liblll/CompilerState.cpp b/liblll/CompilerState.cpp
index c22242a3..5d38bb8c 100644
--- a/liblll/CompilerState.cpp
+++ b/liblll/CompilerState.cpp
@@ -49,13 +49,15 @@ void CompilerState::populateStandard()
"(def 'allgas (- (gas) 21))"
"(def 'send (to value) (call allgas to value 0 0 0 0))"
"(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 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 })"
+ // NOTE: in this macro, memory location 0 is set in order to force msize to be at least 32 bytes.
+ "(def 'msg (gaslimit to value data datasize outsize) { [0]:0 [0]:(msize) (call gaslimit to value data datasize @0 outsize) @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 allgas to value 0 32) })"
"(def 'msg (to data) { [0]:data (msg allgas to 0 0 32) })"
- "(def 'create (value code) { [0]:(msize) (create value @0 (lll code @0)) })"
- "(def 'create (code) { [0]:(msize) (create 0 @0 (lll code @0)) })"
+ // NOTE: in the create macros, memory location 0 is set in order to force msize to be at least 32 bytes.
+ "(def 'create (value code) { [0]:0 [0]:(msize) (create value @0 (lll code @0)) })"
+ "(def 'create (code) { [0]:0 [0]:(msize) (create 0 @0 (lll code @0)) })"
"(def 'sha3 (loc len) (keccak256 loc len))"
"(def 'sha3 (val) { [0]:val (sha3 0 32) })"
"(def 'sha3pair (a b) { [0]:a [32]:b (sha3 0 64) })"
@@ -65,7 +67,7 @@ void CompilerState::populateStandard()
"(def 'makeperm (name pos) { (def name (sload pos)) (def name (v) (sstore pos v)) } )"
"(def 'permcount 0)"
"(def 'perm (name) { (makeperm name permcount) (def 'permcount (+ permcount 1)) } )"
- "(def 'ecrecover (r s v hash) { [0] r [32] s [64] v [96] hash (msg allgas 1 0 0 128) })"
+ "(def 'ecrecover (hash v r s) { [0] hash [32] v [64] r [96] s (msg allgas 1 0 0 128) })"
"(def 'sha256 (data datasize) (msg allgas 2 0 data datasize))"
"(def 'ripemd160 (data datasize) (msg allgas 3 0 data datasize))"
"(def 'sha256 (val) { [0]:val (sha256 0 32) })"
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp
index 03112d2d..40dfa348 100644
--- a/libsolidity/ast/AST.cpp
+++ b/libsolidity/ast/AST.cpp
@@ -20,10 +20,8 @@
* Solidity abstract syntax tree.
*/
-#include <libsolidity/interface/Utils.h>
#include <libsolidity/ast/AST.h>
#include <libsolidity/ast/ASTVisitor.h>
-#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/ast/AST_accept.h>
#include <libdevcore/SHA3.h>
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h
index ba1d0589..83572692 100644
--- a/libsolidity/ast/AST.h
+++ b/libsolidity/ast/AST.h
@@ -29,7 +29,6 @@
#include <boost/noncopyable.hpp>
#include <libevmasm/SourceLocation.h>
#include <libevmasm/Instruction.h>
-#include <libsolidity/interface/Utils.h>
#include <libsolidity/ast/ASTForward.h>
#include <libsolidity/parsing/Token.h>
#include <libsolidity/ast/Types.h>
diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp
index 4ad1f962..a90debb2 100644
--- a/libsolidity/ast/ASTJsonConverter.cpp
+++ b/libsolidity/ast/ASTJsonConverter.cpp
@@ -24,7 +24,6 @@
#include <boost/algorithm/string/join.hpp>
#include <libdevcore/UTF8.h>
#include <libsolidity/ast/AST.h>
-#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/inlineasm/AsmData.h>
#include <libsolidity/inlineasm/AsmPrinter.h>
diff --git a/libsolidity/ast/ASTJsonConverter.h b/libsolidity/ast/ASTJsonConverter.h
index c2de5c48..27114c2a 100644
--- a/libsolidity/ast/ASTJsonConverter.h
+++ b/libsolidity/ast/ASTJsonConverter.h
@@ -26,7 +26,6 @@
#include <stack>
#include <libsolidity/ast/ASTVisitor.h>
#include <libsolidity/interface/Exceptions.h>
-#include <libsolidity/interface/Utils.h>
#include <libsolidity/ast/ASTAnnotations.h>
#include <json/json.h>
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index cfee041e..bd3346f9 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -22,7 +22,6 @@
#include <libsolidity/ast/Types.h>
-#include <libsolidity/interface/Utils.h>
#include <libsolidity/ast/AST.h>
#include <libdevcore/CommonIO.h>
diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp
index 6a641b02..67ca22f1 100644
--- a/libsolidity/codegen/ArrayUtils.cpp
+++ b/libsolidity/codegen/ArrayUtils.cpp
@@ -25,7 +25,7 @@
#include <libsolidity/codegen/CompilerContext.h>
#include <libsolidity/codegen/CompilerUtils.h>
#include <libsolidity/ast/Types.h>
-#include <libsolidity/interface/Utils.h>
+#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/codegen/LValue.h>
using namespace std;
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index 25154bc0..03bba80c 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -32,6 +32,7 @@
#include <libsolidity/codegen/CompilerUtils.h>
#include <libsolidity/codegen/LValue.h>
#include <libevmasm/GasMeter.h>
+
using namespace std;
namespace dev
diff --git a/libsolidity/codegen/ExpressionCompiler.h b/libsolidity/codegen/ExpressionCompiler.h
index d0a8ac15..3b8cf1c6 100644
--- a/libsolidity/codegen/ExpressionCompiler.h
+++ b/libsolidity/codegen/ExpressionCompiler.h
@@ -28,7 +28,7 @@
#include <libevmasm/SourceLocation.h>
#include <libsolidity/ast/ASTVisitor.h>
#include <libsolidity/codegen/LValue.h>
-#include <libsolidity/interface/Utils.h>
+#include <libsolidity/interface/Exceptions.h>
namespace dev {
namespace eth
diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp
index 2891ec95..b0d044ae 100644
--- a/libsolidity/inlineasm/AsmAnalysis.cpp
+++ b/libsolidity/inlineasm/AsmAnalysis.cpp
@@ -26,7 +26,6 @@
#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
#include <libsolidity/interface/ErrorReporter.h>
-#include <libsolidity/interface/Utils.h>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/algorithm/string.hpp>
diff --git a/libsolidity/inlineasm/AsmPrinter.cpp b/libsolidity/inlineasm/AsmPrinter.cpp
index 0d06fedd..062ff453 100644
--- a/libsolidity/inlineasm/AsmPrinter.cpp
+++ b/libsolidity/inlineasm/AsmPrinter.cpp
@@ -22,7 +22,7 @@
#include <libsolidity/inlineasm/AsmPrinter.h>
#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/interface/Utils.h>
+#include <libsolidity/interface/Exceptions.h>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/replace.hpp>
diff --git a/libsolidity/inlineasm/AsmScopeFiller.cpp b/libsolidity/inlineasm/AsmScopeFiller.cpp
index 3bef9cec..5b3174b8 100644
--- a/libsolidity/inlineasm/AsmScopeFiller.cpp
+++ b/libsolidity/inlineasm/AsmScopeFiller.cpp
@@ -25,7 +25,7 @@
#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
#include <libsolidity/interface/ErrorReporter.h>
-#include <libsolidity/interface/Utils.h>
+#include <libsolidity/interface/Exceptions.h>
#include <boost/range/adaptor/reversed.hpp>
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp
index b09108b0..8be2c8dd 100644
--- a/libsolidity/interface/CompilerStack.cpp
+++ b/libsolidity/interface/CompilerStack.cpp
@@ -481,12 +481,12 @@ Json::Value const& CompilerStack::natspec(Contract const& _contract, Documentati
return *(*doc);
}
-Json::Value CompilerStack::functionHashes(ContractDefinition const& _contract)
+Json::Value CompilerStack::methodIdentifiers(string const& _contractName) const
{
- Json::Value functionHashes(Json::objectValue);
- for (auto const& it: _contract.interfaceFunctions())
- functionHashes[it.second->externalSignature()] = toHex(it.first.ref());
- return functionHashes;
+ Json::Value methodIdentifiers(Json::objectValue);
+ for (auto const& it: contractDefinition(_contractName).interfaceFunctions())
+ methodIdentifiers[it.second->externalSignature()] = toHex(it.first.ref());
+ return methodIdentifiers;
}
string const& CompilerStack::onChainMetadata(string const& _contractName) const
diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h
index 3250429b..f7435f0e 100644
--- a/libsolidity/interface/CompilerStack.h
+++ b/libsolidity/interface/CompilerStack.h
@@ -178,7 +178,8 @@ public:
/// Can be one of 4 types defined at @c DocumentationType
Json::Value const& natspec(std::string const& _contractName, DocumentationType _type) const;
- Json::Value functionHashes(ContractDefinition const& _contract);
+ /// @returns a JSON representing a map of method identifiers (hashes) to function names.
+ Json::Value methodIdentifiers(std::string const& _contractName) const;
std::string const& onChainMetadata(std::string const& _contractName) const;
void useMetadataLiteralSources(bool _metadataLiteralSources) { m_metadataLiteralSources = _metadataLiteralSources; }
@@ -190,9 +191,6 @@ public:
Scanner const& scanner(std::string const& _sourceName = "") const;
/// @returns the parsed source unit with the supplied name.
SourceUnit const& ast(std::string const& _sourceName = "") const;
- /// @returns the parsed contract with the supplied name. Throws an exception if the contract
- /// does not exist.
- ContractDefinition const& contractDefinition(std::string const& _contractName) const;
/// Helper function for logs printing. Do only use in error cases, it's quite expensive.
/// line and columns are numbered starting from 1 with following order:
@@ -257,6 +255,10 @@ private:
Contract const& contract(std::string const& _contractName = "") const;
Source const& source(std::string const& _sourceName = "") const;
+ /// @returns the parsed contract with the supplied name. Throws an exception if the contract
+ /// does not exist.
+ ContractDefinition const& contractDefinition(std::string const& _contractName) const;
+
std::string createOnChainMetadata(Contract const& _contract) const;
std::string computeSourceMapping(eth::AssemblyItems const& _items) const;
Json::Value const& contractABI(Contract const&) const;
diff --git a/libsolidity/interface/Exceptions.cpp b/libsolidity/interface/Exceptions.cpp
index c09180de..deee92aa 100644
--- a/libsolidity/interface/Exceptions.cpp
+++ b/libsolidity/interface/Exceptions.cpp
@@ -21,7 +21,6 @@
*/
#include <libsolidity/interface/Exceptions.h>
-#include <libsolidity/interface/Utils.h>
using namespace std;
using namespace dev;
diff --git a/libsolidity/interface/Exceptions.h b/libsolidity/interface/Exceptions.h
index 0803d8cc..5fdb8f11 100644
--- a/libsolidity/interface/Exceptions.h
+++ b/libsolidity/interface/Exceptions.h
@@ -25,6 +25,7 @@
#include <string>
#include <utility>
#include <libdevcore/Exceptions.h>
+#include <libdevcore/Assertions.h>
#include <libevmasm/SourceLocation.h>
namespace dev
@@ -39,6 +40,16 @@ struct InternalCompilerError: virtual Exception {};
struct FatalError: virtual Exception {};
struct UnimplementedFeatureError: virtual Exception{};
+/// Assertion that throws an InternalCompilerError containing the given description if it is not met.
+#define solAssert(CONDITION, DESCRIPTION) \
+ assertThrow(CONDITION, ::dev::solidity::InternalCompilerError, DESCRIPTION)
+
+#define solUnimplementedAssert(CONDITION, DESCRIPTION) \
+ assertThrow(CONDITION, ::dev::solidity::UnimplementedFeatureError, DESCRIPTION)
+
+#define solUnimplemented(DESCRIPTION) \
+ solUnimplementedAssert(false, DESCRIPTION)
+
class Error: virtual public Exception
{
public:
diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp
index d5dbaa46..2e5005b8 100644
--- a/libsolidity/interface/StandardCompiler.cpp
+++ b/libsolidity/interface/StandardCompiler.cpp
@@ -115,14 +115,6 @@ StringMap createSourceList(Json::Value const& _input)
return sources;
}
-Json::Value methodIdentifiers(ContractDefinition const& _contract)
-{
- Json::Value methodIdentifiers(Json::objectValue);
- for (auto const& it: _contract.interfaceFunctions())
- methodIdentifiers[it.second->externalSignature()] = toHex(it.first.ref());
- return methodIdentifiers;
-}
-
Json::Value formatLinkReferences(std::map<size_t, std::string> const& linkReferences)
{
Json::Value ret(Json::objectValue);
@@ -404,7 +396,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
m_compilerStack.streamAssembly(tmp, contractName, createSourceList(_input), false);
evmData["assembly"] = tmp.str();
evmData["legacyAssembly"] = m_compilerStack.streamAssembly(tmp, contractName, createSourceList(_input), true);
- evmData["methodIdentifiers"] = methodIdentifiers(m_compilerStack.contractDefinition(contractName));
+ evmData["methodIdentifiers"] = m_compilerStack.methodIdentifiers(contractName);
evmData["gasEstimates"] = m_compilerStack.gasEstimates(contractName);
evmData["bytecode"] = collectEVMObject(
diff --git a/libsolidity/interface/Utils.h b/libsolidity/interface/Utils.h
deleted file mode 100644
index 0027759c..00000000
--- a/libsolidity/interface/Utils.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- This file is part of solidity.
-
- solidity 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.
-
- solidity 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 solidity. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * @author Christian <c@ethdev.com>
- * @date 2014
- * Solidity Utilities.
- */
-
-#pragma once
-
-#include <libdevcore/Assertions.h>
-#include <libsolidity/interface/Exceptions.h>
-
-namespace dev
-{
-namespace solidity
-{
-struct InternalCompilerError;
-struct UnimplementedFeatureError;
-}
-}
-
-/// Assertion that throws an InternalCompilerError containing the given description if it is not met.
-#define solAssert(CONDITION, DESCRIPTION) \
- assertThrow(CONDITION, ::dev::solidity::InternalCompilerError, DESCRIPTION)
-
-#define solUnimplementedAssert(CONDITION, DESCRIPTION) \
- assertThrow(CONDITION, ::dev::solidity::UnimplementedFeatureError, DESCRIPTION)
-
-#define solUnimplemented(DESCRIPTION) \
- solUnimplementedAssert(false, DESCRIPTION)
diff --git a/libsolidity/interface/Version.cpp b/libsolidity/interface/Version.cpp
index 0d23f9c3..a35bfd29 100644
--- a/libsolidity/interface/Version.cpp
+++ b/libsolidity/interface/Version.cpp
@@ -24,7 +24,7 @@
#include <string>
#include <libdevcore/CommonData.h>
#include <libdevcore/Common.h>
-#include <libsolidity/interface/Utils.h>
+#include <libsolidity/interface/Exceptions.h>
#include <solidity/BuildInfo.h>
using namespace dev;
diff --git a/libsolidity/parsing/DocStringParser.cpp b/libsolidity/parsing/DocStringParser.cpp
index cd6c1d8a..0409de72 100644
--- a/libsolidity/parsing/DocStringParser.cpp
+++ b/libsolidity/parsing/DocStringParser.cpp
@@ -1,7 +1,7 @@
#include <libsolidity/parsing/DocStringParser.h>
#include <libsolidity/interface/ErrorReporter.h>
-#include <libsolidity/interface/Utils.h>
+#include <libsolidity/interface/Exceptions.h>
#include <boost/range/irange.hpp>
#include <boost/range/algorithm.hpp>
diff --git a/libsolidity/parsing/Scanner.cpp b/libsolidity/parsing/Scanner.cpp
index 0e60fd0b..fdca23ea 100644
--- a/libsolidity/parsing/Scanner.cpp
+++ b/libsolidity/parsing/Scanner.cpp
@@ -52,7 +52,7 @@
#include <algorithm>
#include <tuple>
-#include <libsolidity/interface/Utils.h>
+#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/parsing/Scanner.h>
using namespace std;
diff --git a/libsolidity/parsing/Token.h b/libsolidity/parsing/Token.h
index 9a557ebd..39c0eff9 100644
--- a/libsolidity/parsing/Token.h
+++ b/libsolidity/parsing/Token.h
@@ -43,7 +43,6 @@
#pragma once
#include <libdevcore/Common.h>
-#include <libsolidity/interface/Utils.h>
#include <libsolidity/interface/Exceptions.h>
#include <libdevcore/UndefMacros.h>
diff --git a/scripts/bytecodecompare/prepare_report.py b/scripts/bytecodecompare/prepare_report.py
index 5a770981..427724b7 100755
--- a/scripts/bytecodecompare/prepare_report.py
+++ b/scripts/bytecodecompare/prepare_report.py
@@ -6,7 +6,7 @@ import subprocess
import json
solc = sys.argv[1]
-report = open("report.txt", "w")
+report = open("report.txt", "wb")
for optimize in [False, True]:
for f in sorted(glob.glob("*.sol")):
diff --git a/scripts/bytecodecompare/storebytecode.bat b/scripts/bytecodecompare/storebytecode.bat
index aa829d20..e64e9276 100644
--- a/scripts/bytecodecompare/storebytecode.bat
+++ b/scripts/bytecodecompare/storebytecode.bat
@@ -27,15 +27,16 @@ cd bytecode
..\scripts\isolate_tests.py ..\test\
..\scripts\bytecodecompare\prepare_report.py ..\build\solc\%CONFIGURATION%\solc.exe
-git clone --depth 2 git@github.com:ethereum/solidity-test-bytecode.git
+REM Send to stdout instead of stderr to not confuse powershell
+git clone --depth 2 git@github.com:ethereum/solidity-test-bytecode.git 2>&1
cd solidity-test-bytecode
git config user.name "travis"
git config user.email "chris@ethereum.org"
-git clean -f -d -x
+git clean -f -d -x 2>&1
if not exist %DIRECTORY% mkdir %DIRECTORY%
set REPORT=%DIRECTORY%/windows.txt
cp ../report.txt %REPORT%
git add %REPORT%
git commit -a -m "Added report."
-git push origin
+git push origin 2>&1
diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp
index e37922c6..0dbedd3c 100644
--- a/solc/CommandLineInterface.cpp
+++ b/solc/CommandLineInterface.cpp
@@ -281,9 +281,10 @@ void CommandLineInterface::handleSignatureHashes(string const& _contract)
if (!m_args.count(g_argSignatureHashes))
return;
+ Json::Value methodIdentifiers = m_compiler->methodIdentifiers(_contract);
string out;
- for (auto const& it: m_compiler->contractDefinition(_contract).interfaceFunctions())
- out += toHex(it.first.ref()) + ": " + it.second->externalSignature() + "\n";
+ for (auto const& name: methodIdentifiers.getMemberNames())
+ out += methodIdentifiers[name].asString() + ": " + name + "\n";
if (m_args.count(g_argOutputDir))
createFile(m_compiler->filesystemFriendlyName(_contract) + ".signatures", out);
@@ -889,7 +890,7 @@ void CommandLineInterface::handleCombinedJSON()
contractData[g_strSrcMapRuntime] = map ? *map : "";
}
if (requests.count(g_strSignatureHashes))
- contractData[g_strSignatureHashes] = m_compiler->functionHashes(m_compiler->contractDefinition(contractName));
+ contractData[g_strSignatureHashes] = m_compiler->methodIdentifiers(contractName);
if (requests.count(g_strNatspecDev))
contractData[g_strNatspecDev] = dev::jsonCompactPrint(m_compiler->natspec(contractName, DocumentationType::NatspecDev));
if (requests.count(g_strNatspecUser))
diff --git a/solc/jsonCompiler.cpp b/solc/jsonCompiler.cpp
index c01c8061..5165f984 100644
--- a/solc/jsonCompiler.cpp
+++ b/solc/jsonCompiler.cpp
@@ -192,7 +192,7 @@ string compile(StringMap const& _sources, bool _optimize, CStyleReadFileCallback
contractData["runtimeBytecode"] = compiler.runtimeObject(contractName).toHex();
contractData["opcodes"] = solidity::disassemble(compiler.object(contractName).bytecode);
contractData["metadata"] = compiler.onChainMetadata(contractName);
- contractData["functionHashes"] = compiler.functionHashes(compiler.contractDefinition(contractName));
+ contractData["functionHashes"] = compiler.methodIdentifiers(contractName);
contractData["gasEstimates"] = estimateGas(compiler, contractName);
auto sourceMap = compiler.sourceMapping(contractName);
contractData["srcmap"] = sourceMap ? *sourceMap : "";
diff --git a/test/liblll/EndToEndTest.cpp b/test/liblll/EndToEndTest.cpp
index 3928ff45..02d024a4 100644
--- a/test/liblll/EndToEndTest.cpp
+++ b/test/liblll/EndToEndTest.cpp
@@ -57,6 +57,68 @@ BOOST_AUTO_TEST_CASE(panic)
BOOST_REQUIRE(m_output.empty());
}
+BOOST_AUTO_TEST_CASE(when)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (seq
+ (when (= (calldatasize) 0) (return 1))
+ (when (!= (calldatasize) 0) (return 2))))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2)));
+ BOOST_CHECK(callFallback() == toBigEndian(u256(1)));
+}
+
+BOOST_AUTO_TEST_CASE(unless)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (seq
+ (unless (!= (calldatasize) 0) (return 1))
+ (unless (= (calldatasize) 0) (return 2))))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2)));
+ BOOST_CHECK(callFallback() == toBigEndian(u256(1)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_literal)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (seq
+ (return (if (= (calldatasize) 0) 1 2))))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2)));
+ BOOST_CHECK(callFallback() == toBigEndian(u256(1)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (seq
+ (if (= (calldatasize) 0) (return 1) (return 2))))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2)));
+ BOOST_CHECK(callFallback() == toBigEndian(u256(1)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_seq)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (seq
+ (return (if (= (calldatasize) 0) { 0 2 1 } { 0 1 2 }))))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2)));
+ BOOST_CHECK(callFallback() == toBigEndian(u256(1)));
+}
+
BOOST_AUTO_TEST_CASE(exp_operator_const)
{
char const* sourceCode = R"(
@@ -304,6 +366,51 @@ BOOST_AUTO_TEST_CASE(keccak256_32bytes)
fromHex("b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6")));
}
+BOOST_AUTO_TEST_CASE(msg_six_args)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (seq
+ (when (= 0 (calldatasize))
+ (seq
+ (mstore 0x40 1)
+ (def 'outsize 0x20)
+ (return (msg 1000 (address) 42 0x40 0x20 outsize) outsize)))
+ (when (= 1 (calldataload 0x00))
+ (return (callvalue)))))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callFallbackWithValue(42) == encodeArgs(u256(42)));
+}
+
+BOOST_AUTO_TEST_CASE(create_1_arg)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (seq
+ (call allgas
+ (create (returnlll (return 42)))
+ 0 0 0 0x00 0x20)
+ (return 0x00 0x20)))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callFallback() == encodeArgs(u256(42)));
+}
+
+BOOST_AUTO_TEST_CASE(create_2_args)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (seq
+ (call allgas
+ (create 42 (returnlll (return (balance (address)))))
+ 0 0 0 0x00 0x20)
+ (return 0x00 0x20)))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callFallbackWithValue(42) == encodeArgs(u256(42)));
+}
+
BOOST_AUTO_TEST_CASE(sha3_two_args)
{
char const* sourceCode = R"(
@@ -328,6 +435,25 @@ BOOST_AUTO_TEST_CASE(sha3_one_arg)
fromHex("b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6")));
}
+BOOST_AUTO_TEST_CASE(ecrecover)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (return
+ (ecrecover
+ ; Hash of 'hello world'
+ 0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad
+ ; v = 1 + 27
+ 0x1c
+ ; r
+ 0xdebaaa0cddb321b2dcaaf846d39605de7b97e77ba6106587855b9106cb104215
+ ; s
+ 0x61a22d94fa8b8a687ff9c911c844d1c016d1a685a9166858f9c7c1bc85128aca)))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callFallback() == encodeArgs(fromHex("0x8743523d96a1b2cbe0c6909653a56da18ed484af")));
+}
+
BOOST_AUTO_TEST_CASE(shift_left)
{
char const* sourceCode = R"(