mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Implement inline arrays.
This commit is contained in:
parent
ac95e98b2b
commit
50a54fa8aa
@ -1620,26 +1620,45 @@ string YulUtilFunctions::zeroComplexMemoryArrayFunction(ArrayType const& _type)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string YulUtilFunctions::allocateMemoryArrayFunction(ArrayType const& _type)
|
||||||
|
{
|
||||||
|
string functionName = "allocate_memory_array_" + _type.identifier();
|
||||||
|
return m_functionCollector.createFunction(functionName, [&]() {
|
||||||
|
return Whiskers(R"(
|
||||||
|
function <functionName>(length) -> memPtr {
|
||||||
|
let allocSize := <allocSize>(length)
|
||||||
|
memPtr := <alloc>(allocSize)
|
||||||
|
<?dynamic>
|
||||||
|
mstore(memPtr, length)
|
||||||
|
</dynamic>
|
||||||
|
}
|
||||||
|
)")
|
||||||
|
("functionName", functionName)
|
||||||
|
("alloc", allocationFunction())
|
||||||
|
("allocSize", arrayAllocationSizeFunction(_type))
|
||||||
|
("dynamic", _type.isDynamicallySized())
|
||||||
|
.render();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
string YulUtilFunctions::allocateAndInitializeMemoryArrayFunction(ArrayType const& _type)
|
string YulUtilFunctions::allocateAndInitializeMemoryArrayFunction(ArrayType const& _type)
|
||||||
{
|
{
|
||||||
string functionName = "allocate_and_zero_memory_array_" + _type.identifier();
|
string functionName = "allocate_and_zero_memory_array_" + _type.identifier();
|
||||||
return m_functionCollector.createFunction(functionName, [&]() {
|
return m_functionCollector.createFunction(functionName, [&]() {
|
||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(length) -> memPtr {
|
function <functionName>(length) -> memPtr {
|
||||||
let allocSize := <allocSize>(length)
|
memPtr := <allocArray>(length)
|
||||||
memPtr := <alloc>(allocSize)
|
|
||||||
let dataStart := memPtr
|
let dataStart := memPtr
|
||||||
let dataSize := allocSize
|
let dataSize := <allocSize>(length)
|
||||||
<?dynamic>
|
<?dynamic>
|
||||||
dataStart := add(dataStart, 32)
|
dataStart := add(dataStart, 32)
|
||||||
dataSize := sub(dataSize, 32)
|
dataSize := sub(dataSize, 32)
|
||||||
mstore(memPtr, length)
|
|
||||||
</dynamic>
|
</dynamic>
|
||||||
<zeroArrayFunction>(dataStart, dataSize)
|
<zeroArrayFunction>(dataStart, dataSize)
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("alloc", allocationFunction())
|
("allocArray", allocateMemoryArrayFunction(_type))
|
||||||
("allocSize", arrayAllocationSizeFunction(_type))
|
("allocSize", arrayAllocationSizeFunction(_type))
|
||||||
("zeroArrayFunction", zeroMemoryArrayFunction(_type))
|
("zeroArrayFunction", zeroMemoryArrayFunction(_type))
|
||||||
("dynamic", _type.isDynamicallySized())
|
("dynamic", _type.isDynamicallySized())
|
||||||
|
@ -282,6 +282,12 @@ public:
|
|||||||
/// signature: (dataStart, dataSizeInBytes) ->
|
/// signature: (dataStart, dataSizeInBytes) ->
|
||||||
std::string zeroComplexMemoryArrayFunction(ArrayType const& _type);
|
std::string zeroComplexMemoryArrayFunction(ArrayType const& _type);
|
||||||
|
|
||||||
|
/// @returns the name of a function that allocates a memory array.
|
||||||
|
/// For dynamic arrays it adds space for length and stores it.
|
||||||
|
/// The contents of the data area are unspecified.
|
||||||
|
/// signature: (length) -> memPtr
|
||||||
|
std::string allocateMemoryArrayFunction(ArrayType const& _type);
|
||||||
|
|
||||||
/// @returns the name of a function that allocates and zeroes a memory array.
|
/// @returns the name of a function that allocates and zeroes a memory array.
|
||||||
/// For dynamic arrays it adds space for length and stores it.
|
/// For dynamic arrays it adds space for length and stores it.
|
||||||
/// signature: (length) -> memPtr
|
/// signature: (length) -> memPtr
|
||||||
|
@ -311,7 +311,31 @@ bool IRGeneratorForStatements::visit(Assignment const& _assignment)
|
|||||||
bool IRGeneratorForStatements::visit(TupleExpression const& _tuple)
|
bool IRGeneratorForStatements::visit(TupleExpression const& _tuple)
|
||||||
{
|
{
|
||||||
if (_tuple.isInlineArray())
|
if (_tuple.isInlineArray())
|
||||||
solUnimplementedAssert(false, "");
|
{
|
||||||
|
auto const& arrayType = dynamic_cast<ArrayType const&>(*_tuple.annotation().type);
|
||||||
|
solAssert(!arrayType.isDynamicallySized(), "Cannot create dynamically sized inline array.");
|
||||||
|
define(_tuple) <<
|
||||||
|
m_utils.allocateMemoryArrayFunction(arrayType) <<
|
||||||
|
"(" <<
|
||||||
|
_tuple.components().size() <<
|
||||||
|
")\n";
|
||||||
|
|
||||||
|
string mpos = IRVariable(_tuple).part("mpos").name();
|
||||||
|
Type const& baseType = *arrayType.baseType();
|
||||||
|
for (size_t i = 0; i < _tuple.components().size(); i++)
|
||||||
|
{
|
||||||
|
Expression const& component = *_tuple.components()[i];
|
||||||
|
component.accept(*this);
|
||||||
|
IRVariable converted = convert(component, baseType);
|
||||||
|
m_code <<
|
||||||
|
m_utils.writeToMemoryFunction(baseType) <<
|
||||||
|
"(" <<
|
||||||
|
("add(" + mpos + ", " + to_string(i * arrayType.memoryStride()) + ")") <<
|
||||||
|
", " <<
|
||||||
|
converted.name() <<
|
||||||
|
")\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool willBeWrittenTo = _tuple.annotation().willBeWrittenTo;
|
bool willBeWrittenTo = _tuple.annotation().willBeWrittenTo;
|
||||||
|
@ -4,6 +4,7 @@ contract C {
|
|||||||
return [4][0];
|
return [4][0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f() -> 4
|
// f() -> 4
|
||||||
|
Loading…
Reference in New Issue
Block a user