mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9177 from ethereum/fixYulStructMemberAccess
[Sol -> Yul] Fix struct member access for memory and implement for calldata.
This commit is contained in:
@@ -2457,6 +2457,21 @@ set<string> StructType::membersMissingInMemory() const
|
||||
return missing;
|
||||
}
|
||||
|
||||
vector<tuple<string, TypePointer>> StructType::makeStackItems() const
|
||||
{
|
||||
switch (m_location)
|
||||
{
|
||||
case DataLocation::CallData:
|
||||
return {std::make_tuple("offset", TypeProvider::uint256())};
|
||||
case DataLocation::Memory:
|
||||
return {std::make_tuple("mpos", TypeProvider::uint256())};
|
||||
case DataLocation::Storage:
|
||||
return {std::make_tuple("slot", TypeProvider::uint256())};
|
||||
}
|
||||
solAssert(false, "");
|
||||
}
|
||||
|
||||
|
||||
TypePointer EnumType::encodingType() const
|
||||
{
|
||||
return TypeProvider::uint(8 * storageBytes());
|
||||
|
||||
@@ -980,6 +980,8 @@ public:
|
||||
|
||||
void clearCache() const override;
|
||||
|
||||
protected:
|
||||
std::vector<std::tuple<std::string, TypePointer>> makeStackItems() const override;
|
||||
private:
|
||||
StructDefinition const& m_struct;
|
||||
// Caches for interfaceType(bool)
|
||||
|
||||
@@ -1477,7 +1477,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||
pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member);
|
||||
string slot = m_context.newYulVariable();
|
||||
m_code << "let " << slot << " := " <<
|
||||
("add(" + expression.name() + ", " + offsets.first.str() + ")\n");
|
||||
("add(" + expression.part("slot").name() + ", " + offsets.first.str() + ")\n");
|
||||
setLValue(_memberAccess, IRLValue{
|
||||
type(_memberAccess),
|
||||
IRLValue::Storage{slot, offsets.second}
|
||||
@@ -1497,7 +1497,25 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||
}
|
||||
case DataLocation::CallData:
|
||||
{
|
||||
solUnimplementedAssert(false, "");
|
||||
string baseRef = expression.part("offset").name();
|
||||
string offset = m_context.newYulVariable();
|
||||
m_code << "let " << offset << " := " << "add(" << baseRef << ", " << to_string(structType.calldataOffsetOfMember(member)) << ")\n";
|
||||
if (_memberAccess.annotation().type->isDynamicallyEncoded())
|
||||
define(_memberAccess) <<
|
||||
m_utils.accessCalldataTailFunction(*_memberAccess.annotation().type) <<
|
||||
"(" <<
|
||||
baseRef <<
|
||||
", " <<
|
||||
offset <<
|
||||
")" <<
|
||||
std::endl;
|
||||
else
|
||||
define(_memberAccess) <<
|
||||
m_utils.readFromCalldata(*_memberAccess.annotation().type) <<
|
||||
"(" <<
|
||||
offset <<
|
||||
")" <<
|
||||
std::endl;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user