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);
|
dialect = &EVMDialect::strictAssemblyForEVMObjects(m_evmVersion);
|
||||||
break;
|
break;
|
||||||
case Language::Yul:
|
case Language::Yul:
|
||||||
dialect = &EVMDialect::yulForEVM(m_evmVersion);
|
dialect = &EVMDialectTyped::instance(m_evmVersion);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
solAssert(false, "Invalid language.");
|
solAssert(false, "Invalid language.");
|
||||||
|
@ -203,15 +203,6 @@ EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _
|
|||||||
return *dialects[_version];
|
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)
|
SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instruction)
|
||||||
{
|
{
|
||||||
return SideEffects{
|
return SideEffects{
|
||||||
@ -222,3 +213,58 @@ SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instructio
|
|||||||
evmasm::SemanticInformation::invalidatesMemory(_instruction)
|
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& strictAssemblyForEVM(langutil::EVMVersion _version);
|
||||||
static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _version);
|
static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _version);
|
||||||
static EVMDialect const& yulForEVM(langutil::EVMVersion _version);
|
|
||||||
|
|
||||||
langutil::EVMVersion evmVersion() const { return m_evmVersion; }
|
langutil::EVMVersion evmVersion() const { return m_evmVersion; }
|
||||||
|
|
||||||
@ -88,4 +87,23 @@ protected:
|
|||||||
std::map<YulString, BuiltinFunctionForEVM> m_functions;
|
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