mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Refactor SideEffects struct
This commit is contained in:
@@ -155,8 +155,10 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool
|
||||
);
|
||||
break;
|
||||
default:
|
||||
bool invMem = SemanticInformation::invalidatesMemory(_item.instruction());
|
||||
bool invStor = SemanticInformation::invalidatesStorage(_item.instruction());
|
||||
bool invMem =
|
||||
SemanticInformation::memory(_item.instruction()) == SemanticInformation::Write;
|
||||
bool invStor =
|
||||
SemanticInformation::storage(_item.instruction()) == SemanticInformation::Write;
|
||||
// We could be a bit more fine-grained here (CALL only invalidates part of
|
||||
// memory, etc), but we do not for now.
|
||||
if (invMem)
|
||||
@@ -420,4 +422,3 @@ KnownState::Id KnownState::tagUnion(set<u256> _tags)
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ bool SemanticInformation::movable(Instruction _instruction)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SemanticInformation::sideEffectFree(Instruction _instruction)
|
||||
bool SemanticInformation::canBeRemoved(Instruction _instruction)
|
||||
{
|
||||
// These are not really functional.
|
||||
assertThrow(!isDupInstruction(_instruction) && !isSwapInstruction(_instruction), AssemblyException, "");
|
||||
@@ -241,15 +241,15 @@ bool SemanticInformation::sideEffectFree(Instruction _instruction)
|
||||
return !instructionInfo(_instruction).sideEffects;
|
||||
}
|
||||
|
||||
bool SemanticInformation::sideEffectFreeIfNoMSize(Instruction _instruction)
|
||||
bool SemanticInformation::canBeRemovedIfNoMSize(Instruction _instruction)
|
||||
{
|
||||
if (_instruction == Instruction::KECCAK256 || _instruction == Instruction::MLOAD)
|
||||
return true;
|
||||
else
|
||||
return sideEffectFree(_instruction);
|
||||
return canBeRemoved(_instruction);
|
||||
}
|
||||
|
||||
bool SemanticInformation::invalidatesMemory(Instruction _instruction)
|
||||
SemanticInformation::Effect SemanticInformation::memory(Instruction _instruction)
|
||||
{
|
||||
switch (_instruction)
|
||||
{
|
||||
@@ -263,13 +263,47 @@ bool SemanticInformation::invalidatesMemory(Instruction _instruction)
|
||||
case Instruction::CALLCODE:
|
||||
case Instruction::DELEGATECALL:
|
||||
case Instruction::STATICCALL:
|
||||
return true;
|
||||
return SemanticInformation::Write;
|
||||
|
||||
case Instruction::CREATE:
|
||||
case Instruction::CREATE2:
|
||||
case Instruction::KECCAK256:
|
||||
case Instruction::MLOAD:
|
||||
case Instruction::MSIZE:
|
||||
case Instruction::RETURN:
|
||||
case Instruction::REVERT:
|
||||
case Instruction::LOG0:
|
||||
case Instruction::LOG1:
|
||||
case Instruction::LOG2:
|
||||
case Instruction::LOG3:
|
||||
case Instruction::LOG4:
|
||||
return SemanticInformation::Read;
|
||||
|
||||
default:
|
||||
return false;
|
||||
return SemanticInformation::None;
|
||||
}
|
||||
}
|
||||
|
||||
bool SemanticInformation::invalidatesStorage(Instruction _instruction)
|
||||
bool SemanticInformation::movableApartFromEffects(Instruction _instruction)
|
||||
{
|
||||
switch (_instruction)
|
||||
{
|
||||
case Instruction::EXTCODEHASH:
|
||||
case Instruction::EXTCODESIZE:
|
||||
case Instruction::RETURNDATASIZE:
|
||||
case Instruction::BALANCE:
|
||||
case Instruction::SELFBALANCE:
|
||||
case Instruction::SLOAD:
|
||||
case Instruction::KECCAK256:
|
||||
case Instruction::MLOAD:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return movable(_instruction);
|
||||
}
|
||||
}
|
||||
|
||||
SemanticInformation::Effect SemanticInformation::storage(Instruction _instruction)
|
||||
{
|
||||
switch (_instruction)
|
||||
{
|
||||
@@ -279,9 +313,45 @@ bool SemanticInformation::invalidatesStorage(Instruction _instruction)
|
||||
case Instruction::CREATE:
|
||||
case Instruction::CREATE2:
|
||||
case Instruction::SSTORE:
|
||||
return true;
|
||||
return SemanticInformation::Write;
|
||||
|
||||
case Instruction::SLOAD:
|
||||
case Instruction::STATICCALL:
|
||||
return SemanticInformation::Read;
|
||||
|
||||
default:
|
||||
return false;
|
||||
return SemanticInformation::None;
|
||||
}
|
||||
}
|
||||
|
||||
SemanticInformation::Effect SemanticInformation::otherState(Instruction _instruction)
|
||||
{
|
||||
switch (_instruction)
|
||||
{
|
||||
case Instruction::CALL:
|
||||
case Instruction::CALLCODE:
|
||||
case Instruction::DELEGATECALL:
|
||||
case Instruction::CREATE:
|
||||
case Instruction::CREATE2:
|
||||
case Instruction::SELFDESTRUCT:
|
||||
case Instruction::STATICCALL: // because it can affect returndatasize
|
||||
// Strictly speaking, log0, .., log4 writes to the state, but the EVM cannot read it, so they
|
||||
// are just marked as having 'other side effects.'
|
||||
return SemanticInformation::Write;
|
||||
|
||||
case Instruction::EXTCODESIZE:
|
||||
case Instruction::EXTCODEHASH:
|
||||
case Instruction::RETURNDATASIZE:
|
||||
case Instruction::BALANCE:
|
||||
case Instruction::SELFBALANCE:
|
||||
case Instruction::RETURNDATACOPY:
|
||||
case Instruction::EXTCODECOPY:
|
||||
// PC and GAS are specifically excluded here. Instructions such as CALLER, CALLVALUE,
|
||||
// ADDRESS are excluded because they cannot change during execution.
|
||||
return SemanticInformation::Read;
|
||||
|
||||
default:
|
||||
return SemanticInformation::None;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,15 @@ class AssemblyItem;
|
||||
*/
|
||||
struct SemanticInformation
|
||||
{
|
||||
/// Corresponds to the effect that a YUL-builtin has on a generic data location (storage, memory
|
||||
/// and other blockchain state).
|
||||
enum Effect
|
||||
{
|
||||
None,
|
||||
Read,
|
||||
Write
|
||||
};
|
||||
|
||||
/// @returns true if the given items starts a new block for common subexpression analysis.
|
||||
/// @param _msizeImportant if false, consider an operation non-breaking if its only side-effect is that it modifies msize.
|
||||
static bool breaksCSEAnalysisBlock(AssemblyItem const& _item, bool _msizeImportant);
|
||||
@@ -57,20 +66,23 @@ struct SemanticInformation
|
||||
/// without altering the semantics. This means it cannot depend on storage or memory,
|
||||
/// cannot have any side-effects, but it can depend on a call-constant state of the blockchain.
|
||||
static bool movable(Instruction _instruction);
|
||||
/// If true, the expressions in this code can be moved or copied (together with their arguments)
|
||||
/// across control flow branches and instructions as long as these instructions' 'effects' do
|
||||
/// not influence the 'effects' of the aforementioned expressions.
|
||||
static bool movableApartFromEffects(Instruction _instruction);
|
||||
/// @returns true if the instruction can be removed without changing the semantics.
|
||||
/// This does not mean that it has to be deterministic or retrieve information from
|
||||
/// somewhere else than purely the values of its arguments.
|
||||
static bool sideEffectFree(Instruction _instruction);
|
||||
static bool canBeRemoved(Instruction _instruction);
|
||||
/// @returns true if the instruction can be removed without changing the semantics.
|
||||
/// This does not mean that it has to be deterministic or retrieve information from
|
||||
/// somewhere else than purely the values of its arguments.
|
||||
/// If true, the instruction is still allowed to influence the value returned by the
|
||||
/// msize instruction.
|
||||
static bool sideEffectFreeIfNoMSize(Instruction _instruction);
|
||||
/// @returns true if the given instruction modifies memory.
|
||||
static bool invalidatesMemory(Instruction _instruction);
|
||||
/// @returns true if the given instruction modifies storage (even indirectly).
|
||||
static bool invalidatesStorage(Instruction _instruction);
|
||||
static bool canBeRemovedIfNoMSize(Instruction _instruction);
|
||||
static Effect memory(Instruction _instruction);
|
||||
static Effect storage(Instruction _instruction);
|
||||
static Effect otherState(Instruction _instruction);
|
||||
static bool invalidInPureFunctions(Instruction _instruction);
|
||||
static bool invalidInViewFunctions(Instruction _instruction);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user