@@ -29,6 +29,125 @@ using namespace std;
29
29
using namespace solidity ;
30
30
using namespace solidity ::evmasm;
31
31
32
+ vector<SemanticInformation::Operation> SemanticInformation::readWriteOperations (Instruction _instruction)
33
+ {
34
+ switch (_instruction)
35
+ {
36
+ case Instruction::SSTORE:
37
+ case Instruction::SLOAD:
38
+ {
39
+ assertThrow (memory (_instruction) == Effect::None, OptimizerException, " " );
40
+ assertThrow (storage (_instruction) != Effect::None, OptimizerException, " " );
41
+ Operation op;
42
+ op.effect = storage (_instruction);
43
+ op.location = Location::Storage;
44
+ op.startParameter = 0 ;
45
+ // We know that exactly one slot is affected.
46
+ op.lengthConstant = 1 ;
47
+ return {op};
48
+ }
49
+ case Instruction::MSTORE:
50
+ case Instruction::MSTORE8:
51
+ case Instruction::MLOAD:
52
+ {
53
+ assertThrow (memory (_instruction) != Effect::None, OptimizerException, " " );
54
+ assertThrow (storage (_instruction) == Effect::None, OptimizerException, " " );
55
+ Operation op;
56
+ op.effect = memory (_instruction);
57
+ op.location = Location::Memory;
58
+ op.startParameter = 0 ;
59
+ if (_instruction == Instruction::MSTORE || _instruction == Instruction::MLOAD)
60
+ op.lengthConstant = 32 ;
61
+ else if (_instruction == Instruction::MSTORE8)
62
+ op.lengthConstant = 1 ;
63
+
64
+ return {op};
65
+ }
66
+ case Instruction::REVERT:
67
+ case Instruction::RETURN:
68
+ case Instruction::KECCAK256:
69
+ case Instruction::LOG0:
70
+ case Instruction::LOG1:
71
+ case Instruction::LOG2:
72
+ case Instruction::LOG3:
73
+ case Instruction::LOG4:
74
+ {
75
+ assertThrow (storage (_instruction) == Effect::None, OptimizerException, " " );
76
+ assertThrow (memory (_instruction) == Effect::Read, OptimizerException, " " );
77
+ Operation op;
78
+ op.effect = memory (_instruction);
79
+ op.location = Location::Memory;
80
+ op.startParameter = 0 ;
81
+ op.lengthParameter = 1 ;
82
+ return {op};
83
+ }
84
+ case Instruction::EXTCODECOPY:
85
+ {
86
+ assertThrow (memory (_instruction) == Effect::Write, OptimizerException, " " );
87
+ assertThrow (storage (_instruction) == Effect::None, OptimizerException, " " );
88
+ Operation op;
89
+ op.effect = memory (_instruction);
90
+ op.location = Location::Memory;
91
+ op.startParameter = 1 ;
92
+ op.lengthParameter = 3 ;
93
+ return {op};
94
+ }
95
+ case Instruction::CODECOPY:
96
+ case Instruction::CALLDATACOPY:
97
+ case Instruction::RETURNDATACOPY:
98
+ {
99
+ assertThrow (memory (_instruction) == Effect::Write, OptimizerException, " " );
100
+ assertThrow (storage (_instruction) == Effect::None, OptimizerException, " " );
101
+ Operation op;
102
+ op.effect = memory (_instruction);
103
+ op.location = Location::Memory;
104
+ op.startParameter = 0 ;
105
+ op.lengthParameter = 2 ;
106
+ return {op};
107
+ }
108
+ case Instruction::STATICCALL:
109
+ case Instruction::CALL:
110
+ case Instruction::CALLCODE:
111
+ case Instruction::DELEGATECALL:
112
+ {
113
+ size_t paramCount = static_cast <size_t >(instructionInfo (_instruction).args );
114
+ vector<Operation> operations{
115
+ Operation{Location::Memory, Effect::Read, paramCount - 4 , paramCount - 3 , {}},
116
+ Operation{Location::Storage, Effect::Read, {}, {}, {}}
117
+ };
118
+ if (_instruction != Instruction::STATICCALL)
119
+ operations.emplace_back (Operation{Location::Storage, Effect::Write, {}, {}, {}});
120
+ operations.emplace_back (Operation{
121
+ Location::Memory,
122
+ Effect::Write,
123
+ paramCount - 2 ,
124
+ paramCount - 1 ,
125
+ {}
126
+ });
127
+ return operations;
128
+ }
129
+ case Instruction::CREATE:
130
+ case Instruction::CREATE2:
131
+ return vector<Operation>{
132
+ Operation{
133
+ Location::Memory,
134
+ Effect::Read,
135
+ 1 ,
136
+ 2 ,
137
+ {}
138
+ },
139
+ Operation{Location::Storage, Effect::Read, {}, {}, {}},
140
+ Operation{Location::Storage, Effect::Write, {}, {}, {}}
141
+ };
142
+ case Instruction::MSIZE:
143
+ // This is just to satisfy the assert below.
144
+ return vector<Operation>{};
145
+ default :
146
+ assertThrow (storage (_instruction) == None && memory (_instruction) == None, AssemblyException, " " );
147
+ }
148
+ return {};
149
+ }
150
+
32
151
bool SemanticInformation::breaksCSEAnalysisBlock (AssemblyItem const & _item, bool _msizeImportant)
33
152
{
34
153
switch (_item.type ())
@@ -49,7 +168,7 @@ bool SemanticInformation::breaksCSEAnalysisBlock(AssemblyItem const& _item, bool
49
168
case PushLibraryAddress:
50
169
case PushImmutable:
51
170
return false ;
52
- case Operation:
171
+ case evmasm:: Operation:
53
172
{
54
173
if (isSwapInstruction (_item) || isDupInstruction (_item))
55
174
return false ;
@@ -79,7 +198,7 @@ bool SemanticInformation::breaksCSEAnalysisBlock(AssemblyItem const& _item, bool
79
198
80
199
bool SemanticInformation::isCommutativeOperation (AssemblyItem const & _item)
81
200
{
82
- if (_item.type () != Operation)
201
+ if (_item.type () != evmasm:: Operation)
83
202
return false ;
84
203
switch (_item.instruction ())
85
204
{
@@ -97,14 +216,14 @@ bool SemanticInformation::isCommutativeOperation(AssemblyItem const& _item)
97
216
98
217
bool SemanticInformation::isDupInstruction (AssemblyItem const & _item)
99
218
{
100
- if (_item.type () != Operation)
219
+ if (_item.type () != evmasm:: Operation)
101
220
return false ;
102
221
return evmasm::isDupInstruction (_item.instruction ());
103
222
}
104
223
105
224
bool SemanticInformation::isSwapInstruction (AssemblyItem const & _item)
106
225
{
107
- if (_item.type () != Operation)
226
+ if (_item.type () != evmasm:: Operation)
108
227
return false ;
109
228
return evmasm::isSwapInstruction (_item.instruction ());
110
229
}
@@ -116,7 +235,7 @@ bool SemanticInformation::isJumpInstruction(AssemblyItem const& _item)
116
235
117
236
bool SemanticInformation::altersControlFlow (AssemblyItem const & _item)
118
237
{
119
- if (_item.type () != Operation)
238
+ if (_item.type () != evmasm:: Operation)
120
239
return false ;
121
240
switch (_item.instruction ())
122
241
{
@@ -166,7 +285,7 @@ bool SemanticInformation::isDeterministic(AssemblyItem const& _item)
166
285
{
167
286
assertThrow (_item.type () != VerbatimBytecode, AssemblyException, " " );
168
287
169
- if (_item.type () != Operation)
288
+ if (_item.type () != evmasm:: Operation)
170
289
return true ;
171
290
172
291
switch (_item.instruction ())
0 commit comments