From 60bfab0a4384ab44680ae30255514d0a6fb0c451 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 30 Sep 2024 17:22:41 +0200 Subject: [PATCH] eof: Pass `eofVersion` flag to `EVMDialect` --- libevmasm/Assembly.cpp | 1 + liblangutil/EVMVersion.cpp | 24 +++- liblangutil/EVMVersion.h | 2 +- libsolidity/ast/ASTJsonImporter.cpp | 7 +- libsolidity/ast/ASTJsonImporter.h | 6 +- libsolidity/codegen/Compiler.h | 6 +- libsolidity/codegen/CompilerContext.cpp | 3 +- libsolidity/codegen/CompilerContext.h | 4 + libsolidity/codegen/ContractCompiler.cpp | 1 + libsolidity/interface/CompilerStack.cpp | 9 +- libsolidity/parsing/Parser.cpp | 2 +- libsolidity/parsing/Parser.h | 7 +- libyul/AsmAnalysis.cpp | 3 +- libyul/ObjectOptimizer.cpp | 6 +- libyul/ObjectOptimizer.h | 3 +- libyul/YulStack.cpp | 13 +- libyul/backends/evm/AsmCodeGen.cpp | 3 +- libyul/backends/evm/AsmCodeGen.h | 1 + libyul/backends/evm/EVMDialect.cpp | 17 +-- libyul/backends/evm/EVMDialect.h | 8 +- libyul/backends/evm/NoOutputAssembly.cpp | 2 +- test/libsolidity/Assembly.cpp | 6 +- test/libsolidity/MemoryGuardTest.cpp | 2 +- .../SolidityExpressionCompiler.cpp | 7 +- test/libsolidity/SolidityParser.cpp | 3 +- test/libyul/Common.cpp | 8 +- test/libyul/CompilabilityChecker.cpp | 6 +- test/libyul/ControlFlowSideEffectsTest.cpp | 3 +- test/libyul/EVMCodeTransformTest.cpp | 4 +- test/libyul/FunctionSideEffects.cpp | 3 +- test/libyul/KnowledgeBaseTest.cpp | 3 +- test/libyul/ObjectParser.cpp | 3 +- test/libyul/Parser.cpp | 129 ++++++++++++------ test/libyul/YulInterpreterTest.cpp | 2 +- .../tools/ossfuzz/StackReuseCodegenFuzzer.cpp | 3 +- test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp | 5 +- test/tools/ossfuzz/yulProtoFuzzer.cpp | 3 +- test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp | 9 +- test/tools/yulopti.cpp | 2 +- test/tools/yulrun.cpp | 2 +- tools/yulPhaser/Program.cpp | 3 +- 41 files changed, 226 insertions(+), 108 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index ab26526e14c2..00496a06c415 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1380,6 +1380,7 @@ LinkerObject const& Assembly::assembleEOF() const switch (item.type()) { case Operation: + solAssert(!(item.instruction() >= Instruction::PUSH0 && item.instruction() <= Instruction::PUSH32)); ret.bytecode += assembleOperation(item); break; case Push: diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index 438932a1cdaa..4245938f4e88 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -26,8 +26,11 @@ using namespace solidity; using namespace solidity::evmasm; using namespace solidity::langutil; -bool EVMVersion::hasOpcode(Instruction _opcode) const +bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersion) const { + // EOF version can be only defined since prague + assert(!_eofVersion.has_value() || this->m_version >= prague()); + switch (_opcode) { case Instruction::RETURNDATACOPY: @@ -40,9 +43,9 @@ bool EVMVersion::hasOpcode(Instruction _opcode) const case Instruction::SAR: return hasBitwiseShifting(); case Instruction::CREATE2: - return hasCreate2(); + return !_eofVersion.has_value() && hasCreate2(); case Instruction::EXTCODEHASH: - return hasExtCodeHash(); + return !_eofVersion.has_value() && hasExtCodeHash(); case Instruction::CHAINID: return hasChainID(); case Instruction::SELFBALANCE: @@ -58,6 +61,21 @@ bool EVMVersion::hasOpcode(Instruction _opcode) const case Instruction::TSTORE: case Instruction::TLOAD: return supportsTransientStorage(); + // Instructions below are deprecated in EOF + case Instruction::CALL: + case Instruction::CALLCODE: + case Instruction::DELEGATECALL: + case Instruction::SELFDESTRUCT: + case Instruction::JUMP: + case Instruction::JUMPI: + case Instruction::PC: + case Instruction::CREATE: + case Instruction::CODESIZE: + case Instruction::CODECOPY: + case Instruction::EXTCODESIZE: + case Instruction::EXTCODECOPY: + case Instruction::GAS: + return !_eofVersion.has_value(); default: return true; } diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index 774268917483..3d58fed43709 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -124,7 +124,7 @@ class EVMVersion: bool hasMcopy() const { return *this >= cancun(); } bool supportsTransientStorage() const { return *this >= cancun(); } - bool hasOpcode(evmasm::Instruction _opcode) const; + bool hasOpcode(evmasm::Instruction _opcode, std::optional _eofVersion) const; /// Whether we have to retain the costs for the call opcode itself (false), /// or whether we can just forward easily all remaining gas (true). diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index 8d72b41f7579..857eabdd01fc 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -720,7 +720,12 @@ ASTPointer ASTJsonImporter::createInlineAssembly(Json const& _no astAssert(evmVersion.has_value(), "Invalid EVM version!"); astAssert(m_evmVersion == evmVersion, "Imported tree evm version differs from configured evm version!"); - yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(evmVersion.value()); + std::optional eofVersion; + if (auto const it = _node.find("eofVersion"); it != _node.end()) + eofVersion = it->get(); + astAssert(m_eofVersion == eofVersion, "Imported tree EOF version differs from configured EOF version!"); + + yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(evmVersion.value(), eofVersion); ASTPointer>> flags; if (_node.contains("flags")) { diff --git a/libsolidity/ast/ASTJsonImporter.h b/libsolidity/ast/ASTJsonImporter.h index 943415df93ca..e4a7c2da3fe9 100644 --- a/libsolidity/ast/ASTJsonImporter.h +++ b/libsolidity/ast/ASTJsonImporter.h @@ -40,8 +40,8 @@ namespace solidity::frontend class ASTJsonImporter { public: - ASTJsonImporter(langutil::EVMVersion _evmVersion) - :m_evmVersion(_evmVersion) + ASTJsonImporter(langutil::EVMVersion _evmVersion, std::optional _eofVersion) + :m_evmVersion(_evmVersion), m_eofVersion(_eofVersion) {} /// Converts the AST from JSON-format to ASTPointer @@ -166,6 +166,8 @@ class ASTJsonImporter std::set m_usedIDs; /// Configured EVM version langutil::EVMVersion m_evmVersion; + /// Configured EOF version. Equals std::nullopt if non-EOF + std::optional m_eofVersion; }; } diff --git a/libsolidity/codegen/Compiler.h b/libsolidity/codegen/Compiler.h index 1267c1a2d92c..63e362e3ff0e 100644 --- a/libsolidity/codegen/Compiler.h +++ b/libsolidity/codegen/Compiler.h @@ -37,10 +37,10 @@ namespace solidity::frontend class Compiler { public: - Compiler(langutil::EVMVersion _evmVersion, RevertStrings _revertStrings, OptimiserSettings _optimiserSettings): + Compiler(langutil::EVMVersion _evmVersion, std::optional _eofVersion, RevertStrings _revertStrings, OptimiserSettings _optimiserSettings): m_optimiserSettings(std::move(_optimiserSettings)), - m_runtimeContext(_evmVersion, _revertStrings), - m_context(_evmVersion, _revertStrings, &m_runtimeContext) + m_runtimeContext(_evmVersion, _eofVersion, _revertStrings), + m_context(_evmVersion, _eofVersion, _revertStrings, &m_runtimeContext) { } /// Compiles a contract. diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 83b4589fe982..ca27b3a28258 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -436,7 +436,7 @@ void CompilerContext::appendInlineAssembly( ErrorList errors; ErrorReporter errorReporter(errors); langutil::CharStream charStream(_assembly, _sourceName); - yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion); + yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion, m_eofVersion); std::optional locationOverride; if (!_system) locationOverride = m_asm->currentSourceLocation(); @@ -522,6 +522,7 @@ void CompilerContext::appendInlineAssembly( analysisInfo, *m_asm, m_evmVersion, + m_eofVersion, identifierAccess.generateCode, _system, _optimiserSettings.optimizeStackAllocation diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 3469ee7d278a..e428be01daea 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -62,11 +62,13 @@ class CompilerContext public: explicit CompilerContext( langutil::EVMVersion _evmVersion, + std::optional _eofVersion, RevertStrings _revertStrings, CompilerContext* _runtimeContext = nullptr ): m_asm(std::make_shared(_evmVersion, _runtimeContext != nullptr, std::nullopt, std::string{})), m_evmVersion(_evmVersion), + m_eofVersion(_eofVersion), m_revertStrings(_revertStrings), m_reservedMemory{0}, m_runtimeContext(_runtimeContext), @@ -78,6 +80,7 @@ class CompilerContext } langutil::EVMVersion const& evmVersion() const { return m_evmVersion; } + std::optional eofVersion() const { return m_eofVersion; } void setUseABICoderV2(bool _value) { m_useABICoderV2 = _value; } bool useABICoderV2() const { return m_useABICoderV2; } @@ -349,6 +352,7 @@ class CompilerContext evmasm::AssemblyPointer m_asm; /// Version of the EVM to compile against. langutil::EVMVersion m_evmVersion; + std::optional m_eofVersion; RevertStrings const m_revertStrings; bool m_useABICoderV2 = false; /// Other already compiled contracts to be used in contract creation calls. diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 5ed6e8f96418..957a33db48e3 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -958,6 +958,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) *analysisInfo, *m_context.assemblyPtr(), m_context.evmVersion(), + m_context.eofVersion(), identifierAccessCodeGen, false, m_optimiserSettings.optimizeStackAllocation diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index a9f2708d8023..c4ea623f0ff3 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -349,7 +349,7 @@ bool CompilerStack::parse() try { - Parser parser{m_errorReporter, m_evmVersion}; + Parser parser{m_errorReporter, m_evmVersion, m_eofVersion}; std::vector sourcesToParse; for (auto const& s: m_sources) @@ -419,7 +419,8 @@ bool CompilerStack::parse() void CompilerStack::importASTs(std::map const& _sources) { solAssert(m_stackState == Empty, "Must call importASTs only before the SourcesSet state."); - std::map> reconstructedSources = ASTJsonImporter(m_evmVersion).jsonToSourceUnit(_sources); + std::map> reconstructedSources = + ASTJsonImporter(m_evmVersion, m_eofVersion).jsonToSourceUnit(_sources); for (auto& src: reconstructedSources) { solUnimplementedAssert(!src.second->experimentalSolidity()); @@ -873,7 +874,7 @@ Json CompilerStack::generatedSources(std::string const& _contractName, bool _run ErrorList errors; ErrorReporter errorReporter(errors); CharStream charStream(source, sourceName); - yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion); + yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion, m_eofVersion); std::shared_ptr parserResult = yul::Parser{errorReporter, dialect}.parse(charStream); solAssert(parserResult); sources[0]["ast"] = yul::AsmJsonConverter{sourceIndex}(parserResult->root()); @@ -1463,7 +1464,7 @@ void CompilerStack::compileContract( Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName()); - std::shared_ptr compiler = std::make_shared(m_evmVersion, m_revertStrings, m_optimiserSettings); + std::shared_ptr compiler = std::make_shared(m_evmVersion, m_eofVersion, m_revertStrings, m_optimiserSettings); solAssert(!m_viaIR, ""); bytes cborEncodedMetadata = createCBORMetadata(compiledContract, /* _forIR */ false); diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 208d7446395b..13303170d6ad 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1448,7 +1448,7 @@ ASTPointer Parser::parseInlineAssembly(ASTPointer con SourceLocation location = currentLocation(); expectToken(Token::Assembly); - yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion); + yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion, m_eofVersion); if (m_scanner->currentToken() == Token::StringLiteral) { if (m_scanner->currentLiteral() != "evmasm") diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index 8f0868ac1172..830df05c27c8 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -40,10 +40,12 @@ class Parser: public langutil::ParserBase public: explicit Parser( langutil::ErrorReporter& _errorReporter, - langutil::EVMVersion _evmVersion + langutil::EVMVersion _evmVersion, + std::optional _eofVersion ): ParserBase(_errorReporter), - m_evmVersion(_evmVersion) + m_evmVersion(_evmVersion), + m_eofVersion(_eofVersion) {} ASTPointer parse(langutil::CharStream& _charStream); @@ -247,6 +249,7 @@ class Parser: public langutil::ParserBase /// Flag that signifies whether '_' is parsed as a PlaceholderStatement or a regular identifier. bool m_insideModifier = false; langutil::EVMVersion m_evmVersion; + std::optional m_eofVersion; /// Counter for the next AST node ID int64_t m_currentNodeID = 0; /// Flag that indicates whether experimental mode is enabled in the current source unit diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 64630fa2bee9..cf8c720f6b36 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -625,7 +625,8 @@ void AsmAnalyzer::expectValidIdentifier(YulName _identifier, SourceLocation cons bool AsmAnalyzer::validateInstructions(std::string const& _instructionIdentifier, langutil::SourceLocation const& _location) { // NOTE: This function uses the default EVM version instead of the currently selected one. - auto const builtin = EVMDialect::strictAssemblyForEVM(EVMVersion{}).builtin(YulName(_instructionIdentifier)); + // TODO: Add EOF support + auto const builtin = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt).builtin(YulName(_instructionIdentifier)); if (builtin && builtin->instruction.has_value()) return validateInstructions(builtin->instruction.value(), _location); else diff --git a/libyul/ObjectOptimizer.cpp b/libyul/ObjectOptimizer.cpp index 3694367c5e32..c99cf73f8f9e 100644 --- a/libyul/ObjectOptimizer.cpp +++ b/libyul/ObjectOptimizer.cpp @@ -43,13 +43,13 @@ using namespace solidity::util; using namespace solidity::yul; -Dialect const& yul::languageToDialect(Language _language, EVMVersion _version) +Dialect const& yul::languageToDialect(Language _language, EVMVersion _version, std::optional _eofVersion) { switch (_language) { case Language::Assembly: case Language::StrictAssembly: - return EVMDialect::strictAssemblyForEVMObjects(_version); + return EVMDialect::strictAssemblyForEVMObjects(_version, _eofVersion); } util::unreachable(); } @@ -77,7 +77,7 @@ void ObjectOptimizer::optimize(Object& _object, Settings const& _settings, bool ); } - Dialect const& dialect = languageToDialect(_settings.language, _settings.evmVersion); + Dialect const& dialect = languageToDialect(_settings.language, _settings.evmVersion, _settings.eofVersion); std::unique_ptr meter; if (EVMDialect const* evmDialect = dynamic_cast(&dialect)) meter = std::make_unique(*evmDialect, _isCreation, _settings.expectedExecutionsPerDeployment); diff --git a/libyul/ObjectOptimizer.h b/libyul/ObjectOptimizer.h index e570d69c4b8a..b2019d36b206 100644 --- a/libyul/ObjectOptimizer.h +++ b/libyul/ObjectOptimizer.h @@ -38,7 +38,7 @@ enum class Language StrictAssembly, }; -Dialect const& languageToDialect(Language _language, langutil::EVMVersion _version); +Dialect const& languageToDialect(Language _language, langutil::EVMVersion _version, std::optional _eofVersion); /// Encapsulates logic for applying @a yul::OptimiserSuite to a whole hierarchy of Yul objects. /// Also, acts as a transparent cache for optimized objects. @@ -58,6 +58,7 @@ class ObjectOptimizer { Language language; langutil::EVMVersion evmVersion; + std::optional eofVersion; bool optimizeStackAllocation; std::string yulOptimiserSteps; std::string yulOptimiserCleanupSteps; diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 67bc6d11a586..8b559e23f46d 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -57,7 +57,7 @@ bool YulStack::parse(std::string const& _sourceName, std::string const& _source) { m_charStream = std::make_unique(_source, _sourceName); std::shared_ptr scanner = std::make_shared(*m_charStream); - m_parserResult = ObjectParser(m_errorReporter, languageToDialect(m_language, m_evmVersion)).parse(scanner, false); + m_parserResult = ObjectParser(m_errorReporter, languageToDialect(m_language, m_evmVersion, m_eofVersion)).parse(scanner, false); } catch (UnimplementedFeatureError const& _error) { @@ -94,7 +94,7 @@ void YulStack::optimize() { if ( !m_optimiserSettings.runYulOptimiser && - yul::MSizeFinder::containsMSize(languageToDialect(m_language, m_evmVersion), *m_parserResult) + yul::MSizeFinder::containsMSize(languageToDialect(m_language, m_evmVersion, m_eofVersion), *m_parserResult) ) return; @@ -130,6 +130,7 @@ void YulStack::optimize() ObjectOptimizer::Settings{ m_language, m_evmVersion, + m_eofVersion, optimizeStackAllocation, yulOptimiserSteps, yulOptimiserCleanupSteps, @@ -163,7 +164,7 @@ bool YulStack::analyzeParsed(Object& _object) AsmAnalyzer analyzer( *_object.analysisInfo, m_errorReporter, - languageToDialect(m_language, m_evmVersion), + languageToDialect(m_language, m_evmVersion, m_eofVersion), {}, _object.qualifiedDataNames() ); @@ -196,7 +197,7 @@ void YulStack::compileEVM(AbstractAssembly& _assembly, bool _optimize) const { case Language::Assembly: case Language::StrictAssembly: - dialect = &EVMDialect::strictAssemblyForEVMObjects(m_evmVersion); + dialect = &EVMDialect::strictAssemblyForEVMObjects(m_evmVersion, m_eofVersion); break; default: yulAssert(false, "Invalid language."); @@ -316,7 +317,7 @@ YulStack::assembleEVMWithDeployed(std::optional _deployName) // it with the minimal steps required to avoid "stack too deep". bool optimize = m_optimiserSettings.optimizeStackAllocation || ( !m_optimiserSettings.runYulOptimiser && - !yul::MSizeFinder::containsMSize(languageToDialect(m_language, m_evmVersion), *m_parserResult) + !yul::MSizeFinder::containsMSize(languageToDialect(m_language, m_evmVersion, m_eofVersion), *m_parserResult) ); try { @@ -385,7 +386,7 @@ Json YulStack::cfgJson() const // NOTE: The block Ids are reset for each object std::unique_ptr controlFlow = SSAControlFlowGraphBuilder::build( *_object.analysisInfo.get(), - languageToDialect(m_language, m_evmVersion), + languageToDialect(m_language, m_evmVersion, m_eofVersion), _object.code()->root() ); YulControlFlowGraphExporter exporter(*controlFlow); diff --git a/libyul/backends/evm/AsmCodeGen.cpp b/libyul/backends/evm/AsmCodeGen.cpp index 645d1fd87bc1..91d06e2f0850 100644 --- a/libyul/backends/evm/AsmCodeGen.cpp +++ b/libyul/backends/evm/AsmCodeGen.cpp @@ -38,6 +38,7 @@ void CodeGenerator::assemble( AsmAnalysisInfo& _analysisInfo, evmasm::Assembly& _assembly, langutil::EVMVersion _evmVersion, + std::optional _eofVersion, ExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen, bool _useNamedLabelsForFunctions, bool _optimizeStackAllocation @@ -49,7 +50,7 @@ void CodeGenerator::assemble( assemblyAdapter, _analysisInfo, _parsedData, - EVMDialect::strictAssemblyForEVM(_evmVersion), + EVMDialect::strictAssemblyForEVM(_evmVersion, _eofVersion), builtinContext, _optimizeStackAllocation, _identifierAccessCodeGen, diff --git a/libyul/backends/evm/AsmCodeGen.h b/libyul/backends/evm/AsmCodeGen.h index b79338074957..d7a6b5c928f5 100644 --- a/libyul/backends/evm/AsmCodeGen.h +++ b/libyul/backends/evm/AsmCodeGen.h @@ -44,6 +44,7 @@ class CodeGenerator AsmAnalysisInfo& _analysisInfo, evmasm::Assembly& _assembly, langutil::EVMVersion _evmVersion, + std::optional _eofVersion, ExternalIdentifierAccess::CodeGenerator _identifierAccess = {}, bool _useNamedLabelsForFunctions = false, bool _optimizeStackAllocation = false diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index dd5cad1dd700..0beec06b51ea 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -177,7 +177,7 @@ std::set createReservedIdentifiers(langutil::EVMVersion _evmVersion) return reserved; } -std::map createBuiltins(langutil::EVMVersion _evmVersion, bool _objectAccess) +std::map createBuiltins(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess) { // Exclude prevrandao as builtin for VMs before paris and difficulty for VMs after paris. @@ -199,7 +199,7 @@ std::map createBuiltins(langutil::EVMVersion _ev opcode != evmasm::Instruction::JUMP && opcode != evmasm::Instruction::JUMPI && opcode != evmasm::Instruction::JUMPDEST && - _evmVersion.hasOpcode(opcode) && + _evmVersion.hasOpcode(opcode, _eofVersion) && !prevRandaoException(name) ) builtins.emplace(createEVMFunction(_evmVersion, name, opcode)); @@ -355,10 +355,11 @@ std::regex const& verbatimPattern() } -EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, bool _objectAccess): +EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess): m_objectAccess(_objectAccess), m_evmVersion(_evmVersion), - m_functions(createBuiltins(_evmVersion, _objectAccess)), + m_eofVersion(_eofVersion), + m_functions(createBuiltins(_evmVersion, _eofVersion, _objectAccess)), m_reserved(createReservedIdentifiers(_evmVersion)) { } @@ -386,21 +387,21 @@ bool EVMDialect::reservedIdentifier(YulName _name) const return m_reserved.count(_name) != 0; } -EVMDialect const& EVMDialect::strictAssemblyForEVM(langutil::EVMVersion _version) +EVMDialect const& EVMDialect::strictAssemblyForEVM(langutil::EVMVersion _version, std::optional _eofVersion) { static std::map> dialects; static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }}; if (!dialects[_version]) - dialects[_version] = std::make_unique(_version, false); + dialects[_version] = std::make_unique(_version, _eofVersion, false); return *dialects[_version]; } -EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _version) +EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _version, std::optional _eofVersion) { static std::map> dialects; static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }}; if (!dialects[_version]) - dialects[_version] = std::make_unique(_version, true); + dialects[_version] = std::make_unique(_version, _eofVersion, true); return *dialects[_version]; } diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 3627a7fea9b7..30bce5d15ba1 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -65,7 +65,7 @@ struct BuiltinFunctionForEVM: public BuiltinFunction struct EVMDialect: public Dialect { /// Constructor, should only be used internally. Use the factory functions below. - EVMDialect(langutil::EVMVersion _evmVersion, bool _objectAccess); + EVMDialect(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess); /// @returns the builtin function of the given name or a nullptr if it is not a builtin function. BuiltinFunctionForEVM const* builtin(YulName _name) const override; @@ -82,10 +82,11 @@ struct EVMDialect: public Dialect BuiltinFunctionForEVM const* storageLoadFunction() const override { return builtin("sload"_yulname); } YulName hashFunction() const override { return "keccak256"_yulname; } - static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _version); - static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _version); + static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _version,std::optional _eofVersion); + static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _version, std::optional _eofVersion); langutil::EVMVersion evmVersion() const { return m_evmVersion; } + std::optional eofVersion() const { return m_eofVersion; } bool providesObjectAccess() const { return m_objectAccess; } @@ -96,6 +97,7 @@ struct EVMDialect: public Dialect bool const m_objectAccess; langutil::EVMVersion const m_evmVersion; + std::optional m_eofVersion; std::map m_functions; std::map, std::shared_ptr> mutable m_verbatimFunctions; std::set m_reserved; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 04324fa06204..c444a71435c0 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -130,7 +130,7 @@ void NoOutputAssembly::appendImmutableAssignment(std::string const&) } NoOutputEVMDialect::NoOutputEVMDialect(EVMDialect const& _copyFrom): - EVMDialect(_copyFrom.evmVersion(), _copyFrom.providesObjectAccess()) + EVMDialect(_copyFrom.evmVersion(), _copyFrom.eofVersion(), _copyFrom.providesObjectAccess()) { for (auto& fun: m_functions) { diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp index 03897c454c37..19b55a803fe6 100644 --- a/test/libsolidity/Assembly.cpp +++ b/test/libsolidity/Assembly.cpp @@ -56,7 +56,10 @@ evmasm::AssemblyItems compileContract(std::shared_ptr _sourceCode) { ErrorList errors; ErrorReporter errorReporter(errors); - Parser parser(errorReporter, solidity::test::CommonOptions::get().evmVersion()); + Parser parser( + errorReporter, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); ASTPointer sourceUnit; BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(*_sourceCode)); BOOST_CHECK(!!sourceUnit); @@ -86,6 +89,7 @@ evmasm::AssemblyItems compileContract(std::shared_ptr _sourceCode) { Compiler compiler( solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion(), RevertStrings::Default, solidity::test::CommonOptions::get().optimize ? OptimiserSettings::standard() : OptimiserSettings::minimal() ); diff --git a/test/libsolidity/MemoryGuardTest.cpp b/test/libsolidity/MemoryGuardTest.cpp index b2e0b75d367a..08a2814c95e3 100644 --- a/test/libsolidity/MemoryGuardTest.cpp +++ b/test/libsolidity/MemoryGuardTest.cpp @@ -62,7 +62,7 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con ErrorList errors; auto [object, analysisInfo] = yul::test::parse( compiler().yulIR(contractName), - EVMDialect::strictAssemblyForEVMObjects(CommonOptions::get().evmVersion()), + EVMDialect::strictAssemblyForEVMObjects(CommonOptions::get().evmVersion(), CommonOptions::get().eofVersion()), errors ); diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp index 4810b01439b2..b636880691c4 100644 --- a/test/libsolidity/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -108,7 +108,11 @@ bytes compileFirstExpression( { ErrorList errors; ErrorReporter errorReporter(errors); - sourceUnit = Parser(errorReporter, solidity::test::CommonOptions::get().evmVersion()).parse(stream); + sourceUnit = Parser( + errorReporter, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ).parse(stream); if (!sourceUnit) return bytes(); } @@ -139,6 +143,7 @@ bytes compileFirstExpression( CompilerContext context( solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion(), RevertStrings::Default ); context.resetVisitedNodes(contract); diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index e0f010c49e17..a0fd1fe94bec 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -44,7 +44,8 @@ ASTPointer parseText(std::string const& _source, ErrorList& auto charStream = CharStream(_source, ""); ASTPointer sourceUnit = Parser( errorReporter, - solidity::test::CommonOptions::get().evmVersion() + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() ).parse(charStream); if (!sourceUnit) return ASTPointer(); diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index 7640e4a5ddf7..7dca3c560beb 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -46,7 +46,10 @@ namespace { Dialect const& defaultDialect() { - return yul::EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion()); + return yul::EVMDialect::strictAssemblyForEVM( + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); } } @@ -105,7 +108,8 @@ std::map const { "evm", [](langutil::EVMVersion _evmVersion) -> yul::Dialect const& - { return yul::EVMDialect::strictAssemblyForEVMObjects(_evmVersion); } + // TODO: Add support for EOF + { return yul::EVMDialect::strictAssemblyForEVMObjects(_evmVersion, std::nullopt); } } }; diff --git a/test/libyul/CompilabilityChecker.cpp b/test/libyul/CompilabilityChecker.cpp index 13788b75f8ff..6c86ac21f32f 100644 --- a/test/libyul/CompilabilityChecker.cpp +++ b/test/libyul/CompilabilityChecker.cpp @@ -38,7 +38,11 @@ std::string check(std::string const& _input) auto parsingResult = yul::test::parse(_input); obj.setCode(parsingResult.first, parsingResult.second); BOOST_REQUIRE(obj.hasCode()); - auto functions = CompilabilityChecker(EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion()), obj, true).stackDeficit; + auto functions = CompilabilityChecker( + EVMDialect::strictAssemblyForEVM( + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ), obj, true).stackDeficit; std::string out; for (auto const& function: functions) out += function.first.str() + ": " + std::to_string(function.second) + " "; diff --git a/test/libyul/ControlFlowSideEffectsTest.cpp b/test/libyul/ControlFlowSideEffectsTest.cpp index 3ad70f5a02ce..50c69b179dd1 100644 --- a/test/libyul/ControlFlowSideEffectsTest.cpp +++ b/test/libyul/ControlFlowSideEffectsTest.cpp @@ -62,8 +62,9 @@ TestCase::TestResult ControlFlowSideEffectsTest::run(std::ostream& _stream, std: if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); + // TODO: Add EOF support ControlFlowSideEffectsCollector sideEffects( - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), obj.code()->root() ); m_obtainedResult.clear(); diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index e54ab9c8f002..23c24ce305fd 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -67,12 +67,14 @@ TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::strin return TestResult::FatalError; } + // TODO: Add EOF support evmasm::Assembly assembly{solidity::test::CommonOptions::get().evmVersion(), false, std::nullopt, {}}; EthAssemblyAdapter adapter(assembly); EVMObjectCompiler::compile( *stack.parserResult(), adapter, - EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}), + // TODO: Make sure that why we cannot pass here solidity::test::CommonOptions::get().evmVersion() and assembly.eofVersion() + EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}, std::nullopt), m_stackOpt, std::nullopt ); diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index 9d6599f42bc1..7a153de7d362 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -88,8 +88,9 @@ TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); + // TODO: Add EOF support std::map functionSideEffects = SideEffectsPropagator::sideEffects( - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), CallGraphGenerator::callGraph(obj.code()->root()) ); diff --git a/test/libyul/KnowledgeBaseTest.cpp b/test/libyul/KnowledgeBaseTest.cpp index 0293f8ee4472..badeb21fe7f9 100644 --- a/test/libyul/KnowledgeBaseTest.cpp +++ b/test/libyul/KnowledgeBaseTest.cpp @@ -63,7 +63,8 @@ class KnowledgeBaseTest return KnowledgeBase([this](YulName _var) { return util::valueOrNullptr(m_values, _var); }); } - EVMDialect m_dialect{EVMVersion{}, true}; + // TODO: Add EOF support + EVMDialect m_dialect{EVMVersion{}, std::nullopt, true}; std::shared_ptr m_object; SSAValueTracker m_ssaValues; std::map m_values; diff --git a/test/libyul/ObjectParser.cpp b/test/libyul/ObjectParser.cpp index b23e530601da..6c84f59102c6 100644 --- a/test/libyul/ObjectParser.cpp +++ b/test/libyul/ObjectParser.cpp @@ -112,7 +112,8 @@ std::tuple, ErrorList> tryGetSourceLocationMapping( ErrorList errors; ErrorReporter reporter(errors); - Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(EVMVersion::berlin()); + // TODO: Add EOF support + Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(EVMVersion::berlin(), std::nullopt); ObjectParser objectParser{reporter, dialect}; CharStream stream(std::move(source), ""); auto object = objectParser.parse(std::make_shared(stream), false); diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 9b8ce42921b6..930a34cf1a04 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -162,7 +162,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_empty_block) auto const sourceText = "/// @src 0:234:543\n" "{}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -180,7 +181,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_with_children) "let z := true\n" "let y := add(1, 2)\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -203,7 +205,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_different_sources) "let z := true\n" "let y := add(1, 2)\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -225,7 +228,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_nested) "/// @src 0:343:434\n" "switch y case 0 {} default {}\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -249,7 +253,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_switch_case) " let z := add(3, 4)\n" "}\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -281,7 +286,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_inherit_into_outer_scope) "let z := true\n" "let y := add(1, 2)\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); @@ -312,7 +318,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_assign_empty) "/// @src 1:1:10\n" "a := true\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); // should still parse BOOST_REQUIRE_EQUAL(2, result->root().statements.size()); @@ -333,7 +340,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_source_index) "let b := true\n" "\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); // should still parse BOOST_REQUIRE(errorList.size() == 1); @@ -353,7 +361,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_1) "/// @src 0:234:2026\n" ":= true\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); @@ -376,7 +385,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_2) 2) } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(1, result->root().statements.size()); @@ -410,7 +420,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_3) mstore(1, 2) // FunctionCall } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(2, result->root().statements.size()); @@ -446,7 +457,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_comments_after_valid) let a := true } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(1, result->root().statements.size()); @@ -465,7 +477,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_suffix) /// @src 0:420:680foo {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -482,7 +495,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_prefix) /// abc@src 0:111:222 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); @@ -496,7 +510,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_unspecified) /// @src -1:-1:-1 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); @@ -510,7 +525,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_non_integer) /// @src a:b:c {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -527,7 +543,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_bad_integer) /// @src 111111111111111111111:222222222222222222222:333333333333333333333 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -548,7 +565,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_ensure_last_match) let x := true } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); @@ -566,7 +584,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_no_whitespace) /// @src 0:111:222@src 1:333:444 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -583,7 +602,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_separated_with_single_s /// @src 0:111:222 @src 1:333:444 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 333, 444); @@ -594,7 +614,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_leading_trailing_whitespace) ErrorList errorList; ErrorReporter reporter(errorList); auto const sourceText = "/// @src 0:111:222 \n{}"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -611,7 +632,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_reference_original_sloc) let x := true } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); @@ -633,7 +655,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets) let y := /** @src 1:96:165 "contract D {..." */ 128 } )~~~"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(result->root().statements.size(), 2); @@ -658,7 +681,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_empty_snippet) /// @src 0:111:222 "" {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -672,7 +696,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_befo /// @src 0:111:222"abc" def {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -689,7 +714,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_afte /// @src 0:111:222 "abc"def {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -703,7 +729,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_no_whites /// @src 0:111:222 "abc"@src 1:333:444 "abc" {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 333, 444); @@ -717,7 +744,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_untermina /// @src 0:111:222 " abc @src 1:333:444 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -735,7 +763,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote) /// {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -752,7 +781,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_snippets_with_hex_comment) /// @src 0:111:222 hex"abc"@src 1:333:444 "abc" {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); // the second source location is not parsed as such, as the hex string isn't interpreted as snippet but @@ -768,7 +798,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_escapes) /// @src 0:111:222 "\n\\x\x\w\uö\xy\z\y\fq" {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -783,7 +814,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote_snippet_with_whitespaces /// @src 1 : 222 : 333 '\x33\u1234\t\n' {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 222, 333); @@ -798,7 +830,8 @@ BOOST_DATA_TEST_CASE(customSourceLocations_scanner_errors_outside_string_lits_ar /// @src 1:222:333 {{}} )", invalid); - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.empty()); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 222, 333); @@ -816,7 +849,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_multi_line_source_loc) /// " @src 0:333:444 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.empty()); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 333, 444); @@ -834,7 +868,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_with_nested_locati let y := /** @src 1:96:165 "function f() internal { \"\/** @src 0:6:7 *\/\"; }" */ 128 } )~~~"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(result->root().statements.size(), 2); @@ -863,7 +898,8 @@ BOOST_AUTO_TEST_CASE(astid) mstore(1, 2) } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_CHECK(result->root().debugData->astID == int64_t(7)); @@ -885,7 +921,8 @@ BOOST_AUTO_TEST_CASE(astid_reset) mstore(1, 2) } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_CHECK(result->root().debugData->astID == int64_t(7)); @@ -903,7 +940,8 @@ BOOST_AUTO_TEST_CASE(astid_multi) /// @src -1:-1:-1 @ast-id 7 @src 1:1:1 @ast-id 8 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_CHECK(result->root().debugData->astID == int64_t(8)); @@ -917,7 +955,8 @@ BOOST_AUTO_TEST_CASE(astid_invalid) /// @src -1:-1:-1 @ast-id abc @src 1:1:1 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -934,7 +973,8 @@ BOOST_AUTO_TEST_CASE(astid_too_large) /// @ast-id 9223372036854775808 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -950,7 +990,8 @@ BOOST_AUTO_TEST_CASE(astid_way_too_large) /// @ast-id 999999999999999999999999999999999999999 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -966,7 +1007,8 @@ BOOST_AUTO_TEST_CASE(astid_not_fully_numeric) /// @ast-id 9x {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -988,7 +1030,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_multiple_src_tags_on_one_line) "\n" " let x := 123\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(result->root().statements.size(), 1); diff --git a/test/libyul/YulInterpreterTest.cpp b/test/libyul/YulInterpreterTest.cpp index 9d4ccd81ba49..343a17b4a4a1 100644 --- a/test/libyul/YulInterpreterTest.cpp +++ b/test/libyul/YulInterpreterTest.cpp @@ -98,7 +98,7 @@ std::string YulInterpreterTest::interpret() { Interpreter::run( state, - EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion()), + EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion(), std::nullopt), m_ast->root(), /*disableExternalCalls=*/ !m_simulateExternalCallsToSelf, /*disableMemoryTracing=*/ false diff --git a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp index a064fcdc80ed..6f603e335d46 100644 --- a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp +++ b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp @@ -105,8 +105,9 @@ DEFINE_PROTO_FUZZER(Program const& _input) YulAssembler assembler{version, std::nullopt, settings, yul_source}; unoptimisedByteCode = assembler.assemble(); auto yulObject = assembler.object(); + // TODO: Add EOF support recursiveFunction = recursiveFunctionExists( - EVMDialect::strictAssemblyForEVMObjects(version), + EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt), *yulObject ); } diff --git a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp index f685aa90da4b..ffeb14702183 100644 --- a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp @@ -87,10 +87,11 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) // such as unused write to memory e.g., // { mstore(0, 1) } // that would be removed by the redundant store eliminator. + // TODO: Add EOF support yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( os1, stack.parserResult()->code()->root(), - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), /*disableMemoryTracing=*/true ); if (yulFuzzerUtil::resourceLimitsExceeded(termReason)) @@ -100,7 +101,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) termReason = yulFuzzerUtil::interpret( os2, stack.parserResult()->code()->root(), - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), /*disableMemoryTracing=*/true ); diff --git a/test/tools/ossfuzz/yulProtoFuzzer.cpp b/test/tools/ossfuzz/yulProtoFuzzer.cpp index cfdb20813007..4e9387f6f51e 100644 --- a/test/tools/ossfuzz/yulProtoFuzzer.cpp +++ b/test/tools/ossfuzz/yulProtoFuzzer.cpp @@ -78,10 +78,11 @@ DEFINE_PROTO_FUZZER(Program const& _input) ) yulAssert(false, "Proto fuzzer generated malformed program"); + // TODO: Add EOF support // Optimize YulOptimizerTestCommon optimizerTest( stack.parserResult(), - EVMDialect::strictAssemblyForEVMObjects(version) + EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt) ); optimizerTest.setStep(optimizerTest.randomOptimiserStep(_input.step())); auto const* astRoot = optimizerTest.run(); diff --git a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp index 13ac4aea8460..eff96f831eaf 100644 --- a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp @@ -87,27 +87,30 @@ DEFINE_PROTO_FUZZER(Program const& _input) // such as unused write to memory e.g., // { mstore(0, 1) } // that would be removed by the redundant store eliminator. + // TODO: Add EOF support yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( os1, stack.parserResult()->code()->root(), - EVMDialect::strictAssemblyForEVMObjects(version), + EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt), /*disableMemoryTracing=*/true ); if (yulFuzzerUtil::resourceLimitsExceeded(termReason)) return; + // TODO: Add EOF support YulOptimizerTestCommon optimizerTest( stack.parserResult(), - EVMDialect::strictAssemblyForEVMObjects(version) + EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt) ); optimizerTest.setStep(optimizerTest.randomOptimiserStep(_input.step())); auto const* astRoot = optimizerTest.run(); yulAssert(astRoot != nullptr, "Optimiser error."); + // TODO: Add EOF support termReason = yulFuzzerUtil::interpret( os2, *astRoot, - EVMDialect::strictAssemblyForEVMObjects(version), + EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt), true ); if (yulFuzzerUtil::resourceLimitsExceeded(termReason)) diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index 13375f827762..cbe0219676fa 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -242,7 +242,7 @@ class YulOpti private: std::shared_ptr m_astRoot; - Dialect const& m_dialect{EVMDialect::strictAssemblyForEVMObjects(EVMVersion{})}; + Dialect const& m_dialect{EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}, std::nullopt)}; std::unique_ptr m_analysisInfo; std::set const m_reservedIdentifiers = {}; NameDispenser m_nameDispenser{m_dialect, m_reservedIdentifiers}; diff --git a/test/tools/yulrun.cpp b/test/tools/yulrun.cpp index e857c26645ee..36d48858620b 100644 --- a/test/tools/yulrun.cpp +++ b/test/tools/yulrun.cpp @@ -87,7 +87,7 @@ void interpret(std::string const& _source, bool _inspect, bool _disableExternalC state.maxTraceSize = 10000; try { - Dialect const& dialect(EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion{})); + Dialect const& dialect(EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion{}, std::nullopt)); if (_inspect) InspectedInterpreter::run(std::make_shared(_source, state), state, dialect, ast->root(), _disableExternalCalls, /*disableMemoryTracing=*/false); diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index 57e1bf2b9342..fa7fbe274c95 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -68,7 +68,8 @@ Program::Program(Program const& program): std::variant Program::load(CharStream& _sourceCode) { // ASSUMPTION: parseSource() rewinds the stream on its own - Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}); + // TODO: Add support for EOF + Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}, std::nullopt); std::variant, ErrorList> astOrErrors = parseObject(dialect, _sourceCode); if (std::holds_alternative(astOrErrors))