mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #8240 from ethereum/wasmTypeConversions
Remove wasm type conversions
This commit is contained in:
commit
8d3c2ba6d9
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <libyul/backends/wasm/WasmCodeTransform.h>
|
#include <libyul/backends/wasm/WasmCodeTransform.h>
|
||||||
|
|
||||||
|
#include <libyul/backends/wasm/WasmDialect.h>
|
||||||
|
|
||||||
#include <libyul/optimiser/NameCollector.h>
|
#include <libyul/optimiser/NameCollector.h>
|
||||||
|
|
||||||
#include <libyul/AsmData.h>
|
#include <libyul/AsmData.h>
|
||||||
@ -40,7 +42,8 @@ wasm::Module WasmCodeTransform::run(Dialect const& _dialect, yul::Block const& _
|
|||||||
{
|
{
|
||||||
wasm::Module module;
|
wasm::Module module;
|
||||||
|
|
||||||
WasmCodeTransform transform(_dialect, _ast);
|
TypeInfo typeInfo(_dialect, _ast);
|
||||||
|
WasmCodeTransform transform(_dialect, _ast, typeInfo);
|
||||||
|
|
||||||
for (auto const& statement: _ast.statements)
|
for (auto const& statement: _ast.statements)
|
||||||
{
|
{
|
||||||
@ -70,14 +73,18 @@ wasm::Expression WasmCodeTransform::generateMultiAssignment(
|
|||||||
if (_variableNames.size() == 1)
|
if (_variableNames.size() == 1)
|
||||||
return { std::move(assignment) };
|
return { std::move(assignment) };
|
||||||
|
|
||||||
allocateGlobals(_variableNames.size() - 1);
|
vector<wasm::Type> typesForGlobals;
|
||||||
|
for (size_t i = 1; i < _variableNames.size(); ++i)
|
||||||
|
typesForGlobals.push_back(translatedType(m_typeInfo.typeOfVariable(YulString(_variableNames[i]))));
|
||||||
|
vector<size_t> allocatedIndices = allocateGlobals(typesForGlobals);
|
||||||
|
yulAssert(allocatedIndices.size() == _variableNames.size() - 1, "");
|
||||||
|
|
||||||
wasm::Block block;
|
wasm::Block block;
|
||||||
block.statements.emplace_back(move(assignment));
|
block.statements.emplace_back(move(assignment));
|
||||||
for (size_t i = 1; i < _variableNames.size(); ++i)
|
for (size_t i = 1; i < _variableNames.size(); ++i)
|
||||||
block.statements.emplace_back(wasm::LocalAssignment{
|
block.statements.emplace_back(wasm::LocalAssignment{
|
||||||
move(_variableNames.at(i)),
|
move(_variableNames.at(i)),
|
||||||
make_unique<wasm::Expression>(wasm::GlobalVariable{m_globalVariables.at(i - 1).variableName})
|
make_unique<wasm::Expression>(wasm::GlobalVariable{m_globalVariables.at(allocatedIndices[i - 1]).variableName})
|
||||||
});
|
});
|
||||||
return { std::move(block) };
|
return { std::move(block) };
|
||||||
}
|
}
|
||||||
@ -88,7 +95,7 @@ wasm::Expression WasmCodeTransform::operator()(VariableDeclaration const& _varDe
|
|||||||
for (auto const& var: _varDecl.variables)
|
for (auto const& var: _varDecl.variables)
|
||||||
{
|
{
|
||||||
variableNames.emplace_back(var.name.str());
|
variableNames.emplace_back(var.name.str());
|
||||||
m_localVariables.emplace_back(wasm::VariableDeclaration{variableNames.back(), wasm::Type::i64});
|
m_localVariables.emplace_back(wasm::VariableDeclaration{variableNames.back(), translatedType(var.type)});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_varDecl.value)
|
if (_varDecl.value)
|
||||||
@ -112,8 +119,6 @@ wasm::Expression WasmCodeTransform::operator()(ExpressionStatement const& _state
|
|||||||
|
|
||||||
wasm::Expression WasmCodeTransform::operator()(FunctionCall const& _call)
|
wasm::Expression WasmCodeTransform::operator()(FunctionCall const& _call)
|
||||||
{
|
{
|
||||||
bool typeConversionNeeded = false;
|
|
||||||
|
|
||||||
if (BuiltinFunction const* builtin = m_dialect.builtin(_call.functionName.name))
|
if (BuiltinFunction const* builtin = m_dialect.builtin(_call.functionName.name))
|
||||||
{
|
{
|
||||||
if (_call.functionName.name.str().substr(0, 4) == "eth.")
|
if (_call.functionName.name.str().substr(0, 4) == "eth.")
|
||||||
@ -133,7 +138,6 @@ wasm::Expression WasmCodeTransform::operator()(FunctionCall const& _call)
|
|||||||
imp.paramTypes.emplace_back(translatedType(param));
|
imp.paramTypes.emplace_back(translatedType(param));
|
||||||
m_functionsToImport[builtin->name] = std::move(imp);
|
m_functionsToImport[builtin->name] = std::move(imp);
|
||||||
}
|
}
|
||||||
typeConversionNeeded = true;
|
|
||||||
}
|
}
|
||||||
else if (builtin->literalArguments && contains(builtin->literalArguments.value(), true))
|
else if (builtin->literalArguments && contains(builtin->literalArguments.value(), true))
|
||||||
{
|
{
|
||||||
@ -147,18 +151,10 @@ wasm::Expression WasmCodeTransform::operator()(FunctionCall const& _call)
|
|||||||
return wasm::BuiltinCall{_call.functionName.name.str(), std::move(literals)};
|
return wasm::BuiltinCall{_call.functionName.name.str(), std::move(literals)};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
return wasm::BuiltinCall{
|
||||||
wasm::BuiltinCall call{
|
|
||||||
_call.functionName.name.str(),
|
_call.functionName.name.str(),
|
||||||
injectTypeConversionIfNeeded(visit(_call.arguments), builtin->parameters)
|
visit(_call.arguments)
|
||||||
};
|
};
|
||||||
if (!builtin->returns.empty() && !builtin->returns.front().empty() && builtin->returns.front() != "i64"_yulstring)
|
|
||||||
{
|
|
||||||
yulAssert(builtin->returns.front() == "i32"_yulstring, "Invalid type " + builtin->returns.front().str());
|
|
||||||
call = wasm::BuiltinCall{"i64.extend_i32_u", make_vector<wasm::Expression>(std::move(call))};
|
|
||||||
}
|
|
||||||
return {std::move(call)};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this function returns multiple values, then the first one will
|
// If this function returns multiple values, then the first one will
|
||||||
@ -166,13 +162,7 @@ wasm::Expression WasmCodeTransform::operator()(FunctionCall const& _call)
|
|||||||
// The values have to be used right away in an assignment or variable declaration,
|
// The values have to be used right away in an assignment or variable declaration,
|
||||||
// so it is handled there.
|
// so it is handled there.
|
||||||
|
|
||||||
wasm::FunctionCall funCall{_call.functionName.name.str(), visit(_call.arguments)};
|
return wasm::FunctionCall{_call.functionName.name.str(), visit(_call.arguments)};
|
||||||
if (typeConversionNeeded)
|
|
||||||
// Inject type conversion if needed on the fly. This is just a temporary measure
|
|
||||||
// and can be removed once we have proper types in Yul.
|
|
||||||
return injectTypeConversionIfNeeded(std::move(funCall));
|
|
||||||
else
|
|
||||||
return {std::move(funCall)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm::Expression WasmCodeTransform::operator()(Identifier const& _identifier)
|
wasm::Expression WasmCodeTransform::operator()(Identifier const& _identifier)
|
||||||
@ -182,30 +172,40 @@ wasm::Expression WasmCodeTransform::operator()(Identifier const& _identifier)
|
|||||||
|
|
||||||
wasm::Expression WasmCodeTransform::operator()(Literal const& _literal)
|
wasm::Expression WasmCodeTransform::operator()(Literal const& _literal)
|
||||||
{
|
{
|
||||||
u256 value = valueOfLiteral(_literal);
|
return makeLiteral(translatedType(_literal.type), valueOfLiteral(_literal));
|
||||||
yulAssert(value <= numeric_limits<uint64_t>::max(), "Literal too large: " + value.str());
|
|
||||||
return wasm::Literal{static_cast<uint64_t>(value)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm::Expression WasmCodeTransform::operator()(If const& _if)
|
wasm::Expression WasmCodeTransform::operator()(If const& _if)
|
||||||
{
|
{
|
||||||
// TODO converting i64 to i32 might not always be needed.
|
yul::Type conditionType = m_typeInfo.typeOf(*_if.condition);
|
||||||
|
|
||||||
vector<wasm::Expression> args;
|
wasm::Expression condition;
|
||||||
args.emplace_back(visitReturnByValue(*_if.condition));
|
if (conditionType == "i32"_yulstring)
|
||||||
args.emplace_back(wasm::Literal{static_cast<uint64_t>(0)});
|
condition = visitReturnByValue(*_if.condition);
|
||||||
return wasm::If{
|
else if (conditionType == "i64"_yulstring)
|
||||||
make_unique<wasm::Expression>(wasm::BuiltinCall{"i64.ne", std::move(args)}),
|
{
|
||||||
visit(_if.body.statements),
|
vector<wasm::Expression> args;
|
||||||
{}
|
args.emplace_back(visitReturnByValue(*_if.condition));
|
||||||
};
|
args.emplace_back(makeLiteral(translatedType("i64"_yulstring), 0));
|
||||||
|
|
||||||
|
// NOTE: `if` in wasm requires an i32 argument
|
||||||
|
condition = wasm::BuiltinCall{"i64.ne", std::move(args)};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
yulAssert(false, "Invalid condition type");
|
||||||
|
|
||||||
|
return wasm::If{make_unique<wasm::Expression>(move(condition)), visit(_if.body.statements), {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm::Expression WasmCodeTransform::operator()(Switch const& _switch)
|
wasm::Expression WasmCodeTransform::operator()(Switch const& _switch)
|
||||||
{
|
{
|
||||||
|
yul::Type expressionType = m_typeInfo.typeOf(*_switch.expression);
|
||||||
|
YulString eq_instruction = YulString(expressionType.str() + ".eq");
|
||||||
|
yulAssert(WasmDialect::instance().builtin(eq_instruction), "");
|
||||||
|
|
||||||
wasm::Block block;
|
wasm::Block block;
|
||||||
string condition = m_nameDispenser.newName("condition"_yulstring).str();
|
string condition = m_nameDispenser.newName("condition"_yulstring).str();
|
||||||
m_localVariables.emplace_back(wasm::VariableDeclaration{condition, wasm::Type::i64});
|
m_localVariables.emplace_back(wasm::VariableDeclaration{condition, translatedType(expressionType)});
|
||||||
block.statements.emplace_back(wasm::LocalAssignment{condition, visit(*_switch.expression)});
|
block.statements.emplace_back(wasm::LocalAssignment{condition, visit(*_switch.expression)});
|
||||||
|
|
||||||
vector<wasm::Expression>* currentBlock = &block.statements;
|
vector<wasm::Expression>* currentBlock = &block.statements;
|
||||||
@ -214,7 +214,7 @@ wasm::Expression WasmCodeTransform::operator()(Switch const& _switch)
|
|||||||
Case const& c = _switch.cases.at(i);
|
Case const& c = _switch.cases.at(i);
|
||||||
if (c.value)
|
if (c.value)
|
||||||
{
|
{
|
||||||
wasm::BuiltinCall comparison{"i64.eq", make_vector<wasm::Expression>(
|
wasm::BuiltinCall comparison{eq_instruction.str(), make_vector<wasm::Expression>(
|
||||||
wasm::LocalVariable{condition},
|
wasm::LocalVariable{condition},
|
||||||
visitReturnByValue(*c.value)
|
visitReturnByValue(*c.value)
|
||||||
)};
|
)};
|
||||||
@ -253,11 +253,15 @@ wasm::Expression WasmCodeTransform::operator()(ForLoop const& _for)
|
|||||||
string continueLabel = newLabel();
|
string continueLabel = newLabel();
|
||||||
m_breakContinueLabelNames.push({breakLabel, continueLabel});
|
m_breakContinueLabelNames.push({breakLabel, continueLabel});
|
||||||
|
|
||||||
|
yul::Type conditionType = m_typeInfo.typeOf(*_for.condition);
|
||||||
|
YulString eqz_instruction = YulString(conditionType.str() + ".eqz");
|
||||||
|
yulAssert(WasmDialect::instance().builtin(eqz_instruction), "");
|
||||||
|
|
||||||
wasm::Loop loop;
|
wasm::Loop loop;
|
||||||
loop.labelName = newLabel();
|
loop.labelName = newLabel();
|
||||||
loop.statements = visit(_for.pre.statements);
|
loop.statements = visit(_for.pre.statements);
|
||||||
loop.statements.emplace_back(wasm::BranchIf{wasm::Label{breakLabel}, make_unique<wasm::Expression>(
|
loop.statements.emplace_back(wasm::BranchIf{wasm::Label{breakLabel}, make_unique<wasm::Expression>(
|
||||||
wasm::BuiltinCall{"i64.eqz", make_vector<wasm::Expression>(
|
wasm::BuiltinCall{eqz_instruction.str(), make_vector<wasm::Expression>(
|
||||||
visitReturnByValue(*_for.condition)
|
visitReturnByValue(*_for.condition)
|
||||||
)}
|
)}
|
||||||
)});
|
)});
|
||||||
@ -325,11 +329,11 @@ wasm::FunctionDefinition WasmCodeTransform::translateFunction(yul::FunctionDefin
|
|||||||
wasm::FunctionDefinition fun;
|
wasm::FunctionDefinition fun;
|
||||||
fun.name = _fun.name.str();
|
fun.name = _fun.name.str();
|
||||||
for (auto const& param: _fun.parameters)
|
for (auto const& param: _fun.parameters)
|
||||||
fun.parameters.push_back({param.name.str(), wasm::Type::i64});
|
fun.parameters.push_back({param.name.str(), translatedType(param.type)});
|
||||||
for (auto const& retParam: _fun.returnVariables)
|
for (auto const& retParam: _fun.returnVariables)
|
||||||
fun.locals.emplace_back(wasm::VariableDeclaration{retParam.name.str(), wasm::Type::i64});
|
fun.locals.emplace_back(wasm::VariableDeclaration{retParam.name.str(), translatedType(retParam.type)});
|
||||||
if (!_fun.returnVariables.empty())
|
if (!_fun.returnVariables.empty())
|
||||||
fun.returnType = wasm::Type::i64;
|
fun.returnType = translatedType(_fun.returnVariables[0].type);
|
||||||
|
|
||||||
yulAssert(m_localVariables.empty(), "");
|
yulAssert(m_localVariables.empty(), "");
|
||||||
yulAssert(m_functionBodyLabel.empty(), "");
|
yulAssert(m_functionBodyLabel.empty(), "");
|
||||||
@ -347,10 +351,15 @@ wasm::FunctionDefinition WasmCodeTransform::translateFunction(yul::FunctionDefin
|
|||||||
{
|
{
|
||||||
// First return variable is returned directly, the others are stored
|
// First return variable is returned directly, the others are stored
|
||||||
// in globals.
|
// in globals.
|
||||||
allocateGlobals(_fun.returnVariables.size() - 1);
|
vector<wasm::Type> typesForGlobals;
|
||||||
|
for (size_t i = 1; i < _fun.returnVariables.size(); ++i)
|
||||||
|
typesForGlobals.push_back(translatedType(_fun.returnVariables[i].type));
|
||||||
|
vector<size_t> allocatedIndices = allocateGlobals(typesForGlobals);
|
||||||
|
yulAssert(allocatedIndices.size() == _fun.returnVariables.size() - 1, "");
|
||||||
|
|
||||||
for (size_t i = 1; i < _fun.returnVariables.size(); ++i)
|
for (size_t i = 1; i < _fun.returnVariables.size(); ++i)
|
||||||
fun.body.emplace_back(wasm::GlobalAssignment{
|
fun.body.emplace_back(wasm::GlobalAssignment{
|
||||||
m_globalVariables.at(i - 1).variableName,
|
m_globalVariables.at(allocatedIndices[i - 1]).variableName,
|
||||||
make_unique<wasm::Expression>(wasm::LocalVariable{_fun.returnVariables.at(i).name.str()})
|
make_unique<wasm::Expression>(wasm::LocalVariable{_fun.returnVariables.at(i).name.str()})
|
||||||
});
|
});
|
||||||
fun.body.emplace_back(wasm::LocalVariable{_fun.returnVariables.front().name.str()});
|
fun.body.emplace_back(wasm::LocalVariable{_fun.returnVariables.front().name.str()});
|
||||||
@ -358,52 +367,50 @@ wasm::FunctionDefinition WasmCodeTransform::translateFunction(yul::FunctionDefin
|
|||||||
return fun;
|
return fun;
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm::Expression WasmCodeTransform::injectTypeConversionIfNeeded(wasm::FunctionCall _call) const
|
|
||||||
{
|
|
||||||
wasm::FunctionImport const& import = m_functionsToImport.at(YulString{_call.functionName});
|
|
||||||
for (size_t i = 0; i < _call.arguments.size(); ++i)
|
|
||||||
if (import.paramTypes.at(i) == wasm::Type::i32)
|
|
||||||
_call.arguments[i] = wasm::BuiltinCall{"i32.wrap_i64", make_vector<wasm::Expression>(std::move(_call.arguments[i]))};
|
|
||||||
else
|
|
||||||
yulAssert(import.paramTypes.at(i) == wasm::Type::i64, "Invalid Wasm type");
|
|
||||||
|
|
||||||
if (import.returnType && *import.returnType != wasm::Type::i64)
|
|
||||||
{
|
|
||||||
yulAssert(*import.returnType == wasm::Type::i32, "Invalid Wasm type");
|
|
||||||
return wasm::BuiltinCall{"i64.extend_i32_u", make_vector<wasm::Expression>(std::move(_call))};
|
|
||||||
}
|
|
||||||
return {std::move(_call)};
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<wasm::Expression> WasmCodeTransform::injectTypeConversionIfNeeded(
|
|
||||||
vector<wasm::Expression> _arguments,
|
|
||||||
vector<Type> const& _parameterTypes
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < _arguments.size(); ++i)
|
|
||||||
if (_parameterTypes.at(i) == "i32"_yulstring)
|
|
||||||
_arguments[i] = wasm::BuiltinCall{"i32.wrap_i64", make_vector<wasm::Expression>(std::move(_arguments[i]))};
|
|
||||||
else
|
|
||||||
yulAssert(
|
|
||||||
_parameterTypes.at(i).empty() || _parameterTypes.at(i) == "i64"_yulstring,
|
|
||||||
"Unknown type " + _parameterTypes.at(i).str()
|
|
||||||
);
|
|
||||||
|
|
||||||
return _arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
string WasmCodeTransform::newLabel()
|
string WasmCodeTransform::newLabel()
|
||||||
{
|
{
|
||||||
return m_nameDispenser.newName("label_"_yulstring).str();
|
return m_nameDispenser.newName("label_"_yulstring).str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WasmCodeTransform::allocateGlobals(size_t _amount)
|
vector<size_t> WasmCodeTransform::allocateGlobals(vector<wasm::Type> const& _typesForGlobals)
|
||||||
{
|
{
|
||||||
while (m_globalVariables.size() < _amount)
|
map<wasm::Type, size_t> availableGlobals;
|
||||||
m_globalVariables.emplace_back(wasm::GlobalVariableDeclaration{
|
for (wasm::GlobalVariableDeclaration const& global: m_globalVariables)
|
||||||
m_nameDispenser.newName("global_"_yulstring).str(),
|
++availableGlobals[global.type];
|
||||||
wasm::Type::i64
|
|
||||||
});
|
map<wasm::Type, size_t> neededGlobals;
|
||||||
|
for (wasm::Type const& type: _typesForGlobals)
|
||||||
|
++neededGlobals[type];
|
||||||
|
|
||||||
|
for (auto [type, neededGlobalCount]: neededGlobals)
|
||||||
|
while (availableGlobals[type] < neededGlobalCount)
|
||||||
|
{
|
||||||
|
m_globalVariables.emplace_back(wasm::GlobalVariableDeclaration{
|
||||||
|
m_nameDispenser.newName("global_"_yulstring).str(),
|
||||||
|
type,
|
||||||
|
});
|
||||||
|
|
||||||
|
++availableGlobals[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<size_t> allocatedIndices;
|
||||||
|
map<wasm::Type, size_t> nextGlobal;
|
||||||
|
for (wasm::Type const& type: _typesForGlobals)
|
||||||
|
{
|
||||||
|
while (m_globalVariables[nextGlobal[type]].type != type)
|
||||||
|
++nextGlobal[type];
|
||||||
|
|
||||||
|
allocatedIndices.push_back(nextGlobal[type]++);
|
||||||
|
}
|
||||||
|
|
||||||
|
yulAssert(all_of(
|
||||||
|
allocatedIndices.begin(),
|
||||||
|
allocatedIndices.end(),
|
||||||
|
[this](size_t index){ return index < m_globalVariables.size(); }
|
||||||
|
), "");
|
||||||
|
yulAssert(allocatedIndices.size() == set<size_t>(allocatedIndices.begin(), allocatedIndices.end()).size(), "Indices not unique");
|
||||||
|
yulAssert(allocatedIndices.size() == _typesForGlobals.size(), "");
|
||||||
|
return allocatedIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm::Type WasmCodeTransform::translatedType(yul::Type _yulType)
|
wasm::Type WasmCodeTransform::translatedType(yul::Type _yulType)
|
||||||
@ -415,3 +422,19 @@ wasm::Type WasmCodeTransform::translatedType(yul::Type _yulType)
|
|||||||
else
|
else
|
||||||
yulAssert(false, "This Yul type does not have a corresponding type in Wasm.");
|
yulAssert(false, "This Yul type does not have a corresponding type in Wasm.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wasm::Literal WasmCodeTransform::makeLiteral(wasm::Type _type, u256 _value)
|
||||||
|
{
|
||||||
|
if (_type == wasm::Type::i32)
|
||||||
|
{
|
||||||
|
yulAssert(_value <= numeric_limits<uint32_t>::max(), "Literal too large: " + _value.str());
|
||||||
|
return wasm::Literal{static_cast<uint32_t>(_value)};
|
||||||
|
}
|
||||||
|
else if (_type == wasm::Type::i64)
|
||||||
|
{
|
||||||
|
yulAssert(_value <= numeric_limits<uint64_t>::max(), "Literal too large: " + _value.str());
|
||||||
|
return wasm::Literal{static_cast<uint64_t>(_value)};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
yulAssert(false, "Invalid Wasm literal type");
|
||||||
|
}
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
#include <libyul/AsmDataForward.h>
|
#include <libyul/AsmDataForward.h>
|
||||||
#include <libyul/Dialect.h>
|
#include <libyul/Dialect.h>
|
||||||
#include <libyul/optimiser/NameDispenser.h>
|
#include <libyul/optimiser/NameDispenser.h>
|
||||||
|
#include <libyul/optimiser/TypeInfo.h>
|
||||||
|
|
||||||
|
#include <libsolutil/Common.h>
|
||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -56,10 +59,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
WasmCodeTransform(
|
WasmCodeTransform(
|
||||||
Dialect const& _dialect,
|
Dialect const& _dialect,
|
||||||
Block const& _ast
|
Block const& _ast,
|
||||||
|
TypeInfo& _typeInfo
|
||||||
):
|
):
|
||||||
m_dialect(_dialect),
|
m_dialect(_dialect),
|
||||||
m_nameDispenser(_dialect, _ast)
|
m_nameDispenser(_dialect, _ast),
|
||||||
|
m_typeInfo(_typeInfo)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::unique_ptr<wasm::Expression> visit(yul::Expression const& _expression);
|
std::unique_ptr<wasm::Expression> visit(yul::Expression const& _expression);
|
||||||
@ -79,17 +84,13 @@ private:
|
|||||||
|
|
||||||
wasm::FunctionDefinition translateFunction(yul::FunctionDefinition const& _funDef);
|
wasm::FunctionDefinition translateFunction(yul::FunctionDefinition const& _funDef);
|
||||||
|
|
||||||
wasm::Expression injectTypeConversionIfNeeded(wasm::FunctionCall _call) const;
|
|
||||||
std::vector<wasm::Expression> injectTypeConversionIfNeeded(
|
|
||||||
std::vector<wasm::Expression> _arguments,
|
|
||||||
std::vector<yul::Type> const& _parameterTypes
|
|
||||||
) const;
|
|
||||||
|
|
||||||
std::string newLabel();
|
std::string newLabel();
|
||||||
/// Makes sure that there are at least @a _amount global variables.
|
/// Selects a subset of global variables matching specified sequence of variable types.
|
||||||
void allocateGlobals(size_t _amount);
|
/// Defines more global variables of a given type if there's not enough.
|
||||||
|
std::vector<size_t> allocateGlobals(std::vector<wasm::Type> const& _typesForGlobals);
|
||||||
|
|
||||||
static wasm::Type translatedType(yul::Type _yulType);
|
static wasm::Type translatedType(yul::Type _yulType);
|
||||||
|
static wasm::Literal makeLiteral(wasm::Type _type, u256 _value);
|
||||||
|
|
||||||
Dialect const& m_dialect;
|
Dialect const& m_dialect;
|
||||||
NameDispenser m_nameDispenser;
|
NameDispenser m_nameDispenser;
|
||||||
@ -99,6 +100,7 @@ private:
|
|||||||
std::map<YulString, wasm::FunctionImport> m_functionsToImport;
|
std::map<YulString, wasm::FunctionImport> m_functionsToImport;
|
||||||
std::string m_functionBodyLabel;
|
std::string m_functionBodyLabel;
|
||||||
std::stack<std::pair<std::string, std::string>> m_breakContinueLabelNames;
|
std::stack<std::pair<std::string, std::string>> m_breakContinueLabelNames;
|
||||||
|
TypeInfo& m_typeInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ object "object" {
|
|||||||
|
|
||||||
|
|
||||||
Binary representation:
|
Binary representation:
|
||||||
0061736d0100000001160460000060017e017e60057e7e7e7e7e0060027f7f0002190108657468657265756d0c73746f7261676553746f7265000303060500010101020503010001060100071102066d656d6f72790200046d61696e00010acb01052b01017e0240420021004200200020002000200010054220200020002000420110054200a74220a710000b0b1f01017e024020004208864280fe0383200042088842ff01838421010b20010b1e01027e02402000100242108621022002200042108810028421010b20010b1e01027e02402000100342208621022002200042208810038421010b20010b3f0002402000a7200110043700002000a74208a76aada7200210043700002000a74210a76aada7200310043700002000a74218a76aada7200410043700000b0b
|
0061736d0100000001160460000060017e017e60057f7e7e7e7e0060027f7f0002190108657468657265756d0c73746f7261676553746f7265000303060500010101020503010001060100071102066d656d6f72790200046d61696e00010abc01052901017e0240420021004100200020002000200010054120200020002000420110054100412010000b0b1f01017e024020004208864280fe0383200042088842ff01838421010b20010b1e01027e02402000100242108621022002200042108810028421010b20010b1e01027e02402000100342208621022002200042208810038421010b20010b32000240200020011004370000200041086a20021004370000200041106a20031004370000200041186a200410043700000b0b
|
||||||
|
|
||||||
Text representation:
|
Text representation:
|
||||||
(module
|
(module
|
||||||
@ -57,9 +57,9 @@ Text representation:
|
|||||||
(local $_1 i64)
|
(local $_1 i64)
|
||||||
(block $label_
|
(block $label_
|
||||||
(local.set $_1 (i64.const 0))
|
(local.set $_1 (i64.const 0))
|
||||||
(call $mstore_internal (i64.const 0) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))
|
(call $mstore_internal (i32.const 0) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))
|
||||||
(call $mstore_internal (i64.const 32) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 1))
|
(call $mstore_internal (i32.const 32) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 1))
|
||||||
(call $eth.storageStore (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 32)))
|
(call $eth.storageStore (i32.const 0) (i32.const 32))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -101,16 +101,16 @@ Text representation:
|
|||||||
)
|
)
|
||||||
|
|
||||||
(func $mstore_internal
|
(func $mstore_internal
|
||||||
(param $pos i64)
|
(param $pos i32)
|
||||||
(param $y1 i64)
|
(param $y1 i64)
|
||||||
(param $y2 i64)
|
(param $y2 i64)
|
||||||
(param $y3 i64)
|
(param $y3 i64)
|
||||||
(param $y4 i64)
|
(param $y4 i64)
|
||||||
(block $label__4
|
(block $label__4
|
||||||
(i64.store (i32.wrap_i64 (local.get $pos)) (call $endian_swap (local.get $y1)))
|
(i64.store (local.get $pos) (call $endian_swap (local.get $y1)))
|
||||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $pos)) (i32.wrap_i64 (i64.const 8))))) (call $endian_swap (local.get $y2)))
|
(i64.store (i32.add (local.get $pos) (i32.const 8)) (call $endian_swap (local.get $y2)))
|
||||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $pos)) (i32.wrap_i64 (i64.const 16))))) (call $endian_swap (local.get $y3)))
|
(i64.store (i32.add (local.get $pos) (i32.const 16)) (call $endian_swap (local.get $y3)))
|
||||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $pos)) (i32.wrap_i64 (i64.const 24))))) (call $endian_swap (local.get $y4)))
|
(i64.store (i32.add (local.get $pos) (i32.const 24)) (call $endian_swap (local.get $y4)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ object "object" {
|
|||||||
|
|
||||||
|
|
||||||
Binary representation:
|
Binary representation:
|
||||||
0061736d0100000001480a60000060017e017e60027e7e017e60037e7e7e017e60047e7e7e7e017e60057e7e7e7e7e0060087e7e7e7e7e7e7e7e0060087e7e7e7e7e7e7e7e017e60027f7f0060037f7f7f0002310208657468657265756d0c73746f7261676553746f7265000808657468657265756d0c63616c6c44617461436f70790009030e0d0003070407020704010101050605030100010610037e0142000b7e0142000b7e0142000b071102066d656d6f72790200046d61696e00020aa5090df302011f7e02404200210002402000200020002000100921012300210223012103230221040b2001210520022106200321072004210842012109200020008420002009848450ada745ada745ad210a02400340200aa745ad500d01024002402005200620072008200020002000420a1008210b2300210c2301210d2302210e0b0240200b200c200d200e1005210f2300211023012111230221120b200f20108420112012848450ada745ad42005204400c030b024020052006200720082000200020004202100621132300211423012115230221160b201320148420152016848450ada745ad42005204400c030b0240200520062007200820002000200042041006211723002118230121192302211a0b20172018842019201a848450ada745ad42005204400c010b0b0240200520062007200820002000200020091004211b2300211c2301211d2302211e0b201b2105201c2106201d2107201e21080c000b0b20002000200020002005200620072008100e0b0b2f01037e0240200020017c2105200520027c21032005200054ada72003200554ada772ada7ad21040b2004240020030b72010b7e0240200320077c210c200c42007c210b024020022006200c200354ada7200b200c54ada772ada7ad1003210d2300210e0b200d210a024020012005200e1003210f230021100b200f2109024020002004201010032111230021120b201121080b20092400200a2401200b240220080b2601047e0240200020018420022003848450ada7ad21070b20052400200624012007240220040b4901047e02402000200451ad42005204402001200551ad42005204402002200651ad42005204402003200751ad42005204404201210b0b0b0b0b0b20092400200a2401200b240220080b2d01027e024002402000200154ad21032003420151044042ffffffff0f2102052000200152ad21020b0b0b20020b960101087e02404200210c0240200020041007210d200d42005104400240200120051007210e200e42005104400240200220061007210f200f42005104402003200754ad210c05200f42015104404200210c054201210c0b0b0b05200e42015104404200210c054201210c0b0b0b05200d42015104404200210c054201210c0b0b0b200ca7ad210b0b20092400200a2401200b240220080b8f0101087e02404200200020018420028452ad4200520440000b4200200342208852ad4200520440000b4200a72003a7ada74220a710014200a7290000100c21084200a74208a76aada7290000100c21094200a74210a76aada7290000100c210a4200a74218a76aada7290000100c210b2008210420092105200a2106200b21070b20052400200624012007240220040b1f01017e024020004208864280fe0383200042088842ff01838421010b20010b1e01027e02402000100a421086210220022000421088100a8421010b20010b1e01027e02402000100b422086210220022000422088100b8421010b20010b3f0002402000a72001100c3700002000a74208a76aada72002100c3700002000a74210a76aada72003100c3700002000a74218a76aada72004100c3700000b0b2500024042002000200120022003100d42202004200520062007100d4200a74220a710000b0b
|
0061736d0100000001480a60000060017e017e60027e7e017f60037e7e7e017e60047e7e7e7e017e60087e7e7e7e7e7e7e7e0060087e7e7e7e7e7e7e7e017e60057f7e7e7e7e0060027f7f0060037f7f7f0002310208657468657265756d0c73746f7261676553746f7265000808657468657265756d0c63616c6c44617461436f70790009030e0d0003060406020604010101070505030100010610037e0142000b7e0142000b7e0142000b071102066d656d6f72790200046d61696e00020ac3080dde02030a7e017f147e02404200210002402000200020002000100921012300210223012103230221040b20012105200221062003210720042108420121092000200084200020098484504545210a02400340200a45450d01024002402005200620072008200020002000420a1008210b2300210c2301210d2302210e0b0240200b200c200d200e1005210f2300211023012111230221120b200f201084201120128484504504400c030b024020052006200720082000200020004202100621132300211423012115230221160b2013201484201520168484504504400c030b0240200520062007200820002000200042041006211723002118230121192302211a0b20172018842019201a8484504504400c010b0b0240200520062007200820002000200020091004211b2300211c2301211d2302211e0b201b2105201c2106201d2107201e21080c000b0b20002000200020002005200620072008100e0b0b2901037e0240200020017c2105200520027c21032005200054200320055472ad21040b2004240020030b6c010b7e0240200320077c210c200c42007c210b024020022006200c200354200b200c5472ad1003210d2300210e0b200d210a024020012005200e1003210f230021100b200f2109024020002004201010032111230021120b201121080b20092400200a2401200b240220080b2401047e0240200020018420022003848450ad21070b20052400200624012007240220040b3901047e0240200020045104402001200551044020022006510440200320075104404201210b0b0b0b0b0b20092400200a2401200b240220080b2701027f024002402000200154210320034101460440417f210205200020015221020b0b0b20020b960102047e047f02404100210c0240200020041007210d200d41004604400240200120051007210e200e41004604400240200220061007210f200f41004604402003200754210c05200f41014604404100210c054101210c0b0b0b05200e41014604404100210c054101210c0b0b0b05200d41014604404100210c054101210c0b0b0b200cad210b0b20092400200a2401200b240220080b7601087e024042002000200184200284520440000b42002003422088520440000b41002003a7412010014100290000100c2108410041086a290000100c2109410041106a290000100c210a410041186a290000100c210b2008210420092105200a2106200b21070b20052400200624012007240220040b1f01017e024020004208864280fe0383200042088842ff01838421010b20010b1e01027e02402000100a421086210220022000421088100a8421010b20010b1e01027e02402000100b422086210220022000422088100b8421010b20010b3200024020002001100c370000200041086a2002100c370000200041106a2003100c370000200041186a2004100c3700000b0b2300024041002000200120022003100d41202004200520062007100d4100412010000b0b
|
||||||
|
|
||||||
Text representation:
|
Text representation:
|
||||||
(module
|
(module
|
||||||
@ -177,7 +177,7 @@ Text representation:
|
|||||||
(local $x_6 i64)
|
(local $x_6 i64)
|
||||||
(local $x_7 i64)
|
(local $x_7 i64)
|
||||||
(local $_2 i64)
|
(local $_2 i64)
|
||||||
(local $_3 i64)
|
(local $_3 i32)
|
||||||
(local $_4 i64)
|
(local $_4 i64)
|
||||||
(local $_5 i64)
|
(local $_5 i64)
|
||||||
(local $_6 i64)
|
(local $_6 i64)
|
||||||
@ -212,10 +212,10 @@ Text representation:
|
|||||||
(local.set $x_6 (local.get $x_2))
|
(local.set $x_6 (local.get $x_2))
|
||||||
(local.set $x_7 (local.get $x_3))
|
(local.set $x_7 (local.get $x_3))
|
||||||
(local.set $_2 (i64.const 1))
|
(local.set $_2 (i64.const 1))
|
||||||
(local.set $_3 (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (i64.extend_i32_u (i64.eqz (i64.or (i64.or (local.get $_1) (local.get $_1)) (i64.or (local.get $_1) (local.get $_2))))))))))))
|
(local.set $_3 (i32.eqz (i32.eqz (i64.eqz (i64.or (i64.or (local.get $_1) (local.get $_1)) (i64.or (local.get $_1) (local.get $_2)))))))
|
||||||
(block $label__3
|
(block $label__3
|
||||||
(loop $label__5
|
(loop $label__5
|
||||||
(br_if $label__3 (i64.eqz (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (local.get $_3))))))
|
(br_if $label__3 (i32.eqz (i32.eqz (local.get $_3))))
|
||||||
(block $label__4
|
(block $label__4
|
||||||
(block
|
(block
|
||||||
(local.set $_4 (call $lt (local.get $x_4) (local.get $x_5) (local.get $x_6) (local.get $x_7) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 10)))
|
(local.set $_4 (call $lt (local.get $x_4) (local.get $x_5) (local.get $x_6) (local.get $x_7) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 10)))
|
||||||
@ -231,7 +231,7 @@ Text representation:
|
|||||||
(local.set $_11 (global.get $global__2))
|
(local.set $_11 (global.get $global__2))
|
||||||
|
|
||||||
)
|
)
|
||||||
(if (i64.ne (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (i64.extend_i32_u (i64.eqz (i64.or (i64.or (local.get $_8) (local.get $_9)) (i64.or (local.get $_10) (local.get $_11)))))))) (i64.const 0)) (then
|
(if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $_8) (local.get $_9)) (i64.or (local.get $_10) (local.get $_11))))) (then
|
||||||
(br $label__3)
|
(br $label__3)
|
||||||
))
|
))
|
||||||
(block
|
(block
|
||||||
@ -241,7 +241,7 @@ Text representation:
|
|||||||
(local.set $_15 (global.get $global__2))
|
(local.set $_15 (global.get $global__2))
|
||||||
|
|
||||||
)
|
)
|
||||||
(if (i64.ne (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (i64.extend_i32_u (i64.eqz (i64.or (i64.or (local.get $_12) (local.get $_13)) (i64.or (local.get $_14) (local.get $_15)))))))) (i64.const 0)) (then
|
(if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $_12) (local.get $_13)) (i64.or (local.get $_14) (local.get $_15))))) (then
|
||||||
(br $label__3)
|
(br $label__3)
|
||||||
))
|
))
|
||||||
(block
|
(block
|
||||||
@ -251,7 +251,7 @@ Text representation:
|
|||||||
(local.set $_19 (global.get $global__2))
|
(local.set $_19 (global.get $global__2))
|
||||||
|
|
||||||
)
|
)
|
||||||
(if (i64.ne (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (i64.extend_i32_u (i64.eqz (i64.or (i64.or (local.get $_16) (local.get $_17)) (i64.or (local.get $_18) (local.get $_19)))))))) (i64.const 0)) (then
|
(if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $_16) (local.get $_17)) (i64.or (local.get $_18) (local.get $_19))))) (then
|
||||||
(br $label__4)
|
(br $label__4)
|
||||||
))
|
))
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ Text representation:
|
|||||||
(block $label__6
|
(block $label__6
|
||||||
(local.set $t (i64.add (local.get $x) (local.get $y)))
|
(local.set $t (i64.add (local.get $x) (local.get $y)))
|
||||||
(local.set $r (i64.add (local.get $t) (local.get $c)))
|
(local.set $r (i64.add (local.get $t) (local.get $c)))
|
||||||
(local.set $r_c (i64.extend_i32_u (i32.wrap_i64 (i64.extend_i32_u (i32.or (i32.wrap_i64 (i64.extend_i32_u (i64.lt_u (local.get $t) (local.get $x)))) (i32.wrap_i64 (i64.extend_i32_u (i64.lt_u (local.get $r) (local.get $t)))))))))
|
(local.set $r_c (i64.extend_i32_u (i32.or (i64.lt_u (local.get $t) (local.get $x)) (i64.lt_u (local.get $r) (local.get $t)))))
|
||||||
|
|
||||||
)
|
)
|
||||||
(global.set $global_ (local.get $r_c))
|
(global.set $global_ (local.get $r_c))
|
||||||
@ -318,7 +318,7 @@ Text representation:
|
|||||||
(local.set $t (i64.add (local.get $x4) (local.get $y4)))
|
(local.set $t (i64.add (local.get $x4) (local.get $y4)))
|
||||||
(local.set $r4 (i64.add (local.get $t) (i64.const 0)))
|
(local.set $r4 (i64.add (local.get $t) (i64.const 0)))
|
||||||
(block
|
(block
|
||||||
(local.set $r3_1 (call $add_carry (local.get $x3) (local.get $y3) (i64.extend_i32_u (i32.wrap_i64 (i64.extend_i32_u (i32.or (i32.wrap_i64 (i64.extend_i32_u (i64.lt_u (local.get $t) (local.get $x4)))) (i32.wrap_i64 (i64.extend_i32_u (i64.lt_u (local.get $r4) (local.get $t))))))))))
|
(local.set $r3_1 (call $add_carry (local.get $x3) (local.get $y3) (i64.extend_i32_u (i32.or (i64.lt_u (local.get $t) (local.get $x4)) (i64.lt_u (local.get $r4) (local.get $t))))))
|
||||||
(local.set $carry (global.get $global_))
|
(local.set $carry (global.get $global_))
|
||||||
|
|
||||||
)
|
)
|
||||||
@ -354,7 +354,7 @@ Text representation:
|
|||||||
(local $r3 i64)
|
(local $r3 i64)
|
||||||
(local $r4 i64)
|
(local $r4 i64)
|
||||||
(block $label__8
|
(block $label__8
|
||||||
(local.set $r4 (i64.extend_i32_u (i32.wrap_i64 (i64.extend_i32_u (i64.eqz (i64.or (i64.or (local.get $x1) (local.get $x2)) (i64.or (local.get $x3) (local.get $x4))))))))
|
(local.set $r4 (i64.extend_i32_u (i64.eqz (i64.or (i64.or (local.get $x1) (local.get $x2)) (i64.or (local.get $x3) (local.get $x4))))))
|
||||||
|
|
||||||
)
|
)
|
||||||
(global.set $global_ (local.get $r2))
|
(global.set $global_ (local.get $r2))
|
||||||
@ -378,10 +378,10 @@ Text representation:
|
|||||||
(local $r3 i64)
|
(local $r3 i64)
|
||||||
(local $r4 i64)
|
(local $r4 i64)
|
||||||
(block $label__9
|
(block $label__9
|
||||||
(if (i64.ne (i64.extend_i32_u (i64.eq (local.get $x1) (local.get $y1))) (i64.const 0)) (then
|
(if (i64.eq (local.get $x1) (local.get $y1)) (then
|
||||||
(if (i64.ne (i64.extend_i32_u (i64.eq (local.get $x2) (local.get $y2))) (i64.const 0)) (then
|
(if (i64.eq (local.get $x2) (local.get $y2)) (then
|
||||||
(if (i64.ne (i64.extend_i32_u (i64.eq (local.get $x3) (local.get $y3))) (i64.const 0)) (then
|
(if (i64.eq (local.get $x3) (local.get $y3)) (then
|
||||||
(if (i64.ne (i64.extend_i32_u (i64.eq (local.get $x4) (local.get $y4))) (i64.const 0)) (then
|
(if (i64.eq (local.get $x4) (local.get $y4)) (then
|
||||||
(local.set $r4 (i64.const 1))
|
(local.set $r4 (i64.const 1))
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
@ -398,16 +398,16 @@ Text representation:
|
|||||||
(func $cmp
|
(func $cmp
|
||||||
(param $a i64)
|
(param $a i64)
|
||||||
(param $b i64)
|
(param $b i64)
|
||||||
(result i64)
|
(result i32)
|
||||||
(local $r i64)
|
(local $r i32)
|
||||||
(local $condition i64)
|
(local $condition i32)
|
||||||
(block $label__10
|
(block $label__10
|
||||||
(block
|
(block
|
||||||
(local.set $condition (i64.extend_i32_u (i64.lt_u (local.get $a) (local.get $b))))
|
(local.set $condition (i64.lt_u (local.get $a) (local.get $b)))
|
||||||
(if (i64.eq (local.get $condition) (i64.const 1)) (then
|
(if (i32.eq (local.get $condition) (i32.const 1)) (then
|
||||||
(local.set $r (i64.const 4294967295))
|
(local.set $r (i32.const 4294967295))
|
||||||
)(else
|
)(else
|
||||||
(local.set $r (i64.extend_i32_u (i64.ne (local.get $a) (local.get $b))))
|
(local.set $r (i64.ne (local.get $a) (local.get $b)))
|
||||||
))
|
))
|
||||||
|
|
||||||
)
|
)
|
||||||
@ -430,50 +430,50 @@ Text representation:
|
|||||||
(local $z2 i64)
|
(local $z2 i64)
|
||||||
(local $z3 i64)
|
(local $z3 i64)
|
||||||
(local $z4 i64)
|
(local $z4 i64)
|
||||||
(local $z i64)
|
(local $z i32)
|
||||||
(local $condition_12 i64)
|
(local $condition_12 i32)
|
||||||
(local $condition_13 i64)
|
(local $condition_13 i32)
|
||||||
(local $condition_14 i64)
|
(local $condition_14 i32)
|
||||||
(block $label__11
|
(block $label__11
|
||||||
(local.set $z (i64.const 0))
|
(local.set $z (i32.const 0))
|
||||||
(block
|
(block
|
||||||
(local.set $condition_12 (call $cmp (local.get $x1) (local.get $y1)))
|
(local.set $condition_12 (call $cmp (local.get $x1) (local.get $y1)))
|
||||||
(if (i64.eq (local.get $condition_12) (i64.const 0)) (then
|
(if (i32.eq (local.get $condition_12) (i32.const 0)) (then
|
||||||
(block
|
(block
|
||||||
(local.set $condition_13 (call $cmp (local.get $x2) (local.get $y2)))
|
(local.set $condition_13 (call $cmp (local.get $x2) (local.get $y2)))
|
||||||
(if (i64.eq (local.get $condition_13) (i64.const 0)) (then
|
(if (i32.eq (local.get $condition_13) (i32.const 0)) (then
|
||||||
(block
|
(block
|
||||||
(local.set $condition_14 (call $cmp (local.get $x3) (local.get $y3)))
|
(local.set $condition_14 (call $cmp (local.get $x3) (local.get $y3)))
|
||||||
(if (i64.eq (local.get $condition_14) (i64.const 0)) (then
|
(if (i32.eq (local.get $condition_14) (i32.const 0)) (then
|
||||||
(local.set $z (i64.extend_i32_u (i64.lt_u (local.get $x4) (local.get $y4))))
|
(local.set $z (i64.lt_u (local.get $x4) (local.get $y4)))
|
||||||
)(else
|
)(else
|
||||||
(if (i64.eq (local.get $condition_14) (i64.const 1)) (then
|
(if (i32.eq (local.get $condition_14) (i32.const 1)) (then
|
||||||
(local.set $z (i64.const 0))
|
(local.set $z (i32.const 0))
|
||||||
)(else
|
)(else
|
||||||
(local.set $z (i64.const 1))
|
(local.set $z (i32.const 1))
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
|
|
||||||
)
|
)
|
||||||
)(else
|
)(else
|
||||||
(if (i64.eq (local.get $condition_13) (i64.const 1)) (then
|
(if (i32.eq (local.get $condition_13) (i32.const 1)) (then
|
||||||
(local.set $z (i64.const 0))
|
(local.set $z (i32.const 0))
|
||||||
)(else
|
)(else
|
||||||
(local.set $z (i64.const 1))
|
(local.set $z (i32.const 1))
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
|
|
||||||
)
|
)
|
||||||
)(else
|
)(else
|
||||||
(if (i64.eq (local.get $condition_12) (i64.const 1)) (then
|
(if (i32.eq (local.get $condition_12) (i32.const 1)) (then
|
||||||
(local.set $z (i64.const 0))
|
(local.set $z (i32.const 0))
|
||||||
)(else
|
)(else
|
||||||
(local.set $z (i64.const 1))
|
(local.set $z (i32.const 1))
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
|
|
||||||
)
|
)
|
||||||
(local.set $z4 (i64.extend_i32_u (i32.wrap_i64 (local.get $z))))
|
(local.set $z4 (i64.extend_i32_u (local.get $z)))
|
||||||
|
|
||||||
)
|
)
|
||||||
(global.set $global_ (local.get $z2))
|
(global.set $global_ (local.get $z2))
|
||||||
@ -497,15 +497,15 @@ Text representation:
|
|||||||
(local $z3_1 i64)
|
(local $z3_1 i64)
|
||||||
(local $z4_1 i64)
|
(local $z4_1 i64)
|
||||||
(block $label__15
|
(block $label__15
|
||||||
(if (i64.ne (i64.extend_i32_u (i64.ne (i64.const 0) (i64.or (i64.or (local.get $x1) (local.get $x2)) (local.get $x3)))) (i64.const 0)) (then
|
(if (i64.ne (i64.const 0) (i64.or (i64.or (local.get $x1) (local.get $x2)) (local.get $x3))) (then
|
||||||
(unreachable)))
|
(unreachable)))
|
||||||
(if (i64.ne (i64.extend_i32_u (i64.ne (i64.const 0) (i64.shr_u (local.get $x4) (i64.const 32)))) (i64.const 0)) (then
|
(if (i64.ne (i64.const 0) (i64.shr_u (local.get $x4) (i64.const 32))) (then
|
||||||
(unreachable)))
|
(unreachable)))
|
||||||
(call $eth.callDataCopy (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.extend_i32_u (i32.wrap_i64 (local.get $x4)))) (i32.wrap_i64 (i64.const 32)))
|
(call $eth.callDataCopy (i32.const 0) (i32.wrap_i64 (local.get $x4)) (i32.const 32))
|
||||||
(local.set $z1_1 (call $endian_swap (i64.load (i32.wrap_i64 (i64.const 0)))))
|
(local.set $z1_1 (call $endian_swap (i64.load (i32.const 0))))
|
||||||
(local.set $z2_1 (call $endian_swap (i64.load (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 8))))))))
|
(local.set $z2_1 (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 8)))))
|
||||||
(local.set $z3_1 (call $endian_swap (i64.load (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 16))))))))
|
(local.set $z3_1 (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 16)))))
|
||||||
(local.set $z4_1 (call $endian_swap (i64.load (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 24))))))))
|
(local.set $z4_1 (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 24)))))
|
||||||
(local.set $z1 (local.get $z1_1))
|
(local.set $z1 (local.get $z1_1))
|
||||||
(local.set $z2 (local.get $z2_1))
|
(local.set $z2 (local.get $z2_1))
|
||||||
(local.set $z3 (local.get $z3_1))
|
(local.set $z3 (local.get $z3_1))
|
||||||
@ -556,16 +556,16 @@ Text representation:
|
|||||||
)
|
)
|
||||||
|
|
||||||
(func $mstore_internal
|
(func $mstore_internal
|
||||||
(param $pos i64)
|
(param $pos i32)
|
||||||
(param $y1 i64)
|
(param $y1 i64)
|
||||||
(param $y2 i64)
|
(param $y2 i64)
|
||||||
(param $y3 i64)
|
(param $y3 i64)
|
||||||
(param $y4 i64)
|
(param $y4 i64)
|
||||||
(block $label__19
|
(block $label__19
|
||||||
(i64.store (i32.wrap_i64 (local.get $pos)) (call $endian_swap (local.get $y1)))
|
(i64.store (local.get $pos) (call $endian_swap (local.get $y1)))
|
||||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $pos)) (i32.wrap_i64 (i64.const 8))))) (call $endian_swap (local.get $y2)))
|
(i64.store (i32.add (local.get $pos) (i32.const 8)) (call $endian_swap (local.get $y2)))
|
||||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $pos)) (i32.wrap_i64 (i64.const 16))))) (call $endian_swap (local.get $y3)))
|
(i64.store (i32.add (local.get $pos) (i32.const 16)) (call $endian_swap (local.get $y3)))
|
||||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $pos)) (i32.wrap_i64 (i64.const 24))))) (call $endian_swap (local.get $y4)))
|
(i64.store (i32.add (local.get $pos) (i32.const 24)) (call $endian_swap (local.get $y4)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -579,9 +579,9 @@ Text representation:
|
|||||||
(param $y3 i64)
|
(param $y3 i64)
|
||||||
(param $y4 i64)
|
(param $y4 i64)
|
||||||
(block $label__20
|
(block $label__20
|
||||||
(call $mstore_internal (i64.const 0) (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4))
|
(call $mstore_internal (i32.const 0) (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4))
|
||||||
(call $mstore_internal (i64.const 32) (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4))
|
(call $mstore_internal (i32.const 32) (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4))
|
||||||
(call $eth.storageStore (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 32)))
|
(call $eth.storageStore (i32.const 0) (i32.const 32))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
(func $main
|
(func $main
|
||||||
(local $_1 i64)
|
(local $_1 i64)
|
||||||
(local $p i64)
|
(local $p i32)
|
||||||
(local $r i64)
|
(local $r i32)
|
||||||
(local $_2 i64)
|
(local $_2 i64)
|
||||||
(local $z1 i64)
|
(local $z1 i64)
|
||||||
(local $z2 i64)
|
(local $z2 i64)
|
||||||
@ -19,19 +19,19 @@
|
|||||||
(block $label_
|
(block $label_
|
||||||
(local.set $_1 (i64.const 0))
|
(local.set $_1 (i64.const 0))
|
||||||
(local.set $p (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 64)))
|
(local.set $p (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 64)))
|
||||||
(local.set $r (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $p)) (i32.wrap_i64 (i64.const 64)))))
|
(local.set $r (i32.add (local.get $p) (i32.const 64)))
|
||||||
(if (i64.ne (i64.extend_i32_u (i32.lt_u (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (local.get $p)))) (i64.const 0)) (then
|
(if (i32.lt_u (local.get $r) (local.get $p)) (then
|
||||||
(unreachable)))
|
(unreachable)))
|
||||||
(local.set $_2 (call $endian_swap (local.get $_1)))
|
(local.set $_2 (call $endian_swap (local.get $_1)))
|
||||||
(i64.store (i32.wrap_i64 (local.get $r)) (local.get $_2))
|
(i64.store (local.get $r) (local.get $_2))
|
||||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (i64.const 8))))) (local.get $_2))
|
(i64.store (i32.add (local.get $r) (i32.const 8)) (local.get $_2))
|
||||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (i64.const 16))))) (local.get $_2))
|
(i64.store (i32.add (local.get $r) (i32.const 16)) (local.get $_2))
|
||||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (i64.const 24))))) (call $endian_swap (i64.const 128)))
|
(i64.store (i32.add (local.get $r) (i32.const 24)) (call $endian_swap (i64.const 128)))
|
||||||
(call $eth.getCallValue (i32.wrap_i64 (i64.const 0)))
|
(call $eth.getCallValue (i32.const 0))
|
||||||
(local.set $z1 (call $endian_swap (i64.load (i32.wrap_i64 (i64.const 0)))))
|
(local.set $z1 (call $endian_swap (i64.load (i32.const 0))))
|
||||||
(local.set $z2 (call $endian_swap (i64.load (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 8))))))))
|
(local.set $z2 (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 8)))))
|
||||||
(local.set $z3 (call $endian_swap (i64.load (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 16))))))))
|
(local.set $z3 (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 16)))))
|
||||||
(if (i64.ne (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (i64.extend_i32_u (i64.eqz (i64.or (i64.or (local.get $z1) (local.get $z2)) (i64.or (local.get $z3) (call $endian_swap (i64.load (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 24)))))))))))))) (i64.const 0)) (then
|
(if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $z1) (local.get $z2)) (i64.or (local.get $z3) (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 24)))))))) (then
|
||||||
(call $revert (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))))
|
(call $revert (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))))
|
||||||
(local.set $_3 (datasize \"C_2_deployed\"))
|
(local.set $_3 (datasize \"C_2_deployed\"))
|
||||||
(call $codecopy (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (dataoffset \"C_2_deployed\") (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3))
|
(call $codecopy (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (dataoffset \"C_2_deployed\") (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3))
|
||||||
@ -44,14 +44,14 @@
|
|||||||
(param $x2 i64)
|
(param $x2 i64)
|
||||||
(param $x3 i64)
|
(param $x3 i64)
|
||||||
(param $x4 i64)
|
(param $x4 i64)
|
||||||
(result i64)
|
(result i32)
|
||||||
(local $v i64)
|
(local $v i32)
|
||||||
(block $label__1
|
(block $label__1
|
||||||
(if (i64.ne (i64.extend_i32_u (i64.ne (i64.const 0) (i64.or (i64.or (local.get $x1) (local.get $x2)) (local.get $x3)))) (i64.const 0)) (then
|
(if (i64.ne (i64.const 0) (i64.or (i64.or (local.get $x1) (local.get $x2)) (local.get $x3))) (then
|
||||||
(unreachable)))
|
(unreachable)))
|
||||||
(if (i64.ne (i64.extend_i32_u (i64.ne (i64.const 0) (i64.shr_u (local.get $x4) (i64.const 32)))) (i64.const 0)) (then
|
(if (i64.ne (i64.const 0) (i64.shr_u (local.get $x4) (i64.const 32))) (then
|
||||||
(unreachable)))
|
(unreachable)))
|
||||||
(local.set $v (i64.extend_i32_u (i32.wrap_i64 (local.get $x4))))
|
(local.set $v (i32.wrap_i64 (local.get $x4)))
|
||||||
|
|
||||||
)
|
)
|
||||||
(local.get $v)
|
(local.get $v)
|
||||||
@ -62,13 +62,13 @@
|
|||||||
(param $x2 i64)
|
(param $x2 i64)
|
||||||
(param $x3 i64)
|
(param $x3 i64)
|
||||||
(param $x4 i64)
|
(param $x4 i64)
|
||||||
(result i64)
|
(result i32)
|
||||||
(local $r i64)
|
(local $r i32)
|
||||||
(local $p i64)
|
(local $p i32)
|
||||||
(block $label__2
|
(block $label__2
|
||||||
(local.set $p (call $u256_to_i32 (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)))
|
(local.set $p (call $u256_to_i32 (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)))
|
||||||
(local.set $r (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $p)) (i32.wrap_i64 (i64.const 64)))))
|
(local.set $r (i32.add (local.get $p) (i32.const 64)))
|
||||||
(if (i64.ne (i64.extend_i32_u (i32.lt_u (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (local.get $p)))) (i64.const 0)) (then
|
(if (i32.lt_u (local.get $r) (local.get $p)) (then
|
||||||
(unreachable)))
|
(unreachable)))
|
||||||
|
|
||||||
)
|
)
|
||||||
@ -89,7 +89,7 @@
|
|||||||
(param $z3 i64)
|
(param $z3 i64)
|
||||||
(param $z4 i64)
|
(param $z4 i64)
|
||||||
(block $label__3
|
(block $label__3
|
||||||
(call $eth.codeCopy (i32.wrap_i64 (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4))) (i32.wrap_i64 (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4))) (i32.wrap_i64 (call $u256_to_i32 (local.get $z1) (local.get $z2) (local.get $z3) (local.get $z4))))
|
(call $eth.codeCopy (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)) (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4)) (call $u256_to_i32 (local.get $z1) (local.get $z2) (local.get $z3) (local.get $z4)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -140,7 +140,7 @@
|
|||||||
(param $y3 i64)
|
(param $y3 i64)
|
||||||
(param $y4 i64)
|
(param $y4 i64)
|
||||||
(block $label__7
|
(block $label__7
|
||||||
(call $eth.finish (i32.wrap_i64 (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4))) (i32.wrap_i64 (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4))))
|
(call $eth.finish (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)) (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -154,7 +154,7 @@
|
|||||||
(param $y3 i64)
|
(param $y3 i64)
|
||||||
(param $y4 i64)
|
(param $y4 i64)
|
||||||
(block $label__8
|
(block $label__8
|
||||||
(call $eth.revert (i32.wrap_i64 (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4))) (i32.wrap_i64 (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4))))
|
(call $eth.revert (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)) (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,24 +20,24 @@ object "object" {
|
|||||||
|
|
||||||
|
|
||||||
Binary representation:
|
Binary representation:
|
||||||
0061736d01000000010c0260000060047e7e7e7e017e020100030302000105030100010610037e0142000b7e0142000b7e0142000b071102066d656d6f72790200046d61696e00000a4a022201047e024002404201420242034204100121002300210123012102230221030b0b0b2501047e0240200121042002210720002105200321060b20052400200624012007240220040b
|
0061736d01000000010c0260000060047f7e7e7f017e020100030302000105030100010610037f0141000b7f0141000b7e0142000b071102066d656d6f72790200046d61696e00000a52022603017e027f017e024002404101420242034104100121002300210123012102230221030b0b0b2903017e027f017e0240200121042002210720002105200321060b20052400200624012007240220040b
|
||||||
|
|
||||||
Text representation:
|
Text representation:
|
||||||
(module
|
(module
|
||||||
(memory $memory (export "memory") 1)
|
(memory $memory (export "memory") 1)
|
||||||
(export "main" (func $main))
|
(export "main" (func $main))
|
||||||
(global $global_ (mut i64) (i64.const 0))
|
(global $global_ (mut i32) (i32.const 0))
|
||||||
(global $global__1 (mut i64) (i64.const 0))
|
(global $global__1 (mut i32) (i32.const 0))
|
||||||
(global $global__2 (mut i64) (i64.const 0))
|
(global $global__2 (mut i64) (i64.const 0))
|
||||||
|
|
||||||
(func $main
|
(func $main
|
||||||
(local $m i64)
|
(local $m i64)
|
||||||
(local $n i64)
|
(local $n i32)
|
||||||
(local $p i64)
|
(local $p i32)
|
||||||
(local $q i64)
|
(local $q i64)
|
||||||
(block $label_
|
(block $label_
|
||||||
(block
|
(block
|
||||||
(local.set $m (call $multireturn (i64.const 1) (i64.const 2) (i64.const 3) (i64.const 4)))
|
(local.set $m (call $multireturn (i32.const 1) (i64.const 2) (i64.const 3) (i32.const 4)))
|
||||||
(local.set $n (global.get $global_))
|
(local.set $n (global.get $global_))
|
||||||
(local.set $p (global.get $global__1))
|
(local.set $p (global.get $global__1))
|
||||||
(local.set $q (global.get $global__2))
|
(local.set $q (global.get $global__2))
|
||||||
@ -48,14 +48,14 @@ Text representation:
|
|||||||
)
|
)
|
||||||
|
|
||||||
(func $multireturn
|
(func $multireturn
|
||||||
(param $a i64)
|
(param $a i32)
|
||||||
(param $b i64)
|
(param $b i64)
|
||||||
(param $c i64)
|
(param $c i64)
|
||||||
(param $d i64)
|
(param $d i32)
|
||||||
(result i64)
|
(result i64)
|
||||||
(local $x i64)
|
(local $x i64)
|
||||||
(local $y i64)
|
(local $y i32)
|
||||||
(local $z i64)
|
(local $z i32)
|
||||||
(local $w i64)
|
(local $w i64)
|
||||||
(block $label__3
|
(block $label__3
|
||||||
(local.set $x (local.get $b))
|
(local.set $x (local.get $b))
|
||||||
|
@ -11,7 +11,7 @@ object "object" {
|
|||||||
|
|
||||||
|
|
||||||
Binary representation:
|
Binary representation:
|
||||||
0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a0f010d0002404201a7422a3c00000b0b
|
0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a0e010c0002404101422a3c00000b0b
|
||||||
|
|
||||||
Text representation:
|
Text representation:
|
||||||
(module
|
(module
|
||||||
@ -20,7 +20,7 @@ Text representation:
|
|||||||
|
|
||||||
(func $main
|
(func $main
|
||||||
(block $label_
|
(block $label_
|
||||||
(i64.store8 (i32.wrap_i64 (i64.const 1)) (i64.const 42))
|
(i64.store8 (i32.const 1) (i64.const 42))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user