Some more compression.

This commit is contained in:
chriseth 2019-05-07 15:37:22 +02:00
parent c6b9fa96ae
commit d3d205b6eb

View File

@ -419,64 +419,30 @@ string YulUtilFunctions::arrayDataAreaFunction(ArrayType const& _type)
{ {
string functionName = "array_dataslot_" + _type.identifier(); string functionName = "array_dataslot_" + _type.identifier();
return m_functionCollector->createFunction(functionName, [&]() { return m_functionCollector->createFunction(functionName, [&]() {
switch (_type.location()) // No special processing for calldata arrays, because they are stored as
{ // offset of the data area and length on the stack, so the offset already
case DataLocation::Memory: // points to the data area.
if (_type.isDynamicallySized())
return Whiskers(R"(
function <functionName>(memPtr) -> dataPtr {
dataPtr := add(memPtr, 0x20)
}
)")
("functionName", functionName)
.render();
else
return Whiskers(R"(
function <functionName>(memPtr) -> dataPtr {
dataPtr := memPtr
}
)")
("functionName", functionName)
.render();
case DataLocation::Storage:
if (_type.isDynamicallySized())
{
Whiskers w(R"(
function <functionName>(slot) -> dataSlot {
mstore(0, slot)
dataSlot := keccak256(0, 0x20)
}
)");
w("functionName", functionName);
return w.render();
}
else
{
Whiskers w(R"(
function <functionName>(slot) -> dataSlot {
dataSlot := slot
}
)");
w("functionName", functionName);
return w.render();
}
case DataLocation::CallData:
{
// Calldata arrays are stored as offset of the data area and length
// on the stack, so the offset already points to the data area.
// This might change, if calldata arrays are stored in a single // This might change, if calldata arrays are stored in a single
// stack slot at some point. // stack slot at some point.
Whiskers w(R"( return Whiskers(R"(
function <functionName>(slot) -> dataSlot { function <functionName>(ptr) -> data {
dataSlot := slot data := ptr
} <?dynamic>
)"); <?memory>
w("functionName", functionName); data := add(ptr, 0x20)
return w.render(); </memory>
} <?storage>
default: mstore(0, ptr)
solAssert(false, ""); data := keccak256(0, 0x20)
</storage>
</dynamic>
} }
)")
("functionName", functionName)
("dynamic", _type.isDynamicallySized())
("memory", _type.location() == DataLocation::Memory)
("storage", _type.location() == DataLocation::Storage)
.render();
}); });
} }
@ -487,36 +453,25 @@ string YulUtilFunctions::nextArrayElementFunction(ArrayType const& _type)
solAssert(_type.baseType()->storageBytes() > 16, ""); solAssert(_type.baseType()->storageBytes() > 16, "");
string functionName = "array_nextElement_" + _type.identifier(); string functionName = "array_nextElement_" + _type.identifier();
return m_functionCollector->createFunction(functionName, [&]() { return m_functionCollector->createFunction(functionName, [&]() {
switch (_type.location()) Whiskers templ(R"(
{ function <functionName>(ptr) -> next {
case DataLocation::Memory: next := add(ptr, <advance>)
return Whiskers(R"(
function <functionName>(memPtr) -> nextPtr {
nextPtr := add(memPtr, 0x20)
} }
)") )");
("functionName", functionName) templ("functionName", functionName);
.render(); if (_type.location() == DataLocation::Memory)
case DataLocation::Storage: templ("advance", "0x20");
return Whiskers(R"( else if (_type.location() == DataLocation::Storage)
function <functionName>(slot) -> nextSlot { templ("advance", "1");
nextSlot := add(slot, 1) else if (_type.location() == DataLocation::CallData)
} templ("advance", toCompactHexWithPrefix(
)") _type.baseType()->isDynamicallyEncoded() ?
("functionName", functionName) 32 :
.render(); _type.baseType()->calldataEncodedSize()
case DataLocation::CallData: ));
return Whiskers(R"( else
function <functionName>(calldataPtr) -> nextPtr {
nextPtr := add(calldataPtr, <stride>)
}
)")
("stride", toCompactHexWithPrefix(_type.baseType()->isDynamicallyEncoded() ? 32 : _type.baseType()->calldataEncodedSize()))
("functionName", functionName)
.render();
default:
solAssert(false, ""); solAssert(false, "");
} return templ.render();
}); });
} }