From 1fab5b79fbc4c40340cea40120a42e90e16a8d13 Mon Sep 17 00:00:00 2001 From: Djordje Mijovic Date: Tue, 1 Sep 2020 14:43:40 +0200 Subject: [PATCH] Refactoring signature for updateStorageValueFunction --- libsolidity/codegen/LValue.cpp | 2 +- libsolidity/codegen/YulUtilFunctions.cpp | 37 +++++++++++++------ libsolidity/codegen/YulUtilFunctions.h | 2 +- .../codegen/ir/IRGeneratorForStatements.cpp | 2 +- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp index 40555b658..576a2d4c0 100644 --- a/libsolidity/codegen/LValue.cpp +++ b/libsolidity/codegen/LValue.cpp @@ -362,7 +362,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc solAssert(sourceType.sizeOnStack() == 1, ""); solAssert(structType.sizeOnStack() == 1, ""); m_context << Instruction::DUP2 << Instruction::DUP2; - m_context.callYulFunction(m_context.utilFunctions().updateStorageValueFunction(structType, &sourceType, 0), 2, 0); + m_context.callYulFunction(m_context.utilFunctions().updateStorageValueFunction(sourceType, structType, 0), 2, 0); } else { diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index a93dd57a7..b2f3ad8dd 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -964,7 +964,7 @@ string YulUtilFunctions::storageArrayPushFunction(ArrayType const& _type) ("dataAreaFunction", arrayDataAreaFunction(_type)) ("isByteArray", _type.isByteArray()) ("indexAccess", storageArrayIndexAccessFunction(_type)) - ("storeValue", updateStorageValueFunction(*_type.baseType())) + ("storeValue", updateStorageValueFunction(*_type.baseType(), *_type.baseType())) ("maxArrayLength", (u256(1) << 64).str()) ("shl", shiftLeftFunctionDynamic()) ("shr", shiftRightFunction(248)) @@ -994,7 +994,7 @@ string YulUtilFunctions::storageArrayPushZeroFunction(ArrayType const& _type) ("functionName", functionName) ("fetchLength", arrayLengthFunction(_type)) ("indexAccess", storageArrayIndexAccessFunction(_type)) - ("storeValue", updateStorageValueFunction(*_type.baseType())) + ("storeValue", updateStorageValueFunction(*_type.baseType(), *_type.baseType())) ("maxArrayLength", (u256(1) << 64).str()) ("zeroValueFunction", zeroValueFunction(*_type.baseType())) .render(); @@ -1529,21 +1529,22 @@ string YulUtilFunctions::readFromCalldata(Type const& _type) } string YulUtilFunctions::updateStorageValueFunction( + Type const& _fromType, Type const& _toType, - Type const* _fromType, std::optional const& _offset ) { string const functionName = "update_storage_value_" + (_offset.has_value() ? ("offset_" + to_string(*_offset)) : "") + - (_fromType ? "_from_" + _fromType->identifier() : "") + + _fromType.identifier() + "_to_" + _toType.identifier(); return m_functionCollector.createFunction(functionName, [&] { if (_toType.isValueType()) { + solAssert(_fromType.isImplicitlyConvertibleTo(_toType), ""); solAssert(_toType.storageBytes() <= 32, "Invalid storage bytes size."); solAssert(_toType.storageBytes() > 0, "Invalid storage bytes size."); @@ -1565,13 +1566,20 @@ string YulUtilFunctions::updateStorageValueFunction( } else { + auto const* toReferenceType = dynamic_cast(&_toType); + auto const* fromReferenceType = dynamic_cast(&_toType); + solAssert(fromReferenceType && toReferenceType, ""); + solAssert(*toReferenceType->copyForLocation( + fromReferenceType->location(), + fromReferenceType->isPointer() + ).get() == *fromReferenceType, ""); + if (_toType.category() == Type::Category::Array) solUnimplementedAssert(false, ""); else if (_toType.category() == Type::Category::Struct) { - solAssert(_fromType, ""); - solAssert(_fromType->category() == Type::Category::Struct, ""); - auto const& fromStructType = dynamic_cast(*_fromType); + solAssert(_fromType.category() == Type::Category::Struct, ""); + auto const& fromStructType = dynamic_cast(_fromType); auto const& toStructType = dynamic_cast(_toType); solAssert(fromStructType.structDefinition() == toStructType.structDefinition(), ""); solAssert(fromStructType.location() != DataLocation::Storage, ""); @@ -1597,15 +1605,20 @@ string YulUtilFunctions::updateStorageValueFunction( bool fromCalldata = fromStructType.location() == DataLocation::CallData; auto const& [slotDiff, offset] = toStructType.storageOffsetsOfMember(structMembers[i].name); memberParams[i]["updateMemberCall"] = Whiskers(R"( - let memberValue := (add(value, )) - (add(slot, ), , memberValue) + let := (add(value, )) + (add(slot, ), , ) )") + ("memberValues", suffixedVariableNameList( + "memberValue_", + 0, + structMembers[i].type->stackItems().size() + )) ("hasOffset", structMembers[i].type->isValueType()) ( "updateMember", structMembers[i].type->isValueType() ? - updateStorageValueFunction(*structMembers[i].type, structMembers[i].type) : - updateStorageValueFunction(*structMembers[i].type, structMembers[i].type, offset) + updateStorageValueFunction(*structMembers[i].type, *structMembers[i].type) : + updateStorageValueFunction(*structMembers[i].type, *structMembers[i].type, offset) ) ("memberStorageSlotDiff", slotDiff.str()) ("memberStorageOffset", to_string(offset)) @@ -2632,7 +2645,7 @@ string YulUtilFunctions::storageSetToZeroFunction(Type const& _type) } )") ("functionName", functionName) - ("store", updateStorageValueFunction(_type)) + ("store", updateStorageValueFunction(_type, _type)) ("zeroValue", zeroValueFunction(_type)) .render(); else if (_type.category() == Type::Category::Array) diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index 96ac4dfd4..8394c33af 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -248,8 +248,8 @@ public: /// runtime parameter. /// signature: (slot, [offset,] value) std::string updateStorageValueFunction( + Type const& _fromType, Type const& _toType, - Type const* _fromType = nullptr, std::optional const& _offset = std::optional() ); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 170b636fc..d5d3f19fc 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -2486,7 +2486,7 @@ void IRGeneratorForStatements::writeToLValue(IRLValue const& _lvalue, IRVariable offset = std::get(_storage.offset); m_code << - m_utils.updateStorageValueFunction(_lvalue.type, &_value.type(), offset) << + m_utils.updateStorageValueFunction(_value.type(), _lvalue.type, offset) << "(" << _storage.slot << (