mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Refactoring signature for updateStorageValueFunction
This commit is contained in:
parent
15163b2270
commit
1fab5b79fb
@ -362,7 +362,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
|
|||||||
solAssert(sourceType.sizeOnStack() == 1, "");
|
solAssert(sourceType.sizeOnStack() == 1, "");
|
||||||
solAssert(structType.sizeOnStack() == 1, "");
|
solAssert(structType.sizeOnStack() == 1, "");
|
||||||
m_context << Instruction::DUP2 << Instruction::DUP2;
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -964,7 +964,7 @@ string YulUtilFunctions::storageArrayPushFunction(ArrayType const& _type)
|
|||||||
("dataAreaFunction", arrayDataAreaFunction(_type))
|
("dataAreaFunction", arrayDataAreaFunction(_type))
|
||||||
("isByteArray", _type.isByteArray())
|
("isByteArray", _type.isByteArray())
|
||||||
("indexAccess", storageArrayIndexAccessFunction(_type))
|
("indexAccess", storageArrayIndexAccessFunction(_type))
|
||||||
("storeValue", updateStorageValueFunction(*_type.baseType()))
|
("storeValue", updateStorageValueFunction(*_type.baseType(), *_type.baseType()))
|
||||||
("maxArrayLength", (u256(1) << 64).str())
|
("maxArrayLength", (u256(1) << 64).str())
|
||||||
("shl", shiftLeftFunctionDynamic())
|
("shl", shiftLeftFunctionDynamic())
|
||||||
("shr", shiftRightFunction(248))
|
("shr", shiftRightFunction(248))
|
||||||
@ -994,7 +994,7 @@ string YulUtilFunctions::storageArrayPushZeroFunction(ArrayType const& _type)
|
|||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("fetchLength", arrayLengthFunction(_type))
|
("fetchLength", arrayLengthFunction(_type))
|
||||||
("indexAccess", storageArrayIndexAccessFunction(_type))
|
("indexAccess", storageArrayIndexAccessFunction(_type))
|
||||||
("storeValue", updateStorageValueFunction(*_type.baseType()))
|
("storeValue", updateStorageValueFunction(*_type.baseType(), *_type.baseType()))
|
||||||
("maxArrayLength", (u256(1) << 64).str())
|
("maxArrayLength", (u256(1) << 64).str())
|
||||||
("zeroValueFunction", zeroValueFunction(*_type.baseType()))
|
("zeroValueFunction", zeroValueFunction(*_type.baseType()))
|
||||||
.render();
|
.render();
|
||||||
@ -1529,21 +1529,22 @@ string YulUtilFunctions::readFromCalldata(Type const& _type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
string YulUtilFunctions::updateStorageValueFunction(
|
string YulUtilFunctions::updateStorageValueFunction(
|
||||||
|
Type const& _fromType,
|
||||||
Type const& _toType,
|
Type const& _toType,
|
||||||
Type const* _fromType,
|
|
||||||
std::optional<unsigned> const& _offset
|
std::optional<unsigned> const& _offset
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
string const functionName =
|
string const functionName =
|
||||||
"update_storage_value_" +
|
"update_storage_value_" +
|
||||||
(_offset.has_value() ? ("offset_" + to_string(*_offset)) : "") +
|
(_offset.has_value() ? ("offset_" + to_string(*_offset)) : "") +
|
||||||
(_fromType ? "_from_" + _fromType->identifier() : "") +
|
_fromType.identifier() +
|
||||||
"_to_" +
|
"_to_" +
|
||||||
_toType.identifier();
|
_toType.identifier();
|
||||||
|
|
||||||
return m_functionCollector.createFunction(functionName, [&] {
|
return m_functionCollector.createFunction(functionName, [&] {
|
||||||
if (_toType.isValueType())
|
if (_toType.isValueType())
|
||||||
{
|
{
|
||||||
|
solAssert(_fromType.isImplicitlyConvertibleTo(_toType), "");
|
||||||
solAssert(_toType.storageBytes() <= 32, "Invalid storage bytes size.");
|
solAssert(_toType.storageBytes() <= 32, "Invalid storage bytes size.");
|
||||||
solAssert(_toType.storageBytes() > 0, "Invalid storage bytes size.");
|
solAssert(_toType.storageBytes() > 0, "Invalid storage bytes size.");
|
||||||
|
|
||||||
@ -1565,13 +1566,20 @@ string YulUtilFunctions::updateStorageValueFunction(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
auto const* toReferenceType = dynamic_cast<ReferenceType const*>(&_toType);
|
||||||
|
auto const* fromReferenceType = dynamic_cast<ReferenceType const*>(&_toType);
|
||||||
|
solAssert(fromReferenceType && toReferenceType, "");
|
||||||
|
solAssert(*toReferenceType->copyForLocation(
|
||||||
|
fromReferenceType->location(),
|
||||||
|
fromReferenceType->isPointer()
|
||||||
|
).get() == *fromReferenceType, "");
|
||||||
|
|
||||||
if (_toType.category() == Type::Category::Array)
|
if (_toType.category() == Type::Category::Array)
|
||||||
solUnimplementedAssert(false, "");
|
solUnimplementedAssert(false, "");
|
||||||
else if (_toType.category() == Type::Category::Struct)
|
else if (_toType.category() == Type::Category::Struct)
|
||||||
{
|
{
|
||||||
solAssert(_fromType, "");
|
solAssert(_fromType.category() == Type::Category::Struct, "");
|
||||||
solAssert(_fromType->category() == Type::Category::Struct, "");
|
auto const& fromStructType = dynamic_cast<StructType const&>(_fromType);
|
||||||
auto const& fromStructType = dynamic_cast<StructType const&>(*_fromType);
|
|
||||||
auto const& toStructType = dynamic_cast<StructType const&>(_toType);
|
auto const& toStructType = dynamic_cast<StructType const&>(_toType);
|
||||||
solAssert(fromStructType.structDefinition() == toStructType.structDefinition(), "");
|
solAssert(fromStructType.structDefinition() == toStructType.structDefinition(), "");
|
||||||
solAssert(fromStructType.location() != DataLocation::Storage, "");
|
solAssert(fromStructType.location() != DataLocation::Storage, "");
|
||||||
@ -1597,15 +1605,20 @@ string YulUtilFunctions::updateStorageValueFunction(
|
|||||||
bool fromCalldata = fromStructType.location() == DataLocation::CallData;
|
bool fromCalldata = fromStructType.location() == DataLocation::CallData;
|
||||||
auto const& [slotDiff, offset] = toStructType.storageOffsetsOfMember(structMembers[i].name);
|
auto const& [slotDiff, offset] = toStructType.storageOffsetsOfMember(structMembers[i].name);
|
||||||
memberParams[i]["updateMemberCall"] = Whiskers(R"(
|
memberParams[i]["updateMemberCall"] = Whiskers(R"(
|
||||||
let memberValue := <loadFromMemoryOrCalldata>(add(value, <memberOffset>))
|
let <memberValues> := <loadFromMemoryOrCalldata>(add(value, <memberOffset>))
|
||||||
<updateMember>(add(slot, <memberStorageSlotDiff>), <?hasOffset><memberStorageOffset>,</hasOffset> memberValue)
|
<updateMember>(add(slot, <memberStorageSlotDiff>), <?hasOffset><memberStorageOffset>,</hasOffset> <memberValues>)
|
||||||
)")
|
)")
|
||||||
|
("memberValues", suffixedVariableNameList(
|
||||||
|
"memberValue_",
|
||||||
|
0,
|
||||||
|
structMembers[i].type->stackItems().size()
|
||||||
|
))
|
||||||
("hasOffset", structMembers[i].type->isValueType())
|
("hasOffset", structMembers[i].type->isValueType())
|
||||||
(
|
(
|
||||||
"updateMember",
|
"updateMember",
|
||||||
structMembers[i].type->isValueType() ?
|
structMembers[i].type->isValueType() ?
|
||||||
updateStorageValueFunction(*structMembers[i].type, structMembers[i].type) :
|
updateStorageValueFunction(*structMembers[i].type, *structMembers[i].type) :
|
||||||
updateStorageValueFunction(*structMembers[i].type, structMembers[i].type, offset)
|
updateStorageValueFunction(*structMembers[i].type, *structMembers[i].type, offset)
|
||||||
)
|
)
|
||||||
("memberStorageSlotDiff", slotDiff.str())
|
("memberStorageSlotDiff", slotDiff.str())
|
||||||
("memberStorageOffset", to_string(offset))
|
("memberStorageOffset", to_string(offset))
|
||||||
@ -2632,7 +2645,7 @@ string YulUtilFunctions::storageSetToZeroFunction(Type const& _type)
|
|||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("store", updateStorageValueFunction(_type))
|
("store", updateStorageValueFunction(_type, _type))
|
||||||
("zeroValue", zeroValueFunction(_type))
|
("zeroValue", zeroValueFunction(_type))
|
||||||
.render();
|
.render();
|
||||||
else if (_type.category() == Type::Category::Array)
|
else if (_type.category() == Type::Category::Array)
|
||||||
|
@ -248,8 +248,8 @@ public:
|
|||||||
/// runtime parameter.
|
/// runtime parameter.
|
||||||
/// signature: (slot, [offset,] value)
|
/// signature: (slot, [offset,] value)
|
||||||
std::string updateStorageValueFunction(
|
std::string updateStorageValueFunction(
|
||||||
|
Type const& _fromType,
|
||||||
Type const& _toType,
|
Type const& _toType,
|
||||||
Type const* _fromType = nullptr,
|
|
||||||
std::optional<unsigned> const& _offset = std::optional<unsigned>()
|
std::optional<unsigned> const& _offset = std::optional<unsigned>()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2486,7 +2486,7 @@ void IRGeneratorForStatements::writeToLValue(IRLValue const& _lvalue, IRVariable
|
|||||||
offset = std::get<unsigned>(_storage.offset);
|
offset = std::get<unsigned>(_storage.offset);
|
||||||
|
|
||||||
m_code <<
|
m_code <<
|
||||||
m_utils.updateStorageValueFunction(_lvalue.type, &_value.type(), offset) <<
|
m_utils.updateStorageValueFunction(_value.type(), _lvalue.type, offset) <<
|
||||||
"(" <<
|
"(" <<
|
||||||
_storage.slot <<
|
_storage.slot <<
|
||||||
(
|
(
|
||||||
|
Loading…
Reference in New Issue
Block a user