From 53d6721e47f83f2909bb27a467235bc4fb4128d4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 20 Oct 2020 17:29:11 +0200 Subject: [PATCH] Extract mask bytes function. --- libsolidity/codegen/YulUtilFunctions.cpp | 22 ++++++++++++++++++---- libsolidity/codegen/YulUtilFunctions.h | 5 +++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 7884fcfa4..a4bd0a0aa 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -434,6 +434,21 @@ string YulUtilFunctions::updateByteSliceFunctionDynamic(size_t _numBytes) }); } +string YulUtilFunctions::maskBytesFunctionDynamic() +{ + string functionName = "mask_bytes_dynamic"; + return m_functionCollector.createFunction(functionName, [&]() { + return Whiskers(R"( + function (data, bytes) -> result { + let mask := not((mul(8, bytes), not(0))) + result := and(data, mask) + })") + ("functionName", functionName) + ("shr", shiftRightFunctionDynamic()) + .render(); + }); +} + string YulUtilFunctions::roundUpFunction() { string functionName = "round_up_to_mul_of_32"; @@ -1143,12 +1158,11 @@ string YulUtilFunctions::shortByteArrayEncodeUsedAreaSetLengthFunction() function (data, len) -> used { // we want to save only elements that are part of the array after resizing // others should be set to zero - let mask := (mul(8, sub(32, len)), ) - used := or(and(data, mask), mul(2, len)) + data := (data, len) + used := or(data, mul(2, len)) })") ("functionName", functionName) - ("shl", shiftLeftFunctionDynamic()) - ("ones", formatNumber((bigint(1) << 256) - 1)) + ("maskBytes", maskBytesFunctionDynamic()) .render(); }); } diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index 69e510c48..a91eb525d 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -99,6 +99,11 @@ public: /// signature: (value, shiftBytes, toInsert) -> result std::string updateByteSliceFunctionDynamic(size_t _numBytes); + /// Function that sets all but the first ``bytes`` bytes of ``value`` to zero. + /// @note ``bytes`` has to be small enough not to overflo ``8 * bytes``. + /// signature: (value, bytes) -> result + std::string maskBytesFunctionDynamic(); + /// @returns the name of a function that rounds its input to the next multiple /// of 32 or the input if it is a multiple of 32. /// signature: (value) -> result