diff options
author | chriseth <c@ethdev.com> | 2015-06-23 00:05:13 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-06-23 02:50:47 +0800 |
commit | 8639cf8e3df10bedf8ce808aa7146ac88624df44 (patch) | |
tree | da2a0a835223c6d1adcce4e6b27ef7463eab338e | |
parent | 2eabaa4716997242856b0e33bbc34a4d7204c301 (diff) | |
download | dexon-solidity-8639cf8e3df10bedf8ce808aa7146ac88624df44.tar dexon-solidity-8639cf8e3df10bedf8ce808aa7146ac88624df44.tar.gz dexon-solidity-8639cf8e3df10bedf8ce808aa7146ac88624df44.tar.bz2 dexon-solidity-8639cf8e3df10bedf8ce808aa7146ac88624df44.tar.lz dexon-solidity-8639cf8e3df10bedf8ce808aa7146ac88624df44.tar.xz dexon-solidity-8639cf8e3df10bedf8ce808aa7146ac88624df44.tar.zst dexon-solidity-8639cf8e3df10bedf8ce808aa7146ac88624df44.zip |
Remove dynamic return types.
-rw-r--r-- | ExpressionCompiler.cpp | 9 | ||||
-rw-r--r-- | Types.cpp | 40 | ||||
-rw-r--r-- | Types.h | 23 |
3 files changed, 58 insertions, 14 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index 4714b84e..7d6ed346 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -457,6 +457,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) strings(), Location::Bare, false, + nullptr, true, true ), @@ -1004,9 +1005,14 @@ void ExpressionCompiler::appendExternalFunctionCall( _functionType.getReturnParameterTypes().empty() ? nullptr : _functionType.getReturnParameterTypes().front().get(); - unsigned retSize = firstReturnType ? firstReturnType->getCalldataEncodedSize() : 0; + unsigned retSize = 0; if (returnSuccessCondition) retSize = 0; // return value actually is success condition + else if (firstReturnType) + { + retSize = firstReturnType->getCalldataEncodedSize(); + solAssert(retSize > 0, "Unable to return dynamic type from external call."); + } // Evaluate arguments. TypePointers argumentTypes; @@ -1123,6 +1129,7 @@ void ExpressionCompiler::appendExternalFunctionCall( //@todo manually update free memory pointer if we accept returning memory-stored objects utils().fetchFreeMemoryPointer(); utils().loadFromMemoryDynamic(*firstReturnType, false, true, false); + } } @@ -822,16 +822,16 @@ string ArrayType::toString(bool _short) const TypePointer ArrayType::externalType() const { if (m_arrayKind != ArrayKind::Ordinary) - return shared_from_this(); + return this->copyForLocation(DataLocation::Memory, true); if (!m_baseType->externalType()) return TypePointer(); if (m_baseType->getCategory() == Category::Array && m_baseType->isDynamicallySized()) return TypePointer(); if (isDynamicallySized()) - return std::make_shared<ArrayType>(DataLocation::CallData, m_baseType->externalType()); + return std::make_shared<ArrayType>(DataLocation::Memory, m_baseType->externalType()); else - return std::make_shared<ArrayType>(DataLocation::CallData, m_baseType->externalType(), m_length); + return std::make_shared<ArrayType>(DataLocation::Memory, m_baseType->externalType(), m_length); } TypePointer ArrayType::copyForLocation(DataLocation _location, bool _isPointer) const @@ -903,7 +903,7 @@ MemberList const& ContractType::getMembers() const for (auto const& it: m_contract.getInterfaceFunctions()) members.push_back(MemberList::Member( it.second->getDeclaration().getName(), - it.second, + it.second->removeDynamicReturnTypes(), &it.second->getDeclaration() )); m_members.reset(new MemberList(members)); @@ -1084,7 +1084,11 @@ FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal for (ASTPointer<VariableDeclaration> const& var: _function.getParameters()) { paramNames.push_back(var->getName()); - params.push_back(var->getType()); + if (_isInternal) + params.push_back(var->getType()); + else + params.push_back(var->getType()->externalType()); + solAssert(!!params.back(), "Function argument type not valid in this context."); } retParams.reserve(_function.getReturnParameters().size()); retParamNames.reserve(_function.getReturnParameters().size()); @@ -1284,6 +1288,7 @@ MemberList const& FunctionType::getMembers() const strings(), Location::SetValue, false, + nullptr, m_gasSet, m_valueSet ) @@ -1300,6 +1305,7 @@ MemberList const& FunctionType::getMembers() const strings(), Location::SetGas, false, + nullptr, m_gasSet, m_valueSet ) @@ -1404,11 +1410,35 @@ TypePointer FunctionType::copyAndSetGasOrValue(bool _setGas, bool _setValue) con m_returnParameterNames, m_location, m_arbitraryParameters, + m_declaration, m_gasSet || _setGas, m_valueSet || _setValue ); } +FunctionTypePointer FunctionType::removeDynamicReturnTypes() const +{ + //@todo make this more intelligent once we support destructuring assignments + TypePointers returnParameterTypes; + vector<string> returnParameterNames; + if (!m_returnParameterTypes.empty() && m_returnParameterTypes.front()->getCalldataEncodedSize() > 0) + { + returnParameterTypes.push_back(m_returnParameterTypes.front()); + returnParameterNames.push_back(m_returnParameterNames.front()); + } + return make_shared<FunctionType>( + m_parameterTypes, + returnParameterTypes, + m_parameterNames, + returnParameterNames, + m_location, + m_arbitraryParameters, + m_declaration, + m_gasSet, + m_valueSet + ); +} + vector<string> const FunctionType::getParameterTypeNames() const { vector<string> names; @@ -669,17 +669,19 @@ public: strings _returnParameterNames = strings(), Location _location = Location::Internal, bool _arbitraryParameters = false, + Declaration const* _declaration = nullptr, bool _gasSet = false, bool _valueSet = false ): - m_parameterTypes (_parameterTypes), - m_returnParameterTypes (_returnParameterTypes), - m_parameterNames (_parameterNames), - m_returnParameterNames (_returnParameterNames), - m_location (_location), - m_arbitraryParameters (_arbitraryParameters), - m_gasSet (_gasSet), - m_valueSet (_valueSet) + m_parameterTypes(_parameterTypes), + m_returnParameterTypes(_returnParameterTypes), + m_parameterNames(_parameterNames), + m_returnParameterNames(_returnParameterNames), + m_location(_location), + m_arbitraryParameters(_arbitraryParameters), + m_gasSet(_gasSet), + m_valueSet(_valueSet), + m_declaration(_declaration) {} TypePointers const& getParameterTypes() const { return m_parameterTypes; } @@ -733,6 +735,11 @@ public: /// of the parameters to fals. TypePointer copyAndSetGasOrValue(bool _setGas, bool _setValue) const; + /// @returns a copy of this function type where all return parameters of dynamic size are removed. + /// This is needed if external functions are called internally, as they cannot return dynamic + /// values. + FunctionTypePointer removeDynamicReturnTypes() const; + private: static TypePointers parseElementaryTypeVector(strings const& _types); |