Introduce typed named functions to dialect.

This commit is contained in:
chriseth 2020-02-19 00:18:13 +01:00
parent b9b36cd89e
commit e728cd76b6
5 changed files with 54 additions and 11 deletions

View File

@ -58,8 +58,8 @@ struct Dialect: boost::noncopyable
/// @returns the builtin function of the given name or a nullptr if it is not a builtin function. /// @returns the builtin function of the given name or a nullptr if it is not a builtin function.
virtual BuiltinFunction const* builtin(YulString /*_name*/) const { return nullptr; } virtual BuiltinFunction const* builtin(YulString /*_name*/) const { return nullptr; }
virtual BuiltinFunction const* discardFunction() const { return nullptr; } virtual BuiltinFunction const* discardFunction(YulString /* _type */) const { return nullptr; }
virtual BuiltinFunction const* equalityFunction() const { return nullptr; } virtual BuiltinFunction const* equalityFunction(YulString /* _type */) const { return nullptr; }
virtual BuiltinFunction const* booleanNegationFunction() const { return nullptr; } virtual BuiltinFunction const* booleanNegationFunction() const { return nullptr; }
/// Check whether the given type is legal for the given literal value. /// Check whether the given type is legal for the given literal value.

View File

@ -290,6 +290,28 @@ EVMDialectTyped::EVMDialectTyped(langutil::EVMVersion _evmVersion, bool _objectA
m_functions["u256_to_bool"_yulstring].returns = {"bool"_yulstring}; m_functions["u256_to_bool"_yulstring].returns = {"bool"_yulstring};
} }
BuiltinFunctionForEVM const* EVMDialectTyped::discardFunction(YulString _type) const
{
if (_type == "bool"_yulstring)
return builtin("popbool"_yulstring);
else
{
yulAssert(_type == defaultType, "");
return builtin("pop"_yulstring);
}
}
BuiltinFunctionForEVM const* EVMDialectTyped::equalityFunction(YulString _type) const
{
if (_type == "bool"_yulstring)
return nullptr;
else
{
yulAssert(_type == defaultType, "");
return builtin("eq"_yulstring);
}
}
EVMDialectTyped const& EVMDialectTyped::instance(langutil::EVMVersion _version) EVMDialectTyped const& EVMDialectTyped::instance(langutil::EVMVersion _version)
{ {
static map<langutil::EVMVersion, unique_ptr<EVMDialectTyped const>> dialects; static map<langutil::EVMVersion, unique_ptr<EVMDialectTyped const>> dialects;

View File

@ -68,8 +68,8 @@ struct EVMDialect: public Dialect
/// @returns the builtin function of the given name or a nullptr if it is not a builtin function. /// @returns the builtin function of the given name or a nullptr if it is not a builtin function.
BuiltinFunctionForEVM const* builtin(YulString _name) const override; BuiltinFunctionForEVM const* builtin(YulString _name) const override;
BuiltinFunctionForEVM const* discardFunction() const override { return builtin("pop"_yulstring); } BuiltinFunctionForEVM const* discardFunction(YulString /*_type*/) const override { return builtin("pop"_yulstring); }
BuiltinFunctionForEVM const* equalityFunction() const override { return builtin("eq"_yulstring); } BuiltinFunctionForEVM const* equalityFunction(YulString /*_type*/) const override { return builtin("eq"_yulstring); }
BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("iszero"_yulstring); } BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("iszero"_yulstring); }
static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _version); static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _version);
@ -102,6 +102,10 @@ struct EVMDialectTyped: public EVMDialect
/// Constructor, should only be used internally. Use the factory function below. /// Constructor, should only be used internally. Use the factory function below.
EVMDialectTyped(langutil::EVMVersion _evmVersion, bool _objectAccess); EVMDialectTyped(langutil::EVMVersion _evmVersion, bool _objectAccess);
BuiltinFunctionForEVM const* discardFunction(YulString _type) const override;
BuiltinFunctionForEVM const* equalityFunction(YulString _type) const override;
BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("not"_yulstring); }
static EVMDialectTyped const& instance(langutil::EVMVersion _version); static EVMDialectTyped const& instance(langutil::EVMVersion _version);
}; };

View File

@ -91,8 +91,9 @@ WasmDialect::WasmDialect()
m_functions["i64.load"_yulstring].sideEffects.sideEffectFreeIfNoMSize = true; m_functions["i64.load"_yulstring].sideEffects.sideEffectFreeIfNoMSize = true;
// Drop is actually overloaded for all types, but Yul does not support that. // Drop is actually overloaded for all types, but Yul does not support that.
// We could introduce "i32.drop". // Because of that, we introduce "i32.drop".
addFunction("drop", {i64}, {}); addFunction("drop", {i64}, {});
addFunction("i32.drop", {i32}, {});
addFunction("nop", {}, {}); addFunction("nop", {}, {});
addFunction("unreachable", {}, {}, false); addFunction("unreachable", {}, {}, false);
@ -114,6 +115,22 @@ BuiltinFunction const* WasmDialect::builtin(YulString _name) const
return nullptr; return nullptr;
} }
BuiltinFunction const* WasmDialect::discardFunction(YulString _type) const
{
if (_type == "i32"_yulstring)
return builtin("i32.drop"_yulstring);
yulAssert(_type == "i64"_yulstring, "");
return builtin("drop"_yulstring);
}
BuiltinFunction const* WasmDialect::equalityFunction(YulString _type) const
{
if (_type == "i32"_yulstring)
return builtin("i32.eq"_yulstring);
yulAssert(_type == "i64"_yulstring, "");
return builtin("i64.eq"_yulstring);
}
WasmDialect const& WasmDialect::instance() WasmDialect const& WasmDialect::instance()
{ {
static std::unique_ptr<WasmDialect> dialect; static std::unique_ptr<WasmDialect> dialect;

View File

@ -35,19 +35,19 @@ struct Object;
/** /**
* Yul dialect for Wasm as a backend. * Yul dialect for Wasm as a backend.
* *
* Builtin functions are a subset of the wasm instructions, always implicitly assuming * Builtin functions are a subset of the wasm instructions.
* unsigned 64 bit types. *
* There is a builtin function `i32.drop` that takes an i32, while `drop` takes i64.
* *
* !This is subject to changes!
*/ */
struct WasmDialect: public Dialect struct WasmDialect: public Dialect
{ {
WasmDialect(); WasmDialect();
BuiltinFunction const* builtin(YulString _name) const override; BuiltinFunction const* builtin(YulString _name) const override;
BuiltinFunction const* discardFunction() const override { return builtin("drop"_yulstring); } BuiltinFunction const* discardFunction(YulString _type) const override;
BuiltinFunction const* equalityFunction() const override { return builtin("i64.eq"_yulstring); } BuiltinFunction const* equalityFunction(YulString _type) const override;
BuiltinFunction const* booleanNegationFunction() const override { return builtin("i64.eqz"_yulstring); } BuiltinFunction const* booleanNegationFunction() const override { return builtin("i32.eqz"_yulstring); }
std::set<YulString> fixedFunctionNames() const override { return {"main"_yulstring}; } std::set<YulString> fixedFunctionNames() const override { return {"main"_yulstring}; }