| 140 | } |
| 141 | |
| 142 | void StorageOffsets::computeOffsets(TypePointers const& _types, u256 _baseSlot) |
| 143 | { |
| 144 | bigint slotOffset = bigint(_baseSlot); |
| 145 | unsigned byteOffset = 0; |
| 146 | std::map<size_t, std::pair<u256, unsigned>> offsets; |
| 147 | for (size_t i = 0; i < _types.size(); ++i) |
| 148 | { |
| 149 | Type const* type = _types[i]; |
| 150 | solAssert(type->canBeStored()); |
| 151 | solAssert(type->storageBytes() <= 32); |
| 152 | if (byteOffset + type->storageBytes() > 32) |
| 153 | { |
| 154 | // would overflow, go to next slot |
| 155 | ++slotOffset; |
| 156 | byteOffset = 0; |
| 157 | } |
| 158 | solAssert(slotOffset < bigint(1) << 256, "Object extends past the end of storage."); |
| 159 | offsets[i] = std::make_pair(u256(slotOffset), byteOffset); |
| 160 | solAssert(type->storageSize() >= 1, "Invalid storage size."); |
| 161 | if (type->storageSize() == 1 && byteOffset + type->storageBytes() <= 32) |
| 162 | byteOffset += type->storageBytes(); |
| 163 | else |
| 164 | { |
| 165 | slotOffset += type->storageSize(); |
| 166 | byteOffset = 0; |
| 167 | } |
| 168 | } |
| 169 | if (byteOffset > 0) |
| 170 | ++slotOffset; |
| 171 | |
| 172 | solAssert(slotOffset < bigint(1) << 256, "Object extends past the end of storage."); |
| 173 | m_storageSize = u256(slotOffset - _baseSlot); |
| 174 | swap(m_offsets, offsets); |
| 175 | } |
| 176 | |
| 177 | std::pair<u256, unsigned> const* StorageOffsets::offset(size_t _index) const |
| 178 | { |
no test coverage detected