| 127 | } |
| 128 | |
| 129 | void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl) |
| 130 | { |
| 131 | solAssert(!_varDecl.isConstant(), ""); |
| 132 | CompilerContext::LocationSetter locationSetter(m_context, _varDecl); |
| 133 | FunctionType accessorType(_varDecl); |
| 134 | |
| 135 | TypePointers paramTypes = accessorType.parameterTypes(); |
| 136 | if (_varDecl.immutable()) |
| 137 | solAssert(paramTypes.empty(), ""); |
| 138 | |
| 139 | m_context.adjustStackOffset(static_cast<int>(1 + CompilerUtils::sizeOnStack(paramTypes))); |
| 140 | |
| 141 | if (!_varDecl.immutable()) |
| 142 | { |
| 143 | // retrieve the position of the variable |
| 144 | auto const& location = m_context.storageLocationOfVariable(_varDecl); |
| 145 | m_context << location.first << u256(location.second); |
| 146 | } |
| 147 | |
| 148 | Type const* returnType = _varDecl.annotation().type; |
| 149 | |
| 150 | for (size_t i = 0; i < paramTypes.size(); ++i) |
| 151 | { |
| 152 | if (auto mappingType = dynamic_cast<MappingType const*>(returnType)) |
| 153 | { |
| 154 | solAssert(CompilerUtils::freeMemoryPointer >= 0x40, ""); |
| 155 | solAssert(_varDecl.referenceLocation() != VariableDeclaration::Location::Transient); |
| 156 | |
| 157 | // pop offset |
| 158 | m_context << Instruction::POP; |
| 159 | if (paramTypes[i]->isDynamicallySized()) |
| 160 | { |
| 161 | solAssert( |
| 162 | dynamic_cast<ArrayType const&>(*paramTypes[i]).isByteArrayOrString(), |
| 163 | "Expected string or byte array for mapping key type" |
| 164 | ); |
| 165 | |
| 166 | // stack: <keys..> <slot position> |
| 167 | |
| 168 | // copy key[i] to top. |
| 169 | utils().copyToStackTop(static_cast<unsigned>(paramTypes.size() - i + 1), 1); |
| 170 | |
| 171 | m_context.appendInlineAssembly(R"({ |
| 172 | let key_len := mload(key_ptr) |
| 173 | // Temp. use the memory after the array data for the slot |
| 174 | // position |
| 175 | let post_data_ptr := add(key_ptr, add(key_len, 0x20)) |
| 176 | let orig_data := mload(post_data_ptr) |
| 177 | mstore(post_data_ptr, slot_pos) |
| 178 | let hash := keccak256(add(key_ptr, 0x20), add(key_len, 0x20)) |
| 179 | mstore(post_data_ptr, orig_data) |
| 180 | slot_pos := hash |
| 181 | })", {"slot_pos", "key_ptr"}); |
| 182 | |
| 183 | m_context << Instruction::POP; |
| 184 | } |
| 185 | else |
| 186 | { |
no test coverage detected