aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLefteris Karapetsas <lefteris@refu.co>2015-02-03 21:02:58 +0800
committerLefteris Karapetsas <lefteris@refu.co>2015-02-06 16:38:04 +0800
commit8c1d928c944b70cf7318d8277cdfbf2ef0421857 (patch)
tree6033cb8918ae2049b6b339e716067a7f3db82198
parent59a390937637111ebdadf2d3af57122a10bdd012 (diff)
downloaddexon-solidity-8c1d928c944b70cf7318d8277cdfbf2ef0421857.tar
dexon-solidity-8c1d928c944b70cf7318d8277cdfbf2ef0421857.tar.gz
dexon-solidity-8c1d928c944b70cf7318d8277cdfbf2ef0421857.tar.bz2
dexon-solidity-8c1d928c944b70cf7318d8277cdfbf2ef0421857.tar.lz
dexon-solidity-8c1d928c944b70cf7318d8277cdfbf2ef0421857.tar.xz
dexon-solidity-8c1d928c944b70cf7318d8277cdfbf2ef0421857.tar.zst
dexon-solidity-8c1d928c944b70cf7318d8277cdfbf2ef0421857.zip
Solidity SHA3 can now take multiple arguments
-rw-r--r--AST.cpp19
-rw-r--r--ExpressionCompiler.cpp23
-rw-r--r--ExpressionCompiler.h8
3 files changed, 39 insertions, 11 deletions
diff --git a/AST.cpp b/AST.cpp
index d1c7d537..c4fd7e2d 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -487,14 +487,27 @@ void FunctionCall::checkTypeRequirements()
// and then ask if that is implicitly convertible to the struct represented by the
// function parameters
TypePointers const& parameterTypes = functionType->getParameterTypes();
- if (parameterTypes.size() != m_arguments.size())
+ if (functionType->getLocation() !=FunctionType::Location::SHA3 && parameterTypes.size() != m_arguments.size())
BOOST_THROW_EXCEPTION(createTypeError("Wrong argument count for function call."));
- if (m_names.empty())
+ if (m_names.empty()) // LTODO: Totally ignoring sha3 case for named arguments for now just for the rebase to work
{
for (size_t i = 0; i < m_arguments.size(); ++i)
- if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[i]))
+ {
+ if (functionType->getLocation() == FunctionType::Location::SHA3)
+ {
+#if 0 // are we sure we want that? Literal constant nums can't live outside storage and so sha3(42) will fail
+ if (!m_arguments[i]->getType()->canLiveOutsideStorage())
+ BOOST_THROW_EXCEPTION(createTypeError("SHA3 called with argument that can't live outside storage"));
+#endif
+ if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[0]))
+ BOOST_THROW_EXCEPTION(createTypeError(std::string("SHA3 argument ") +
+ boost::lexical_cast<std::string>(i) +
+ std::string("can't be converted to hash")));
+
+ } else if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[i]))
BOOST_THROW_EXCEPTION(createTypeError("Invalid type for argument in function call."));
+ }
}
else
{
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 875e00bc..8672611a 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -206,7 +206,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
TypePointers const& parameterTypes = function.getParameterTypes();
vector<ASTPointer<Expression const>> const& callArguments = _functionCall.getArguments();
vector<ASTPointer<ASTString>> const& callArgumentNames = _functionCall.getNames();
- solAssert(callArguments.size() == parameterTypes.size(), "");
+ if (function.getLocation() != Location::SHA3)
+ solAssert(callArguments.size() == parameterTypes.size(), "");
vector<ASTPointer<Expression const>> arguments;
if (callArgumentNames.empty())
@@ -325,9 +326,11 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
m_context << eth::Instruction::SUICIDE;
break;
case Location::SHA3:
- appendExpressionCopyToMemory(*function.getParameterTypes().front(), *arguments.front());
- m_context << u256(32) << u256(0) << eth::Instruction::SHA3;
+ {
+ unsigned length = appendSameTypeArgumentsCopyToMemory(function.getParameterTypes().front(), arguments, 0);
+ m_context << u256(length) << u256(0) << eth::Instruction::SHA3;
break;
+ }
case Location::LOG0:
case Location::LOG1:
case Location::LOG2:
@@ -843,8 +846,18 @@ unsigned ExpressionCompiler::appendArgumentCopyToMemory(TypePointers const& _typ
return length;
}
-unsigned ExpressionCompiler::appendTypeConversionAndMoveToMemory(Type const& _expectedType, Type const& _type,
- Location const& _location, unsigned _memoryOffset)
+unsigned ExpressionCompiler::appendSameTypeArgumentsCopyToMemory(TypePointer const& _type,
+ vector<ASTPointer<Expression const>> const& _arguments,
+ unsigned _memoryOffset)
+{
+ unsigned length = 0;
+ for (unsigned i = 0; i < _arguments.size(); ++i)
+ length += appendExpressionCopyToMemory(*_type, *_arguments[i], _memoryOffset + length);
+ return length;
+}
+
+unsigned ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType,
+ Expression const& _expression, unsigned _memoryOffset)
{
appendTypeConversion(_type, _expectedType, true);
unsigned const c_numBytes = CompilerUtils::getPaddedSize(_expectedType.getCalldataEncodedSize());
diff --git a/ExpressionCompiler.h b/ExpressionCompiler.h
index 7de577e6..b977657b 100644
--- a/ExpressionCompiler.h
+++ b/ExpressionCompiler.h
@@ -97,10 +97,12 @@ private:
unsigned appendArgumentCopyToMemory(TypePointers const& _types,
std::vector<ASTPointer<Expression const>> const& _arguments,
unsigned _memoryOffset = 0);
- /// Appends code that copies a type to memory.
+ /// Appends code that copies the given arguments that should all have the
+ /// same @a _type to memory (with optional offset).
/// @returns the number of bytes copied to memory
- unsigned appendTypeConversionAndMoveToMemory(Type const& _expectedType, Type const& _type,
- Location const& _location, unsigned _memoryOffset = 0);
+ unsigned appendSameTypeArgumentsCopyToMemory(TypePointer const& _type,
+ std::vector<ASTPointer<Expression const>> const& _arguments,
+ unsigned _memoryOffset = 0);
/// Appends code that evaluates a single expression and copies it to memory (with optional offset).
/// @returns the number of bytes copied to memory
unsigned appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression,