This commit is contained in:
Daniel Kirchner 2023-06-24 19:30:05 +02:00
parent 423972883c
commit 1bc8caf54a
7 changed files with 39 additions and 53 deletions

View File

@ -100,20 +100,3 @@ Sort Sort::operator-(Sort const& _rhs) const
result.classes -= _rhs.classes;
return result;
}
bool TypeConstant::operator<(TypeConstant const& _rhs) const
{
if (constructor < _rhs.constructor)
return true;
if (_rhs.constructor < constructor)
return false;
solAssert(arguments.size() == _rhs.arguments.size());
for(auto [lhs, rhs]: ranges::zip_view(arguments, _rhs.arguments))
{
if (lhs < rhs)
return true;
if (rhs < lhs)
return false;
}
return false;
}

View File

@ -56,16 +56,6 @@ struct TypeConstant
{
TypeConstructor constructor;
std::vector<Type> arguments;
bool operator<(TypeConstant const& _rhs) const;
bool operator==(TypeConstant const& _rhs) const
{
// TODO
return !(*this < _rhs) && !(_rhs < *this);
}
bool operator!=(TypeConstant const& _rhs) const
{
return !operator==(_rhs);
}
};
enum class BuiltinClass
@ -105,20 +95,6 @@ struct TypeVariable
size_t index() const { return m_index; }
bool generic() const { return m_generic; }
Sort const& sort() const { return m_sort; }
bool operator<(TypeVariable const& _rhs) const
{
// TODO: more robust comparison?
return m_index < _rhs.m_index;
}
bool operator==(TypeVariable const& _rhs) const
{
// TODO
return !(*this < _rhs) && !(_rhs < *this);
}
bool operator!=(TypeVariable const& _rhs) const
{
return !operator==(_rhs);
}
private:
friend class TypeSystem;
size_t m_index = 0;

View File

@ -228,6 +228,33 @@ vector<TypeEnvironment::UnificationFailure> TypeEnvironment::unify(Type _a, Type
return failures;
}
bool TypeEnvironment::typeEquals(Type _lhs, Type _rhs) const
{
return std::visit(util::GenericVisitor{
[&](TypeVariable _left, TypeVariable _right) {
if (_left.index() == _right.index())
{
solAssert(_left.sort() == _right.sort());
return true;
}
return false;
},
[&](TypeConstant _left, TypeConstant _right) {
if(_left.constructor != _right.constructor)
return false;
if (_left.arguments.size() != _right.arguments.size())
return false;
for (auto&& [left, right]: ranges::zip_view(_left.arguments, _right.arguments))
if (!typeEquals(left, right))
return false;
return true;
},
[&](auto, auto) {
return false;
}
}, resolve(_lhs), resolve(_rhs));
}
TypeEnvironment TypeEnvironment::clone() const
{
TypeEnvironment result{m_typeSystem};

View File

@ -45,6 +45,7 @@ public:
std::string canonicalTypeName(Type _type) const;
std::string typeToString(Type const& _type) const;
Sort sort(Type _type) const;
bool typeEquals(Type _lhs, Type _rhs) const;
private:
TypeEnvironment(TypeEnvironment&& _env): m_typeSystem(_env.m_typeSystem), m_typeVariables(std::move(_env.m_typeVariables)) {}
[[nodiscard]] std::vector<TypeEnvironment::UnificationFailure> instantiate(TypeVariable _variable, Type _type);

View File

@ -38,19 +38,18 @@ struct IRGenerationContext
void enqueueFunctionDefinition(FunctionDefinition const* _functionDefinition, Type _type)
{
QueuedFunction queue{_functionDefinition, env->resolve(_type)};
if (!generatedFunctions.count(queue))
functionQueue.emplace_back(queue);
for (auto type: generatedFunctions[_functionDefinition])
if (env->typeEquals(type, _type))
return;
functionQueue.emplace_back(queue);
}
struct QueuedFunction
{
FunctionDefinition const* function;
Type type;
bool operator<(QueuedFunction const& _rhs) const {
return std::make_tuple(function, type) < std::make_tuple(_rhs.function, _rhs.type);
}
};
std::list<QueuedFunction> functionQueue;
std::set<QueuedFunction> generatedFunctions;
std::map<FunctionDefinition const*, std::vector<Type>> generatedFunctions;
};
}

View File

@ -107,12 +107,13 @@ string IRGenerator::generate(ContractDefinition const& _contract)
while (!m_context.functionQueue.empty())
{
auto function = m_context.functionQueue.front();
auto [function, type] = m_context.functionQueue.front();
m_context.functionQueue.pop_front();
if (!m_context.generatedFunctions.count(function))
auto& generatedTypes = m_context.generatedFunctions[function];
if (!util::contains_if(generatedTypes, [&, type=type](auto _generatedType) { return m_context.env->typeEquals(_generatedType, type); }))
{
m_context.generatedFunctions.insert(function);
code << generate(*function.function, function.type);
m_context.generatedFunctions[function].emplace_back(type);
code << generate(*function, type);
}
}

View File

@ -99,8 +99,7 @@ private:
solAssert(varDecl, "External reference in inline assembly to something that is not a variable declaration.");
auto type = m_context.analysis.annotation<TypeInference>(*varDecl).type;
solAssert(type);
type = m_context.env->resolve(*type);
solAssert(*type == m_context.analysis.typeSystem().type(BuiltinType::Word, {}));
solAssert(m_context.env->typeEquals(*type, m_context.analysis.typeSystem().type(BuiltinType::Word, {})));
string value = IRNames::localVariable(*varDecl);
return yul::Identifier{_identifier.debugData, yul::YulString{value}};
}