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.
virtual BuiltinFunction const* builtin(YulString /*_name*/) const { return nullptr; }
virtual BuiltinFunction const* discardFunction() const { return nullptr; }
virtual BuiltinFunction const* equalityFunction() const { return nullptr; }
virtual BuiltinFunction const* discardFunction(YulString /* _type */) const { return nullptr; }
virtual BuiltinFunction const* equalityFunction(YulString /* _type */) const { return nullptr; }
virtual BuiltinFunction const* booleanNegationFunction() const { return nullptr; }
/// 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};
}
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)
{
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.
BuiltinFunctionForEVM const* builtin(YulString _name) const override;
BuiltinFunctionForEVM const* discardFunction() const override { return builtin("pop"_yulstring); }
BuiltinFunctionForEVM const* equalityFunction() const override { return builtin("eq"_yulstring); }
BuiltinFunctionForEVM const* discardFunction(YulString /*_type*/) const override { return builtin("pop"_yulstring); }
BuiltinFunctionForEVM const* equalityFunction(YulString /*_type*/) const override { return builtin("eq"_yulstring); }
BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("iszero"_yulstring); }
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.
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);
};

View File

@ -91,8 +91,9 @@ WasmDialect::WasmDialect()
m_functions["i64.load"_yulstring].sideEffects.sideEffectFreeIfNoMSize = true;
// 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("i32.drop", {i32}, {});
addFunction("nop", {}, {});
addFunction("unreachable", {}, {}, false);
@ -114,6 +115,22 @@ BuiltinFunction const* WasmDialect::builtin(YulString _name) const
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()
{
static std::unique_ptr<WasmDialect> dialect;

View File

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