From fea3f848f9be1d47c14a42d45db58a143f835e24 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 2 Nov 2020 21:07:27 +0100 Subject: [PATCH] Prepare store for external function types. --- libsolidity/codegen/YulUtilFunctions.cpp | 41 ++++++++++++++++-------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 9b80c5e7d..c9b23dec2 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -2487,22 +2487,37 @@ string YulUtilFunctions::cleanupFromStorageFunction(Type const& _type, bool _spl string YulUtilFunctions::prepareStoreFunction(Type const& _type) { - if (_type.category() == Type::Category::Function) - solUnimplementedAssert(dynamic_cast(_type).kind() == FunctionType::Kind::Internal, ""); - string functionName = "prepare_store_" + _type.identifier(); return m_functionCollector.createFunction(functionName, [&]() { - Whiskers templ(R"( - function (value) -> ret { - ret := - } - )"); - templ("functionName", functionName); - if (_type.category() == Type::Category::FixedBytes) - templ("actualPrepare", shiftRightFunction(256 - 8 * _type.storageBytes()) + "(value)"); + solAssert(_type.isValueType(), ""); + auto const* funType = dynamic_cast(&_type); + if (funType && funType->kind() == FunctionType::Kind::External) + { + Whiskers templ(R"( + function (addr, selector) -> ret { + ret := ((addr, selector)) + } + )"); + templ("functionName", functionName); + templ("prepareBytes", prepareStoreFunction(*TypeProvider::fixedBytes(24))); + templ("combine", combineExternalFunctionIdFunction()); + return templ.render(); + } else - templ("actualPrepare", "value"); - return templ.render(); + { + solAssert(_type.sizeOnStack() == 1, ""); + Whiskers templ(R"( + function (value) -> ret { + ret := + } + )"); + templ("functionName", functionName); + if (_type.category() == Type::Category::FixedBytes) + templ("actualPrepare", shiftRightFunction(256 - 8 * _type.storageBytes()) + "(value)"); + else + templ("actualPrepare", "value"); + return templ.render(); + } }); }