aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libevmasm/PeepholeOptimiser.h1
-rw-r--r--libsolidity/ast/ASTJsonConverter.cpp2
-rw-r--r--libsolidity/ast/Types.cpp9
-rw-r--r--libsolidity/ast/Types.h1
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp31
-rw-r--r--libsolidity/codegen/CompilerUtils.h2
-rw-r--r--libsolidity/interface/CompilerStack.cpp2
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp6
8 files changed, 33 insertions, 21 deletions
diff --git a/libevmasm/PeepholeOptimiser.h b/libevmasm/PeepholeOptimiser.h
index dfc9a03b..372e49c5 100644
--- a/libevmasm/PeepholeOptimiser.h
+++ b/libevmasm/PeepholeOptimiser.h
@@ -22,6 +22,7 @@
#include <vector>
#include <cstddef>
+#include <iterator>
namespace dev
{
diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp
index d6aca175..37dfd3c6 100644
--- a/libsolidity/ast/ASTJsonConverter.cpp
+++ b/libsolidity/ast/ASTJsonConverter.cpp
@@ -236,7 +236,7 @@ bool ASTJsonConverter::visit(FunctionTypeName const& _node)
make_pair("payable", _node.isPayable()),
make_pair("visibility", visibility),
make_pair("constant", _node.isDeclaredConst())
- });
+ }, true);
return true;
}
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index c1ae183e..3a8fc075 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -1930,6 +1930,12 @@ TypePointer FunctionType::unaryOperatorResult(Token::Value _operator) const
return TypePointer();
}
+string FunctionType::canonicalName(bool) const
+{
+ solAssert(m_location == Location::External, "");
+ return "function";
+}
+
string FunctionType::toString(bool _short) const
{
string name = "function (";
@@ -2102,7 +2108,6 @@ TypePointer FunctionType::encodingType() const
{
// Only external functions can be encoded, internal functions cannot leave code boundaries.
if (m_location == Location::External)
- // This looks like bytes24, but bytes24 is stored differently on the stack.
return shared_from_this();
else
return TypePointer();
@@ -2111,7 +2116,7 @@ TypePointer FunctionType::encodingType() const
TypePointer FunctionType::interfaceType(bool /*_inLibrary*/) const
{
if (m_location == Location::External)
- return make_shared<FixedBytesType>(storageBytes());
+ return shared_from_this();
else
return TypePointer();
}
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index 84e56663..34fcfc82 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -897,6 +897,7 @@ public:
virtual bool operator==(Type const& _other) const override;
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
+ virtual std::string canonicalName(bool /*_addDataLocation*/) const override;
virtual std::string toString(bool _short) const override;
virtual unsigned calldataEncodedSize(bool _padded) const override;
virtual bool canBeStored() const override { return m_location == Location::Internal || m_location == Location::External; }
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index 1e21c020..1e819ed4 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -317,27 +317,32 @@ void CompilerUtils::memoryCopy()
void CompilerUtils::splitExternalFunctionType(bool _leftAligned)
{
- // We have to split the left-aligned <function identifier><address> into two stack slots:
+ // We have to split the left-aligned <address><function identifier> into two stack slots:
// address (right aligned), function identifier (right aligned)
if (_leftAligned)
- m_context << (u256(1) << 64) << Instruction::SWAP1 << Instruction::DIV;
- m_context << Instruction::DUP1 << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::SWAP1;
- m_context << (u256(1) << 160) << Instruction::SWAP1 << Instruction::DIV;
- if (!_leftAligned)
- m_context << u256(0xffffffffUL) << Instruction::AND;
+ {
+ m_context << Instruction::DUP1 << (u256(1) << (64 + 32)) << Instruction::SWAP1 << Instruction::DIV;
+ // <input> <address>
+ m_context << Instruction::SWAP1 << (u256(1) << 64) << Instruction::SWAP1 << Instruction::DIV;
+ }
+ else
+ {
+ m_context << Instruction::DUP1 << (u256(1) << 32) << Instruction::SWAP1 << Instruction::DIV;
+ m_context << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::SWAP1;
+ }
+ m_context << u256(0xffffffffUL) << Instruction::AND;
}
void CompilerUtils::combineExternalFunctionType(bool _leftAligned)
{
- if (_leftAligned)
- m_context << (u256(1) << 224);
- else
- m_context << u256(0xffffffffUL) << Instruction::AND << (u256(1) << 160);
- m_context << Instruction::MUL << Instruction::SWAP1;
- m_context << ((u256(1) << 160) - 1) << Instruction::AND;
+ // <address> <function_id>
+ m_context << u256(0xffffffffUL) << Instruction::AND << Instruction::SWAP1;
+ if (!_leftAligned)
+ m_context << ((u256(1) << 160) - 1) << Instruction::AND;
+ m_context << (u256(1) << 32) << Instruction::MUL;
+ m_context << Instruction::OR;
if (_leftAligned)
m_context << (u256(1) << 64) << Instruction::MUL;
- m_context << Instruction::OR;
}
void CompilerUtils::pushCombinedFunctionEntryLabel(Declaration const& _function)
diff --git a/libsolidity/codegen/CompilerUtils.h b/libsolidity/codegen/CompilerUtils.h
index 2ebec81a..8e4033d6 100644
--- a/libsolidity/codegen/CompilerUtils.h
+++ b/libsolidity/codegen/CompilerUtils.h
@@ -115,7 +115,7 @@ public:
void memoryCopy();
/// Converts the combined and left-aligned (right-aligned if @a _rightAligned is true)
- /// external function type <function identifier><address> into two stack slots:
+ /// external function type <address><function identifier> into two stack slots:
/// address (right aligned), function identifier (right aligned)
void splitExternalFunctionType(bool _rightAligned);
/// Performs the opposite operation of splitExternalFunctionType(_rightAligned)
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp
index c86de43f..f1eb2614 100644
--- a/libsolidity/interface/CompilerStack.cpp
+++ b/libsolidity/interface/CompilerStack.cpp
@@ -597,7 +597,7 @@ void CompilerStack::compileContract(
cloneCompiler.compileClone(_contract, _compiledContracts);
compiledContract.cloneObject = cloneCompiler.assembledObject();
}
- catch (eth::AssemblyException const& _e)
+ catch (eth::AssemblyException const&)
{
// In some cases (if the constructor requests a runtime function), it is not
// possible to compile the clone.
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index c01d11d2..ed95d687 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -7703,8 +7703,8 @@ BOOST_AUTO_TEST_CASE(receive_external_function_type)
compileAndRun(sourceCode, 0, "C");
BOOST_CHECK(callContractFunction(
- "f(bytes24)",
- FixedHash<4>(dev::keccak256("g()")).asBytes() + m_contractAddress.asBytes() + bytes(32 - 4 - 20, 0)
+ "f(function)",
+ m_contractAddress.asBytes() + FixedHash<4>(dev::keccak256("g()")).asBytes() + bytes(32 - 4 - 20, 0)
) == encodeArgs(u256(7)));
}
@@ -7722,7 +7722,7 @@ BOOST_AUTO_TEST_CASE(return_external_function_type)
compileAndRun(sourceCode, 0, "C");
BOOST_CHECK(
callContractFunction("f()") ==
- FixedHash<4>(dev::keccak256("g()")).asBytes() + m_contractAddress.asBytes() + bytes(32 - 4 - 20, 0)
+ m_contractAddress.asBytes() + FixedHash<4>(dev::keccak256("g()")).asBytes() + bytes(32 - 4 - 20, 0)
);
}