4545using namespace solidity ;
4646using namespace solidity ::yul;
4747
48- StackLayout StackLayoutGenerator::run (CFG const & _cfg, bool _simulateFunctionsWithJumps, size_t _reachableStackDepth )
48+ StackLayout StackLayoutGenerator::run (CFG const & _cfg, EVMDialect const & _evmDialect )
4949{
5050 StackLayout stackLayout{{}, {}};
5151 StackLayoutGenerator{
5252 stackLayout,
5353 nullptr ,
54- _simulateFunctionsWithJumps,
55- _reachableStackDepth
54+ _evmDialect
5655 }.processEntryPoint (*_cfg.entry );
5756
5857 for (auto & functionInfo: _cfg.functionInfo | ranges::views::values)
5958 StackLayoutGenerator{
6059 stackLayout,
6160 &functionInfo,
62- _simulateFunctionsWithJumps,
63- _reachableStackDepth
61+ _evmDialect
6462 }.processEntryPoint (*functionInfo.entry , &functionInfo);
6563
6664 return stackLayout;
6765}
6866
6967std::map<YulName, std::vector<StackLayoutGenerator::StackTooDeep>> StackLayoutGenerator::reportStackTooDeep (
7068 CFG const & _cfg,
71- bool _simulateFunctionsWithJumps,
72- size_t _reachableStackDepth
69+ EVMDialect const & _evmDialect
7370)
7471{
7572 std::map<YulName, std::vector<StackLayoutGenerator::StackTooDeep>> stackTooDeepErrors;
76- stackTooDeepErrors[YulName{}] = reportStackTooDeep (_cfg, YulName{}, _simulateFunctionsWithJumps, _reachableStackDepth );
73+ stackTooDeepErrors[YulName{}] = reportStackTooDeep (_cfg, YulName{}, _evmDialect );
7774 for (auto const & function: _cfg.functions )
78- if (auto errors = reportStackTooDeep (_cfg, function->name , _simulateFunctionsWithJumps, _reachableStackDepth ); !errors.empty ())
75+ if (auto errors = reportStackTooDeep (_cfg, function->name , _evmDialect ); !errors.empty ())
7976 stackTooDeepErrors[function->name ] = std::move (errors);
8077 return stackTooDeepErrors;
8178}
8279
8380std::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep (
8481 CFG const & _cfg,
8582 YulName _functionName,
86- bool _simulateFunctionsWithJumps,
87- size_t _reachableStackDepth
83+ EVMDialect const & _evmDialect
8884)
8985{
9086 StackLayout stackLayout{{}, {}};
@@ -99,7 +95,7 @@ std::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStac
9995 yulAssert (functionInfo, " Function not found." );
10096 }
10197
102- StackLayoutGenerator generator{stackLayout, functionInfo, _simulateFunctionsWithJumps, _reachableStackDepth };
98+ StackLayoutGenerator generator{stackLayout, functionInfo, _evmDialect };
10399 CFG::BasicBlock const * entry = functionInfo ? functionInfo->entry : _cfg.entry ;
104100 generator.processEntryPoint (*entry);
105101 return generator.reportStackTooDeep (*entry);
@@ -108,13 +104,11 @@ std::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStac
108104StackLayoutGenerator::StackLayoutGenerator (
109105 StackLayout& _layout,
110106 CFG::FunctionInfo const * _functionInfo,
111- bool _simulateFunctionsWithJumps,
112- size_t _reachableStackDepth
107+ EVMDialect const & _evmDialect
113108):
114109 m_layout(_layout),
115110 m_currentFunctionInfo(_functionInfo),
116- m_simulateFunctionsWithJumps(_simulateFunctionsWithJumps),
117- m_reachableStackDepth(_reachableStackDepth)
111+ m_evmDialect(_evmDialect)
118112{
119113}
120114
@@ -312,7 +306,7 @@ Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG
312306
313307 // Determine the ideal permutation of the slots in _exitLayout that are not operation outputs (and not to be
314308 // generated on the fly), s.t. shuffling the `stack + _operation.output` to _exitLayout is cheap.
315- Stack stack = createIdealLayout (_operation.output , _exitStack, generateSlotOnTheFly, m_reachableStackDepth );
309+ Stack stack = createIdealLayout (_operation.output , _exitStack, generateSlotOnTheFly, reachableStackDepth () );
316310
317311 // Make sure the resulting previous slots do not overlap with any assignmed variables.
318312 if (auto const * assignment = std::get_if<CFG::Assignment>(&_operation.operation ))
@@ -336,7 +330,7 @@ Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG
336330 stack.pop_back ();
337331 else if (auto offset = util::findOffset (stack | ranges::views::reverse | ranges::views::drop (1 ), stack.back ()))
338332 {
339- if (*offset + 2 < m_reachableStackDepth )
333+ if (*offset + 2 < reachableStackDepth () )
340334 stack.pop_back ();
341335 else
342336 break ;
@@ -354,7 +348,7 @@ Stack StackLayoutGenerator::propagateStackThroughBlock(Stack _exitStack, CFG::Ba
354348 for (auto && [idx, operation]: _block.operations | ranges::views::enumerate | ranges::views::reverse)
355349 {
356350 Stack newStack = propagateStackThroughOperation (stack, operation, _aggressiveStackCompression);
357- if (!_aggressiveStackCompression && !findStackTooDeep (newStack, stack, m_reachableStackDepth ).empty ())
351+ if (!_aggressiveStackCompression && !findStackTooDeep (newStack, stack, reachableStackDepth () ).empty ())
358352 // If we had stack errors, run again with aggressive stack compression.
359353 return propagateStackThroughBlock (std::move (_exitStack), _block, true );
360354 stack = std::move (newStack);
@@ -476,7 +470,7 @@ std::optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies(
476470 Stack stack = combineStack (
477471 m_layout.blockInfos .at (_conditionalJump.zero ).entryLayout ,
478472 m_layout.blockInfos .at (_conditionalJump.nonZero ).entryLayout ,
479- m_reachableStackDepth
473+ reachableStackDepth ()
480474 );
481475 // Additionally, the jump condition has to be at the stack top at exit.
482476 stack.emplace_back (_conditionalJump.condition );
@@ -497,7 +491,7 @@ std::optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies(
497491 return StackSlot{_varSlot};
498492 }) | ranges::to<Stack>;
499493
500- if (m_simulateFunctionsWithJumps )
494+ if (simulateFunctionsWithJumps () )
501495 stack.emplace_back (FunctionReturnLabelSlot{_functionReturn.info ->function });
502496 return stack;
503497 },
@@ -677,7 +671,7 @@ std::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStac
677671 {
678672 Stack& operationEntry = m_layout.operationEntryLayout .at (&operation);
679673
680- stackTooDeepErrors += findStackTooDeep (currentStack, operationEntry, m_reachableStackDepth );
674+ stackTooDeepErrors += findStackTooDeep (currentStack, operationEntry, reachableStackDepth () );
681675 currentStack = operationEntry;
682676 for (size_t i = 0 ; i < operation.input .size (); i++)
683677 currentStack.pop_back ();
@@ -691,7 +685,7 @@ std::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStac
691685 [&](CFG::BasicBlock::Jump const & _jump)
692686 {
693687 Stack const & targetLayout = m_layout.blockInfos .at (_jump.target ).entryLayout ;
694- stackTooDeepErrors += findStackTooDeep (currentStack, targetLayout, m_reachableStackDepth );
688+ stackTooDeepErrors += findStackTooDeep (currentStack, targetLayout, reachableStackDepth () );
695689
696690 if (!_jump.backwards )
697691 _addChild (_jump.target );
@@ -702,7 +696,7 @@ std::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStac
702696 m_layout.blockInfos .at (_conditionalJump.zero ).entryLayout ,
703697 m_layout.blockInfos .at (_conditionalJump.nonZero ).entryLayout
704698 })
705- stackTooDeepErrors += findStackTooDeep (currentStack, targetLayout, m_reachableStackDepth );
699+ stackTooDeepErrors += findStackTooDeep (currentStack, targetLayout, reachableStackDepth () );
706700
707701 _addChild (_conditionalJump.zero );
708702 _addChild (_conditionalJump.nonZero );
@@ -769,7 +763,7 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi
769763 _addChild (_conditionalJump.zero );
770764 _addChild (_conditionalJump.nonZero );
771765 },
772- [&](CFG::BasicBlock::FunctionReturn const &) { yulAssert (!m_simulateFunctionsWithJumps ); },
766+ [&](CFG::BasicBlock::FunctionReturn const &) { yulAssert (!simulateFunctionsWithJumps () ); },
773767 [&](CFG::BasicBlock::Terminated const &) {},
774768 }, _block->exit );
775769 });
@@ -779,21 +773,21 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi
779773 size_t opGas = 0 ;
780774 auto swap = [&](unsigned _swapDepth)
781775 {
782- if (_swapDepth > m_reachableStackDepth )
776+ if (_swapDepth > reachableStackDepth () )
783777 opGas += 1000 ;
784778 else
785- opGas += evmasm::GasMeter::swapGas (_swapDepth, langutil::EVMVersion{} );
779+ opGas += evmasm::GasMeter::swapGas (_swapDepth, m_evmDialect. evmVersion () );
786780 };
787781 auto dupOrPush = [&](StackSlot const & _slot)
788782 {
789783 if (canBeFreelyGenerated (_slot))
790- opGas += evmasm::GasMeter::runGas (evmasm::pushInstruction (32 ), langutil::EVMVersion ());
784+ opGas += evmasm::GasMeter::runGas (evmasm::pushInstruction (32 ), m_evmDialect. evmVersion ());
791785 else
792786 {
793787 if (auto depth = util::findOffset (_source | ranges::views::reverse, _slot))
794788 {
795- if (*depth < m_reachableStackDepth )
796- opGas += evmasm::GasMeter::dupGas (*depth + 1 , langutil::EVMVersion{} );
789+ if (*depth < reachableStackDepth () )
790+ opGas += evmasm::GasMeter::dupGas (*depth + 1 , m_evmDialect. evmVersion () );
797791 else
798792 opGas += 1000 ;
799793 }
@@ -805,12 +799,12 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi
805799 yulAssert (util::contains (m_currentFunctionInfo->returnVariables , std::get<VariableSlot>(_slot)));
806800 // Strictly speaking the cost of the PUSH0 depends on the targeted EVM version, but the difference
807801 // will not matter here.
808- opGas += evmasm::GasMeter::pushGas (u256 (0 ), langutil::EVMVersion ());
802+ opGas += evmasm::GasMeter::pushGas (u256 (0 ), m_evmDialect. evmVersion ());
809803 }
810804 }
811805 };
812- auto pop = [&]() { opGas += evmasm::GasMeter::runGas (evmasm::Instruction::POP,langutil::EVMVersion ()); };
813- createStackLayout (_source, _target, swap, dupOrPush, pop, m_reachableStackDepth );
806+ auto pop = [&]() { opGas += evmasm::GasMeter::runGas (evmasm::Instruction::POP, m_evmDialect. evmVersion ()); };
807+ createStackLayout (_source, _target, swap, dupOrPush, pop, reachableStackDepth () );
814808 return opGas;
815809 };
816810 // / @returns the number of junk slots to be prepended to @a _targetLayout for an optimal transition from
0 commit comments