mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Introduce typed EVM dialect.
This commit is contained in:
parent
e41155cf48
commit
90c98a3289
@ -157,7 +157,7 @@ void AssemblyStack::compileEVM(AbstractAssembly& _assembly, bool _evm15, bool _o
|
||||
dialect = &EVMDialect::strictAssemblyForEVMObjects(m_evmVersion);
|
||||
break;
|
||||
case Language::Yul:
|
||||
dialect = &EVMDialect::yulForEVM(m_evmVersion);
|
||||
dialect = &EVMDialectTyped::instance(m_evmVersion);
|
||||
break;
|
||||
default:
|
||||
solAssert(false, "Invalid language.");
|
||||
|
@ -203,15 +203,6 @@ EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _
|
||||
return *dialects[_version];
|
||||
}
|
||||
|
||||
EVMDialect const& EVMDialect::yulForEVM(langutil::EVMVersion _version)
|
||||
{
|
||||
static map<langutil::EVMVersion, unique_ptr<EVMDialect const>> dialects;
|
||||
static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }};
|
||||
if (!dialects[_version])
|
||||
dialects[_version] = make_unique<EVMDialect>(_version, false);
|
||||
return *dialects[_version];
|
||||
}
|
||||
|
||||
SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instruction)
|
||||
{
|
||||
return SideEffects{
|
||||
@ -222,3 +213,58 @@ SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instructio
|
||||
evmasm::SemanticInformation::invalidatesMemory(_instruction)
|
||||
};
|
||||
}
|
||||
|
||||
EVMDialectTyped::EVMDialectTyped(langutil::EVMVersion _evmVersion, bool _objectAccess):
|
||||
EVMDialect(_evmVersion, _objectAccess)
|
||||
{
|
||||
defaultType = "u256"_yulstring;
|
||||
m_functions["lt"_yulstring].returns = {"bool"_yulstring};
|
||||
m_functions["gt"_yulstring].returns = {"bool"_yulstring};
|
||||
m_functions["slt"_yulstring].returns = {"bool"_yulstring};
|
||||
m_functions["sgt"_yulstring].returns = {"bool"_yulstring};
|
||||
m_functions["eq"_yulstring].returns = {"bool"_yulstring};
|
||||
m_functions["iszero"_yulstring].returns = {"bool"_yulstring};
|
||||
m_functions["bitand"_yulstring] = m_functions["and"_yulstring];
|
||||
m_functions["bitor"_yulstring] = m_functions["or"_yulstring];
|
||||
m_functions["bitxor"_yulstring] = m_functions["xor"_yulstring];
|
||||
m_functions["and"_yulstring].parameters = {"bool"_yulstring, "bool"_yulstring};
|
||||
m_functions["and"_yulstring].returns = {"bool"_yulstring};
|
||||
m_functions["or"_yulstring].parameters = {"bool"_yulstring, "bool"_yulstring};
|
||||
m_functions["or"_yulstring].returns = {"bool"_yulstring};
|
||||
m_functions["xor"_yulstring].parameters = {"bool"_yulstring, "bool"_yulstring};
|
||||
m_functions["xor"_yulstring].returns = {"bool"_yulstring};
|
||||
m_functions["isfalse"_yulstring] = m_functions["iszero"_yulstring];
|
||||
m_functions["isfalse"_yulstring].parameters = {"bool"_yulstring};
|
||||
m_functions["popbool"_yulstring] = m_functions["pop"_yulstring];
|
||||
m_functions["popbool"_yulstring].parameters = {"bool"_yulstring};
|
||||
m_functions.insert(createFunction("bool_to_u256", 1, 1, {}, false, [](
|
||||
FunctionCall const&,
|
||||
AbstractAssembly&,
|
||||
BuiltinContext&,
|
||||
std::function<void()> _visitArguments
|
||||
) {
|
||||
_visitArguments();
|
||||
}));
|
||||
m_functions["bool_to_u256"_yulstring].parameters = {"bool"_yulstring};
|
||||
m_functions.insert(createFunction("u256_to_bool", 1, 1, {}, false, [](
|
||||
FunctionCall const&,
|
||||
AbstractAssembly& _assembly,
|
||||
BuiltinContext&,
|
||||
std::function<void()> _visitArguments
|
||||
) {
|
||||
// TODO Should a value larger than 1 be invalid?
|
||||
_visitArguments();
|
||||
_assembly.appendInstruction(evmasm::Instruction::ISZERO);
|
||||
_assembly.appendInstruction(evmasm::Instruction::ISZERO);
|
||||
}));
|
||||
m_functions["u256_to_bool"_yulstring].returns = {"bool"_yulstring};
|
||||
}
|
||||
|
||||
EVMDialectTyped const& EVMDialectTyped::instance(langutil::EVMVersion _version)
|
||||
{
|
||||
static map<langutil::EVMVersion, unique_ptr<EVMDialectTyped const>> dialects;
|
||||
static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }};
|
||||
if (!dialects[_version])
|
||||
dialects[_version] = make_unique<EVMDialectTyped>(_version, true);
|
||||
return *dialects[_version];
|
||||
}
|
||||
|
@ -74,7 +74,6 @@ struct EVMDialect: public Dialect
|
||||
|
||||
static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _version);
|
||||
static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _version);
|
||||
static EVMDialect const& yulForEVM(langutil::EVMVersion _version);
|
||||
|
||||
langutil::EVMVersion evmVersion() const { return m_evmVersion; }
|
||||
|
||||
@ -88,4 +87,23 @@ protected:
|
||||
std::map<YulString, BuiltinFunctionForEVM> m_functions;
|
||||
};
|
||||
|
||||
/**
|
||||
* EVM dialect with types u256 (default) and bool.
|
||||
* Difference to EVMDialect:
|
||||
* - All comparison functions return type bool
|
||||
* - bitwise operations are called bitor, bitand, bitxor and bitnot
|
||||
* - and, or, xor take bool and return bool
|
||||
* - iszero returns bool
|
||||
* - isfalse takes bool and returns bool
|
||||
* - there are conversion functions bool_to_u256 and u256_to_bool.
|
||||
* - there is popbool
|
||||
*/
|
||||
struct EVMDialectTyped: public EVMDialect
|
||||
{
|
||||
/// Constructor, should only be used internally. Use the factory function below.
|
||||
EVMDialectTyped(langutil::EVMVersion _evmVersion, bool _objectAccess);
|
||||
|
||||
static EVMDialectTyped const& instance(langutil::EVMVersion _version);
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user