aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-06-23 00:05:13 +0800
committerchriseth <c@ethdev.com>2015-06-23 02:50:47 +0800
commit8639cf8e3df10bedf8ce808aa7146ac88624df44 (patch)
treeda2a0a835223c6d1adcce4e6b27ef7463eab338e
parent2eabaa4716997242856b0e33bbc34a4d7204c301 (diff)
downloaddexon-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.cpp9
-rw-r--r--Types.cpp40
-rw-r--r--Types.h23
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);
+
}
}
diff --git a/Types.cpp b/Types.cpp
index b90b8884..377b2b15 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -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;
diff --git a/Types.h b/Types.h
index cca5dde7..11bc3536 100644
--- a/Types.h
+++ b/Types.h
@@ -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);