mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Move dynamic type removal out of the type system.
This commit is contained in:
parent
32c94f5059
commit
cc2f71e4ac
@ -1551,16 +1551,22 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
|
|||||||
_functionCall.expression().annotation().isPure &&
|
_functionCall.expression().annotation().isPure &&
|
||||||
functionType->isPure();
|
functionType->isPure();
|
||||||
|
|
||||||
|
bool allowDynamicTypes = false; // @TODO
|
||||||
if (!functionType)
|
if (!functionType)
|
||||||
{
|
{
|
||||||
m_errorReporter.typeError(_functionCall.location(), "Type is not callable");
|
m_errorReporter.typeError(_functionCall.location(), "Type is not callable");
|
||||||
_functionCall.annotation().type = make_shared<TupleType>();
|
_functionCall.annotation().type = make_shared<TupleType>();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (functionType->returnParameterTypes().size() == 1)
|
|
||||||
_functionCall.annotation().type = functionType->returnParameterTypes().front();
|
auto returnTypes =
|
||||||
|
allowDynamicTypes ?
|
||||||
|
functionType->returnParameterTypes() :
|
||||||
|
functionType->returnParameterTypesWithoutDynamicTypes();
|
||||||
|
if (returnTypes.size() == 1)
|
||||||
|
_functionCall.annotation().type = returnTypes.front();
|
||||||
else
|
else
|
||||||
_functionCall.annotation().type = make_shared<TupleType>(functionType->returnParameterTypes());
|
_functionCall.annotation().type = make_shared<TupleType>(returnTypes);
|
||||||
|
|
||||||
if (auto functionName = dynamic_cast<Identifier const*>(&_functionCall.expression()))
|
if (auto functionName = dynamic_cast<Identifier const*>(&_functionCall.expression()))
|
||||||
{
|
{
|
||||||
|
@ -2311,6 +2311,18 @@ vector<string> FunctionType::parameterNames() const
|
|||||||
return vector<string>(m_parameterNames.cbegin() + 1, m_parameterNames.cend());
|
return vector<string>(m_parameterNames.cbegin() + 1, m_parameterNames.cend());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypePointers FunctionType::returnParameterTypesWithoutDynamicTypes() const
|
||||||
|
{
|
||||||
|
TypePointers returnParameterTypes = m_returnParameterTypes;
|
||||||
|
|
||||||
|
if (m_kind == Kind::External || m_kind == Kind::CallCode || m_kind == Kind::DelegateCall)
|
||||||
|
for (auto& param: returnParameterTypes)
|
||||||
|
if (param->isDynamicallySized() && !param->dataStoredIn(DataLocation::Storage))
|
||||||
|
param = make_shared<InaccessibleDynamicType>();
|
||||||
|
|
||||||
|
return returnParameterTypes;
|
||||||
|
}
|
||||||
|
|
||||||
TypePointers FunctionType::parameterTypes() const
|
TypePointers FunctionType::parameterTypes() const
|
||||||
{
|
{
|
||||||
if (!bound())
|
if (!bound())
|
||||||
@ -2772,18 +2784,9 @@ FunctionTypePointer FunctionType::asMemberFunction(bool _inLibrary, bool _bound)
|
|||||||
kind = Kind::DelegateCall;
|
kind = Kind::DelegateCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointers returnParameterTypes = m_returnParameterTypes;
|
|
||||||
if (kind != Kind::Internal)
|
|
||||||
{
|
|
||||||
// Alter dynamic types to be non-accessible.
|
|
||||||
for (auto& param: returnParameterTypes)
|
|
||||||
if (param->isDynamicallySized())
|
|
||||||
param = make_shared<InaccessibleDynamicType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return make_shared<FunctionType>(
|
return make_shared<FunctionType>(
|
||||||
parameterTypes,
|
parameterTypes,
|
||||||
returnParameterTypes,
|
m_returnParameterTypes,
|
||||||
m_parameterNames,
|
m_parameterNames,
|
||||||
m_returnParameterNames,
|
m_returnParameterNames,
|
||||||
kind,
|
kind,
|
||||||
|
@ -973,6 +973,9 @@ public:
|
|||||||
TypePointers parameterTypes() const;
|
TypePointers parameterTypes() const;
|
||||||
std::vector<std::string> parameterNames() const;
|
std::vector<std::string> parameterNames() const;
|
||||||
TypePointers const& returnParameterTypes() const { return m_returnParameterTypes; }
|
TypePointers const& returnParameterTypes() const { return m_returnParameterTypes; }
|
||||||
|
/// @returns the list of return parameter types. All dynamically-sized types (this excludes
|
||||||
|
/// storage pointers) are replaced by InaccessibleDynamicType instances.
|
||||||
|
TypePointers returnParameterTypesWithoutDynamicTypes() const;
|
||||||
std::vector<std::string> const& returnParameterNames() const { return m_returnParameterNames; }
|
std::vector<std::string> const& returnParameterNames() const { return m_returnParameterNames; }
|
||||||
/// @returns the "self" parameter type for a bound function
|
/// @returns the "self" parameter type for a bound function
|
||||||
TypePointer const& selfType() const;
|
TypePointer const& selfType() const;
|
||||||
|
@ -139,8 +139,8 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
|
|||||||
utils().popStackSlots(paramTypes.size() - 1);
|
utils().popStackSlots(paramTypes.size() - 1);
|
||||||
}
|
}
|
||||||
unsigned retSizeOnStack = 0;
|
unsigned retSizeOnStack = 0;
|
||||||
solAssert(accessorType.returnParameterTypes().size() >= 1, "");
|
auto returnTypes = accessorType.returnParameterTypes();
|
||||||
auto const& returnTypes = accessorType.returnParameterTypes();
|
solAssert(returnTypes.size() >= 1, "");
|
||||||
if (StructType const* structType = dynamic_cast<StructType const*>(returnType.get()))
|
if (StructType const* structType = dynamic_cast<StructType const*>(returnType.get()))
|
||||||
{
|
{
|
||||||
// remove offset
|
// remove offset
|
||||||
@ -1618,15 +1618,22 @@ void ExpressionCompiler::appendExternalFunctionCall(
|
|||||||
m_context.experimentalFeatureActive(ExperimentalFeature::V050) &&
|
m_context.experimentalFeatureActive(ExperimentalFeature::V050) &&
|
||||||
m_context.evmVersion().hasStaticCall();
|
m_context.evmVersion().hasStaticCall();
|
||||||
|
|
||||||
|
bool allowDynamicTypes = false; // @TODO
|
||||||
unsigned retSize = 0;
|
unsigned retSize = 0;
|
||||||
|
TypePointers returnTypes;
|
||||||
if (returnSuccessCondition)
|
if (returnSuccessCondition)
|
||||||
retSize = 0; // return value actually is success condition
|
retSize = 0; // return value actually is success condition
|
||||||
|
else if (allowDynamicTypes)
|
||||||
|
returnTypes = _functionType.returnParameterTypes();
|
||||||
else
|
else
|
||||||
for (auto const& retType: _functionType.returnParameterTypes())
|
{
|
||||||
|
returnTypes = _functionType.returnParameterTypesWithoutDynamicTypes();
|
||||||
|
for (auto const& retType: returnTypes)
|
||||||
{
|
{
|
||||||
solAssert(!retType->isDynamicallySized(), "Unable to return dynamic type from external call.");
|
solAssert(!retType->isDynamicallySized(), "Unable to return dynamic type from external call.");
|
||||||
retSize += retType->calldataEncodedSize();
|
retSize += retType->calldataEncodedSize();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Evaluate arguments.
|
// Evaluate arguments.
|
||||||
TypePointers argumentTypes;
|
TypePointers argumentTypes;
|
||||||
@ -1824,11 +1831,11 @@ void ExpressionCompiler::appendExternalFunctionCall(
|
|||||||
utils().fetchFreeMemoryPointer();
|
utils().fetchFreeMemoryPointer();
|
||||||
m_context << Instruction::SUB << Instruction::MLOAD;
|
m_context << Instruction::SUB << Instruction::MLOAD;
|
||||||
}
|
}
|
||||||
else if (!_functionType.returnParameterTypes().empty())
|
else if (!returnTypes.empty())
|
||||||
{
|
{
|
||||||
utils().fetchFreeMemoryPointer();
|
utils().fetchFreeMemoryPointer();
|
||||||
bool memoryNeeded = false;
|
bool memoryNeeded = false;
|
||||||
for (auto const& retType: _functionType.returnParameterTypes())
|
for (auto const& retType: returnTypes)
|
||||||
{
|
{
|
||||||
utils().loadFromMemoryDynamic(*retType, false, true, true);
|
utils().loadFromMemoryDynamic(*retType, false, true, true);
|
||||||
if (dynamic_cast<ReferenceType const*>(retType.get()))
|
if (dynamic_cast<ReferenceType const*>(retType.get()))
|
||||||
|
Loading…
Reference in New Issue
Block a user