diff options
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r-- | ExpressionCompiler.cpp | 74 |
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: |