aboutsummaryrefslogtreecommitdiffstats
path: root/ExpressionCompiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r--ExpressionCompiler.cpp74
1 files changed, 51 insertions, 23 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index b36c7283..81f5d08a 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -313,38 +313,66 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
using Location = FunctionType::Location;
if (_functionCall.isTypeConversion())
{
- //@todo struct construction
solAssert(_functionCall.getArguments().size() == 1, "");
solAssert(_functionCall.getNames().empty(), "");
Expression const& firstArgument = *_functionCall.getArguments().front();
firstArgument.accept(*this);
utils().convertType(*firstArgument.getType(), *_functionCall.getType());
+ return false;
}
+
+ FunctionTypePointer functionType;
+ if (_functionCall.isStructConstructorCall())
+ {
+ TypeType const& type = dynamic_cast<TypeType const&>(*_functionCall.getExpression().getType());
+ auto const& structType = dynamic_cast<StructType const&>(*type.getActualType());
+ functionType = structType.constructorType();
+ }
+ else
+ functionType = dynamic_pointer_cast<FunctionType const>(_functionCall.getExpression().getType());
+
+ TypePointers const& parameterTypes = functionType->getParameterTypes();
+ vector<ASTPointer<Expression const>> const& callArguments = _functionCall.getArguments();
+ vector<ASTPointer<ASTString>> const& callArgumentNames = _functionCall.getNames();
+ if (!functionType->takesArbitraryParameters())
+ solAssert(callArguments.size() == parameterTypes.size(), "");
+
+ vector<ASTPointer<Expression const>> arguments;
+ if (callArgumentNames.empty())
+ // normal arguments
+ arguments = callArguments;
else
+ // named arguments
+ for (auto const& parameterName: functionType->getParameterNames())
+ {
+ bool found = false;
+ for (size_t j = 0; j < callArgumentNames.size() && !found; j++)
+ if ((found = (parameterName == *callArgumentNames[j])))
+ // we found the actual parameter position
+ arguments.push_back(callArguments[j]);
+ solAssert(found, "");
+ }
+
+ if (_functionCall.isStructConstructorCall())
{
- FunctionType const& function = dynamic_cast<FunctionType const&>(*_functionCall.getExpression().getType());
- TypePointers const& parameterTypes = function.getParameterTypes();
- vector<ASTPointer<Expression const>> const& callArguments = _functionCall.getArguments();
- vector<ASTPointer<ASTString>> const& callArgumentNames = _functionCall.getNames();
- if (!function.takesArbitraryParameters())
- solAssert(callArguments.size() == parameterTypes.size(), "");
-
- vector<ASTPointer<Expression const>> arguments;
- if (callArgumentNames.empty())
- // normal arguments
- arguments = callArguments;
- else
- // named arguments
- for (auto const& parameterName: function.getParameterNames())
- {
- bool found = false;
- for (size_t j = 0; j < callArgumentNames.size() && !found; j++)
- if ((found = (parameterName == *callArgumentNames[j])))
- // we found the actual parameter position
- arguments.push_back(callArguments[j]);
- solAssert(found, "");
- }
+ TypeType const& type = dynamic_cast<TypeType const&>(*_functionCall.getExpression().getType());
+ auto const& structType = dynamic_cast<StructType const&>(*type.getActualType());
+
+ m_context << u256(max(32u, structType.getCalldataEncodedSize(true)));
+ utils().allocateMemory();
+ m_context << eth::Instruction::DUP1;
+ for (unsigned i = 0; i < arguments.size(); ++i)
+ {
+ arguments[i]->accept(*this);
+ utils().convertType(*arguments[i]->getType(), *functionType->getParameterTypes()[i]);
+ utils().storeInMemoryDynamic(*functionType->getParameterTypes()[i]);
+ }
+ m_context << eth::Instruction::POP;
+ }
+ else
+ {
+ FunctionType const& function = *functionType;
switch (function.getLocation())
{
case Location::Internal: