mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Mapping getters for Yul IR.
This commit is contained in:
parent
d3cbfb0c5c
commit
af9fc8b634
@ -159,21 +159,70 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
|
|||||||
solAssert(!_varDecl.isConstant(), "");
|
solAssert(!_varDecl.isConstant(), "");
|
||||||
solAssert(_varDecl.isStateVariable(), "");
|
solAssert(_varDecl.isStateVariable(), "");
|
||||||
|
|
||||||
solUnimplementedAssert(type->isValueType(), "");
|
if (auto const* mappingType = dynamic_cast<MappingType const*>(type))
|
||||||
|
return m_context.functionCollector()->createFunction(functionName, [&]() {
|
||||||
return m_context.functionCollector()->createFunction(functionName, [&]() {
|
pair<u256, unsigned> slot_offset = m_context.storageLocationOfVariable(_varDecl);
|
||||||
pair<u256, unsigned> slot_offset = m_context.storageLocationOfVariable(_varDecl);
|
solAssert(slot_offset.second == 0, "");
|
||||||
|
FunctionType funType(_varDecl);
|
||||||
return Whiskers(R"(
|
solUnimplementedAssert(funType.returnParameterTypes().size() == 1, "");
|
||||||
function <functionName>() -> rval {
|
TypePointer returnType = funType.returnParameterTypes().front();
|
||||||
rval := <readStorage>(<slot>)
|
unsigned num_keys = 0;
|
||||||
|
stringstream indexAccesses;
|
||||||
|
string slot = m_context.newYulVariable();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
solUnimplementedAssert(
|
||||||
|
mappingType->keyType()->sizeOnStack() == 1,
|
||||||
|
"Multi-slot mapping key unimplemented - might not be a problem"
|
||||||
|
);
|
||||||
|
indexAccesses <<
|
||||||
|
slot <<
|
||||||
|
" := " <<
|
||||||
|
m_utils.mappingIndexAccessFunction(*mappingType, *mappingType->keyType()) <<
|
||||||
|
"(" <<
|
||||||
|
slot;
|
||||||
|
if (mappingType->keyType()->sizeOnStack() > 0)
|
||||||
|
indexAccesses <<
|
||||||
|
", " <<
|
||||||
|
suffixedVariableNameList("key", num_keys, num_keys + mappingType->keyType()->sizeOnStack());
|
||||||
|
indexAccesses << ")\n";
|
||||||
|
num_keys += mappingType->keyType()->sizeOnStack();
|
||||||
}
|
}
|
||||||
)")
|
while ((mappingType = dynamic_cast<MappingType const*>(mappingType->valueType())));
|
||||||
("functionName", functionName)
|
|
||||||
("readStorage", m_utils.readFromStorage(*type, slot_offset.second, false))
|
return Whiskers(R"(
|
||||||
("slot", slot_offset.first.str())
|
function <functionName>(<keys>) -> rval {
|
||||||
.render();
|
let <slot> := <base>
|
||||||
});
|
<indexAccesses>
|
||||||
|
rval := <readStorage>(<slot>)
|
||||||
|
}
|
||||||
|
)")
|
||||||
|
("functionName", functionName)
|
||||||
|
("keys", suffixedVariableNameList("key", 0, num_keys))
|
||||||
|
("readStorage", m_utils.readFromStorage(*returnType, 0, false))
|
||||||
|
("indexAccesses", indexAccesses.str())
|
||||||
|
("slot", slot)
|
||||||
|
("base", slot_offset.first.str())
|
||||||
|
.render();
|
||||||
|
});
|
||||||
|
else
|
||||||
|
{
|
||||||
|
solUnimplementedAssert(type->isValueType(), "");
|
||||||
|
|
||||||
|
return m_context.functionCollector()->createFunction(functionName, [&]() {
|
||||||
|
pair<u256, unsigned> slot_offset = m_context.storageLocationOfVariable(_varDecl);
|
||||||
|
|
||||||
|
return Whiskers(R"(
|
||||||
|
function <functionName>() -> rval {
|
||||||
|
rval := <readStorage>(<slot>)
|
||||||
|
}
|
||||||
|
)")
|
||||||
|
("functionName", functionName)
|
||||||
|
("readStorage", m_utils.readFromStorage(*type, slot_offset.second, false))
|
||||||
|
("slot", slot_offset.first.str())
|
||||||
|
.render();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string IRGenerator::constructorCode(ContractDefinition const& _contract)
|
string IRGenerator::constructorCode(ContractDefinition const& _contract)
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
contract test {
|
||||||
|
enum E { A, B, C }
|
||||||
|
mapping(E => uint8) public table;
|
||||||
|
function set(E k, uint8 v) public {
|
||||||
|
table[k] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
|
// ----
|
||||||
|
// table(uint8): 0 -> 0
|
||||||
|
// table(uint8): 0x01 -> 0
|
||||||
|
// table(uint8): 0xa7 -> FAILURE
|
||||||
|
// set(uint8,uint8): 0x01, 0xa1 ->
|
||||||
|
// table(uint8): 0 -> 0
|
||||||
|
// table(uint8): 0x01 -> 0xa1
|
||||||
|
// table(uint8): 0xa7 -> FAILURE
|
||||||
|
// set(uint8,uint8): 0x00, 0xef ->
|
||||||
|
// table(uint8): 0 -> 0xef
|
||||||
|
// table(uint8): 0x01 -> 0xa1
|
||||||
|
// table(uint8): 0xa7 -> FAILURE
|
||||||
|
// set(uint8,uint8): 0x01, 0x05 ->
|
||||||
|
// table(uint8): 0 -> 0xef
|
||||||
|
// table(uint8): 0x01 -> 0x05
|
||||||
|
// table(uint8): 0xa7 -> FAILURE
|
40
test/libsolidity/semanticTests/viaYul/mapping_getters.sol
Normal file
40
test/libsolidity/semanticTests/viaYul/mapping_getters.sol
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
contract test {
|
||||||
|
mapping(uint256 => uint256) public m1;
|
||||||
|
mapping(uint256 => mapping(uint256 => uint256)) public m2;
|
||||||
|
function set(uint256 k, uint256 v) public {
|
||||||
|
m1[k] = v;
|
||||||
|
}
|
||||||
|
function set(uint256 k1, uint256 k2, uint256 v) public {
|
||||||
|
m2[k1][k2] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
|
// ----
|
||||||
|
// m1(uint256): 0 -> 0
|
||||||
|
// m1(uint256): 0x01 -> 0
|
||||||
|
// m1(uint256): 0xa7 -> 0
|
||||||
|
// set(uint256,uint256): 0x01, 0xa1 ->
|
||||||
|
// m1(uint256): 0 -> 0
|
||||||
|
// m1(uint256): 0x01 -> 0xa1
|
||||||
|
// m1(uint256): 0xa7 -> 0
|
||||||
|
// set(uint256,uint256): 0x00, 0xef ->
|
||||||
|
// m1(uint256): 0 -> 0xef
|
||||||
|
// m1(uint256): 0x01 -> 0xa1
|
||||||
|
// m1(uint256): 0xa7 -> 0
|
||||||
|
// set(uint256,uint256): 0x01, 0x05 ->
|
||||||
|
// m1(uint256): 0 -> 0xef
|
||||||
|
// m1(uint256): 0x01 -> 0x05
|
||||||
|
// m1(uint256): 0xa7 -> 0
|
||||||
|
// m2(uint256,uint256): 0, 0 -> 0
|
||||||
|
// m2(uint256,uint256): 0, 0x01 -> 0
|
||||||
|
// m2(uint256,uint256): 0xa7, 0 -> 0
|
||||||
|
// m2(uint256,uint256): 0xa7, 0x01 -> 0
|
||||||
|
// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23
|
||||||
|
// m2(uint256,uint256): 0, 0x01 -> 0
|
||||||
|
// m2(uint256,uint256): 0xa7, 0 -> 0
|
||||||
|
// m2(uint256,uint256): 0xa7, 0x01 -> 0x23
|
||||||
|
// set(uint256,uint256,uint256): 0, 0x01, 0xef
|
||||||
|
// m2(uint256,uint256): 0, 0x01 -> 0xef
|
||||||
|
// m2(uint256,uint256): 0xa7, 0 -> 0
|
||||||
|
// m2(uint256,uint256): 0xa7, 0x01 -> 0x23
|
Loading…
Reference in New Issue
Block a user