mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Binary transform for br and br_if.
This commit is contained in:
@@ -358,13 +358,13 @@ bytes BinaryTransform::operator()(If const& _if)
|
||||
toBytes(Opcode::If) +
|
||||
toBytes(ValueType::Void);
|
||||
|
||||
m_labels.push({});
|
||||
m_labels.emplace_back();
|
||||
|
||||
result += visit(_if.statements);
|
||||
if (_if.elseStatements)
|
||||
result += toBytes(Opcode::Else) + visit(*_if.elseStatements);
|
||||
|
||||
m_labels.pop();
|
||||
m_labels.pop_back();
|
||||
|
||||
result += toBytes(Opcode::End);
|
||||
return result;
|
||||
@@ -374,26 +374,24 @@ bytes BinaryTransform::operator()(Loop const& _loop)
|
||||
{
|
||||
bytes result = toBytes(Opcode::Loop) + toBytes(ValueType::Void);
|
||||
|
||||
m_labels.push(_loop.labelName);
|
||||
m_labels.emplace_back(_loop.labelName);
|
||||
result += visit(_loop.statements);
|
||||
m_labels.pop();
|
||||
m_labels.pop_back();
|
||||
|
||||
result += toBytes(Opcode::End);
|
||||
return result;
|
||||
}
|
||||
|
||||
bytes BinaryTransform::operator()(Break const&)
|
||||
bytes BinaryTransform::operator()(Break const& _break)
|
||||
{
|
||||
yulAssert(false, "br not yet implemented.");
|
||||
// TODO the index is just the nesting depth.
|
||||
return {};
|
||||
return toBytes(Opcode::Br) + encodeLabelIdx(_break.label.name);
|
||||
}
|
||||
|
||||
bytes BinaryTransform::operator()(BreakIf const&)
|
||||
bytes BinaryTransform::operator()(BreakIf const& _breakIf)
|
||||
{
|
||||
yulAssert(false, "br_if not yet implemented.");
|
||||
// TODO the index is just the nesting depth.
|
||||
return {};
|
||||
bytes result = std::visit(*this, *_breakIf.condition);
|
||||
result += toBytes(Opcode::BrIf) + encodeLabelIdx(_breakIf.label.name);
|
||||
return result;
|
||||
}
|
||||
|
||||
bytes BinaryTransform::operator()(Return const&)
|
||||
@@ -403,11 +401,14 @@ bytes BinaryTransform::operator()(Return const&)
|
||||
|
||||
bytes BinaryTransform::operator()(Block const& _block)
|
||||
{
|
||||
return
|
||||
m_labels.emplace_back(_block.labelName);
|
||||
bytes result =
|
||||
toBytes(Opcode::Block) +
|
||||
toBytes(ValueType::Void) +
|
||||
visit(_block.statements) +
|
||||
toBytes(Opcode::End);
|
||||
m_labels.pop_back();
|
||||
return result;
|
||||
}
|
||||
|
||||
bytes BinaryTransform::operator()(FunctionDefinition const& _function)
|
||||
@@ -427,9 +428,13 @@ bytes BinaryTransform::operator()(FunctionDefinition const& _function)
|
||||
for (size_t i = 0; i < _function.locals.size(); ++i)
|
||||
m_locals[_function.locals[i].variableName] = varIdx++;
|
||||
|
||||
yulAssert(m_labels.empty(), "Stray labels.");
|
||||
|
||||
ret += visit(_function.body);
|
||||
ret += toBytes(Opcode::End);
|
||||
|
||||
yulAssert(m_labels.empty(), "Stray labels.");
|
||||
|
||||
return prefixSize(std::move(ret));
|
||||
}
|
||||
|
||||
@@ -581,6 +586,18 @@ bytes BinaryTransform::visitReversed(vector<Expression> const& _expressions)
|
||||
return result;
|
||||
}
|
||||
|
||||
bytes BinaryTransform::encodeLabelIdx(string const& _label) const
|
||||
{
|
||||
yulAssert(!_label.empty(), "Empty label.");
|
||||
size_t depth = 0;
|
||||
for (string const& label: m_labels | boost::adaptors::reversed)
|
||||
if (label == _label)
|
||||
return lebEncode(depth);
|
||||
else
|
||||
++depth;
|
||||
yulAssert(false, "Label not found.");
|
||||
}
|
||||
|
||||
bytes BinaryTransform::encodeName(std::string const& _name)
|
||||
{
|
||||
// UTF-8 is allowed here by the Wasm spec, but since all names here should stem from
|
||||
|
||||
@@ -77,13 +77,15 @@ private:
|
||||
bytes visit(std::vector<wasm::Expression> const& _expressions);
|
||||
bytes visitReversed(std::vector<wasm::Expression> const& _expressions);
|
||||
|
||||
bytes encodeLabelIdx(std::string const& _label) const;
|
||||
|
||||
static bytes encodeName(std::string const& _name);
|
||||
|
||||
std::map<std::string, size_t> m_locals;
|
||||
std::map<std::string, size_t> m_globals;
|
||||
std::map<std::string, size_t> m_functions;
|
||||
std::map<std::string, size_t> m_functionTypes;
|
||||
std::stack<std::string> m_labels;
|
||||
std::vector<std::string> m_labels;
|
||||
std::map<std::string, std::pair<size_t, size_t>> m_subModulePosAndSize;
|
||||
};
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ string TextTransform::operator()(wasm::Loop const& _loop)
|
||||
|
||||
string TextTransform::operator()(wasm::Break const& _break)
|
||||
{
|
||||
return "(break $" + _break.label.name + ")\n";
|
||||
return "(br $" + _break.label.name + ")\n";
|
||||
}
|
||||
|
||||
string TextTransform::operator()(wasm::BreakIf const& _break)
|
||||
|
||||
Reference in New Issue
Block a user