mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #13733 from ethereum/eofSetting
Add experimental EOF options for CLI and Standard JSON.
This commit is contained in:
commit
eb2f874eac
@ -97,6 +97,7 @@ pair<string, string> IRGenerator::run(
|
||||
|
||||
yul::YulStack asmStack(
|
||||
m_evmVersion,
|
||||
m_eofVersion,
|
||||
yul::YulStack::Language::StrictAssembly,
|
||||
m_optimiserSettings,
|
||||
m_context.debugInfoSelection()
|
||||
|
@ -46,6 +46,7 @@ public:
|
||||
|
||||
IRGenerator(
|
||||
langutil::EVMVersion _evmVersion,
|
||||
std::optional<uint8_t> _eofVersion,
|
||||
RevertStrings _revertStrings,
|
||||
OptimiserSettings _optimiserSettings,
|
||||
std::map<std::string, unsigned> _sourceIndices,
|
||||
@ -53,6 +54,7 @@ public:
|
||||
langutil::CharStreamProvider const* _soliditySourceProvider
|
||||
):
|
||||
m_evmVersion(_evmVersion),
|
||||
m_eofVersion(_eofVersion),
|
||||
m_optimiserSettings(_optimiserSettings),
|
||||
m_context(
|
||||
_evmVersion,
|
||||
@ -138,6 +140,7 @@ private:
|
||||
std::string dispenseLocationComment(ASTNode const& _node);
|
||||
|
||||
langutil::EVMVersion const m_evmVersion;
|
||||
std::optional<uint8_t> const m_eofVersion;
|
||||
OptimiserSettings const m_optimiserSettings;
|
||||
|
||||
IRGenerationContext m_context;
|
||||
|
@ -225,6 +225,15 @@ void CompilerStack::setEVMVersion(langutil::EVMVersion _version)
|
||||
m_evmVersion = _version;
|
||||
}
|
||||
|
||||
void CompilerStack::setEOFVersion(std::optional<uint8_t> _version)
|
||||
{
|
||||
if (m_stackState >= CompilationSuccessful)
|
||||
solThrow(CompilerError, "Must set EOF version before compiling.");
|
||||
if (_version && _version != 1)
|
||||
solThrow(CompilerError, "Invalid EOF version.");
|
||||
m_eofVersion = _version;
|
||||
}
|
||||
|
||||
void CompilerStack::setModelCheckerSettings(ModelCheckerSettings _settings)
|
||||
{
|
||||
if (m_stackState >= ParsedAndImported)
|
||||
@ -1308,6 +1317,7 @@ void CompilerStack::compileContract(
|
||||
)
|
||||
{
|
||||
solAssert(!m_viaIR, "");
|
||||
solUnimplementedAssert(!m_eofVersion.has_value(), "Experimental EOF support is only available for via-IR compilation.");
|
||||
solAssert(m_stackState >= AnalysisPerformed, "");
|
||||
if (m_hasError)
|
||||
solThrow(CompilerError, "Called compile with errors.");
|
||||
@ -1373,7 +1383,15 @@ void CompilerStack::generateIR(ContractDefinition const& _contract)
|
||||
for (auto const& pair: m_contracts)
|
||||
otherYulSources.emplace(pair.second.contract, pair.second.yulIR);
|
||||
|
||||
IRGenerator generator(m_evmVersion, m_revertStrings, m_optimiserSettings, sourceIndices(), m_debugInfoSelection, this);
|
||||
IRGenerator generator(
|
||||
m_evmVersion,
|
||||
m_eofVersion,
|
||||
m_revertStrings,
|
||||
m_optimiserSettings,
|
||||
sourceIndices(),
|
||||
m_debugInfoSelection,
|
||||
this
|
||||
);
|
||||
tie(compiledContract.yulIR, compiledContract.yulIROptimized) = generator.run(
|
||||
_contract,
|
||||
createCBORMetadata(compiledContract, /* _forIR */ true),
|
||||
@ -1398,6 +1416,7 @@ void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract)
|
||||
// Re-parse the Yul IR in EVM dialect
|
||||
yul::YulStack stack(
|
||||
m_evmVersion,
|
||||
m_eofVersion,
|
||||
yul::YulStack::Language::StrictAssembly,
|
||||
m_optimiserSettings,
|
||||
m_debugInfoSelection
|
||||
@ -1430,6 +1449,7 @@ void CompilerStack::generateEwasm(ContractDefinition const& _contract)
|
||||
// Re-parse the Yul IR in EVM dialect
|
||||
yul::YulStack stack(
|
||||
m_evmVersion,
|
||||
m_eofVersion,
|
||||
yul::YulStack::Language::StrictAssembly,
|
||||
m_optimiserSettings,
|
||||
m_debugInfoSelection
|
||||
@ -1580,6 +1600,8 @@ string CompilerStack::createMetadata(Contract const& _contract, bool _forIR) con
|
||||
if (_forIR)
|
||||
meta["settings"]["viaIR"] = _forIR;
|
||||
meta["settings"]["evmVersion"] = m_evmVersion.name();
|
||||
if (m_eofVersion.has_value())
|
||||
meta["settings"]["eofVersion"] = *m_eofVersion;
|
||||
meta["settings"]["compilationTarget"][_contract.contract->sourceUnitName()] =
|
||||
*_contract.contract->annotation().canonicalName;
|
||||
|
||||
@ -1704,7 +1726,7 @@ bytes CompilerStack::createCBORMetadata(Contract const& _contract, bool _forIR)
|
||||
else
|
||||
solAssert(m_metadataHash == MetadataHash::None, "Invalid metadata hash");
|
||||
|
||||
if (experimentalMode)
|
||||
if (experimentalMode || m_eofVersion.has_value())
|
||||
encoder.pushBool("experimental", true);
|
||||
if (m_metadataFormat == MetadataFormat::WithReleaseVersionTag)
|
||||
encoder.pushBytes("solc", VersionCompactBytes);
|
||||
|
@ -181,6 +181,10 @@ public:
|
||||
/// Must be set before parsing.
|
||||
void setEVMVersion(langutil::EVMVersion _version = langutil::EVMVersion{});
|
||||
|
||||
/// Set the EOF version used before running compile.
|
||||
/// If set to std::nullopt (the default), legacy non-EOF bytecode is generated.
|
||||
void setEOFVersion(std::optional<uint8_t> version);
|
||||
|
||||
/// Set model checker settings.
|
||||
void setModelCheckerSettings(ModelCheckerSettings _settings);
|
||||
|
||||
@ -498,6 +502,7 @@ private:
|
||||
State m_stopAfter = State::CompilationSuccessful;
|
||||
bool m_viaIR = false;
|
||||
langutil::EVMVersion m_evmVersion;
|
||||
std::optional<uint8_t> m_eofVersion;
|
||||
ModelCheckerSettings m_modelCheckerSettings;
|
||||
std::map<std::string, std::set<std::string>> m_requestedContractNames;
|
||||
bool m_generateEvmBytecode = true;
|
||||
|
@ -800,6 +800,16 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
|
||||
ret.evmVersion = *version;
|
||||
}
|
||||
|
||||
if (settings.isMember("eofVersion"))
|
||||
{
|
||||
if (!settings["eofVersion"].isUInt())
|
||||
return formatFatalError(Error::Type::JSONError, "eofVersion must be an unsigned integer.");
|
||||
auto eofVersion = settings["evmVersion"].asUInt();
|
||||
if (eofVersion != 1)
|
||||
return formatFatalError(Error::Type::JSONError, "Invalid EOF version requested.");
|
||||
ret.eofVersion = 1;
|
||||
}
|
||||
|
||||
if (settings.isMember("debug"))
|
||||
{
|
||||
if (auto result = checkKeys(settings["debug"], {"revertStrings", "debugInfo"}, "settings.debug"))
|
||||
@ -1413,6 +1423,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
|
||||
|
||||
YulStack stack(
|
||||
_inputsAndSettings.evmVersion,
|
||||
_inputsAndSettings.eofVersion,
|
||||
YulStack::Language::StrictAssembly,
|
||||
_inputsAndSettings.optimiserSettings,
|
||||
_inputsAndSettings.debugInfoSelection.has_value() ?
|
||||
|
@ -77,6 +77,7 @@ private:
|
||||
std::map<std::string, std::string> sources;
|
||||
std::map<util::h256, std::string> smtLib2Responses;
|
||||
langutil::EVMVersion evmVersion;
|
||||
std::optional<uint8_t> eofVersion;
|
||||
std::vector<ImportRemapper::Remapping> remappings;
|
||||
RevertStrings revertStrings = RevertStrings::Default;
|
||||
OptimiserSettings optimiserSettings = OptimiserSettings::minimal();
|
||||
|
@ -164,7 +164,7 @@ void YulStack::compileEVM(AbstractAssembly& _assembly, bool _optimize) const
|
||||
break;
|
||||
}
|
||||
|
||||
EVMObjectCompiler::compile(*m_parserResult, _assembly, *dialect, _optimize);
|
||||
EVMObjectCompiler::compile(*m_parserResult, _assembly, *dialect, _optimize, m_eofVersion);
|
||||
}
|
||||
|
||||
void YulStack::optimize(Object& _object, bool _isCreation)
|
||||
|
@ -72,6 +72,7 @@ public:
|
||||
YulStack():
|
||||
YulStack(
|
||||
langutil::EVMVersion{},
|
||||
std::nullopt,
|
||||
Language::Assembly,
|
||||
solidity::frontend::OptimiserSettings::none(),
|
||||
langutil::DebugInfoSelection::Default()
|
||||
@ -80,12 +81,14 @@ public:
|
||||
|
||||
YulStack(
|
||||
langutil::EVMVersion _evmVersion,
|
||||
std::optional<uint8_t> _eofVersion,
|
||||
Language _language,
|
||||
solidity::frontend::OptimiserSettings _optimiserSettings,
|
||||
langutil::DebugInfoSelection const& _debugInfoSelection
|
||||
):
|
||||
m_language(_language),
|
||||
m_evmVersion(_evmVersion),
|
||||
m_eofVersion(_eofVersion),
|
||||
m_optimiserSettings(std::move(_optimiserSettings)),
|
||||
m_debugInfoSelection(_debugInfoSelection),
|
||||
m_errorReporter(m_errors)
|
||||
@ -146,6 +149,7 @@ private:
|
||||
|
||||
Language m_language = Language::Assembly;
|
||||
langutil::EVMVersion m_evmVersion;
|
||||
std::optional<uint8_t> m_eofVersion;
|
||||
solidity::frontend::OptimiserSettings m_optimiserSettings;
|
||||
langutil::DebugInfoSelection m_debugInfoSelection{};
|
||||
|
||||
|
@ -35,9 +35,15 @@
|
||||
using namespace solidity::yul;
|
||||
using namespace std;
|
||||
|
||||
void EVMObjectCompiler::compile(Object& _object, AbstractAssembly& _assembly, EVMDialect const& _dialect, bool _optimize)
|
||||
void EVMObjectCompiler::compile(
|
||||
Object& _object,
|
||||
AbstractAssembly& _assembly,
|
||||
EVMDialect const& _dialect,
|
||||
bool _optimize,
|
||||
std::optional<uint8_t> _eofVersion
|
||||
)
|
||||
{
|
||||
EVMObjectCompiler compiler(_assembly, _dialect);
|
||||
EVMObjectCompiler compiler(_assembly, _dialect, _eofVersion);
|
||||
compiler.run(_object, _optimize);
|
||||
}
|
||||
|
||||
@ -54,7 +60,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize)
|
||||
auto subAssemblyAndID = m_assembly.createSubAssembly(isCreation, subObject->name.str());
|
||||
context.subIDs[subObject->name] = subAssemblyAndID.second;
|
||||
subObject->subId = subAssemblyAndID.second;
|
||||
compile(*subObject, *subAssemblyAndID.first, m_dialect, _optimize);
|
||||
compile(*subObject, *subAssemblyAndID.first, m_dialect, _optimize, m_eofVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -68,6 +74,11 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize)
|
||||
|
||||
yulAssert(_object.analysisInfo, "No analysis info.");
|
||||
yulAssert(_object.code, "No code.");
|
||||
if (m_eofVersion.has_value())
|
||||
yulAssert(
|
||||
_optimize && (m_dialect.evmVersion() == langutil::EVMVersion()),
|
||||
"Experimental EOF support is only available for optimized via-IR compilation and the most recent EVM version."
|
||||
);
|
||||
if (_optimize && m_dialect.evmVersion().canOverchargeGasForCall())
|
||||
{
|
||||
auto stackErrors = OptimizedEVMCodeTransform::run(
|
||||
|
@ -21,6 +21,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <cstdint>
|
||||
|
||||
namespace solidity::yul
|
||||
{
|
||||
struct Object;
|
||||
@ -30,16 +33,23 @@ struct EVMDialect;
|
||||
class EVMObjectCompiler
|
||||
{
|
||||
public:
|
||||
static void compile(Object& _object, AbstractAssembly& _assembly, EVMDialect const& _dialect, bool _optimize);
|
||||
static void compile(
|
||||
Object& _object,
|
||||
AbstractAssembly& _assembly,
|
||||
EVMDialect const& _dialect,
|
||||
bool _optimize,
|
||||
std::optional<uint8_t> _eofVersion
|
||||
);
|
||||
private:
|
||||
EVMObjectCompiler(AbstractAssembly& _assembly, EVMDialect const& _dialect):
|
||||
m_assembly(_assembly), m_dialect(_dialect)
|
||||
EVMObjectCompiler(AbstractAssembly& _assembly, EVMDialect const& _dialect, std::optional<uint8_t> _eofVersion):
|
||||
m_assembly(_assembly), m_dialect(_dialect), m_eofVersion(_eofVersion)
|
||||
{}
|
||||
|
||||
void run(Object& _object, bool _optimize);
|
||||
|
||||
AbstractAssembly& m_assembly;
|
||||
EVMDialect const& m_dialect;
|
||||
std::optional<uint8_t> m_eofVersion;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -708,6 +708,7 @@ void CommandLineInterface::compile()
|
||||
m_compiler->setLibraries(m_options.linker.libraries);
|
||||
m_compiler->setViaIR(m_options.output.viaIR);
|
||||
m_compiler->setEVMVersion(m_options.output.evmVersion);
|
||||
m_compiler->setEOFVersion(m_options.output.eofVersion);
|
||||
m_compiler->setRevertStringBehaviour(m_options.output.revertStrings);
|
||||
if (m_options.output.debugInfoSelection.has_value())
|
||||
m_compiler->selectDebugInfo(m_options.output.debugInfoSelection.value());
|
||||
@ -1042,6 +1043,7 @@ void CommandLineInterface::assemble(yul::YulStack::Language _language, yul::YulS
|
||||
|
||||
auto& stack = yulStacks[src.first] = yul::YulStack(
|
||||
m_options.output.evmVersion,
|
||||
m_options.output.eofVersion,
|
||||
_language,
|
||||
m_options.optimiserSettings(),
|
||||
m_options.output.debugInfoSelection.has_value() ?
|
||||
|
@ -47,6 +47,7 @@ static string const g_strErrorRecovery = "error-recovery";
|
||||
static string const g_strEVM = "evm";
|
||||
static string const g_strEVMVersion = "evm-version";
|
||||
static string const g_strEwasm = "ewasm";
|
||||
static string const g_strEOFVersion = "experimental-eof-version";
|
||||
static string const g_strViaIR = "via-ir";
|
||||
static string const g_strExperimentalViaIR = "experimental-via-ir";
|
||||
static string const g_strGas = "gas";
|
||||
@ -231,6 +232,7 @@ bool CommandLineOptions::operator==(CommandLineOptions const& _other) const noex
|
||||
output.revertStrings == _other.output.revertStrings &&
|
||||
output.debugInfoSelection == _other.output.debugInfoSelection &&
|
||||
output.stopAfter == _other.output.stopAfter &&
|
||||
output.eofVersion == _other.output.eofVersion &&
|
||||
input.mode == _other.input.mode &&
|
||||
assembly.targetMachine == _other.assembly.targetMachine &&
|
||||
assembly.inputLanguage == _other.assembly.inputLanguage &&
|
||||
@ -509,9 +511,11 @@ void CommandLineParser::parseOutputSelection()
|
||||
"The following outputs are not supported in " + g_inputModeName.at(m_options.input.mode) + " mode: " +
|
||||
joinOptionNames(unsupportedOutputs) + "."
|
||||
);
|
||||
|
||||
// TODO: restrict EOF version to correct EVM version.
|
||||
}
|
||||
|
||||
po::options_description CommandLineParser::optionsDescription()
|
||||
po::options_description CommandLineParser::optionsDescription(bool _forHelp)
|
||||
{
|
||||
// Declare the supported options.
|
||||
po::options_description desc((R"(solc, the Solidity commandline compiler.
|
||||
@ -588,6 +592,18 @@ General Information)").c_str(),
|
||||
"Select desired EVM version. Either homestead, tangerineWhistle, spuriousDragon, "
|
||||
"byzantium, constantinople, petersburg, istanbul, berlin, london or paris."
|
||||
)
|
||||
;
|
||||
if (!_forHelp) // Note: We intentionally keep this undocumented for now.
|
||||
outputOptions.add_options()
|
||||
(
|
||||
g_strEOFVersion.c_str(),
|
||||
// Declared as uint64_t, since uint8_t will be parsed as character by boost.
|
||||
po::value<uint64_t>()->value_name("version")->implicit_value(1),
|
||||
"Select desired EOF version. Currently the only valid value is 1. "
|
||||
"If not specified, legacy non-EOF bytecode will be generated."
|
||||
)
|
||||
;
|
||||
outputOptions.add_options()
|
||||
(
|
||||
g_strExperimentalViaIR.c_str(),
|
||||
"Deprecated synonym of --via-ir."
|
||||
@ -1113,6 +1129,15 @@ void CommandLineParser::processArgs()
|
||||
m_options.output.evmVersion = *versionOption;
|
||||
}
|
||||
|
||||
if (m_args.count(g_strEOFVersion))
|
||||
{
|
||||
// Request as uint64_t, since uint8_t will be parsed as character by boost.
|
||||
uint64_t versionOption = m_args[g_strEOFVersion].as<uint64_t>();
|
||||
if (versionOption != 1)
|
||||
solThrow(CommandLineValidationError, "Invalid option for --" + g_strEOFVersion + ": " + to_string(versionOption));
|
||||
m_options.output.eofVersion = 1;
|
||||
}
|
||||
|
||||
m_options.optimizer.enabled = (m_args.count(g_strOptimize) > 0);
|
||||
m_options.optimizer.noOptimizeYul = (m_args.count(g_strNoOptimizeYul) > 0);
|
||||
if (!m_args[g_strOptimizeRuns].defaulted())
|
||||
|
@ -186,6 +186,7 @@ struct CommandLineOptions
|
||||
RevertStrings revertStrings = RevertStrings::Default;
|
||||
std::optional<langutil::DebugInfoSelection> debugInfoSelection;
|
||||
CompilerStack::State stopAfter = CompilerStack::State::CompilationSuccessful;
|
||||
std::optional<uint8_t> eofVersion;
|
||||
} output;
|
||||
|
||||
struct
|
||||
@ -247,12 +248,12 @@ public:
|
||||
|
||||
CommandLineOptions const& options() const { return m_options; }
|
||||
|
||||
static void printHelp(std::ostream& _out) { _out << optionsDescription(); }
|
||||
static void printHelp(std::ostream& _out) { _out << optionsDescription(true /* _forHelp */); }
|
||||
|
||||
private:
|
||||
/// @returns a specification of all named command-line options accepted by the compiler.
|
||||
/// The object can be used to parse command-line arguments or to generate the help screen.
|
||||
static boost::program_options::options_description optionsDescription();
|
||||
static boost::program_options::options_description optionsDescription(bool _forHelp = false);
|
||||
|
||||
/// @returns a specification of all positional command-line arguments accepted by the compiler.
|
||||
/// The object can be used to parse command-line arguments or to generate the help screen.
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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() :
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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,
|
||||
|
@ -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&)
|
||||
{
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user