Add experimental EOF options for CLI and Standard JSON.

Co-authored-by: Kamil Śliwak <kamil.sliwak@codepoets.it>
This commit is contained in:
Daniel Kirchner
2022-11-23 19:53:44 +01:00
co-authored by Kamil Śliwak
parent 3109ce2dbc
commit bf26d3be5a
38 changed files with 198 additions and 22 deletions
+11 -2
View File
@@ -103,7 +103,9 @@ CommonOptions::CommonOptions(std::string _caption):
void CommonOptions::addOptions()
{
options.add_options()
("evm-version", po::value(&evmVersionString), "which evm version to use")
("evm-version", po::value(&evmVersionString), "which EVM version to use")
// "eof-version" is declared as uint64_t, since uint8_t will be parsed as character by boost.
("eof-version", po::value<uint64_t>()->implicit_value(1u), "which EOF version to use")
("testpath", po::value<fs::path>(&this->testPath)->default_value(solidity::test::testPath()), "path to test files")
("vm", po::value<std::vector<fs::path>>(&vmPaths), "path to evmc library, can be supplied multiple times.")
("ewasm", po::bool_switch(&ewasm)->default_value(ewasm), "tries to automatically find an ewasm vm and enable ewasm test-execution.")
@@ -170,6 +172,14 @@ bool CommonOptions::parse(int argc, char const* const* argv)
auto parsedOptions = cmdLineParser.run();
po::store(parsedOptions, arguments);
po::notify(arguments);
if (arguments.count("eof-version"))
{
// Request as uint64_t, since uint8_t will be parsed as character by boost.
uint64_t eofVersion = arguments["eof-version"].as<uint64_t>();
if (eofVersion != 1)
BOOST_THROW_EXCEPTION(std::runtime_error("Invalid EOF version: " + to_string(eofVersion)));
m_eofVersion = 1;
}
for (auto const& parsedOption: parsedOptions.options)
if (parsedOption.position_key >= 0)
@@ -261,7 +271,6 @@ langutil::EVMVersion CommonOptions::evmVersion() const
return langutil::EVMVersion();
}
CommonOptions const& CommonOptions::get()
{
if (!m_singleton)
+2
View File
@@ -72,6 +72,7 @@ struct CommonOptions
size_t selectedBatch = 0;
langutil::EVMVersion evmVersion() const;
std::optional<uint8_t> eofVersion() const { return m_eofVersion; }
virtual void addOptions();
// @returns true if the program should continue, false if it should exit immediately without
@@ -98,6 +99,7 @@ protected:
private:
std::string evmVersionString;
std::optional<uint8_t> m_eofVersion;
static std::unique_ptr<CommonOptions const> m_singleton;
};
+1
View File
@@ -39,6 +39,7 @@ public:
{
std::string filename;
langutil::EVMVersion evmVersion;
std::optional<uint8_t> eofVersion;
std::vector<boost::filesystem::path> vmPaths;
bool enforceCompileToEwasm = false;
bool enforceGasCost = false;
+3
View File
@@ -62,6 +62,7 @@ std::optional<Error> parseAndReturnFirstError(
{
YulStack stack(
solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion(),
_language,
solidity::frontend::OptimiserSettings::none(),
DebugInfoSelection::None()
@@ -133,6 +134,7 @@ void parsePrintCompare(string const& _source, bool _canWarn = false)
{
YulStack stack(
solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion(),
YulStack::Language::Assembly,
OptimiserSettings::none(),
DebugInfoSelection::None()
@@ -223,6 +225,7 @@ BOOST_AUTO_TEST_CASE(print_string_literal_unicode)
string parsed = "object \"object\" {\n code { let x := \"\\xe1\\xae\\xac\" }\n}\n";
YulStack stack(
solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion(),
YulStack::Language::Assembly,
OptimiserSettings::none(),
DebugInfoSelection::None()
+39
View File
@@ -226,6 +226,45 @@ BOOST_AUTO_TEST_CASE(metadata_stamp_experimental)
}
}
BOOST_AUTO_TEST_CASE(metadata_eof_experimental)
{
// Check that setting an EOF version results in the experimental flag being set.
char const* sourceCode = R"(
pragma solidity >=0.0;
contract test {
function g(function(uint) external returns (uint) x) public {}
}
)";
for (auto metadataFormat: std::set<CompilerStack::MetadataFormat>{
CompilerStack::MetadataFormat::NoMetadata,
CompilerStack::MetadataFormat::WithReleaseVersionTag,
CompilerStack::MetadataFormat::WithPrereleaseVersionTag
})
{
CompilerStack compilerStack;
compilerStack.setMetadataFormat(metadataFormat);
compilerStack.setSources({{"", sourceCode}});
compilerStack.setEVMVersion({});
compilerStack.setViaIR(true);
compilerStack.setEOFVersion(1);
compilerStack.setOptimiserSettings(true);
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
bytes const& bytecode = compilerStack.runtimeObject("test").bytecode;
string const& metadata = compilerStack.metadata("test");
BOOST_CHECK(solidity::test::isValidMetadata(metadata));
auto const cborMetadata = requireParsedCBORMetadata(bytecode, metadataFormat);
if (metadataFormat == CompilerStack::MetadataFormat::NoMetadata)
BOOST_CHECK(cborMetadata.count("experimental") == 0);
else
{
BOOST_CHECK(cborMetadata.count("experimental") == 1);
BOOST_CHECK(cborMetadata.at("experimental") == "true");
}
}
}
BOOST_AUTO_TEST_CASE(metadata_relevant_sources)
{
CompilerStack compilerStack;
+4 -3
View File
@@ -48,12 +48,13 @@ namespace fs = boost::filesystem;
SemanticTest::SemanticTest(
string const& _filename,
langutil::EVMVersion _evmVersion,
optional<uint8_t> _eofVersion,
vector<boost::filesystem::path> const& _vmPaths,
bool _enforceCompileToEwasm,
bool _enforceGasCost,
u256 _enforceGasCostMinValue
):
SolidityExecutionFramework(_evmVersion, _vmPaths, false),
SolidityExecutionFramework(_evmVersion, _eofVersion, _vmPaths, false),
EVMVersionRestrictedTestCase(_filename),
m_sources(m_reader.sources()),
m_lineOffset(m_reader.lineNumber()),
@@ -296,13 +297,13 @@ TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePref
{
TestResult result = TestResult::Success;
if (m_testCaseWantsLegacyRun)
if (m_testCaseWantsLegacyRun && !m_eofVersion.has_value())
result = runTest(_stream, _linePrefix, _formatted, false, false);
if (m_testCaseWantsYulRun && result == TestResult::Success)
result = runTest(_stream, _linePrefix, _formatted, true, false);
if ((m_testCaseWantsEwasmRun || m_enforceCompileToEwasm) && result == TestResult::Success)
if (!m_eofVersion.has_value() && (m_testCaseWantsEwasmRun || m_enforceCompileToEwasm) && result == TestResult::Success)
{
// TODO: Once we have full Ewasm support, we could remove try/catch here.
try
+2
View File
@@ -51,6 +51,7 @@ public:
return std::make_unique<SemanticTest>(
_options.filename,
_options.evmVersion,
_options.eofVersion,
_options.vmPaths,
_options.enforceCompileToEwasm,
_options.enforceGasCost,
@@ -61,6 +62,7 @@ public:
explicit SemanticTest(
std::string const& _filename,
langutil::EVMVersion _evmVersion,
std::optional<uint8_t> _eofVersion,
std::vector<boost::filesystem::path> const& _vmPaths,
bool _enforceCompileToEwasm = false,
bool _enforceGasCost = false,
@@ -58,6 +58,7 @@ bytes SolidityExecutionFramework::multiSourceCompileContract(
m_compiler.setLibraries(_libraryAddresses);
m_compiler.setRevertStringBehaviour(m_revertStrings);
m_compiler.setEVMVersion(m_evmVersion);
m_compiler.setEOFVersion(m_eofVersion);
m_compiler.setOptimiserSettings(m_optimiserSettings);
m_compiler.enableEvmBytecodeGeneration(!m_compileViaYul);
m_compiler.enableIRGeneration(m_compileViaYul);
@@ -102,6 +103,7 @@ bytes SolidityExecutionFramework::multiSourceCompileContract(
yul::YulStack asmStack(
m_evmVersion,
m_eofVersion,
yul::YulStack::Language::StrictAssembly,
optimiserSettings,
DebugInfoSelection::All()
@@ -42,10 +42,12 @@ public:
SolidityExecutionFramework(): m_showMetadata(solidity::test::CommonOptions::get().showMetadata) {}
explicit SolidityExecutionFramework(
langutil::EVMVersion _evmVersion,
std::optional<uint8_t> _eofVersion,
std::vector<boost::filesystem::path> const& _vmPaths,
bool _appendCBORMetadata = true
):
ExecutionFramework(_evmVersion, _vmPaths),
m_eofVersion(_eofVersion),
m_showMetadata(solidity::test::CommonOptions::get().showMetadata),
m_appendCBORMetadata(_appendCBORMetadata)
{}
@@ -82,6 +84,7 @@ public:
static std::string addPreamble(std::string const& _sourceCode);
protected:
using CompilerStack = solidity::frontend::CompilerStack;
std::optional<uint8_t> m_eofVersion;
CompilerStack m_compiler;
bool m_compileViaYul = false;
bool m_compileToEwasm = false;
+1
View File
@@ -57,6 +57,7 @@ pair<shared_ptr<Block>, shared_ptr<yul::AsmAnalysisInfo>> yul::test::parse(strin
{
YulStack stack(
solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion(),
_yul ? YulStack::Language::Yul : YulStack::Language::StrictAssembly,
solidity::test::CommonOptions::get().optimize ?
solidity::frontend::OptimiserSettings::standard() :
+3 -1
View File
@@ -53,6 +53,7 @@ TestCase::TestResult EVMCodeTransformTest::run(ostream& _stream, string const& _
settings.optimizeStackAllocation = m_stackOpt;
YulStack stack(
EVMVersion{},
nullopt,
YulStack::Language::StrictAssembly,
settings,
DebugInfoSelection::All()
@@ -71,7 +72,8 @@ TestCase::TestResult EVMCodeTransformTest::run(ostream& _stream, string const& _
*stack.parserResult(),
adapter,
EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}),
m_stackOpt
m_stackOpt,
nullopt
);
std::ostringstream output;
+1
View File
@@ -82,6 +82,7 @@ bool EwasmTranslationTest::parse(ostream& _stream, string const& _linePrefix, bo
{
m_stack = YulStack(
solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion(),
YulStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::none(),
DebugInfoSelection::All()
+1
View File
@@ -65,6 +65,7 @@ TestCase::TestResult ObjectCompilerTest::run(ostream& _stream, string const& _li
{
YulStack stack(
EVMVersion(),
nullopt,
m_wasm ? YulStack::Language::Ewasm : YulStack::Language::StrictAssembly,
OptimiserSettings::preset(m_optimisationPreset),
DebugInfoSelection::All()
+2
View File
@@ -59,6 +59,7 @@ pair<bool, ErrorList> parse(string const& _source)
{
YulStack asmStack(
solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion(),
YulStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::none(),
DebugInfoSelection::All()
@@ -181,6 +182,7 @@ BOOST_AUTO_TEST_CASE(to_string)
expectation = boost::replace_all_copy(expectation, "\t", " ");
YulStack asmStack(
solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion(),
YulStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::none(),
DebugInfoSelection::All()
+1
View File
@@ -68,6 +68,7 @@ bool YulInterpreterTest::parse(ostream& _stream, string const& _linePrefix, bool
{
YulStack stack(
solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion(),
YulStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::none(),
DebugInfoSelection::All()
+1
View File
@@ -144,6 +144,7 @@ int registerTests(
TestCase::Config config{
fullpath.string(),
solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion(),
solidity::test::CommonOptions::get().vmPaths,
_enforceCompileToEwasm,
solidity::test::CommonOptions::get().enforceGasTest,
+1
View File
@@ -159,6 +159,7 @@ TestTool::Result TestTool::process()
m_test = m_testCaseCreator(TestCase::Config{
m_path.string(),
m_options.evmVersion(),
m_options.eofVersion(),
m_options.vmPaths,
m_options.enforceCompileToEwasm,
m_options.enforceGasTest,
@@ -80,7 +80,7 @@ DEFINE_PROTO_FUZZER(Program const& _input)
bytes unoptimisedByteCode;
try
{
unoptimisedByteCode = YulAssembler{version, settings, yul_source}.assemble();
unoptimisedByteCode = YulAssembler{version, nullopt, settings, yul_source}.assemble();
}
catch (solidity::yul::StackTooDeepError const&)
{
@@ -123,7 +123,7 @@ DEFINE_PROTO_FUZZER(Program const& _input)
bytes optimisedByteCode;
try
{
optimisedByteCode = YulAssembler{version, settings, yul_source}.assemble();
optimisedByteCode = YulAssembler{version, nullopt, settings, yul_source}.assemble();
}
catch (solidity::yul::StackTooDeepError const&)
{
+4 -2
View File
@@ -31,12 +31,14 @@ class YulAssembler
{
public:
YulAssembler(
langutil::EVMVersion _version,
langutil::EVMVersion _evmVersion,
std::optional<uint8_t> _eofVersion,
solidity::frontend::OptimiserSettings _optSettings,
std::string const& _yulSource
):
m_stack(
_version,
_evmVersion,
_eofVersion,
solidity::yul::YulStack::Language::StrictAssembly,
_optSettings,
langutil::DebugInfoSelection::All()
@@ -39,6 +39,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size)
string input(reinterpret_cast<char const*>(_data), _size);
YulStack stack(
langutil::EVMVersion(),
nullopt,
YulStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::full(),
langutil::DebugInfoSelection::All()
@@ -62,6 +62,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size)
YulStack stack(
langutil::EVMVersion(),
nullopt,
YulStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::full(),
DebugInfoSelection::All()
@@ -40,6 +40,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size)
string input(reinterpret_cast<char const*>(_data), _size);
YulStack stack(
langutil::EVMVersion(),
nullopt,
YulStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::full(),
DebugInfoSelection::All()
+1
View File
@@ -64,6 +64,7 @@ DEFINE_PROTO_FUZZER(Program const& _input)
// YulStack entry point
YulStack stack(
version,
nullopt,
YulStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::full(),
DebugInfoSelection::All()
@@ -63,6 +63,7 @@ DEFINE_PROTO_FUZZER(Program const& _input)
// YulStack entry point
YulStack stack(
version,
nullopt,
YulStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::full(),
DebugInfoSelection::All()
+1
View File
@@ -59,6 +59,7 @@ pair<shared_ptr<Block>, shared_ptr<AsmAnalysisInfo>> parse(string const& _source
{
YulStack stack(
langutil::EVMVersion(),
nullopt,
YulStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::none(),
DebugInfoSelection::Default()