diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 1fef003b63f7..68e51cc67d64 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -715,6 +715,7 @@ AssemblyItem Assembly::newFunctionCall(uint16_t _functionID) const AssemblyItem Assembly::newFunctionReturn() const { + solAssert(m_currentCodeSection != 0, "Appending function return without begin function."); return AssemblyItem::functionReturn(m_codeSections.at(m_currentCodeSection).outputs); } @@ -724,13 +725,15 @@ uint16_t Assembly::createFunction(uint8_t _args, uint8_t _rets) solAssert(functionID < 1024, "Too many functions."); solAssert(m_currentCodeSection == 0, "Functions need to be declared from the main block."); solAssert(_rets <= 0x80, "Too many function returns."); + solAssert(_args <= 127, "Too many function inputs."); m_codeSections.emplace_back(CodeSection{_args, _rets, {}}); return static_cast(functionID); } void Assembly::beginFunction(uint16_t _functionID) { - solAssert(m_currentCodeSection == 0, "Atempted to begin a function before ending the last one."); + solAssert(m_currentCodeSection == 0, "Attempted to begin a function before ending the last one."); + solAssert(_functionID != 0, "Attempt to begin a function with id 0"); solAssert(_functionID < m_codeSections.size(), "Attempt to begin an undeclared function."); auto& section = m_codeSections.at(_functionID); solAssert(section.items.empty(), "Function already defined."); @@ -1447,6 +1450,7 @@ LinkerObject const& Assembly::assembleEOF() const for (auto&& [codeSectionIndex, codeSection]: m_codeSections | ranges::views::enumerate) { auto const sectionStart = ret.bytecode.size(); + solAssert(!codeSection.items.empty(), "Empty code section."); for (AssemblyItem const& item: codeSection.items) { // store position of the invalid jump destination diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index 16b9c92f03aa..4b70b4ed9cdb 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -187,7 +187,7 @@ enum class Instruction: uint8_t RJUMP = 0xe0, ///< relative jump RJUMPI = 0xe1, ///< conditional relative jump CALLF = 0xe3, ///< call function in a EOF code section - RETF = 0xe4, ///< return to caller from the code section of EOF continer + RETF = 0xe4, ///< return to caller from the code section of EOF container JUMPF = 0xe5, ///< jump to a code section of EOF container without adding a new return stack frame. EOFCREATE = 0xec, ///< create a new account with associated container code. RETURNCONTRACT = 0xee, ///< return container to be deployed with axiliary data filled in. diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp index 1c6064bfa793..c27945b82e51 100644 --- a/libevmasm/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -304,17 +304,6 @@ bool SemanticInformation::isSwapInstruction(AssemblyItem const& _item) return evmasm::isSwapInstruction(_item.instruction()); } -bool SemanticInformation::isJumpInstruction(AssemblyItem const& _item) -{ - return - _item == Instruction::JUMP || - _item == Instruction::JUMPI || - _item == Instruction::RJUMP || - _item == Instruction::RJUMPI || - _item.type() == RelativeJump || - _item.type() == ConditionalRelativeJump; -} - bool SemanticInformation::altersControlFlow(AssemblyItem const& _item) { if (!_item.hasInstruction()) @@ -404,6 +393,7 @@ bool SemanticInformation::isDeterministic(AssemblyItem const& _item) case Instruction::RETURNDATASIZE: case Instruction::EOFCREATE: case Instruction::CALLF: + case Instruction::JUMPF: return false; default: return true; diff --git a/libevmasm/SemanticInformation.h b/libevmasm/SemanticInformation.h index b62832f238af..457f60052a6a 100644 --- a/libevmasm/SemanticInformation.h +++ b/libevmasm/SemanticInformation.h @@ -82,7 +82,6 @@ struct SemanticInformation static bool isCommutativeOperation(AssemblyItem const& _item); static bool isDupInstruction(AssemblyItem const& _item); static bool isSwapInstruction(AssemblyItem const& _item); - static bool isJumpInstruction(AssemblyItem const& _item); static bool altersControlFlow(AssemblyItem const& _item); static bool terminatesControlFlow(AssemblyItem const& _item); static bool terminatesControlFlow(Instruction _instruction); diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 8ed0b414211c..e54a9ede52bf 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -73,6 +73,16 @@ bool AsmAnalyzer::analyze(Block const& _block) if (!(ScopeFiller(m_info, m_errorReporter))(_block)) return false; + if (m_eofVersion.has_value() && m_info.virtualBlocks.size() >= 1024) + m_errorReporter.syntaxError( + 9633_error, + nativeLocationOf(_block), + fmt::format( + "Too many functions defined in object \"{objectName}\". At most 1023 function definitions are allowed for EOF.", + fmt::arg("objectName", m_objectStructure.objectName) + ) + ); + (*this)(_block); } catch (FatalError const& error) @@ -290,6 +300,18 @@ void AsmAnalyzer::operator()(FunctionDefinition const& _funDef) m_activeVariables.insert(&std::get(varScope.identifiers.at(var.name))); } + if (m_eofVersion.has_value()) + { + if (_funDef.parameters.size() >= 0x80) + m_errorReporter.typeError(8534_error, nativeLocationOf(_funDef), + "Too many function parameters. At most 127 parameters allowed for EOF"); + + if (_funDef.returnVariables.size() >= 0x80) + m_errorReporter.typeError(2101_error, nativeLocationOf(_funDef), + "Too many function return variables. At most 127 return variables allowed for EOF"); + + } + (*this)(_funDef.body); } diff --git a/libyul/backends/evm/AbstractAssembly.h b/libyul/backends/evm/AbstractAssembly.h index 1e1b87680b57..1f93145bc165 100644 --- a/libyul/backends/evm/AbstractAssembly.h +++ b/libyul/backends/evm/AbstractAssembly.h @@ -103,16 +103,21 @@ class AbstractAssembly /// Creates a new sub-assembly, which can be referenced using dataSize and dataOffset. virtual std::pair, SubID> createSubAssembly(bool _creation, std::string _name = "") = 0; - /// Creates new function with given signature and returns newly created function ID - virtual FunctionID createFunction(uint8_t _args, uint8_t _rets) = 0; - /// Starts filling function body under given function ID + /// Registers a new function with given signature and returns its ID. + /// The function is initially empty and its body must be filled with instructions. + virtual FunctionID registerFunction(uint8_t _args, uint8_t _rets) = 0; + /// Selects a function as a target for newly appended instructions. + /// Must not be called when another function is already selected. + /// Filling the same function more than once is not allowed. + /// @a endFunction() must be called at the end to finalize the function. virtual void beginFunction(FunctionID _functionID) = 0; - /// Ends currently being filled function + /// Finalizes the process of filling a function body and switches back to the main code section. + /// Must not be called if no function is selected. virtual void endFunction() = 0; - /// Appends function call to a function under given ID virtual void appendFunctionCall(FunctionID _functionID) = 0; - /// Appends function return from currently being filled function. + /// Appends an instruction that returns values from the current function. + /// Only allowed inside a function body. virtual void appendFunctionReturn() = 0; /// Appends the offset of the given sub-assembly or data. diff --git a/libyul/backends/evm/ControlFlowGraph.h b/libyul/backends/evm/ControlFlowGraph.h index e14586a759fb..0c1059e84f90 100644 --- a/libyul/backends/evm/ControlFlowGraph.h +++ b/libyul/backends/evm/ControlFlowGraph.h @@ -123,7 +123,7 @@ inline bool canBeFreelyGenerated(StackSlot const& _slot) /// Control flow graph consisting of ``CFG::BasicBlock``s connected by control flow. struct CFG { - explicit CFG(bool _useFunctions): useFunctions(_useFunctions) {} + explicit CFG(bool _simulateFunctionsWithJumps): simulateFunctionsWithJumps(_simulateFunctionsWithJumps) {} CFG(CFG const&) = delete; CFG(CFG&&) = delete; CFG& operator=(CFG const&) = delete; @@ -220,8 +220,8 @@ struct CFG bool canContinue = true; }; - /// True if control flow graph uses functions. False otherwise. - bool useFunctions = false; + /// True if control flow graph simulates functions with jumps. False otherwise. True for legacy bytecode + bool simulateFunctionsWithJumps = true; /// The main entry point, i.e. the start of the outermost Yul block. BasicBlock* entry = nullptr; /// Subgraphs for functions. diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index f749a4e03fc4..c48d29b1aa6c 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -216,7 +216,7 @@ std::unique_ptr ControlFlowGraphBuilder::build( if (yul::EVMDialect const* evmDialect = dynamic_cast(&_dialect)) eofVersion = evmDialect->eofVersion(); - auto result = std::make_unique(eofVersion.has_value()); + auto result = std::make_unique(!eofVersion.has_value()); result->entry = &result->makeBlock(debugDataOf(_block)); ControlFlowSideEffectsCollector sideEffects(_dialect, _block); @@ -547,8 +547,8 @@ Stack const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _cal Scope::Function const& function = lookupFunction(_call.functionName.name); canContinue = m_graph.functionInfo.at(&function).canContinue; Stack inputs; - // For EOF (useFunctions == true) we do not have to put return label on stack. - if (!m_graph.useFunctions && canContinue) + // For EOF (simulateFunctionsWithJumps == false) we do not have to put return label on stack. + if (m_graph.simulateFunctionsWithJumps && canContinue) inputs.emplace_back(FunctionCallReturnLabelSlot{_call}); for (auto const& arg: _call.arguments | ranges::views::reverse) inputs.emplace_back(std::visit(*this, arg)); diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index f998b7abbc6d..de1201481a3c 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -209,6 +209,9 @@ std::vector> createBuiltins(langutil::EVMVe opcode != evmasm::Instruction::DATALOADN && opcode != evmasm::Instruction::EOFCREATE && opcode != evmasm::Instruction::RETURNCONTRACT && + opcode != evmasm::Instruction::CALLF && + opcode != evmasm::Instruction::JUMPF && + opcode != evmasm::Instruction::RETF && _evmVersion.hasOpcode(opcode, _eofVersion) && !prevRandaoException(name) ) diff --git a/libyul/backends/evm/EthAssemblyAdapter.cpp b/libyul/backends/evm/EthAssemblyAdapter.cpp index 247e4462d4fe..d9cf47f4dabe 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.cpp +++ b/libyul/backends/evm/EthAssemblyAdapter.cpp @@ -145,7 +145,7 @@ std::pair, AbstractAssembly::SubID> EthAssembl return {std::make_shared(*assembly), static_cast(sub.data())}; } -AbstractAssembly::FunctionID EthAssemblyAdapter::createFunction(uint8_t _args, uint8_t _rets) +AbstractAssembly::FunctionID EthAssemblyAdapter::registerFunction(uint8_t _args, uint8_t _rets) { return m_assembly.createFunction(_args, _rets); } diff --git a/libyul/backends/evm/EthAssemblyAdapter.h b/libyul/backends/evm/EthAssemblyAdapter.h index 202d6927e66c..29a6fba7bef1 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.h +++ b/libyul/backends/evm/EthAssemblyAdapter.h @@ -56,7 +56,7 @@ class EthAssemblyAdapter: public AbstractAssembly void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override; void appendAssemblySize() override; std::pair, SubID> createSubAssembly(bool _creation, std::string _name = {}) override; - AbstractAssembly::FunctionID createFunction(uint8_t _args, uint8_t _rets) override; + AbstractAssembly::FunctionID registerFunction(uint8_t _args, uint8_t _rets) override; void beginFunction(AbstractAssembly::FunctionID _functionID) override; void endFunction() override; void appendFunctionCall(FunctionID _functionID) override; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 74f43cfc7881..c9d6c6292fb5 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -120,29 +120,41 @@ std::pair, AbstractAssembly::SubID> NoOutputAs return {}; } -AbstractAssembly::FunctionID NoOutputAssembly::createFunction(uint8_t _args, uint8_t _rets) +AbstractAssembly::FunctionID NoOutputAssembly::registerFunction(uint8_t _args, uint8_t _rets) { - yulAssert(m_context->numFunctions <= std::numeric_limits::max()); - AbstractAssembly::FunctionID id = static_cast(m_context->numFunctions++); - m_context->functionSignatures[id] = std::make_pair(_args, _rets); + yulAssert(m_context.numFunctions <= std::numeric_limits::max()); + AbstractAssembly::FunctionID id = static_cast(m_context.numFunctions++); + m_context.functionSignatures[id] = std::make_pair(_args, _rets); return id; } -void NoOutputAssembly::beginFunction(FunctionID) -{} +void NoOutputAssembly::beginFunction(FunctionID _functionID) +{ + yulAssert(m_currentFunctionID == 0, "Attempted to begin a function before ending the last one."); + yulAssert(m_context.functionSignatures.count(_functionID) == 1, "Filling unregistered function."); + yulAssert(m_stackHeight == 0, "Non-empty stack on beginFunction call."); + m_currentFunctionID = _functionID; +} void NoOutputAssembly::endFunction() -{} +{ + yulAssert(m_currentFunctionID != 0, "End function without begin function."); + auto const rets = m_context.functionSignatures.at(m_currentFunctionID).second; + yulAssert(rets == 0x80 || m_stackHeight == rets, "Stack height mismatch at function end."); + m_currentFunctionID = 0; +} void NoOutputAssembly::appendFunctionCall(FunctionID _functionID) { - auto [args, rets] = m_context->functionSignatures.at(_functionID); + auto [args, rets] = m_context.functionSignatures.at(_functionID); m_stackHeight += static_cast(rets) - static_cast(args); } void NoOutputAssembly::appendFunctionReturn() { - m_stackHeight = 0; + yulAssert(m_currentFunctionID != 0, "End function without begin function."); + auto const rets = m_context.functionSignatures.at(m_currentFunctionID).second; + yulAssert(rets == 0x80 || m_stackHeight == rets, "Stack height mismatch at function end."); } void NoOutputAssembly::appendDataOffset(std::vector const&) diff --git a/libyul/backends/evm/NoOutputAssembly.h b/libyul/backends/evm/NoOutputAssembly.h index b61186df378f..2669a277c4a4 100644 --- a/libyul/backends/evm/NoOutputAssembly.h +++ b/libyul/backends/evm/NoOutputAssembly.h @@ -52,7 +52,7 @@ struct NoOutputAssemblyContext class NoOutputAssembly: public AbstractAssembly { public: - explicit NoOutputAssembly(langutil::EVMVersion _evmVersion): m_context(std::make_shared()), m_evmVersion(_evmVersion) { } + explicit NoOutputAssembly(langutil::EVMVersion _evmVersion): m_evmVersion(_evmVersion) { } ~NoOutputAssembly() override = default; void setSourceLocation(langutil::SourceLocation const&) override {} @@ -73,7 +73,7 @@ class NoOutputAssembly: public AbstractAssembly void appendAssemblySize() override; std::pair, SubID> createSubAssembly(bool _creation, std::string _name = "") override; - FunctionID createFunction(uint8_t _args, uint8_t _rets) override; + FunctionID registerFunction(uint8_t _args, uint8_t _rets) override; void beginFunction(FunctionID) override; void endFunction() override; void appendFunctionCall(FunctionID _functionID) override; @@ -96,8 +96,9 @@ class NoOutputAssembly: public AbstractAssembly langutil::EVMVersion evmVersion() const override { return m_evmVersion; } private: - std::shared_ptr m_context; + NoOutputAssemblyContext m_context = {}; int m_stackHeight = 0; + FunctionID m_currentFunctionID = 0; langutil::EVMVersion m_evmVersion; }; diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index 52462b378823..22a7098247f8 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -49,18 +49,18 @@ std::vector OptimizedEVMCodeTransform::run( ) { std::unique_ptr dfg = ControlFlowGraphBuilder::build(_analysisInfo, _dialect, _block); - yulAssert(_dialect.eofVersion().has_value() == dfg->useFunctions); + yulAssert(_dialect.eofVersion().has_value() != dfg->simulateFunctionsWithJumps); StackLayout stackLayout = StackLayoutGenerator::run(*dfg); - if (dfg->useFunctions) + if (!dfg->simulateFunctionsWithJumps) { for (Scope::Function const* function: dfg->functions) { auto const& info = dfg->functionInfo.at(function); - yulAssert(info.parameters.size() <= std::numeric_limits::max()); - yulAssert(info.returnVariables.size() <= std::numeric_limits::max()); + yulAssert(info.parameters.size() <= 0x7f); + yulAssert(info.returnVariables.size() <= 0x7f); // According to EOF spec function output num equals 0x80 means non-returning function - auto functionID = _assembly.createFunction( + auto functionID = _assembly.registerFunction( static_cast(info.parameters.size()), static_cast(info.canContinue ? info.returnVariables.size() : 0x80) ); @@ -85,7 +85,7 @@ std::vector OptimizedEVMCodeTransform::run( void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call) { - bool useReturnLabel = !m_dfg.useFunctions && _call.canContinue; + bool useReturnLabel = m_dfg.simulateFunctionsWithJumps && _call.canContinue; // Validate stack. { yulAssert(m_assembly.stackHeight() == static_cast(m_stack.size()), ""); @@ -109,7 +109,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call) // Emit code. { m_assembly.setSourceLocation(originLocationOf(_call)); - if (m_dfg.useFunctions) + if (!m_dfg.simulateFunctionsWithJumps) m_assembly.appendFunctionCall(m_builtinContext.functionIDs.at(&_call.function.get())); else m_assembly.appendJumpTo( @@ -127,7 +127,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call) for (size_t i = 0; i < _call.function.get().numArguments + (useReturnLabel ? 1 : 0); ++i) m_stack.pop_back(); // Push return values to m_stack. - if (m_dfg.useFunctions) + if (!m_dfg.simulateFunctionsWithJumps) yulAssert(_call.function.get().numReturns < 0x80, "Num of function output >= 128"); for (size_t index: ranges::views::iota(0u, _call.function.get().numReturns)) m_stack.emplace_back(TemporarySlot{_call.functionCall, index}); @@ -207,7 +207,7 @@ OptimizedEVMCodeTransform::OptimizedEVMCodeTransform( m_builtinContext(_builtinContext), m_dfg(_dfg), m_stackLayout(_stackLayout), - m_functionLabels(_dfg.useFunctions ? decltype(m_functionLabels)() : [&](){ + m_functionLabels(!_dfg.simulateFunctionsWithJumps ? decltype(m_functionLabels)() : [&](){ std::map functionLabels; std::set assignedFunctionNames; for (Scope::Function const* function: m_dfg.functions) @@ -240,7 +240,7 @@ void OptimizedEVMCodeTransform::assertLayoutCompatibility(Stack const& _currentS AbstractAssembly::LabelID OptimizedEVMCodeTransform::getFunctionLabel(Scope::Function const& _function) { - yulAssert(!m_dfg.useFunctions); + yulAssert(m_dfg.simulateFunctionsWithJumps); return m_functionLabels.at(&m_dfg.functionInfo.at(&_function)); } @@ -518,12 +518,12 @@ void OptimizedEVMCodeTransform::operator()(CFG::BasicBlock const& _block) Stack exitStack = m_currentFunctionInfo->returnVariables | ranges::views::transform([](auto const& _varSlot){ return StackSlot{_varSlot}; }) | ranges::to; - if (!m_dfg.useFunctions) + if (m_dfg.simulateFunctionsWithJumps) exitStack.emplace_back(FunctionReturnLabelSlot{_functionReturn.info->function}); // Create the function return layout and jump. createStackLayout(debugDataOf(_functionReturn), exitStack); - if (m_dfg.useFunctions) + if (!m_dfg.simulateFunctionsWithJumps) m_assembly.appendFunctionReturn(); else m_assembly.appendJump(0, AbstractAssembly::JumpType::OutOfFunction); @@ -547,7 +547,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::BasicBlock const& _block) void OptimizedEVMCodeTransform::operator()(CFG::FunctionInfo const& _functionInfo) { - bool useReturnLabel = !m_dfg.useFunctions && _functionInfo.canContinue; + bool useReturnLabel = m_dfg.simulateFunctionsWithJumps && _functionInfo.canContinue; yulAssert(!m_currentFunctionInfo, ""); ScopedSaveAndRestore currentFunctionInfoRestore(m_currentFunctionInfo, &_functionInfo); @@ -558,12 +558,12 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionInfo const& _functionInf m_stack.emplace_back(FunctionReturnLabelSlot{_functionInfo.function}); for (auto const& param: _functionInfo.parameters | ranges::views::reverse) m_stack.emplace_back(param); - if (m_dfg.useFunctions) + if (!m_dfg.simulateFunctionsWithJumps) m_assembly.beginFunction(m_builtinContext.functionIDs[&_functionInfo.function]); m_assembly.setStackHeight(static_cast(m_stack.size())); m_assembly.setSourceLocation(originLocationOf(_functionInfo)); - if (!m_dfg.useFunctions) + if (m_dfg.simulateFunctionsWithJumps) m_assembly.appendLabel(getFunctionLabel(_functionInfo.function)); // Create the entry layout of the function body block and visit. @@ -571,7 +571,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionInfo const& _functionInf (*this)(*_functionInfo.entry); m_stack.clear(); - if (m_dfg.useFunctions) + if (!m_dfg.simulateFunctionsWithJumps) m_assembly.endFunction(); m_assembly.setStackHeight(0); } diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.h b/libyul/backends/evm/OptimizedEVMCodeTransform.h index 81665f1f787a..cb6cfb0be4b9 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.h +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.h @@ -104,7 +104,7 @@ class OptimizedEVMCodeTransform Stack m_stack; std::map m_returnLabels; std::map m_blockLabels; - /// Non-empty only if m_dfg.useFunctions == false + /// Non-empty only if m_dfg.simulateFunctionsWithJumps == true std::map const m_functionLabels; /// Set of blocks already generated. If any of the contained blocks is ever jumped to, m_blockLabels should /// contain a jump label for it. diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp index a503c034e0b8..56afa4cbf813 100644 --- a/libyul/backends/evm/StackLayoutGenerator.cpp +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -49,11 +49,11 @@ using namespace solidity::yul; StackLayout StackLayoutGenerator::run(CFG const& _cfg) { - StackLayout stackLayout{_cfg.useFunctions, {}, {}}; - StackLayoutGenerator{stackLayout, nullptr}.processEntryPoint(*_cfg.entry); + StackLayout stackLayout{{}, {}}; + StackLayoutGenerator{stackLayout, nullptr, _cfg.simulateFunctionsWithJumps}.processEntryPoint(*_cfg.entry); for (auto& functionInfo: _cfg.functionInfo | ranges::views::values) - StackLayoutGenerator{stackLayout, &functionInfo}.processEntryPoint(*functionInfo.entry, &functionInfo); + StackLayoutGenerator{stackLayout, &functionInfo, _cfg.simulateFunctionsWithJumps}.processEntryPoint(*functionInfo.entry, &functionInfo); return stackLayout; } @@ -70,7 +70,7 @@ std::map> StackLayoutGe std::vector StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, YulName _functionName) { - StackLayout stackLayout{_cfg.useFunctions, {}, {}}; + StackLayout stackLayout{{}, {}}; CFG::FunctionInfo const* functionInfo = nullptr; if (!_functionName.empty()) { @@ -82,15 +82,16 @@ std::vector StackLayoutGenerator::reportStac yulAssert(functionInfo, "Function not found."); } - StackLayoutGenerator generator{stackLayout, functionInfo}; + StackLayoutGenerator generator{stackLayout, functionInfo, _cfg.simulateFunctionsWithJumps}; CFG::BasicBlock const* entry = functionInfo ? functionInfo->entry : _cfg.entry; generator.processEntryPoint(*entry); return generator.reportStackTooDeep(*entry); } -StackLayoutGenerator::StackLayoutGenerator(StackLayout& _layout, CFG::FunctionInfo const* _functionInfo): +StackLayoutGenerator::StackLayoutGenerator(StackLayout& _layout, CFG::FunctionInfo const* _functionInfo, bool _simulateFunctionsWithJumps): m_layout(_layout), - m_currentFunctionInfo(_functionInfo) + m_currentFunctionInfo(_functionInfo), + m_simulateFunctionsWithJumps(_simulateFunctionsWithJumps) { } @@ -465,7 +466,7 @@ std::optional StackLayoutGenerator::getExitLayoutOrStageDependencies( return StackSlot{_varSlot}; }) | ranges::to; - if (!m_layout.useFunctions) + if (m_simulateFunctionsWithJumps) stack.emplace_back(FunctionReturnLabelSlot{_functionReturn.info->function}); return stack; }, @@ -737,7 +738,7 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi _addChild(_conditionalJump.zero); _addChild(_conditionalJump.nonZero); }, - [&](CFG::BasicBlock::FunctionReturn const&) { yulAssert(m_layout.useFunctions); }, + [&](CFG::BasicBlock::FunctionReturn const&) { yulAssert(!m_simulateFunctionsWithJumps); }, [&](CFG::BasicBlock::Terminated const&) {}, }, _block->exit); }); diff --git a/libyul/backends/evm/StackLayoutGenerator.h b/libyul/backends/evm/StackLayoutGenerator.h index cbd1d2b2527a..ffdc9a2d845d 100644 --- a/libyul/backends/evm/StackLayoutGenerator.h +++ b/libyul/backends/evm/StackLayoutGenerator.h @@ -37,7 +37,6 @@ struct StackLayout /// The resulting stack layout after executing the block. Stack exitLayout; }; - bool useFunctions = false; std::map blockInfos; /// For each operation the complete stack layout that: /// - has the slots required for the operation at the stack top. @@ -67,7 +66,7 @@ class StackLayoutGenerator static std::vector reportStackTooDeep(CFG const& _cfg, YulName _functionName); private: - StackLayoutGenerator(StackLayout& _context, CFG::FunctionInfo const* _functionInfo); + StackLayoutGenerator(StackLayout& _context, CFG::FunctionInfo const* _functionInfo, bool _simulateFunctionsWithJumps); /// @returns the optimal entry stack layout, s.t. @a _operation can be applied to it and /// the result can be transformed to @a _exitStack with minimal stack shuffling. @@ -117,6 +116,7 @@ class StackLayoutGenerator StackLayout& m_layout; CFG::FunctionInfo const* m_currentFunctionInfo = nullptr; + bool m_simulateFunctionsWithJumps = true; }; } diff --git a/test/libyul/yulSyntaxTests/eof/too_many_functions_arguments_or_returns.yul b/test/libyul/yulSyntaxTests/eof/too_many_functions_arguments_or_returns.yul new file mode 100644 index 000000000000..6a79a1603224 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/too_many_functions_arguments_or_returns.yul @@ -0,0 +1,28 @@ +object "a" { + code { + function too_many_arguments( + i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, + i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, + i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, + i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, + i121, i122, i123, i124, i125, i126, i127, i128 + ) + {} + + function too_many_returns()-> + i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, + i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, + i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, + i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, + i121, i122, i123, i124, i125, i126, i127, i128 + {} + } +} + +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 8534: (32-800): Too many function parameters. At most 127 parameters allowed for EOF +// TypeError 2101: (810-1569): Too many function return variables. At most 127 return variables allowed for EOF + diff --git a/test/libyul/yulSyntaxTests/eof/too_many_functions_defined.yul b/test/libyul/yulSyntaxTests/eof/too_many_functions_defined.yul new file mode 100644 index 000000000000..e1b763d348b6 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/too_many_functions_defined.yul @@ -0,0 +1,1034 @@ +object "a" { + code { + function f0001() {} + function f0002() {} + function f0003() {} + function f0004() {} + function f0005() {} + function f0006() {} + function f0007() {} + function f0008() {} + function f0009() {} + function f0010() {} + function f0011() {} + function f0012() {} + function f0013() {} + function f0014() {} + function f0015() {} + function f0016() {} + function f0017() {} + function f0018() {} + function f0019() {} + function f0020() {} + function f0021() {} + function f0022() {} + function f0023() {} + function f0024() {} + function f0025() {} + function f0026() {} + function f0027() {} + function f0028() {} + function f0029() {} + function f0030() {} + function f0031() {} + function f0032() {} + function f0033() {} + function f0034() {} + function f0035() {} + function f0036() {} + function f0037() {} + function f0038() {} + function f0039() {} + function f0040() {} + function f0041() {} + function f0042() {} + function f0043() {} + function f0044() {} + function f0045() {} + function f0046() {} + function f0047() {} + function f0048() {} + function f0049() {} + function f0050() {} + function f0051() {} + function f0052() {} + function f0053() {} + function f0054() {} + function f0055() {} + function f0056() {} + function f0057() {} + function f0058() {} + function f0059() {} + function f0060() {} + function f0061() {} + function f0062() {} + function f0063() {} + function f0064() {} + function f0065() {} + function f0066() {} + function f0067() {} + function f0068() {} + function f0069() {} + function f0070() {} + function f0071() {} + function f0072() {} + function f0073() {} + function f0074() {} + function f0075() {} + function f0076() {} + function f0077() {} + function f0078() {} + function f0079() {} + function f0080() {} + function f0081() {} + function f0082() {} + function f0083() {} + function f0084() {} + function f0085() {} + function f0086() {} + function f0087() {} + function f0088() {} + function f0089() {} + function f0090() {} + function f0091() {} + function f0092() {} + function f0093() {} + function f0094() {} + function f0095() {} + function f0096() {} + function f0097() {} + function f0098() {} + function f0099() {} + function f0100() {} + function f0101() {} + function f0102() {} + function f0103() {} + function f0104() {} + function f0105() {} + function f0106() {} + function f0107() {} + function f0108() {} + function f0109() {} + function f0110() {} + function f0111() {} + function f0112() {} + function f0113() {} + function f0114() {} + function f0115() {} + function f0116() {} + function f0117() {} + function f0118() {} + function f0119() {} + function f0120() {} + function f0121() {} + function f0122() {} + function f0123() {} + function f0124() {} + function f0125() {} + function f0126() {} + function f0127() {} + function f0128() {} + function f0129() {} + function f0130() {} + function f0131() {} + function f0132() {} + function f0133() {} + function f0134() {} + function f0135() {} + function f0136() {} + function f0137() {} + function f0138() {} + function f0139() {} + function f0140() {} + function f0141() {} + function f0142() {} + function f0143() {} + function f0144() {} + function f0145() {} + function f0146() {} + function f0147() {} + function f0148() {} + function f0149() {} + function f0150() {} + function f0151() {} + function f0152() {} + function f0153() {} + function f0154() {} + function f0155() {} + function f0156() {} + function f0157() {} + function f0158() {} + function f0159() {} + function f0160() {} + function f0161() {} + function f0162() {} + function f0163() {} + function f0164() {} + function f0165() {} + function f0166() {} + function f0167() {} + function f0168() {} + function f0169() {} + function f0170() {} + function f0171() {} + function f0172() {} + function f0173() {} + function f0174() {} + function f0175() {} + function f0176() {} + function f0177() {} + function f0178() {} + function f0179() {} + function f0180() {} + function f0181() {} + function f0182() {} + function f0183() {} + function f0184() {} + function f0185() {} + function f0186() {} + function f0187() {} + function f0188() {} + function f0189() {} + function f0190() {} + function f0191() {} + function f0192() {} + function f0193() {} + function f0194() {} + function f0195() {} + function f0196() {} + function f0197() {} + function f0198() {} + function f0199() {} + function f0200() {} + function f0201() {} + function f0202() {} + function f0203() {} + function f0204() {} + function f0205() {} + function f0206() {} + function f0207() {} + function f0208() {} + function f0209() {} + function f0210() {} + function f0211() {} + function f0212() {} + function f0213() {} + function f0214() {} + function f0215() {} + function f0216() {} + function f0217() {} + function f0218() {} + function f0219() {} + function f0220() {} + function f0221() {} + function f0222() {} + function f0223() {} + function f0224() {} + function f0225() {} + function f0226() {} + function f0227() {} + function f0228() {} + function f0229() {} + function f0230() {} + function f0231() {} + function f0232() {} + function f0233() {} + function f0234() {} + function f0235() {} + function f0236() {} + function f0237() {} + function f0238() {} + function f0239() {} + function f0240() {} + function f0241() {} + function f0242() {} + function f0243() {} + function f0244() {} + function f0245() {} + function f0246() {} + function f0247() {} + function f0248() {} + function f0249() {} + function f0250() {} + function f0251() {} + function f0252() {} + function f0253() {} + function f0254() {} + function f0255() {} + function f0256() {} + function f0257() {} + function f0258() {} + function f0259() {} + function f0260() {} + function f0261() {} + function f0262() {} + function f0263() {} + function f0264() {} + function f0265() {} + function f0266() {} + function f0267() {} + function f0268() {} + function f0269() {} + function f0270() {} + function f0271() {} + function f0272() {} + function f0273() {} + function f0274() {} + function f0275() {} + function f0276() {} + function f0277() {} + function f0278() {} + function f0279() {} + function f0280() {} + function f0281() {} + function f0282() {} + function f0283() {} + function f0284() {} + function f0285() {} + function f0286() {} + function f0287() {} + function f0288() {} + function f0289() {} + function f0290() {} + function f0291() {} + function f0292() {} + function f0293() {} + function f0294() {} + function f0295() {} + function f0296() {} + function f0297() {} + function f0298() {} + function f0299() {} + function f0300() {} + function f0301() {} + function f0302() {} + function f0303() {} + function f0304() {} + function f0305() {} + function f0306() {} + function f0307() {} + function f0308() {} + function f0309() {} + function f0310() {} + function f0311() {} + function f0312() {} + function f0313() {} + function f0314() {} + function f0315() {} + function f0316() {} + function f0317() {} + function f0318() {} + function f0319() {} + function f0320() {} + function f0321() {} + function f0322() {} + function f0323() {} + function f0324() {} + function f0325() {} + function f0326() {} + function f0327() {} + function f0328() {} + function f0329() {} + function f0330() {} + function f0331() {} + function f0332() {} + function f0333() {} + function f0334() {} + function f0335() {} + function f0336() {} + function f0337() {} + function f0338() {} + function f0339() {} + function f0340() {} + function f0341() {} + function f0342() {} + function f0343() {} + function f0344() {} + function f0345() {} + function f0346() {} + function f0347() {} + function f0348() {} + function f0349() {} + function f0350() {} + function f0351() {} + function f0352() {} + function f0353() {} + function f0354() {} + function f0355() {} + function f0356() {} + function f0357() {} + function f0358() {} + function f0359() {} + function f0360() {} + function f0361() {} + function f0362() {} + function f0363() {} + function f0364() {} + function f0365() {} + function f0366() {} + function f0367() {} + function f0368() {} + function f0369() {} + function f0370() {} + function f0371() {} + function f0372() {} + function f0373() {} + function f0374() {} + function f0375() {} + function f0376() {} + function f0377() {} + function f0378() {} + function f0379() {} + function f0380() {} + function f0381() {} + function f0382() {} + function f0383() {} + function f0384() {} + function f0385() {} + function f0386() {} + function f0387() {} + function f0388() {} + function f0389() {} + function f0390() {} + function f0391() {} + function f0392() {} + function f0393() {} + function f0394() {} + function f0395() {} + function f0396() {} + function f0397() {} + function f0398() {} + function f0399() {} + function f0400() {} + function f0401() {} + function f0402() {} + function f0403() {} + function f0404() {} + function f0405() {} + function f0406() {} + function f0407() {} + function f0408() {} + function f0409() {} + function f0410() {} + function f0411() {} + function f0412() {} + function f0413() {} + function f0414() {} + function f0415() {} + function f0416() {} + function f0417() {} + function f0418() {} + function f0419() {} + function f0420() {} + function f0421() {} + function f0422() {} + function f0423() {} + function f0424() {} + function f0425() {} + function f0426() {} + function f0427() {} + function f0428() {} + function f0429() {} + function f0430() {} + function f0431() {} + function f0432() {} + function f0433() {} + function f0434() {} + function f0435() {} + function f0436() {} + function f0437() {} + function f0438() {} + function f0439() {} + function f0440() {} + function f0441() {} + function f0442() {} + function f0443() {} + function f0444() {} + function f0445() {} + function f0446() {} + function f0447() {} + function f0448() {} + function f0449() {} + function f0450() {} + function f0451() {} + function f0452() {} + function f0453() {} + function f0454() {} + function f0455() {} + function f0456() {} + function f0457() {} + function f0458() {} + function f0459() {} + function f0460() {} + function f0461() {} + function f0462() {} + function f0463() {} + function f0464() {} + function f0465() {} + function f0466() {} + function f0467() {} + function f0468() {} + function f0469() {} + function f0470() {} + function f0471() {} + function f0472() {} + function f0473() {} + function f0474() {} + function f0475() {} + function f0476() {} + function f0477() {} + function f0478() {} + function f0479() {} + function f0480() {} + function f0481() {} + function f0482() {} + function f0483() {} + function f0484() {} + function f0485() {} + function f0486() {} + function f0487() {} + function f0488() {} + function f0489() {} + function f0490() {} + function f0491() {} + function f0492() {} + function f0493() {} + function f0494() {} + function f0495() {} + function f0496() {} + function f0497() {} + function f0498() {} + function f0499() {} + function f0500() {} + function f0501() {} + function f0502() {} + function f0503() {} + function f0504() {} + function f0505() {} + function f0506() {} + function f0507() {} + function f0508() {} + function f0509() {} + function f0510() {} + function f0511() {} + function f0512() {} + function f0513() {} + function f0514() {} + function f0515() {} + function f0516() {} + function f0517() {} + function f0518() {} + function f0519() {} + function f0520() {} + function f0521() {} + function f0522() {} + function f0523() {} + function f0524() {} + function f0525() {} + function f0526() {} + function f0527() {} + function f0528() {} + function f0529() {} + function f0530() {} + function f0531() {} + function f0532() {} + function f0533() {} + function f0534() {} + function f0535() {} + function f0536() {} + function f0537() {} + function f0538() {} + function f0539() {} + function f0540() {} + function f0541() {} + function f0542() {} + function f0543() {} + function f0544() {} + function f0545() {} + function f0546() {} + function f0547() {} + function f0548() {} + function f0549() {} + function f0550() {} + function f0551() {} + function f0552() {} + function f0553() {} + function f0554() {} + function f0555() {} + function f0556() {} + function f0557() {} + function f0558() {} + function f0559() {} + function f0560() {} + function f0561() {} + function f0562() {} + function f0563() {} + function f0564() {} + function f0565() {} + function f0566() {} + function f0567() {} + function f0568() {} + function f0569() {} + function f0570() {} + function f0571() {} + function f0572() {} + function f0573() {} + function f0574() {} + function f0575() {} + function f0576() {} + function f0577() {} + function f0578() {} + function f0579() {} + function f0580() {} + function f0581() {} + function f0582() {} + function f0583() {} + function f0584() {} + function f0585() {} + function f0586() {} + function f0587() {} + function f0588() {} + function f0589() {} + function f0590() {} + function f0591() {} + function f0592() {} + function f0593() {} + function f0594() {} + function f0595() {} + function f0596() {} + function f0597() {} + function f0598() {} + function f0599() {} + function f0600() {} + function f0601() {} + function f0602() {} + function f0603() {} + function f0604() {} + function f0605() {} + function f0606() {} + function f0607() {} + function f0608() {} + function f0609() {} + function f0610() {} + function f0611() {} + function f0612() {} + function f0613() {} + function f0614() {} + function f0615() {} + function f0616() {} + function f0617() {} + function f0618() {} + function f0619() {} + function f0620() {} + function f0621() {} + function f0622() {} + function f0623() {} + function f0624() {} + function f0625() {} + function f0626() {} + function f0627() {} + function f0628() {} + function f0629() {} + function f0630() {} + function f0631() {} + function f0632() {} + function f0633() {} + function f0634() {} + function f0635() {} + function f0636() {} + function f0637() {} + function f0638() {} + function f0639() {} + function f0640() {} + function f0641() {} + function f0642() {} + function f0643() {} + function f0644() {} + function f0645() {} + function f0646() {} + function f0647() {} + function f0648() {} + function f0649() {} + function f0650() {} + function f0651() {} + function f0652() {} + function f0653() {} + function f0654() {} + function f0655() {} + function f0656() {} + function f0657() {} + function f0658() {} + function f0659() {} + function f0660() {} + function f0661() {} + function f0662() {} + function f0663() {} + function f0664() {} + function f0665() {} + function f0666() {} + function f0667() {} + function f0668() {} + function f0669() {} + function f0670() {} + function f0671() {} + function f0672() {} + function f0673() {} + function f0674() {} + function f0675() {} + function f0676() {} + function f0677() {} + function f0678() {} + function f0679() {} + function f0680() {} + function f0681() {} + function f0682() {} + function f0683() {} + function f0684() {} + function f0685() {} + function f0686() {} + function f0687() {} + function f0688() {} + function f0689() {} + function f0690() {} + function f0691() {} + function f0692() {} + function f0693() {} + function f0694() {} + function f0695() {} + function f0696() {} + function f0697() {} + function f0698() {} + function f0699() {} + function f0700() {} + function f0701() {} + function f0702() {} + function f0703() {} + function f0704() {} + function f0705() {} + function f0706() {} + function f0707() {} + function f0708() {} + function f0709() {} + function f0710() {} + function f0711() {} + function f0712() {} + function f0713() {} + function f0714() {} + function f0715() {} + function f0716() {} + function f0717() {} + function f0718() {} + function f0719() {} + function f0720() {} + function f0721() {} + function f0722() {} + function f0723() {} + function f0724() {} + function f0725() {} + function f0726() {} + function f0727() {} + function f0728() {} + function f0729() {} + function f0730() {} + function f0731() {} + function f0732() {} + function f0733() {} + function f0734() {} + function f0735() {} + function f0736() {} + function f0737() {} + function f0738() {} + function f0739() {} + function f0740() {} + function f0741() {} + function f0742() {} + function f0743() {} + function f0744() {} + function f0745() {} + function f0746() {} + function f0747() {} + function f0748() {} + function f0749() {} + function f0750() {} + function f0751() {} + function f0752() {} + function f0753() {} + function f0754() {} + function f0755() {} + function f0756() {} + function f0757() {} + function f0758() {} + function f0759() {} + function f0760() {} + function f0761() {} + function f0762() {} + function f0763() {} + function f0764() {} + function f0765() {} + function f0766() {} + function f0767() {} + function f0768() {} + function f0769() {} + function f0770() {} + function f0771() {} + function f0772() {} + function f0773() {} + function f0774() {} + function f0775() {} + function f0776() {} + function f0777() {} + function f0778() {} + function f0779() {} + function f0780() {} + function f0781() {} + function f0782() {} + function f0783() {} + function f0784() {} + function f0785() {} + function f0786() {} + function f0787() {} + function f0788() {} + function f0789() {} + function f0790() {} + function f0791() {} + function f0792() {} + function f0793() {} + function f0794() {} + function f0795() {} + function f0796() {} + function f0797() {} + function f0798() {} + function f0799() {} + function f0800() {} + function f0801() {} + function f0802() {} + function f0803() {} + function f0804() {} + function f0805() {} + function f0806() {} + function f0807() {} + function f0808() {} + function f0809() {} + function f0810() {} + function f0811() {} + function f0812() {} + function f0813() {} + function f0814() {} + function f0815() {} + function f0816() {} + function f0817() {} + function f0818() {} + function f0819() {} + function f0820() {} + function f0821() {} + function f0822() {} + function f0823() {} + function f0824() {} + function f0825() {} + function f0826() {} + function f0827() {} + function f0828() {} + function f0829() {} + function f0830() {} + function f0831() {} + function f0832() {} + function f0833() {} + function f0834() {} + function f0835() {} + function f0836() {} + function f0837() {} + function f0838() {} + function f0839() {} + function f0840() {} + function f0841() {} + function f0842() {} + function f0843() {} + function f0844() {} + function f0845() {} + function f0846() {} + function f0847() {} + function f0848() {} + function f0849() {} + function f0850() {} + function f0851() {} + function f0852() {} + function f0853() {} + function f0854() {} + function f0855() {} + function f0856() {} + function f0857() {} + function f0858() {} + function f0859() {} + function f0860() {} + function f0861() {} + function f0862() {} + function f0863() {} + function f0864() {} + function f0865() {} + function f0866() {} + function f0867() {} + function f0868() {} + function f0869() {} + function f0870() {} + function f0871() {} + function f0872() {} + function f0873() {} + function f0874() {} + function f0875() {} + function f0876() {} + function f0877() {} + function f0878() {} + function f0879() {} + function f0880() {} + function f0881() {} + function f0882() {} + function f0883() {} + function f0884() {} + function f0885() {} + function f0886() {} + function f0887() {} + function f0888() {} + function f0889() {} + function f0890() {} + function f0891() {} + function f0892() {} + function f0893() {} + function f0894() {} + function f0895() {} + function f0896() {} + function f0897() {} + function f0898() {} + function f0899() {} + function f0900() {} + function f0901() {} + function f0902() {} + function f0903() {} + function f0904() {} + function f0905() {} + function f0906() {} + function f0907() {} + function f0908() {} + function f0909() {} + function f0910() {} + function f0911() {} + function f0912() {} + function f0913() {} + function f0914() {} + function f0915() {} + function f0916() {} + function f0917() {} + function f0918() {} + function f0919() {} + function f0920() {} + function f0921() {} + function f0922() {} + function f0923() {} + function f0924() {} + function f0925() {} + function f0926() {} + function f0927() {} + function f0928() {} + function f0929() {} + function f0930() {} + function f0931() {} + function f0932() {} + function f0933() {} + function f0934() {} + function f0935() {} + function f0936() {} + function f0937() {} + function f0938() {} + function f0939() {} + function f0940() {} + function f0941() {} + function f0942() {} + function f0943() {} + function f0944() {} + function f0945() {} + function f0946() {} + function f0947() {} + function f0948() {} + function f0949() {} + function f0950() {} + function f0951() {} + function f0952() {} + function f0953() {} + function f0954() {} + function f0955() {} + function f0956() {} + function f0957() {} + function f0958() {} + function f0959() {} + function f0960() {} + function f0961() {} + function f0962() {} + function f0963() {} + function f0964() {} + function f0965() {} + function f0966() {} + function f0967() {} + function f0968() {} + function f0969() {} + function f0970() {} + function f0971() {} + function f0972() {} + function f0973() {} + function f0974() {} + function f0975() {} + function f0976() {} + function f0977() {} + function f0978() {} + function f0979() {} + function f0980() {} + function f0981() {} + function f0982() {} + function f0983() {} + function f0984() {} + function f0985() {} + function f0986() {} + function f0987() {} + function f0988() {} + function f0989() {} + function f0990() {} + function f0991() {} + function f0992() {} + function f0993() {} + function f0994() {} + function f0995() {} + function f0996() {} + function f0997() {} + function f0998() {} + function f0999() {} + function f1000() {} + function f1001() {} + function f1002() {} + function f1003() {} + function f1004() {} + function f1005() {} + function f1006() {} + function f1007() {} + function f1008() {} + function f1009() {} + function f1010() {} + function f1011() {} + function f1012() {} + function f1013() {} + function f1014() {} + function f1015() {} + function f1016() {} + function f1017() {} + function f1018() {} + function f1019() {} + function f1020() {} + function f1021() {} + function f1022() {} + function f1023() {} + function f1024() {} + } +} + +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// ---- +// SyntaxError 9633: (22-28701): Too many functions defined in object "a". At most 1023 function definitions are allowed for EOF.