Remove dynamic return types.

This commit is contained in:
chriseth 2015-06-22 18:05:13 +02:00
parent 2eabaa4716
commit 8639cf8e3d
3 changed files with 58 additions and 14 deletions

View File

@ -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);
}
}

View File

@ -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;

23
Types.h
View File

@ -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);