mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Yul grammar generator: Bound memory accesses.
This commit is contained in:
@@ -351,9 +351,22 @@ void ProtoConverter::visit(BinaryOp const& _x)
|
||||
break;
|
||||
}
|
||||
m_output << "(";
|
||||
visit(_x.left());
|
||||
m_output << ",";
|
||||
visit(_x.right());
|
||||
if (op == BinaryOp::KECCAK)
|
||||
{
|
||||
m_output << "mod(";
|
||||
visit(_x.left());
|
||||
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
|
||||
m_output << ",";
|
||||
m_output << "mod(";
|
||||
visit(_x.right());
|
||||
m_output << ", " << to_string(s_maxSize) << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
visit(_x.left());
|
||||
m_output << ",";
|
||||
visit(_x.right());
|
||||
}
|
||||
m_output << ")";
|
||||
}
|
||||
|
||||
@@ -623,7 +636,14 @@ void ProtoConverter::visit(UnaryOp const& _x)
|
||||
break;
|
||||
}
|
||||
m_output << "(";
|
||||
visit(_x.operand());
|
||||
if (op == UnaryOp::MLOAD)
|
||||
{
|
||||
m_output << "mod(";
|
||||
visit(_x.operand());
|
||||
m_output << ", " << to_string(s_maxMemory) << ")";
|
||||
}
|
||||
else
|
||||
visit(_x.operand());
|
||||
m_output << ")";
|
||||
}
|
||||
|
||||
@@ -778,11 +798,15 @@ void ProtoConverter::visit(CopyFunc const& _x)
|
||||
break;
|
||||
}
|
||||
m_output << "(";
|
||||
m_output << "mod(";
|
||||
visit(_x.target());
|
||||
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
|
||||
m_output << ", ";
|
||||
visit(_x.source());
|
||||
m_output << ", ";
|
||||
m_output << "mod(";
|
||||
visit(_x.size());
|
||||
m_output << ", " << to_string(s_maxSize) << ")";
|
||||
m_output << ")\n";
|
||||
}
|
||||
|
||||
@@ -792,32 +816,42 @@ void ProtoConverter::visit(ExtCodeCopy const& _x)
|
||||
m_output << "(";
|
||||
visit(_x.addr());
|
||||
m_output << ", ";
|
||||
m_output << "mod(";
|
||||
visit(_x.target());
|
||||
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
|
||||
m_output << ", ";
|
||||
visit(_x.source());
|
||||
m_output << ", ";
|
||||
m_output << "mod(";
|
||||
visit(_x.size());
|
||||
m_output << ", " << to_string(s_maxSize) << ")";
|
||||
m_output << ")\n";
|
||||
}
|
||||
|
||||
void ProtoConverter::visit(LogFunc const& _x)
|
||||
{
|
||||
auto visitPosAndSize = [&](LogFunc const& _y) {
|
||||
m_output << "mod(";
|
||||
visit(_y.pos());
|
||||
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
|
||||
m_output << ", ";
|
||||
m_output << "mod(";
|
||||
visit(_y.size());
|
||||
m_output << ", " << to_string(s_maxSize) << ")";
|
||||
};
|
||||
|
||||
switch (_x.num_topics())
|
||||
{
|
||||
case LogFunc::ZERO:
|
||||
m_output << "log0";
|
||||
m_output << "(";
|
||||
visit(_x.pos());
|
||||
m_output << ", ";
|
||||
visit(_x.size());
|
||||
visitPosAndSize(_x);
|
||||
m_output << ")\n";
|
||||
break;
|
||||
case LogFunc::ONE:
|
||||
m_output << "log1";
|
||||
m_output << "(";
|
||||
visit(_x.pos());
|
||||
m_output << ", ";
|
||||
visit(_x.size());
|
||||
visitPosAndSize(_x);
|
||||
m_output << ", ";
|
||||
visit(_x.t1());
|
||||
m_output << ")\n";
|
||||
@@ -825,9 +859,7 @@ void ProtoConverter::visit(LogFunc const& _x)
|
||||
case LogFunc::TWO:
|
||||
m_output << "log2";
|
||||
m_output << "(";
|
||||
visit(_x.pos());
|
||||
m_output << ", ";
|
||||
visit(_x.size());
|
||||
visitPosAndSize(_x);
|
||||
m_output << ", ";
|
||||
visit(_x.t1());
|
||||
m_output << ", ";
|
||||
@@ -837,9 +869,7 @@ void ProtoConverter::visit(LogFunc const& _x)
|
||||
case LogFunc::THREE:
|
||||
m_output << "log3";
|
||||
m_output << "(";
|
||||
visit(_x.pos());
|
||||
m_output << ", ";
|
||||
visit(_x.size());
|
||||
visitPosAndSize(_x);
|
||||
m_output << ", ";
|
||||
visit(_x.t1());
|
||||
m_output << ", ";
|
||||
@@ -851,9 +881,7 @@ void ProtoConverter::visit(LogFunc const& _x)
|
||||
case LogFunc::FOUR:
|
||||
m_output << "log4";
|
||||
m_output << "(";
|
||||
visit(_x.pos());
|
||||
m_output << ", ";
|
||||
visit(_x.size());
|
||||
visitPosAndSize(_x);
|
||||
m_output << ", ";
|
||||
visit(_x.t1());
|
||||
m_output << ", ";
|
||||
@@ -1015,13 +1043,21 @@ void ProtoConverter::visit(LowLevelCall const& _x)
|
||||
visit(_x.wei());
|
||||
m_output << ", ";
|
||||
}
|
||||
m_output << "mod(";
|
||||
visit(_x.in());
|
||||
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
|
||||
m_output << ", ";
|
||||
m_output << "mod(";
|
||||
visit(_x.insize());
|
||||
m_output << ", " << to_string(s_maxSize) << ")";
|
||||
m_output << ", ";
|
||||
m_output << "mod(";
|
||||
visit(_x.out());
|
||||
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
|
||||
m_output << ", ";
|
||||
m_output << "mod(";
|
||||
visit(_x.outsize());
|
||||
m_output << ", " << to_string(s_maxSize) << ")";
|
||||
m_output << ")";
|
||||
}
|
||||
|
||||
@@ -1048,9 +1084,13 @@ void ProtoConverter::visit(Create const& _x)
|
||||
}
|
||||
visit(_x.wei());
|
||||
m_output << ", ";
|
||||
m_output << "mod(";
|
||||
visit(_x.position());
|
||||
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
|
||||
m_output << ", ";
|
||||
m_output << "mod(";
|
||||
visit(_x.size());
|
||||
m_output << ", " << to_string(s_maxSize) << ")";
|
||||
if (type == Create::CREATE2)
|
||||
{
|
||||
m_output << ", ";
|
||||
@@ -1069,7 +1109,8 @@ void ProtoConverter::visit(IfStmt const& _x)
|
||||
|
||||
void ProtoConverter::visit(StoreFunc const& _x)
|
||||
{
|
||||
switch (_x.st())
|
||||
auto storeType = _x.st();
|
||||
switch (storeType)
|
||||
{
|
||||
case StoreFunc::MSTORE:
|
||||
m_output << "mstore(";
|
||||
@@ -1081,7 +1122,15 @@ void ProtoConverter::visit(StoreFunc const& _x)
|
||||
m_output << "mstore8(";
|
||||
break;
|
||||
}
|
||||
visit(_x.loc());
|
||||
// Write to memory within bounds, storage is unbounded
|
||||
if (storeType == StoreFunc::SSTORE)
|
||||
visit(_x.loc());
|
||||
else
|
||||
{
|
||||
m_output << "mod(";
|
||||
visit(_x.loc());
|
||||
m_output << ", " << to_string(s_maxMemory) << ")";
|
||||
}
|
||||
m_output << ", ";
|
||||
visit(_x.val());
|
||||
m_output << ")\n";
|
||||
@@ -1262,9 +1311,13 @@ void ProtoConverter::visit(RetRevStmt const& _x)
|
||||
break;
|
||||
}
|
||||
m_output << "(";
|
||||
m_output << "mod(";
|
||||
visit(_x.pos());
|
||||
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
|
||||
m_output << ", ";
|
||||
m_output << "mod(";
|
||||
visit(_x.size());
|
||||
m_output << ", " << to_string(s_maxSize) << ")";
|
||||
m_output << ")\n";
|
||||
}
|
||||
|
||||
@@ -1651,8 +1704,12 @@ void ProtoConverter::fillFunctionCallInput(unsigned _numInParams)
|
||||
m_output << "calldataload(" << slot << ")";
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
// Access memory within stipulated bounds
|
||||
slot = "mod(" + dictionaryToken() + ", " + to_string(s_maxMemory) + ")";
|
||||
m_output << "mload(" << slot << ")";
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
m_output << "sload(" << slot << ")";
|
||||
break;
|
||||
|
||||
@@ -344,6 +344,11 @@ private:
|
||||
static unsigned constexpr s_modOutputParams = 5;
|
||||
/// Hard-coded identifier for a Yul object's data block
|
||||
static auto constexpr s_dataIdentifier = "datablock";
|
||||
/// Upper bound on memory writes = 2**32 - 1
|
||||
/// See: https://eips.ethereum.org/EIPS/eip-1985#memory-size
|
||||
static unsigned constexpr s_maxMemory = 4294967295;
|
||||
/// Upper bound on size for range copy functions
|
||||
static unsigned constexpr s_maxSize = 65536;
|
||||
/// Predicate to keep track of for body scope. If false, break/continue
|
||||
/// statements can not be created.
|
||||
bool m_inForBodyScope;
|
||||
|
||||
Reference in New Issue
Block a user