From 6a82d32ef6f494edd9682f2a4495f066ac64d9af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 May 2020 21:20:19 +0200 Subject: [PATCH] Add the ability to store variable types in wasm AST --- libyul/backends/wasm/BinaryTransform.cpp | 11 ++++++----- libyul/backends/wasm/TextTransform.cpp | 9 +++++---- libyul/backends/wasm/WasmAST.h | 13 ++++++++----- libyul/backends/wasm/WasmCodeTransform.cpp | 18 ++++++++++-------- 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/libyul/backends/wasm/BinaryTransform.cpp b/libyul/backends/wasm/BinaryTransform.cpp index 4bc43f121..875d93dbf 100644 --- a/libyul/backends/wasm/BinaryTransform.cpp +++ b/libyul/backends/wasm/BinaryTransform.cpp @@ -298,7 +298,8 @@ bytes BinaryTransform::run(Module const& _module) bytes BinaryTransform::operator()(Literal const& _literal) { - return toBytes(Opcode::I64Const) + lebEncodeSigned(_literal.value); + yulAssert(holds_alternative(_literal.value), ""); + return toBytes(Opcode::I64Const) + lebEncodeSigned(get(_literal.value)); } bytes BinaryTransform::operator()(StringLiteral const&) @@ -457,8 +458,8 @@ bytes BinaryTransform::operator()(FunctionDefinition const& _function) m_locals.clear(); size_t varIdx = 0; - for (size_t i = 0; i < _function.parameterNames.size(); ++i) - m_locals[_function.parameterNames[i]] = varIdx++; + for (size_t i = 0; i < _function.parameters.size(); ++i) + m_locals[_function.parameters[i].name] = varIdx++; for (size_t i = 0; i < _function.locals.size(); ++i) m_locals[_function.locals[i].variableName] = varIdx++; @@ -484,8 +485,8 @@ BinaryTransform::Type BinaryTransform::typeOf(FunctionDefinition const& _funDef) { return { - encodeTypes(vector(_funDef.parameterNames.size(), wasm::Type::i64)), - encodeTypes(vector(_funDef.returns ? 1 : 0, wasm::Type::i64)) + encodeTypes(vector(_funDef.parameters.size(), wasm::Type::i64)), + encodeTypes(vector(_funDef.returnType.has_value() ? 1 : 0, wasm::Type::i64)) }; } diff --git a/libyul/backends/wasm/TextTransform.cpp b/libyul/backends/wasm/TextTransform.cpp index a14c8069b..84f2ce972 100644 --- a/libyul/backends/wasm/TextTransform.cpp +++ b/libyul/backends/wasm/TextTransform.cpp @@ -67,7 +67,8 @@ string TextTransform::run(wasm::Module const& _module) string TextTransform::operator()(wasm::Literal const& _literal) { - return "(i64.const " + to_string(_literal.value) + ")"; + yulAssert(holds_alternative(_literal.value), ""); + return "(i64.const " + to_string(get(_literal.value)) + ")"; } string TextTransform::operator()(wasm::StringLiteral const& _literal) @@ -164,9 +165,9 @@ string TextTransform::indented(string const& _in) string TextTransform::transform(wasm::FunctionDefinition const& _function) { string ret = "(func $" + _function.name + "\n"; - for (auto const& param: _function.parameterNames) - ret += " (param $" + param + " i64)\n"; - if (_function.returns) + for (auto const& param: _function.parameters) + ret += " (param $" + param.name + " i64)\n"; + if (_function.returnType.has_value()) ret += " (result i64)\n"; for (auto const& local: _function.locals) ret += " (local $" + local.variableName + " i64)\n"; diff --git a/libyul/backends/wasm/WasmAST.h b/libyul/backends/wasm/WasmAST.h index e3a3368ea..b22b0db84 100644 --- a/libyul/backends/wasm/WasmAST.h +++ b/libyul/backends/wasm/WasmAST.h @@ -36,6 +36,9 @@ enum class Type i64, }; +struct TypedName { std::string name; Type type; }; +using TypedNameList = std::vector; + struct Literal; struct StringLiteral; struct LocalVariable; @@ -56,7 +59,7 @@ using Expression = std::variant< Block, If, Loop, Branch, BranchIf, Return >; -struct Literal { uint64_t value; }; +struct Literal { std::variant value; }; struct StringLiteral { std::string value; }; struct LocalVariable { std::string name; }; struct GlobalVariable { std::string name; }; @@ -76,8 +79,8 @@ struct Branch { Label label; }; struct Return {}; struct BranchIf { Label label; std::unique_ptr condition; }; -struct VariableDeclaration { std::string variableName; }; -struct GlobalVariableDeclaration { std::string variableName; }; +struct VariableDeclaration { std::string variableName; Type type; }; +struct GlobalVariableDeclaration { std::string variableName; Type type; }; struct FunctionImport { std::string module; std::string externalName; @@ -89,8 +92,8 @@ struct FunctionImport { struct FunctionDefinition { std::string name; - std::vector parameterNames; - bool returns; + std::vector parameters; + std::optional returnType; std::vector locals; std::vector body; }; diff --git a/libyul/backends/wasm/WasmCodeTransform.cpp b/libyul/backends/wasm/WasmCodeTransform.cpp index 0e3a17f00..8f987824c 100644 --- a/libyul/backends/wasm/WasmCodeTransform.cpp +++ b/libyul/backends/wasm/WasmCodeTransform.cpp @@ -88,7 +88,7 @@ wasm::Expression WasmCodeTransform::operator()(VariableDeclaration const& _varDe for (auto const& var: _varDecl.variables) { variableNames.emplace_back(var.name.str()); - m_localVariables.emplace_back(wasm::VariableDeclaration{variableNames.back()}); + m_localVariables.emplace_back(wasm::VariableDeclaration{variableNames.back(), wasm::Type::i64}); } if (_varDecl.value) @@ -184,7 +184,7 @@ wasm::Expression WasmCodeTransform::operator()(Literal const& _literal) { u256 value = valueOfLiteral(_literal); yulAssert(value <= numeric_limits::max(), "Literal too large: " + value.str()); - return wasm::Literal{uint64_t(value)}; + return wasm::Literal{static_cast(value)}; } wasm::Expression WasmCodeTransform::operator()(If const& _if) @@ -193,7 +193,7 @@ wasm::Expression WasmCodeTransform::operator()(If const& _if) vector args; args.emplace_back(visitReturnByValue(*_if.condition)); - args.emplace_back(wasm::Literal{0}); + args.emplace_back(wasm::Literal{static_cast(0)}); return wasm::If{ make_unique(wasm::BuiltinCall{"i64.ne", std::move(args)}), visit(_if.body.statements), @@ -205,7 +205,7 @@ wasm::Expression WasmCodeTransform::operator()(Switch const& _switch) { wasm::Block block; string condition = m_nameDispenser.newName("condition"_yulstring).str(); - m_localVariables.emplace_back(wasm::VariableDeclaration{condition}); + m_localVariables.emplace_back(wasm::VariableDeclaration{condition, wasm::Type::i64}); block.statements.emplace_back(wasm::LocalAssignment{condition, visit(*_switch.expression)}); vector* currentBlock = &block.statements; @@ -325,10 +325,11 @@ wasm::FunctionDefinition WasmCodeTransform::translateFunction(yul::FunctionDefin wasm::FunctionDefinition fun; fun.name = _fun.name.str(); for (auto const& param: _fun.parameters) - fun.parameterNames.emplace_back(param.name.str()); + fun.parameters.push_back({param.name.str(), wasm::Type::i64}); for (auto const& retParam: _fun.returnVariables) - fun.locals.emplace_back(wasm::VariableDeclaration{retParam.name.str()}); - fun.returns = !_fun.returnVariables.empty(); + fun.locals.emplace_back(wasm::VariableDeclaration{retParam.name.str(), wasm::Type::i64}); + if (!_fun.returnVariables.empty()) + fun.returnType = wasm::Type::i64; yulAssert(m_localVariables.empty(), ""); yulAssert(m_functionBodyLabel.empty(), ""); @@ -400,7 +401,8 @@ void WasmCodeTransform::allocateGlobals(size_t _amount) { while (m_globalVariables.size() < _amount) m_globalVariables.emplace_back(wasm::GlobalVariableDeclaration{ - m_nameDispenser.newName("global_"_yulstring).str() + m_nameDispenser.newName("global_"_yulstring).str(), + wasm::Type::i64 }); }