From 857ed12b056489eb53131b196bf8ea5e4257c956 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 2 Mar 2020 18:08:19 +0100 Subject: [PATCH] Use plain members and references instead of shared pointers for MultiUseYulFunctionCollector --- libsolidity/codegen/ABIFunctions.cpp | 2 +- libsolidity/codegen/ABIFunctions.h | 6 +- libsolidity/codegen/CompilerContext.cpp | 2 +- libsolidity/codegen/CompilerContext.h | 2 +- libsolidity/codegen/YulUtilFunctions.cpp | 110 +++++++++--------- libsolidity/codegen/YulUtilFunctions.h | 6 +- .../codegen/ir/IRGenerationContext.cpp | 2 +- libsolidity/codegen/ir/IRGenerationContext.h | 7 +- libsolidity/codegen/ir/IRGenerator.cpp | 13 +-- 9 files changed, 74 insertions(+), 76 deletions(-) diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index b6d690898..5cca1c1e4 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -1492,7 +1492,7 @@ string ABIFunctions::arrayStoreLengthForEncodingFunction(ArrayType const& _type, string ABIFunctions::createFunction(string const& _name, function const& _creator) { - return m_functionCollector->createFunction(_name, _creator); + return m_functionCollector.createFunction(_name, _creator); } size_t ABIFunctions::headSize(TypePointers const& _targetTypes) diff --git a/libsolidity/codegen/ABIFunctions.h b/libsolidity/codegen/ABIFunctions.h index 1099e3593..e760917ac 100644 --- a/libsolidity/codegen/ABIFunctions.h +++ b/libsolidity/codegen/ABIFunctions.h @@ -57,11 +57,11 @@ public: explicit ABIFunctions( langutil::EVMVersion _evmVersion, RevertStrings _revertStrings, - std::shared_ptr _functionCollector = std::make_shared() + MultiUseYulFunctionCollector& _functionCollector ): m_evmVersion(_evmVersion), m_revertStrings(_revertStrings), - m_functionCollector(std::move(_functionCollector)), + m_functionCollector(_functionCollector), m_utils(_evmVersion, m_revertStrings, m_functionCollector) {} @@ -247,7 +247,7 @@ private: langutil::EVMVersion m_evmVersion; RevertStrings const m_revertStrings; - std::shared_ptr m_functionCollector; + MultiUseYulFunctionCollector& m_functionCollector; YulUtilFunctions m_utils; }; diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 1d1eb92b9..cb195c49f 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -151,7 +151,7 @@ pair> CompilerContext::requestedYulFunctions() { set empty; swap(empty, m_externallyUsedYulFunctions); - return make_pair(m_yulFunctionCollector->requestedFunctions(), std::move(empty)); + return {m_yulFunctionCollector.requestedFunctions(), std::move(empty)}; } void CompilerContext::addVariable( diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 76c72770d..8c5775239 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -371,7 +371,7 @@ private: /// An index of low-level function labels by name. std::map m_lowLevelFunctions; /// Collector for yul functions. - std::shared_ptr m_yulFunctionCollector = std::make_shared(); + MultiUseYulFunctionCollector m_yulFunctionCollector; /// Set of externally used yul functions. std::set m_externallyUsedYulFunctions; /// Container for ABI functions to be generated. diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 0472dd588..bcb309c99 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -39,7 +39,7 @@ using namespace solidity::frontend; string YulUtilFunctions::combineExternalFunctionIdFunction() { string functionName = "combine_external_function_id"; - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (addr, selector) -> combined { combined := (or((addr), and(selector, 0xffffffff))) @@ -55,7 +55,7 @@ string YulUtilFunctions::combineExternalFunctionIdFunction() string YulUtilFunctions::splitExternalFunctionIdFunction() { string functionName = "split_external_function_id"; - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (combined) -> addr, selector { combined := (combined) @@ -73,7 +73,7 @@ string YulUtilFunctions::splitExternalFunctionIdFunction() string YulUtilFunctions::copyToMemoryFunction(bool _fromCalldata) { string functionName = "copy_" + string(_fromCalldata ? "calldata" : "memory") + "_to_memory"; - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { if (_fromCalldata) { return Whiskers(R"( @@ -116,7 +116,7 @@ string YulUtilFunctions::requireOrAssertFunction(bool _assert, Type const* _mess solAssert(!_assert || !_messageType, "Asserts can't have messages!"); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { if (!_messageType) return Whiskers(R"( function (condition) { @@ -166,7 +166,7 @@ string YulUtilFunctions::requireOrAssertFunction(bool _assert, Type const* _mess string YulUtilFunctions::leftAlignFunction(Type const& _type) { string functionName = string("leftAlign_") + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { Whiskers templ(R"( function (value) -> aligned { @@ -228,7 +228,7 @@ string YulUtilFunctions::shiftLeftFunction(size_t _numBits) solAssert(_numBits < 256, ""); string functionName = "shift_left_" + to_string(_numBits); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (value) -> newValue { @@ -251,7 +251,7 @@ string YulUtilFunctions::shiftLeftFunction(size_t _numBits) string YulUtilFunctions::shiftLeftFunctionDynamic() { string functionName = "shift_left_dynamic"; - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (bits, value) -> newValue { @@ -277,7 +277,7 @@ string YulUtilFunctions::shiftRightFunction(size_t _numBits) // the opcodes SAR and SDIV behave differently with regards to rounding! string functionName = "shift_right_" + to_string(_numBits) + "_unsigned"; - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (value) -> newValue { @@ -303,7 +303,7 @@ string YulUtilFunctions::shiftRightFunctionDynamic() // the opcodes SAR and SDIV behave differently with regards to rounding! string const functionName = "shift_right_unsigned_dynamic"; - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (bits, value) -> newValue { @@ -328,7 +328,7 @@ string YulUtilFunctions::updateByteSliceFunction(size_t _numBytes, size_t _shift size_t numBits = _numBytes * 8; size_t shiftBits = _shiftBytes * 8; string functionName = "update_byte_slice_" + to_string(_numBytes) + "_shift_" + to_string(_shiftBytes); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (value, toInsert) -> result { @@ -350,7 +350,7 @@ string YulUtilFunctions::updateByteSliceFunctionDynamic(size_t _numBytes) solAssert(_numBytes <= 32, ""); size_t numBits = _numBytes * 8; string functionName = "update_byte_slice_dynamic" + to_string(_numBytes); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (value, shiftBytes, toInsert) -> result { @@ -371,7 +371,7 @@ string YulUtilFunctions::updateByteSliceFunctionDynamic(size_t _numBytes) string YulUtilFunctions::roundUpFunction() { string functionName = "round_up_to_mul_of_32"; - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (value) -> result { @@ -389,7 +389,7 @@ string YulUtilFunctions::overflowCheckedIntAddFunction(IntegerType const& _type) // TODO: Consider to add a special case for unsigned 256-bit integers // and use the following instead: // sum := add(x, y) if lt(sum, x) { revert(0, 0) } - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (x, y) -> sum { @@ -416,7 +416,7 @@ string YulUtilFunctions::overflowCheckedIntAddFunction(IntegerType const& _type) string YulUtilFunctions::overflowCheckedIntMulFunction(IntegerType const& _type) { string functionName = "checked_mul_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return // Multiplication by zero could be treated separately and directly return zero. Whiskers(R"( @@ -448,7 +448,7 @@ string YulUtilFunctions::overflowCheckedIntMulFunction(IntegerType const& _type) string YulUtilFunctions::overflowCheckedIntDivFunction(IntegerType const& _type) { string functionName = "checked_div_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (x, y) -> r { @@ -473,7 +473,7 @@ string YulUtilFunctions::overflowCheckedIntDivFunction(IntegerType const& _type) string YulUtilFunctions::checkedIntModFunction(IntegerType const& _type) { string functionName = "checked_mod_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (x, y) -> r { @@ -490,7 +490,7 @@ string YulUtilFunctions::checkedIntModFunction(IntegerType const& _type) string YulUtilFunctions::overflowCheckedIntSubFunction(IntegerType const& _type) { string functionName = "checked_sub_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&] { + return m_functionCollector.createFunction(functionName, [&] { return Whiskers(R"( function (x, y) -> diff { @@ -516,7 +516,7 @@ string YulUtilFunctions::overflowCheckedIntSubFunction(IntegerType const& _type) string YulUtilFunctions::arrayLengthFunction(ArrayType const& _type) { string functionName = "array_length_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { Whiskers w(R"( function (value) -> length { @@ -564,7 +564,7 @@ std::string YulUtilFunctions::resizeDynamicArrayFunction(ArrayType const& _type) solUnimplementedAssert(_type.baseType()->storageSize() == 1, ""); string functionName = "resize_array_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (array, newLen) { if gt(newLen, ) { @@ -604,7 +604,7 @@ string YulUtilFunctions::storageArrayPopFunction(ArrayType const& _type) solUnimplementedAssert(_type.baseType()->storageBytes() <= 32, "Base type is not yet implemented."); string functionName = "array_pop_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (array) { let oldLen := (array) @@ -632,7 +632,7 @@ string YulUtilFunctions::storageArrayPushFunction(ArrayType const& _type) solUnimplementedAssert(_type.baseType()->storageBytes() <= 32, "Base type is not yet implemented."); string functionName = "array_push_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (array, value) { let oldLen := (array) @@ -659,7 +659,7 @@ string YulUtilFunctions::storageArrayPushZeroFunction(ArrayType const& _type) solUnimplementedAssert(_type.baseType()->storageBytes() <= 32, "Base type is not yet implemented."); string functionName = "array_push_zero_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (array) -> slot, offset { let oldLen := (array) @@ -684,7 +684,7 @@ string YulUtilFunctions::clearStorageRangeFunction(Type const& _type) solAssert(_type.storageBytes() >= 32, "Expected smaller value for storage bytes"); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (start, end) { for {} lt(start, end) { start := add(start, ) } @@ -715,7 +715,7 @@ string YulUtilFunctions::clearStorageArrayFunction(ArrayType const& _type) string functionName = "clear_storage_array_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (slot) { @@ -745,7 +745,7 @@ string YulUtilFunctions::clearStorageArrayFunction(ArrayType const& _type) string YulUtilFunctions::arrayConvertLengthToSize(ArrayType const& _type) { string functionName = "array_convert_length_to_size_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { Type const& baseType = *_type.baseType(); switch (_type.location()) @@ -798,7 +798,7 @@ string YulUtilFunctions::arrayAllocationSizeFunction(ArrayType const& _type) { solAssert(_type.dataStoredIn(DataLocation::Memory), ""); string functionName = "array_allocation_size_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { Whiskers w(R"( function (length) -> size { // Make sure we can allocate memory without overflow @@ -825,7 +825,7 @@ string YulUtilFunctions::arrayAllocationSizeFunction(ArrayType const& _type) string YulUtilFunctions::arrayDataAreaFunction(ArrayType const& _type) { string functionName = "array_dataslot_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { // No special processing for calldata arrays, because they are stored as // offset of the data area and length on the stack, so the offset already // points to the data area. @@ -858,7 +858,7 @@ string YulUtilFunctions::storageArrayIndexAccessFunction(ArrayType const& _type) solUnimplementedAssert(_type.baseType()->storageBytes() > 16, ""); string functionName = "storage_array_index_access_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (array, index) -> slot, offset { if iszero(lt(index, (array))) { @@ -886,7 +886,7 @@ string YulUtilFunctions::storageArrayIndexAccessFunction(ArrayType const& _type) string YulUtilFunctions::memoryArrayIndexAccessFunction(ArrayType const& _type) { string functionName = "memory_array_index_access_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (baseRef, index) -> addr { if iszero(lt(index, (baseRef))) { @@ -912,7 +912,7 @@ string YulUtilFunctions::calldataArrayIndexAccessFunction(ArrayType const& _type { solAssert(_type.dataStoredIn(DataLocation::CallData), ""); string functionName = "calldata_array_index_access_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (base_ref, length, index) -> addr, len { if iszero(lt(index, length)) { invalid() } @@ -938,7 +938,7 @@ string YulUtilFunctions::accessCalldataTailFunction(Type const& _type) solAssert(_type.isDynamicallyEncoded(), ""); solAssert(_type.dataStoredIn(DataLocation::CallData), ""); string functionName = "access_calldata_tail_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (base_ref, ptr_to_tail) -> addr, length { let rel_offset_of_tail := calldataload(ptr_to_tail) @@ -966,7 +966,7 @@ string YulUtilFunctions::nextArrayElementFunction(ArrayType const& _type) if (_type.dataStoredIn(DataLocation::Storage)) solAssert(_type.baseType()->storageBytes() > 16, ""); string functionName = "array_nextElement_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { Whiskers templ(R"( function (ptr) -> next { next := add(ptr, ) @@ -1002,7 +1002,7 @@ string YulUtilFunctions::mappingIndexAccessFunction(MappingType const& _mappingT solAssert(_keyType.sizeOnStack() <= 1, ""); string functionName = "mapping_index_access_" + _mappingType.identifier() + "_of_" + _keyType.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { if (_mappingType.keyType()->isDynamicallySized()) return Whiskers(R"( function (slot ) -> dataSlot { @@ -1050,7 +1050,7 @@ string YulUtilFunctions::readFromStorage(Type const& _type, size_t _offset, bool to_string(_offset) + "_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&] { + return m_functionCollector.createFunction(functionName, [&] { solAssert(_type.sizeOnStack() == 1, ""); return Whiskers(R"( function (slot) -> value { @@ -1071,7 +1071,7 @@ string YulUtilFunctions::readFromStorageDynamic(Type const& _type, bool _splitFu string(_splitFunctionTypes ? "split_" : "") + "_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&] { + return m_functionCollector.createFunction(functionName, [&] { solAssert(_type.sizeOnStack() == 1, ""); return Whiskers(R"( function (slot, offset) -> value { @@ -1101,7 +1101,7 @@ string YulUtilFunctions::updateStorageValueFunction(Type const& _type, std::opti (_offset.has_value() ? ("offset_" + to_string(*_offset)) : "") + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&] { + return m_functionCollector.createFunction(functionName, [&] { if (_type.isValueType()) { solAssert(_type.storageBytes() <= 32, "Invalid storage bytes size."); @@ -1141,7 +1141,7 @@ string YulUtilFunctions::writeToMemoryFunction(Type const& _type) string("write_to_memory_") + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&] { + return m_functionCollector.createFunction(functionName, [&] { solAssert(!dynamic_cast(&_type), ""); if (auto ref = dynamic_cast(&_type)) { @@ -1201,7 +1201,7 @@ string YulUtilFunctions::extractFromStorageValueDynamic(Type const& _type, bool "extract_from_storage_value_dynamic" + string(_splitFunctionTypes ? "split_" : "") + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&] { + return m_functionCollector.createFunction(functionName, [&] { return Whiskers(R"( function (slot_value, offset) -> value { value := ((mul(offset, 8), slot_value)) @@ -1224,7 +1224,7 @@ string YulUtilFunctions::extractFromStorageValue(Type const& _type, size_t _offs "offset_" + to_string(_offset) + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&] { + return m_functionCollector.createFunction(functionName, [&] { return Whiskers(R"( function (slot_value) -> value { value := ((slot_value)) @@ -1243,7 +1243,7 @@ string YulUtilFunctions::cleanupFromStorageFunction(Type const& _type, bool _spl solUnimplementedAssert(!_splitFunctionTypes, ""); string functionName = string("cleanup_from_storage_") + (_splitFunctionTypes ? "split_" : "") + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&] { + return m_functionCollector.createFunction(functionName, [&] { Whiskers templ(R"( function (value) -> cleaned { cleaned := @@ -1275,7 +1275,7 @@ string YulUtilFunctions::prepareStoreFunction(Type const& _type) solUnimplementedAssert(_type.category() != Type::Category::Function, ""); string functionName = "prepare_store_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { Whiskers templ(R"( function (value) -> ret { ret := @@ -1293,7 +1293,7 @@ string YulUtilFunctions::prepareStoreFunction(Type const& _type) string YulUtilFunctions::allocationFunction() { string functionName = "allocateMemory"; - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (size) -> memPtr { memPtr := mload() @@ -1314,7 +1314,7 @@ string YulUtilFunctions::allocateMemoryArrayFunction(ArrayType const& _type) solUnimplementedAssert(!_type.isByteArray(), ""); string functionName = "allocate_memory_array_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (length) -> memPtr { memPtr := ((length)) @@ -1341,7 +1341,7 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) _from.identifier() + "_to_" + _to.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { Whiskers templ(R"( function (value) -> converted { @@ -1519,7 +1519,7 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) string YulUtilFunctions::cleanupFunction(Type const& _type) { string functionName = string("cleanup_") + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { Whiskers templ(R"( function (value) -> cleaned { @@ -1606,7 +1606,7 @@ string YulUtilFunctions::cleanupFunction(Type const& _type) string YulUtilFunctions::validatorFunction(Type const& _type, bool _revertOnFailure) { string functionName = string("validator_") + (_revertOnFailure ? "revert_" : "assert_") + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { Whiskers templ(R"( function (value) { if iszero() { } @@ -1667,7 +1667,7 @@ string YulUtilFunctions::packedHashFunction( size_t sizeOnStack = 0; for (Type const* t: _givenTypes) sizeOnStack += t->sizeOnStack(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { Whiskers templ(R"( function () -> hash { let pos := mload() @@ -1688,7 +1688,7 @@ string YulUtilFunctions::forwardingRevertFunction() { bool forward = m_evmVersion.supportsReturndata(); string functionName = "revert_forward_" + to_string(forward); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { if (forward) return Whiskers(R"( function () { @@ -1715,7 +1715,7 @@ std::string YulUtilFunctions::decrementCheckedFunction(Type const& _type) string const functionName = "decrement_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { u256 minintval; // Smallest admissible value to decrement @@ -1743,7 +1743,7 @@ std::string YulUtilFunctions::incrementCheckedFunction(Type const& _type) string const functionName = "increment_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { u256 maxintval; // Biggest admissible value to increment @@ -1774,7 +1774,7 @@ string YulUtilFunctions::negateNumberCheckedFunction(Type const& _type) u256 const minintval = 0 - (u256(1) << (type.numBits() - 1)) + 1; - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (_value) -> ret { if slt(_value, ) { revert(0,0) } @@ -1794,7 +1794,7 @@ string YulUtilFunctions::zeroValueFunction(Type const& _type) string const functionName = "zero_value_for_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function () -> ret { @@ -1810,7 +1810,7 @@ string YulUtilFunctions::storageSetToZeroFunction(Type const& _type) { string const functionName = "storage_set_to_zero_" + _type.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { if (_type.isValueType()) return Whiskers(R"( function (slot, offset) { @@ -1842,7 +1842,7 @@ string YulUtilFunctions::conversionFunctionSpecial(Type const& _from, Type const _from.identifier() + "_to_" + _to.identifier(); - return m_functionCollector->createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&]() { if ( auto fromTuple = dynamic_cast(&_from), toTuple = dynamic_cast(&_to); fromTuple && toTuple && fromTuple->components().size() == toTuple->components().size() @@ -1950,7 +1950,7 @@ string YulUtilFunctions::readFromMemoryOrCalldata(Type const& _type, bool _fromC if (_fromCalldata) solAssert(!_type.isDynamicallyEncoded(), ""); - return m_functionCollector->createFunction(functionName, [&] { + return m_functionCollector.createFunction(functionName, [&] { if (auto refType = dynamic_cast(&_type)) { solAssert(refType->sizeOnStack() == 1, ""); diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index 8c92d7b4f..cf50c785f 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -47,11 +47,11 @@ public: explicit YulUtilFunctions( langutil::EVMVersion _evmVersion, RevertStrings _revertStrings, - std::shared_ptr _functionCollector + MultiUseYulFunctionCollector& _functionCollector ): m_evmVersion(_evmVersion), m_revertStrings(_revertStrings), - m_functionCollector(std::move(_functionCollector)) + m_functionCollector(_functionCollector) {} /// @returns a function that combines the address and selector to a single value @@ -306,7 +306,7 @@ private: langutil::EVMVersion m_evmVersion; RevertStrings m_revertStrings; - std::shared_ptr m_functionCollector; + MultiUseYulFunctionCollector& m_functionCollector; }; } diff --git a/libsolidity/codegen/ir/IRGenerationContext.cpp b/libsolidity/codegen/ir/IRGenerationContext.cpp index 43cb6a040..7184247f4 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.cpp +++ b/libsolidity/codegen/ir/IRGenerationContext.cpp @@ -100,7 +100,7 @@ string IRGenerationContext::newYulVariable() string IRGenerationContext::internalDispatch(size_t _in, size_t _out) { string funName = "dispatch_internal_in_" + to_string(_in) + "_out_" + to_string(_out); - return m_functions->createFunction(funName, [&]() { + return m_functions.createFunction(funName, [&]() { Whiskers templ(R"( function (fun ) { switch fun diff --git a/libsolidity/codegen/ir/IRGenerationContext.h b/libsolidity/codegen/ir/IRGenerationContext.h index d4c29ab10..473b62482 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.h +++ b/libsolidity/codegen/ir/IRGenerationContext.h @@ -56,11 +56,10 @@ public: ): m_evmVersion(_evmVersion), m_revertStrings(_revertStrings), - m_optimiserSettings(std::move(_optimiserSettings)), - m_functions(std::make_shared()) + m_optimiserSettings(std::move(_optimiserSettings)) {} - std::shared_ptr functionCollector() const { return m_functions; } + MultiUseYulFunctionCollector& functionCollector() { return m_functions; } /// Sets the current inheritance hierarchy from derived to base. void setInheritanceHierarchy(std::vector _hierarchy) @@ -108,7 +107,7 @@ private: std::map m_localVariables; /// Storage offsets of state variables std::map> m_stateVariables; - std::shared_ptr m_functions; + MultiUseYulFunctionCollector m_functions; size_t m_varCounter = 0; }; diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 9c2d8807c..8da576055 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -107,7 +107,7 @@ string IRGenerator::generate(ContractDefinition const& _contract) for (auto const* contract: _contract.annotation().linearizedBaseContracts) for (auto const* fun: contract->definedFunctions()) generateFunction(*fun); - t("functions", m_context.functionCollector()->requestedFunctions()); + t("functions", m_context.functionCollector().requestedFunctions()); resetContext(_contract); m_context.setInheritanceHierarchy(_contract.annotation().linearizedBaseContracts); @@ -116,7 +116,7 @@ string IRGenerator::generate(ContractDefinition const& _contract) for (auto const* contract: _contract.annotation().linearizedBaseContracts) for (auto const* fun: contract->definedFunctions()) generateFunction(*fun); - t("runtimeFunctions", m_context.functionCollector()->requestedFunctions()); + t("runtimeFunctions", m_context.functionCollector().requestedFunctions()); return t.render(); } @@ -130,7 +130,7 @@ string IRGenerator::generate(Block const& _block) string IRGenerator::generateFunction(FunctionDefinition const& _function) { string functionName = m_context.functionName(_function); - return m_context.functionCollector()->createFunction(functionName, [&]() { + return m_context.functionCollector().createFunction(functionName, [&]() { Whiskers t(R"( function () { @@ -160,7 +160,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) solAssert(_varDecl.isStateVariable(), ""); if (auto const* mappingType = dynamic_cast(type)) - return m_context.functionCollector()->createFunction(functionName, [&]() { + return m_context.functionCollector().createFunction(functionName, [&]() { pair slot_offset = m_context.storageLocationOfVariable(_varDecl); solAssert(slot_offset.second == 0, ""); FunctionType funType(_varDecl); @@ -209,7 +209,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) { solUnimplementedAssert(type->isValueType(), ""); - return m_context.functionCollector()->createFunction(functionName, [&]() { + return m_context.functionCollector().createFunction(functionName, [&]() { pair slot_offset = m_context.storageLocationOfVariable(_varDecl); return Whiskers(R"( @@ -383,11 +383,10 @@ string IRGenerator::memoryInit() void IRGenerator::resetContext(ContractDefinition const& _contract) { solAssert( - m_context.functionCollector()->requestedFunctions().empty(), + m_context.functionCollector().requestedFunctions().empty(), "Reset context while it still had functions." ); m_context = IRGenerationContext(m_evmVersion, m_context.revertStrings(), m_optimiserSettings); - m_utils = YulUtilFunctions(m_evmVersion, m_context.revertStrings(), m_context.functionCollector()); m_context.setInheritanceHierarchy(_contract.annotation().linearizedBaseContracts); for (auto const& var: ContractType(_contract).stateVariables())