Prepare store for external function types.

This commit is contained in:
chriseth 2020-11-02 21:07:27 +01:00
parent 06d0459a72
commit fea3f848f9

View File

@ -2487,11 +2487,25 @@ string YulUtilFunctions::cleanupFromStorageFunction(Type const& _type, bool _spl
string YulUtilFunctions::prepareStoreFunction(Type const& _type) string YulUtilFunctions::prepareStoreFunction(Type const& _type)
{ {
if (_type.category() == Type::Category::Function)
solUnimplementedAssert(dynamic_cast<FunctionType const&>(_type).kind() == FunctionType::Kind::Internal, "");
string functionName = "prepare_store_" + _type.identifier(); string functionName = "prepare_store_" + _type.identifier();
return m_functionCollector.createFunction(functionName, [&]() { return m_functionCollector.createFunction(functionName, [&]() {
solAssert(_type.isValueType(), "");
auto const* funType = dynamic_cast<FunctionType const*>(&_type);
if (funType && funType->kind() == FunctionType::Kind::External)
{
Whiskers templ(R"(
function <functionName>(addr, selector) -> ret {
ret := <prepareBytes>(<combine>(addr, selector))
}
)");
templ("functionName", functionName);
templ("prepareBytes", prepareStoreFunction(*TypeProvider::fixedBytes(24)));
templ("combine", combineExternalFunctionIdFunction());
return templ.render();
}
else
{
solAssert(_type.sizeOnStack() == 1, "");
Whiskers templ(R"( Whiskers templ(R"(
function <functionName>(value) -> ret { function <functionName>(value) -> ret {
ret := <actualPrepare> ret := <actualPrepare>
@ -2503,6 +2517,7 @@ string YulUtilFunctions::prepareStoreFunction(Type const& _type)
else else
templ("actualPrepare", "value"); templ("actualPrepare", "value");
return templ.render(); return templ.render();
}
}); });
} }