mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
new container
This commit is contained in:
@@ -101,7 +101,8 @@ public:
|
||||
/// Creates a new sub-assembly, which can be referenced using dataSize and dataOffset.
|
||||
virtual std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(bool _creation, std::optional<uint8_t> _eofVersion, std::string _name = "") = 0;
|
||||
|
||||
virtual FunctionID createFunction(uint8_t _args, uint8_t _rets) = 0;
|
||||
virtual FunctionID createFunction(uint8_t _args, uint8_t _rets, uint16_t _maxStackHeight) = 0;
|
||||
virtual void setMaxStackHeight(FunctionID _functionID, uint16_t _maxStackHeight) = 0;
|
||||
virtual void beginFunction(FunctionID _functionID) = 0;
|
||||
virtual void endFunction() = 0;
|
||||
|
||||
|
||||
@@ -146,9 +146,14 @@ pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> EthAssemblyAdapter::
|
||||
return {make_shared<EthAssemblyAdapter>(*assembly), static_cast<size_t>(sub.data())};
|
||||
}
|
||||
|
||||
AbstractAssembly::FunctionID EthAssemblyAdapter::createFunction(uint8_t _args, uint8_t _rets)
|
||||
AbstractAssembly::FunctionID EthAssemblyAdapter::createFunction(uint8_t _args, uint8_t _rets, uint16_t _maxStackArgs)
|
||||
{
|
||||
return m_assembly.createFunction(_args, _rets);
|
||||
return m_assembly.createFunction(_args, _rets, _maxStackArgs);
|
||||
}
|
||||
|
||||
void EthAssemblyAdapter::setMaxStackHeight(FunctionID _functionID, uint16_t _maxStackHeight)
|
||||
{
|
||||
m_assembly.setMaxStackHeight(_functionID, _maxStackHeight);
|
||||
}
|
||||
|
||||
void EthAssemblyAdapter::beginFunction(AbstractAssembly::FunctionID _functionID)
|
||||
|
||||
@@ -56,7 +56,8 @@ public:
|
||||
void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override;
|
||||
void appendAssemblySize() override;
|
||||
std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(bool _creation, std::optional<uint8_t> _eofVersion, std::string _name = {}) override;
|
||||
AbstractAssembly::FunctionID createFunction(uint8_t _args, uint8_t _rets) override;
|
||||
AbstractAssembly::FunctionID createFunction(uint8_t _args, uint8_t _rets, uint16_t _maxStackHeight) override;
|
||||
void setMaxStackHeight(FunctionID _functionID, uint16_t _maxStackHeight) override;
|
||||
void beginFunction(AbstractAssembly::FunctionID _functionID) override;
|
||||
void endFunction() override;
|
||||
void appendFunctionCall(FunctionID _functionID) override;
|
||||
|
||||
@@ -104,7 +104,7 @@ pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> NoOutputAssembly::cr
|
||||
return {};
|
||||
}
|
||||
|
||||
AbstractAssembly::FunctionID NoOutputAssembly::createFunction(uint8_t _args, uint8_t _rets)
|
||||
AbstractAssembly::FunctionID NoOutputAssembly::createFunction(uint8_t _args, uint8_t _rets, uint16_t)
|
||||
{
|
||||
yulAssert(m_context->numFunctions <= std::numeric_limits<AbstractAssembly::FunctionID>::max());
|
||||
AbstractAssembly::FunctionID id = static_cast<AbstractAssembly::FunctionID>(m_context->numFunctions++);
|
||||
|
||||
@@ -74,7 +74,8 @@ public:
|
||||
|
||||
void appendAssemblySize() override;
|
||||
std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(bool _creation, std::optional<uint8_t> _eofVersion, std::string _name = "") override;
|
||||
FunctionID createFunction(uint8_t _args, uint8_t rets) override;
|
||||
FunctionID createFunction(uint8_t _args, uint8_t rets, uint16_t _maxStackHeight) override;
|
||||
void setMaxStackHeight(AbstractAssembly::FunctionID, uint16_t) override {}
|
||||
void beginFunction(FunctionID) override;
|
||||
void endFunction() override;
|
||||
void appendFunctionCall(FunctionID _functionID) override;
|
||||
|
||||
@@ -40,6 +40,54 @@ using namespace solidity;
|
||||
using namespace solidity::yul;
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
|
||||
uint16_t getMaxStackHeight(CFG::BasicBlock const& _block, StackLayout const& _stackLayout)
|
||||
{
|
||||
size_t maxStackHeight = 0;
|
||||
|
||||
std::list<CFG::BasicBlock const*> toVisit;
|
||||
std::set<CFG::BasicBlock const*> visited;
|
||||
toVisit.push_back(&_block);
|
||||
|
||||
while(!toVisit.empty())
|
||||
{
|
||||
CFG::BasicBlock const* block = toVisit.back();
|
||||
toVisit.pop_back();
|
||||
if (!visited.insert(block).second)
|
||||
continue;
|
||||
|
||||
auto& blockInfo = _stackLayout.blockInfos.at(block);
|
||||
|
||||
maxStackHeight = std::max(maxStackHeight, blockInfo.entryLayout.size());
|
||||
for (auto const& operation: block->operations)
|
||||
{
|
||||
size_t entryLayout = _stackLayout.operationEntryLayout.at(&operation).size();
|
||||
maxStackHeight = std::max(maxStackHeight, entryLayout);
|
||||
size_t exitLayout = entryLayout - operation.input.size() + operation.output.size();
|
||||
maxStackHeight = std::max(maxStackHeight, exitLayout);
|
||||
}
|
||||
maxStackHeight = std::max(maxStackHeight, blockInfo.exitLayout.size());
|
||||
|
||||
std::visit(util::GenericVisitor{
|
||||
[&](CFG::BasicBlock::MainExit const&) {},
|
||||
[&](CFG::BasicBlock::Jump const& _jump) { toVisit.emplace_back(_jump.target); },
|
||||
[&](CFG::BasicBlock::ConditionalJump const& _conditionalJump)
|
||||
{
|
||||
toVisit.emplace_back(_conditionalJump.zero);
|
||||
toVisit.emplace_back(_conditionalJump.nonZero);
|
||||
},
|
||||
[&](CFG::BasicBlock::FunctionReturn const&) {},
|
||||
[&](CFG::BasicBlock::Terminated const&) {}
|
||||
}, block->exit);
|
||||
}
|
||||
|
||||
yulAssert(maxStackHeight <= 0xFFFF);
|
||||
return static_cast<uint16_t>(maxStackHeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
vector<StackTooDeepError> OptimizedEVMCodeTransform::run(
|
||||
AbstractAssembly& _assembly,
|
||||
AsmAnalysisInfo& _analysisInfo,
|
||||
@@ -55,6 +103,8 @@ vector<StackTooDeepError> OptimizedEVMCodeTransform::run(
|
||||
StackLayout stackLayout = StackLayoutGenerator::run(*dfg);
|
||||
|
||||
if (dfg->useFunctions)
|
||||
{
|
||||
_assembly.setMaxStackHeight(0, getMaxStackHeight(*dfg->entry, stackLayout));
|
||||
for (Scope::Function const* function: dfg->functions)
|
||||
{
|
||||
auto const& info = dfg->functionInfo.at(function);
|
||||
@@ -62,10 +112,12 @@ vector<StackTooDeepError> OptimizedEVMCodeTransform::run(
|
||||
yulAssert(info.returnVariables.size() <= 0xFF);
|
||||
auto functionID = _assembly.createFunction(
|
||||
static_cast<uint8_t>(info.parameters.size()),
|
||||
static_cast<uint8_t>(info.returnVariables.size())
|
||||
static_cast<uint8_t>(info.returnVariables.size()),
|
||||
getMaxStackHeight(*info.entry, stackLayout)
|
||||
);
|
||||
_builtinContext.functionIDs[function] = functionID;
|
||||
}
|
||||
}
|
||||
|
||||
OptimizedEVMCodeTransform optimizedCodeTransform(
|
||||
_assembly,
|
||||
|
||||
Reference in New Issue
Block a user