mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Define wasm::Type enum and use it for import parameters and result
This commit is contained in:
parent
d7f29a33b9
commit
840ff40263
@ -25,6 +25,7 @@
|
||||
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
#include <boost/range/adaptor/map.hpp>
|
||||
#include <boost/range/adaptor/transformed.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity;
|
||||
@ -475,7 +476,7 @@ BinaryTransform::Type BinaryTransform::typeOf(FunctionImport const& _import)
|
||||
{
|
||||
return {
|
||||
encodeTypes(_import.paramTypes),
|
||||
encodeTypes(_import.returnType ? vector<string>(1, *_import.returnType) : vector<string>())
|
||||
encodeTypes(_import.returnType ? vector<wasm::Type>(1, *_import.returnType) : vector<wasm::Type>())
|
||||
};
|
||||
}
|
||||
|
||||
@ -483,26 +484,26 @@ BinaryTransform::Type BinaryTransform::typeOf(FunctionDefinition const& _funDef)
|
||||
{
|
||||
|
||||
return {
|
||||
encodeTypes(vector<string>(_funDef.parameterNames.size(), "i64")),
|
||||
encodeTypes(vector<string>(_funDef.returns ? 1 : 0, "i64"))
|
||||
encodeTypes(vector<wasm::Type>(_funDef.parameterNames.size(), wasm::Type::i64)),
|
||||
encodeTypes(vector<wasm::Type>(_funDef.returns ? 1 : 0, wasm::Type::i64))
|
||||
};
|
||||
}
|
||||
|
||||
uint8_t BinaryTransform::encodeType(string const& _typeName)
|
||||
uint8_t BinaryTransform::encodeType(wasm::Type _type)
|
||||
{
|
||||
if (_typeName == "i32")
|
||||
if (_type == wasm::Type::i32)
|
||||
return uint8_t(ValueType::I32);
|
||||
else if (_typeName == "i64")
|
||||
else if (_type == wasm::Type::i64)
|
||||
return uint8_t(ValueType::I64);
|
||||
else
|
||||
yulAssert(false, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
vector<uint8_t> BinaryTransform::encodeTypes(vector<string> const& _typeNames)
|
||||
vector<uint8_t> BinaryTransform::encodeTypes(vector<wasm::Type> const& _types)
|
||||
{
|
||||
vector<uint8_t> result;
|
||||
for (auto const& t: _typeNames)
|
||||
for (wasm::Type t: _types)
|
||||
result.emplace_back(encodeType(t));
|
||||
return result;
|
||||
}
|
||||
|
@ -71,8 +71,8 @@ private:
|
||||
static Type typeOf(wasm::FunctionImport const& _import);
|
||||
static Type typeOf(wasm::FunctionDefinition const& _funDef);
|
||||
|
||||
static uint8_t encodeType(std::string const& _typeName);
|
||||
static std::vector<uint8_t> encodeTypes(std::vector<std::string> const& _typeNames);
|
||||
static uint8_t encodeType(wasm::Type _type);
|
||||
static std::vector<uint8_t> encodeTypes(std::vector<wasm::Type> const& _types);
|
||||
|
||||
static std::map<Type, std::vector<std::string>> typeToFunctionMap(
|
||||
std::vector<wasm::FunctionImport> const& _imports,
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
#include <libyul/backends/wasm/TextTransform.h>
|
||||
|
||||
#include <libyul/Exceptions.h>
|
||||
|
||||
#include <libsolutil/StringUtils.h>
|
||||
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
@ -44,9 +46,9 @@ string TextTransform::run(wasm::Module const& _module)
|
||||
{
|
||||
ret += " (import \"" + imp.module + "\" \"" + imp.externalName + "\" (func $" + imp.internalName;
|
||||
if (!imp.paramTypes.empty())
|
||||
ret += " (param" + joinHumanReadablePrefixed(imp.paramTypes, " ", " ") + ")";
|
||||
ret += " (param" + joinHumanReadablePrefixed(imp.paramTypes | boost::adaptors::transformed(encodeType), " ", " ") + ")";
|
||||
if (imp.returnType)
|
||||
ret += " (result " + *imp.returnType + ")";
|
||||
ret += " (result " + encodeType(*imp.returnType) + ")";
|
||||
ret += "))\n";
|
||||
}
|
||||
|
||||
@ -193,3 +195,13 @@ string TextTransform::joinTransformed(vector<wasm::Expression> const& _expressio
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
string TextTransform::encodeType(wasm::Type _type)
|
||||
{
|
||||
if (_type == wasm::Type::i32)
|
||||
return "i32";
|
||||
else if (_type == wasm::Type::i64)
|
||||
return "i64";
|
||||
else
|
||||
yulAssert(false, "Invalid wasm type");
|
||||
}
|
||||
|
@ -63,6 +63,8 @@ private:
|
||||
std::vector<wasm::Expression> const& _expressions,
|
||||
char _separator = ' '
|
||||
);
|
||||
|
||||
static std::string encodeType(wasm::Type _type);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -30,6 +30,12 @@
|
||||
namespace solidity::yul::wasm
|
||||
{
|
||||
|
||||
enum class Type
|
||||
{
|
||||
i32,
|
||||
i64,
|
||||
};
|
||||
|
||||
struct Literal;
|
||||
struct StringLiteral;
|
||||
struct LocalVariable;
|
||||
@ -76,8 +82,8 @@ struct FunctionImport {
|
||||
std::string module;
|
||||
std::string externalName;
|
||||
std::string internalName;
|
||||
std::vector<std::string> paramTypes;
|
||||
std::optional<std::string> returnType;
|
||||
std::vector<Type> paramTypes;
|
||||
std::optional<Type> returnType;
|
||||
};
|
||||
|
||||
struct FunctionDefinition
|
||||
|
@ -127,10 +127,10 @@ wasm::Expression WasmCodeTransform::operator()(FunctionCall const& _call)
|
||||
builtin->name.str().substr(4),
|
||||
builtin->name.str(),
|
||||
{},
|
||||
builtin->returns.empty() ? nullopt : make_optional<string>(builtin->returns.front().str())
|
||||
builtin->returns.empty() ? nullopt : make_optional<wasm::Type>(translatedType(builtin->returns.front()))
|
||||
};
|
||||
for (auto const& param: builtin->parameters)
|
||||
imp.paramTypes.emplace_back(param.str());
|
||||
imp.paramTypes.emplace_back(translatedType(param));
|
||||
m_functionsToImport[builtin->name] = std::move(imp);
|
||||
}
|
||||
typeConversionNeeded = true;
|
||||
@ -361,14 +361,14 @@ wasm::Expression WasmCodeTransform::injectTypeConversionIfNeeded(wasm::FunctionC
|
||||
{
|
||||
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) == "i32")
|
||||
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) == "i64", "Unknown type " + import.paramTypes.at(i));
|
||||
yulAssert(import.paramTypes.at(i) == wasm::Type::i64, "Invalid Wasm type");
|
||||
|
||||
if (import.returnType && *import.returnType != "i64")
|
||||
if (import.returnType && *import.returnType != wasm::Type::i64)
|
||||
{
|
||||
yulAssert(*import.returnType == "i32", "Invalid type " + *import.returnType);
|
||||
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)};
|
||||
@ -403,3 +403,13 @@ void WasmCodeTransform::allocateGlobals(size_t _amount)
|
||||
m_nameDispenser.newName("global_"_yulstring).str()
|
||||
});
|
||||
}
|
||||
|
||||
wasm::Type WasmCodeTransform::translatedType(yul::Type _yulType)
|
||||
{
|
||||
if (_yulType == "i32"_yulstring)
|
||||
return wasm::Type::i32;
|
||||
else if (_yulType == "i64"_yulstring)
|
||||
return wasm::Type::i64;
|
||||
else
|
||||
yulAssert(false, "This Yul type does not have a corresponding type in Wasm.");
|
||||
}
|
||||
|
@ -89,6 +89,8 @@ private:
|
||||
/// Makes sure that there are at least @a _amount global variables.
|
||||
void allocateGlobals(size_t _amount);
|
||||
|
||||
static wasm::Type translatedType(yul::Type _yulType);
|
||||
|
||||
Dialect const& m_dialect;
|
||||
NameDispenser m_nameDispenser;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user