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,22 +2487,37 @@ 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, [&]() {
Whiskers templ(R"( solAssert(_type.isValueType(), "");
function <functionName>(value) -> ret { auto const* funType = dynamic_cast<FunctionType const*>(&_type);
ret := <actualPrepare> if (funType && funType->kind() == FunctionType::Kind::External)
} {
)"); Whiskers templ(R"(
templ("functionName", functionName); function <functionName>(addr, selector) -> ret {
if (_type.category() == Type::Category::FixedBytes) ret := <prepareBytes>(<combine>(addr, selector))
templ("actualPrepare", shiftRightFunction(256 - 8 * _type.storageBytes()) + "(value)"); }
)");
templ("functionName", functionName);
templ("prepareBytes", prepareStoreFunction(*TypeProvider::fixedBytes(24)));
templ("combine", combineExternalFunctionIdFunction());
return templ.render();
}
else else
templ("actualPrepare", "value"); {
return templ.render(); solAssert(_type.sizeOnStack() == 1, "");
Whiskers templ(R"(
function <functionName>(value) -> ret {
ret := <actualPrepare>
}
)");
templ("functionName", functionName);
if (_type.category() == Type::Category::FixedBytes)
templ("actualPrepare", shiftRightFunction(256 - 8 * _type.storageBytes()) + "(value)");
else
templ("actualPrepare", "value");
return templ.render();
}
}); });
} }