diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index 438932a1cdaa..6435e0f15455 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -26,23 +26,26 @@ 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: case Instruction::RETURNDATASIZE: return supportsReturndata(); case Instruction::STATICCALL: - return hasStaticCall(); + return !_eofVersion.has_value() && hasStaticCall(); case Instruction::SHL: case Instruction::SHR: 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/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index 910cc257eb4a..7183c64a3f18 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -664,12 +664,21 @@ bool ASTJsonExporter::visit(InlineAssembly const& _node) for (Json& it: externalReferences | ranges::views::values) externalReferencesJson.emplace_back(std::move(it)); + auto const& evmDialect = dynamic_cast(_node.dialect()); + std::vector> attributes = { std::make_pair("AST", Json(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations().root()))), std::make_pair("externalReferences", std::move(externalReferencesJson)), - std::make_pair("evmVersion", dynamic_cast(_node.dialect()).evmVersion().name()) + std::make_pair("evmVersion", evmDialect.evmVersion().name()) }; + // TODO: Add test in test/linsolidity/ASTJSON/assembly. This requires adding support for eofVersion in ASTJSONTest + if (evmDialect.eofVersion()) + { + solAssert(*evmDialect.eofVersion() > 0); + attributes.push_back(std::make_pair("eofVersion", *evmDialect.eofVersion())); + } + if (_node.flags()) { Json flags = Json::array(); diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index 8d72b41f7579..ee52bf53c27d 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -720,7 +720,16 @@ 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()); + // TODO: Add test in test/linsolidity/ASTJSON/assembly. This requires adding support for eofVersion in ASTJSONTest + std::optional eofVersion; + if (auto const it = _node.find("eofVersion"); it != _node.end()) + { + eofVersion = it->get(); + astAssert(eofVersion > 0); + } + 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/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 83b4589fe982..4a0f636dc974 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, std::nullopt); std::optional locationOverride; if (!_system) locationOverride = m_asm->currentSourceLocation(); @@ -522,6 +522,7 @@ void CompilerContext::appendInlineAssembly( analysisInfo, *m_asm, m_evmVersion, + std::nullopt, identifierAccess.generateCode, _system, _optimiserSettings.optimizeStackAllocation diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 5ed6e8f96418..96b1ea54823d 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(), + std::nullopt, identifierAccessCodeGen, false, m_optimiserSettings.optimizeStackAllocation diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 39977629d69d..c68df205f941 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -357,7 +357,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) @@ -427,7 +427,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()); @@ -896,7 +897,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()); 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..511fc979ddb0 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); @@ -158,6 +158,8 @@ std::optional ObjectOptimizer::calculateCacheKey( rawKey += h256(u256(_settings.expectedExecutionsPerDeployment)).asBytes(); rawKey += FixedHash<1>(uint8_t(_isCreation ? 0 : 1)).asBytes(); rawKey += keccak256(_settings.evmVersion.name()).asBytes(); + yulAssert(!_settings.eofVersion.has_value() || *_settings.eofVersion > 0); + rawKey += FixedHash<1>(uint8_t(_settings.eofVersion ? 0 : *_settings.eofVersion)).asBytes(); rawKey += keccak256(_settings.yulOptimiserSteps).asBytes(); rawKey += keccak256(_settings.yulOptimiserCleanupSteps).asBytes(); 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..6bfdc9cb9de3 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)); @@ -235,113 +235,116 @@ std::map createBuiltins(langutil::EVMVersion _ev }) ); - builtins.emplace(createFunction("datasize", 1, 1, SideEffects{}, {LiteralKind::String}, []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& _context - ) { - yulAssert(_context.currentObject, "No object available."); - yulAssert(_call.arguments.size() == 1, ""); - Expression const& arg = _call.arguments.front(); - YulName const dataName (formatLiteral(std::get(arg))); - if (_context.currentObject->name == dataName.str()) - _assembly.appendAssemblySize(); - else - { - std::vector subIdPath = - _context.subIDs.count(dataName.str()) == 0 ? - _context.currentObject->pathToSubObject(dataName.str()) : - std::vector{_context.subIDs.at(dataName.str())}; - yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); - _assembly.appendDataSize(subIdPath); - } - })); - builtins.emplace(createFunction("dataoffset", 1, 1, SideEffects{}, {LiteralKind::String}, []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& _context - ) { - yulAssert(_context.currentObject, "No object available."); - yulAssert(_call.arguments.size() == 1, ""); - Expression const& arg = _call.arguments.front(); - YulName const dataName (formatLiteral(std::get(arg))); - if (_context.currentObject->name == dataName.str()) - _assembly.appendConstant(0); - else - { - std::vector subIdPath = - _context.subIDs.count(dataName.str()) == 0 ? - _context.currentObject->pathToSubObject(dataName.str()) : - std::vector{_context.subIDs.at(dataName.str())}; - yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); - _assembly.appendDataOffset(subIdPath); - } - })); - builtins.emplace(createFunction( - "datacopy", - 3, - 0, - SideEffects{ - false, // movable - true, // movableApartFromEffects - false, // canBeRemoved - false, // canBeRemovedIfNotMSize - true, // cannotLoop - SideEffects::None, // otherState - SideEffects::None, // storage - SideEffects::Write, // memory - SideEffects::None // transientStorage - }, - {}, - []( - FunctionCall const&, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - _assembly.appendInstruction(evmasm::Instruction::CODECOPY); - } - )); - builtins.emplace(createFunction( - "setimmutable", - 3, - 0, - SideEffects{ - false, // movable - false, // movableApartFromEffects - false, // canBeRemoved - false, // canBeRemovedIfNotMSize - true, // cannotLoop - SideEffects::None, // otherState - SideEffects::None, // storage - SideEffects::Write, // memory - SideEffects::None // transientStorage - }, - {std::nullopt, LiteralKind::String, std::nullopt}, - []( + if (!_eofVersion.has_value()) + { + builtins.emplace(createFunction("datasize", 1, 1, SideEffects{}, {LiteralKind::String}, []( FunctionCall const& _call, AbstractAssembly& _assembly, - BuiltinContext& + BuiltinContext& _context ) { - yulAssert(_call.arguments.size() == 3, ""); - auto const identifier = (formatLiteral(std::get(_call.arguments[1]))); - _assembly.appendImmutableAssignment(identifier); - } - )); - builtins.emplace(createFunction( - "loadimmutable", - 1, - 1, - SideEffects{}, - {LiteralKind::String}, - []( + yulAssert(_context.currentObject, "No object available."); + yulAssert(_call.arguments.size() == 1, ""); + Expression const& arg = _call.arguments.front(); + YulName const dataName (formatLiteral(std::get(arg))); + if (_context.currentObject->name == dataName.str()) + _assembly.appendAssemblySize(); + else + { + std::vector subIdPath = + _context.subIDs.count(dataName.str()) == 0 ? + _context.currentObject->pathToSubObject(dataName.str()) : + std::vector{_context.subIDs.at(dataName.str())}; + yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); + _assembly.appendDataSize(subIdPath); + } + })); + builtins.emplace(createFunction("dataoffset", 1, 1, SideEffects{}, {LiteralKind::String}, []( FunctionCall const& _call, AbstractAssembly& _assembly, - BuiltinContext& + BuiltinContext& _context ) { + yulAssert(_context.currentObject, "No object available."); yulAssert(_call.arguments.size() == 1, ""); - _assembly.appendImmutable(formatLiteral(std::get(_call.arguments.front()))); - } - )); + Expression const& arg = _call.arguments.front(); + YulName const dataName (formatLiteral(std::get(arg))); + if (_context.currentObject->name == dataName.str()) + _assembly.appendConstant(0); + else + { + std::vector subIdPath = + _context.subIDs.count(dataName.str()) == 0 ? + _context.currentObject->pathToSubObject(dataName.str()) : + std::vector{_context.subIDs.at(dataName.str())}; + yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); + _assembly.appendDataOffset(subIdPath); + } + })); + builtins.emplace(createFunction( + "datacopy", + 3, + 0, + SideEffects{ + false, // movable + true, // movableApartFromEffects + false, // canBeRemoved + false, // canBeRemovedIfNotMSize + true, // cannotLoop + SideEffects::None, // otherState + SideEffects::None, // storage + SideEffects::Write, // memory + SideEffects::None // transientStorage + }, + {}, + []( + FunctionCall const&, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + _assembly.appendInstruction(evmasm::Instruction::CODECOPY); + } + )); + builtins.emplace(createFunction( + "setimmutable", + 3, + 0, + SideEffects{ + false, // movable + false, // movableApartFromEffects + false, // canBeRemoved + false, // canBeRemovedIfNotMSize + true, // cannotLoop + SideEffects::None, // otherState + SideEffects::None, // storage + SideEffects::Write, // memory + SideEffects::None // transientStorage + }, + {std::nullopt, LiteralKind::String, std::nullopt}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + yulAssert(_call.arguments.size() == 3, ""); + auto const identifier = (formatLiteral(std::get(_call.arguments[1]))); + _assembly.appendImmutableAssignment(identifier); + } + )); + builtins.emplace(createFunction( + "loadimmutable", + 1, + 1, + SideEffects{}, + {LiteralKind::String}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + yulAssert(_call.arguments.size() == 1, ""); + _assembly.appendImmutable(formatLiteral(std::get(_call.arguments.front()))); + } + )); + } } return builtins; } @@ -355,10 +358,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,22 +390,22 @@ 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 _evmVersion, std::optional _eofVersion) { - static std::map> dialects; + static std::map>, std::unique_ptr> dialects; static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }}; - if (!dialects[_version]) - dialects[_version] = std::make_unique(_version, false); - return *dialects[_version]; + if (!dialects[{_evmVersion, _eofVersion}]) + dialects[{_evmVersion, _eofVersion}] = std::make_unique(_evmVersion, _eofVersion, false); + return *dialects[{_evmVersion, _eofVersion}]; } -EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _version) +EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _evmVersion, std::optional _eofVersion) { - static std::map> dialects; + static std::map>, std::unique_ptr> dialects; static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }}; - if (!dialects[_version]) - dialects[_version] = std::make_unique(_version, true); - return *dialects[_version]; + if (!dialects[{_evmVersion, _eofVersion}]) + dialects[{_evmVersion, _eofVersion}] = std::make_unique(_evmVersion, _eofVersion, true); + return *dialects[{_evmVersion, _eofVersion}]; } SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instruction) diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 3627a7fea9b7..cc064c3a0f1e 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 _evmVersion, std::optional _eofVersion); + static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _evmVersion, 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..bf1e5caf7c04 100644 --- a/test/libsolidity/Assembly.cpp +++ b/test/libsolidity/Assembly.cpp @@ -56,7 +56,11 @@ 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); 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..20983b650990 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(); } 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..6562e1743588 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() + ); } } @@ -101,11 +104,11 @@ std::string yul::test::format(std::string const& _source) namespace { -std::map const validDialects = { +std::map)> const validDialects = { { "evm", - [](langutil::EVMVersion _evmVersion) -> yul::Dialect const& - { return yul::EVMDialect::strictAssemblyForEVMObjects(_evmVersion); } + [](langutil::EVMVersion _evmVersion, std::optional _eofVersion) -> yul::Dialect const& + { return yul::EVMDialect::strictAssemblyForEVMObjects(_evmVersion, _eofVersion); } } }; @@ -118,7 +121,7 @@ std::map const } } -yul::Dialect const& yul::test::dialect(std::string const& _name, langutil::EVMVersion _evmVersion) +yul::Dialect const& yul::test::dialect(std::string const& _name, langutil::EVMVersion _evmVersion, std::optional _eofVersion) { if (!validDialects.count(_name)) BOOST_THROW_EXCEPTION(std::runtime_error{ @@ -129,5 +132,5 @@ yul::Dialect const& yul::test::dialect(std::string const& _name, langutil::EVMVe "." }); - return validDialects.at(_name)(_evmVersion); + return validDialects.at(_name)(_evmVersion, _eofVersion); } diff --git a/test/libyul/Common.h b/test/libyul/Common.h index c87f1c68be17..2255272b6b5e 100644 --- a/test/libyul/Common.h +++ b/test/libyul/Common.h @@ -54,6 +54,6 @@ parse(std::string const& _source, Dialect const& _dialect, langutil::ErrorList& Block disambiguate(std::string const& _source); std::string format(std::string const& _source); -solidity::yul::Dialect const& dialect(std::string const& _name, langutil::EVMVersion _evmVersion); +solidity::yul::Dialect const& dialect(std::string const& _name, langutil::EVMVersion _evmVersion, std::optional _eofVersion); } 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/ControlFlowGraphTest.cpp b/test/libyul/ControlFlowGraphTest.cpp index 0060b850efbb..b7264bc0e96d 100644 --- a/test/libyul/ControlFlowGraphTest.cpp +++ b/test/libyul/ControlFlowGraphTest.cpp @@ -45,7 +45,11 @@ ControlFlowGraphTest::ControlFlowGraphTest(std::string const& _filename): { m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect(dialectName, solidity::test::CommonOptions::get().evmVersion()); + m_dialect = &dialect( + dialectName, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); m_expectation = m_reader.simpleExpectations(); } 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..7ed321cd48e6 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{}, 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/SSAControlFlowGraphTest.cpp b/test/libyul/SSAControlFlowGraphTest.cpp index a316356dbf0f..c0d1e87270ef 100644 --- a/test/libyul/SSAControlFlowGraphTest.cpp +++ b/test/libyul/SSAControlFlowGraphTest.cpp @@ -48,7 +48,11 @@ SSAControlFlowGraphTest::SSAControlFlowGraphTest(std::string const& _filename): { m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect(dialectName, solidity::test::CommonOptions::get().evmVersion()); + m_dialect = &dialect( + dialectName, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); m_expectation = m_reader.simpleExpectations(); } diff --git a/test/libyul/StackLayoutGeneratorTest.cpp b/test/libyul/StackLayoutGeneratorTest.cpp index 9c16eaefc110..f50d2d23b028 100644 --- a/test/libyul/StackLayoutGeneratorTest.cpp +++ b/test/libyul/StackLayoutGeneratorTest.cpp @@ -49,7 +49,11 @@ StackLayoutGeneratorTest::StackLayoutGeneratorTest(std::string const& _filename) { m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect(dialectName, solidity::test::CommonOptions::get().evmVersion()); + m_dialect = &dialect( + dialectName, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); m_expectation = m_reader.simpleExpectations(); } diff --git a/test/libyul/SyntaxTest.cpp b/test/libyul/SyntaxTest.cpp index 7ed87bee450a..aa37e85afdd8 100644 --- a/test/libyul/SyntaxTest.cpp +++ b/test/libyul/SyntaxTest.cpp @@ -75,5 +75,9 @@ SyntaxTest::SyntaxTest(std::string const& _filename, langutil::EVMVersion _evmVe CommonSyntaxTest(_filename, _evmVersion) { std::string dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect(dialectName, solidity::test::CommonOptions::get().evmVersion()); + m_dialect = &dialect( + dialectName, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); } 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/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 7f2f5815a675..308afef5f904 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -56,7 +56,11 @@ YulOptimizerTest::YulOptimizerTest(std::string const& _filename): m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect(dialectName, solidity::test::CommonOptions::get().evmVersion()); + m_dialect = &dialect( + dialectName, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); m_expectation = m_reader.simpleExpectations(); } 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))