Remove circular deps

This commit is contained in:
Bhargava Shastry 2021-05-19 10:38:00 +02:00
parent f234c8e53f
commit c5f92c6bdc
2 changed files with 49 additions and 39 deletions

View File

@ -27,7 +27,6 @@
#include <boost/range/algorithm/copy.hpp> #include <boost/range/algorithm/copy.hpp>
using namespace solidity::test::fuzzer; using namespace solidity::test::fuzzer;
using namespace solidity::test::fuzzer::mutator; using namespace solidity::test::fuzzer::mutator;
using namespace solidity::util; using namespace solidity::util;
@ -38,6 +37,20 @@ GeneratorBase::GeneratorBase(SolidityGenerator* _mutator): state(_mutator->testS
mutator = _mutator; mutator = _mutator;
} }
template <typename T>
std::shared_ptr<T> GeneratorBase::generator()
{
for (auto& g: generators)
if (std::holds_alternative<std::shared_ptr<T>>(g.first))
return std::get<std::shared_ptr<T>>(g.first);
solAssert(false, "");
}
void GeneratorBase::addGenerators(set<pair<GeneratorPtr, unsigned>>&& _generators)
{
generators = std::move(_generators);
}
string GeneratorBase::visitChildren() string GeneratorBase::visitChildren()
{ {
ostringstream os; ostringstream os;
@ -120,9 +133,8 @@ string TestState::randomNonCurrentPath() const
void TestCaseGenerator::setup() void TestCaseGenerator::setup()
{ {
addGenerators({ set<pair<GeneratorPtr, unsigned>> dependsOn = {{mutator->generator<SourceUnitGenerator>(), s_maxSourceUnits}};
{mutator->generator<SourceUnitGenerator>(), s_maxSourceUnits} addGenerators(std::move(dependsOn));
});
} }
string TestCaseGenerator::visit() string TestCaseGenerator::visit()
@ -132,12 +144,13 @@ string TestCaseGenerator::visit()
void SourceUnitGenerator::setup() void SourceUnitGenerator::setup()
{ {
addGenerators({ set<pair<GeneratorPtr, unsigned>> dependsOn = {
{mutator->generator<ImportGenerator>(), s_maxImports}, {mutator->generator<ImportGenerator>(), s_maxImports},
{mutator->generator<PragmaGenerator>(), 1}, {mutator->generator<PragmaGenerator>(), 1},
{mutator->generator<ContractGenerator>(), 1}, {mutator->generator<ContractGenerator>(), 1},
{mutator->generator<FunctionGenerator>(), s_maxFreeFunctions} {mutator->generator<FunctionGenerator>(), s_maxFreeFunctions}
}); };
addGenerators(std::move(dependsOn));
} }
string SourceUnitGenerator::visit() string SourceUnitGenerator::visit()
@ -207,9 +220,8 @@ string ImportGenerator::visit()
void ContractGenerator::setup() void ContractGenerator::setup()
{ {
addGenerators({ set<pair<GeneratorPtr, unsigned>> dependsOn = {{mutator->generator<FunctionGenerator>(), s_maxFunctions}};
{mutator->generator<FunctionGenerator>(), s_maxFunctions} addGenerators(std::move(dependsOn));
});
} }
string ContractGenerator::visit() string ContractGenerator::visit()
@ -415,11 +427,12 @@ string AssignmentStmtGenerator::visit()
void StatementGenerator::setup() void StatementGenerator::setup()
{ {
addGenerators({ set<pair<GeneratorPtr, unsigned>> dependsOn = {
{mutator->generator<BlockStmtGenerator>(), 1}, {mutator->generator<BlockStmtGenerator>(), 1},
{mutator->generator<AssignmentStmtGenerator>(), 1}, {mutator->generator<AssignmentStmtGenerator>(), 1},
{mutator->generator<FunctionCallGenerator>(), 1} {mutator->generator<FunctionCallGenerator>(), 1}
}); };
addGenerators(std::move(dependsOn));
} }
string StatementGenerator::visit() string StatementGenerator::visit()
@ -456,9 +469,8 @@ string StatementGenerator::visit()
void BlockStmtGenerator::setup() void BlockStmtGenerator::setup()
{ {
addGenerators({ set<pair<GeneratorPtr, unsigned>> dependsOn = {{mutator->generator<StatementGenerator>(), s_maxStatements}};
{mutator->generator<StatementGenerator>(), s_maxStatements}, addGenerators(std::move(dependsOn));
});
} }
string BlockStmtGenerator::visit() string BlockStmtGenerator::visit()
@ -490,7 +502,8 @@ string BlockStmtGenerator::visit()
void FunctionGenerator::setup() void FunctionGenerator::setup()
{ {
addGenerators({{mutator->generator<BlockStmtGenerator>(), 1}}); set<pair<GeneratorPtr, unsigned>> dependsOn = {{mutator->generator<BlockStmtGenerator>(), 1}};
addGenerators(std::move(dependsOn));
} }
string FunctionGenerator::visit() string FunctionGenerator::visit()
@ -1281,6 +1294,17 @@ SolidityGenerator::SolidityGenerator(unsigned _seed)
m_state = make_shared<TestState>(m_urd); m_state = make_shared<TestState>(m_urd);
} }
SolidityGenerator::~SolidityGenerator()
{
for (auto& g: m_generators)
std::visit(GenericVisitor{
[&](auto const& _item) { return _item->teardown(); }
}, g);
m_generators.clear();
m_urd.reset();
m_state.reset();
}
template <size_t I> template <size_t I>
void SolidityGenerator::createGenerators() void SolidityGenerator::createGenerators()
{ {

View File

@ -413,7 +413,6 @@ struct SourceState
importedSources.clear(); importedSources.clear();
freeFunctions.clear(); freeFunctions.clear();
exports.clear(); exports.clear();
uRandDist.reset();
} }
/// Prints source state to @param _os. /// Prints source state to @param _os.
void print(std::ostream& _os) const; void print(std::ostream& _os) const;
@ -494,7 +493,6 @@ struct ContractState
~ContractState() ~ContractState()
{ {
functions.clear(); functions.clear();
uRandDist.reset();
} }
void addFunction(std::shared_ptr<FunctionState> _function) void addFunction(std::shared_ptr<FunctionState> _function)
{ {
@ -649,7 +647,6 @@ struct TestState
sourceUnitState.clear(); sourceUnitState.clear();
contractState.clear(); contractState.clear();
functionState.clear(); functionState.clear();
uRandDist.reset();
} }
/// Prints test state to @param _os. /// Prints test state to @param _os.
void print(std::ostream& _os) const; void print(std::ostream& _os) const;
@ -842,12 +839,7 @@ class SolidityGenerator
public: public:
explicit SolidityGenerator(unsigned _seed); explicit SolidityGenerator(unsigned _seed);
~SolidityGenerator() ~SolidityGenerator();
{
m_generators.clear();
m_urd.reset();
m_state.reset();
}
/// @returns the generator of type @param T. /// @returns the generator of type @param T.
template <typename T> template <typename T>
@ -869,8 +861,7 @@ private:
template <typename T> template <typename T>
void createGenerator() void createGenerator()
{ {
auto generator = std::make_shared<T>(this); m_generators.emplace(std::make_shared<T>(this));
m_generators.insert(std::move(generator));
} }
template <std::size_t I = 0> template <std::size_t I = 0>
void createGenerators(); void createGenerators();
@ -886,13 +877,8 @@ struct GeneratorBase
{ {
explicit GeneratorBase(SolidityGenerator* _mutator); explicit GeneratorBase(SolidityGenerator* _mutator);
template <typename T> template <typename T>
std::shared_ptr<T> generator() std::shared_ptr<T> generator();
{
for (auto& g: generators)
if (std::holds_alternative<std::shared_ptr<T>>(g.first))
return std::get<std::shared_ptr<T>>(g.first);
solAssert(false, "");
}
/// @returns test fragment created by this generator. /// @returns test fragment created by this generator.
std::string generate() std::string generate()
{ {
@ -918,20 +904,20 @@ struct GeneratorBase
std::string visitChildren(); std::string visitChildren();
/// Adds generators for child grammar elements of /// Adds generators for child grammar elements of
/// this grammar element. /// this grammar element.
void addGenerators(std::set<std::pair<GeneratorPtr, unsigned>> _generators) void addGenerators(std::set<std::pair<GeneratorPtr, unsigned>>&& _generators);
{
generators += std::move(_generators);
}
/// Virtual method to obtain string name of generator. /// Virtual method to obtain string name of generator.
virtual std::string name() = 0; virtual std::string name() { return {}; }
/// Virtual method to add generators that this grammar /// Virtual method to add generators that this grammar
/// element depends on. If not overridden, there are /// element depends on. If not overridden, there are
/// no dependencies. /// no dependencies.
virtual void setup() {} virtual void setup() {}
virtual ~GeneratorBase() /// Remove generators.
void teardown()
{ {
generators.clear(); generators.clear();
} }
virtual ~GeneratorBase() {}
std::shared_ptr<UniformRandomDistribution>& uRandDist() std::shared_ptr<UniformRandomDistribution>& uRandDist()
{ {
return mutator->uniformRandomDist(); return mutator->uniformRandomDist();