@arbitrum/nitro-contracts 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierrc +5 -0
- package/.solhint.json +18 -0
- package/deploy/BridgeStubCreator.js +10 -0
- package/deploy/HashProofHelper.js +13 -0
- package/deploy/InboxStubCreator.js +17 -0
- package/deploy/OneStepProofEntryCreator.js +19 -0
- package/deploy/OneStepProver0Creator.js +14 -0
- package/deploy/OneStepProverHostIoCreator.js +14 -0
- package/deploy/OneStepProverMathCreator.js +14 -0
- package/deploy/OneStepProverMemoryCreator.js +14 -0
- package/deploy/SequencerInboxStubCreator.js +13 -0
- package/deploy/ValueArrayTesterCreator.js +13 -0
- package/hardhat.config.ts +47 -0
- package/hardhat.prod-config.js +18 -0
- package/package.json +49 -0
- package/scripts/build.bash +5 -0
- package/src/bridge/Bridge.sol +168 -0
- package/src/bridge/IBridge.sol +68 -0
- package/src/bridge/IInbox.sol +80 -0
- package/src/bridge/IMessageProvider.sol +11 -0
- package/src/bridge/IOutbox.sol +52 -0
- package/src/bridge/ISequencerInbox.sol +85 -0
- package/src/bridge/Inbox.sol +414 -0
- package/src/bridge/Messages.sol +38 -0
- package/src/bridge/Outbox.sol +188 -0
- package/src/bridge/SequencerInbox.sol +274 -0
- package/src/challenge/ChallengeLib.sol +135 -0
- package/src/challenge/ChallengeManager.sol +367 -0
- package/src/challenge/IChallengeManager.sol +75 -0
- package/src/challenge/IChallengeResultReceiver.sol +13 -0
- package/src/libraries/AddressAliasHelper.sol +29 -0
- package/src/libraries/AdminFallbackProxy.sol +153 -0
- package/src/libraries/ArbitrumProxy.sol +20 -0
- package/src/libraries/Constants.sol +10 -0
- package/src/libraries/CryptographyPrimitives.sol +323 -0
- package/src/libraries/DelegateCallAware.sol +44 -0
- package/src/libraries/Error.sol +38 -0
- package/src/libraries/IGasRefunder.sol +35 -0
- package/src/libraries/MerkleLib.sol +46 -0
- package/src/libraries/MessageTypes.sol +14 -0
- package/src/libraries/SecondaryLogicUUPSUpgradeable.sol +58 -0
- package/src/libraries/UUPSNotUpgradeable.sol +56 -0
- package/src/mocks/BridgeStub.sol +115 -0
- package/src/mocks/Counter.sol +13 -0
- package/src/mocks/ExecutionManager.sol +41 -0
- package/src/mocks/InboxStub.sol +131 -0
- package/src/mocks/MockResultReceiver.sol +59 -0
- package/src/mocks/SequencerInboxStub.sol +42 -0
- package/src/mocks/SimpleProxy.sol +19 -0
- package/src/node-interface/NodeInterface.sol +50 -0
- package/src/osp/HashProofHelper.sol +154 -0
- package/src/osp/IOneStepProofEntry.sol +20 -0
- package/src/osp/IOneStepProver.sol +27 -0
- package/src/osp/OneStepProofEntry.sol +129 -0
- package/src/osp/OneStepProver0.sol +566 -0
- package/src/osp/OneStepProverHostIo.sol +357 -0
- package/src/osp/OneStepProverMath.sol +514 -0
- package/src/osp/OneStepProverMemory.sol +313 -0
- package/src/precompiles/ArbAddressTable.sol +60 -0
- package/src/precompiles/ArbAggregator.sol +62 -0
- package/src/precompiles/ArbBLS.sol +53 -0
- package/src/precompiles/ArbDebug.sol +39 -0
- package/src/precompiles/ArbFunctionTable.sol +29 -0
- package/src/precompiles/ArbGasInfo.sol +121 -0
- package/src/precompiles/ArbInfo.sol +15 -0
- package/src/precompiles/ArbOwner.sol +65 -0
- package/src/precompiles/ArbOwnerPublic.sol +18 -0
- package/src/precompiles/ArbRetryableTx.sol +89 -0
- package/src/precompiles/ArbStatistics.sol +29 -0
- package/src/precompiles/ArbSys.sol +134 -0
- package/src/precompiles/ArbosActs.sol +41 -0
- package/src/precompiles/ArbosTest.sol +14 -0
- package/src/rollup/BridgeCreator.sol +120 -0
- package/src/rollup/IRollupCore.sol +152 -0
- package/src/rollup/IRollupLogic.sol +183 -0
- package/src/rollup/Node.sol +99 -0
- package/src/rollup/RollupAdminLogic.sol +322 -0
- package/src/rollup/RollupCore.sol +627 -0
- package/src/rollup/RollupCreator.sol +133 -0
- package/src/rollup/RollupEventBridge.sol +46 -0
- package/src/rollup/RollupLib.sol +135 -0
- package/src/rollup/RollupUserLogic.sol +712 -0
- package/src/rollup/ValidatorUtils.sol +243 -0
- package/src/rollup/ValidatorWallet.sol +76 -0
- package/src/rollup/ValidatorWalletCreator.sol +43 -0
- package/src/state/Deserialize.sol +321 -0
- package/src/state/GlobalState.sol +44 -0
- package/src/state/Instructions.sol +159 -0
- package/src/state/Machine.sol +65 -0
- package/src/state/MerkleProof.sol +99 -0
- package/src/state/Module.sol +33 -0
- package/src/state/ModuleMemory.sol +42 -0
- package/src/state/PcArray.sol +45 -0
- package/src/state/PcStack.sol +32 -0
- package/src/state/StackFrame.sol +63 -0
- package/src/state/Value.sol +65 -0
- package/src/state/ValueArray.sol +47 -0
- package/src/state/ValueStack.sol +39 -0
- package/src/test-helpers/CryptographyPrimitivesTester.sol +27 -0
- package/src/test-helpers/MessageTester.sol +34 -0
- package/src/test-helpers/ValueArrayTester.sol +34 -0
- package/test/contract/arbRollup.spec.ts +869 -0
- package/test/contract/common/challengeLib.ts +43 -0
- package/test/contract/common/globalStateLib.ts +17 -0
- package/test/contract/common/rolluplib.ts +259 -0
- package/test/contract/cryptographyPrimitives.spec.ts +82 -0
- package/test/contract/sequencerInboxForceInclude.spec.ts +516 -0
- package/test/contract/utils.ts +40 -0
- package/test/prover/hash-proofs.ts +75 -0
- package/test/prover/one-step-proof.ts +93 -0
- package/test/prover/proofs/.gitkeep +0 -0
- package/test/prover/value-arrays.ts +11 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
// Copyright 2021-2022, Offchain Labs, Inc.
|
|
2
|
+
// For license information, see https://github.com/nitro/blob/master/LICENSE
|
|
3
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
4
|
+
|
|
5
|
+
pragma solidity ^0.8.0;
|
|
6
|
+
|
|
7
|
+
import "../state/Value.sol";
|
|
8
|
+
import "../state/Machine.sol";
|
|
9
|
+
import "../state/Module.sol";
|
|
10
|
+
import "../state/Deserialize.sol";
|
|
11
|
+
import "./IOneStepProver.sol";
|
|
12
|
+
|
|
13
|
+
contract OneStepProverMath is IOneStepProver {
|
|
14
|
+
using ValueLib for Value;
|
|
15
|
+
using ValueStackLib for ValueStack;
|
|
16
|
+
|
|
17
|
+
function executeEqz(
|
|
18
|
+
Machine memory mach,
|
|
19
|
+
Module memory,
|
|
20
|
+
Instruction calldata inst,
|
|
21
|
+
bytes calldata
|
|
22
|
+
) internal pure {
|
|
23
|
+
Value memory v = mach.valueStack.pop();
|
|
24
|
+
if (inst.opcode == Instructions.I32_EQZ) {
|
|
25
|
+
require(v.valueType == ValueType.I32, "NOT_I32");
|
|
26
|
+
} else if (inst.opcode == Instructions.I64_EQZ) {
|
|
27
|
+
require(v.valueType == ValueType.I64, "NOT_I64");
|
|
28
|
+
} else {
|
|
29
|
+
revert("BAD_EQZ");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
uint32 output;
|
|
33
|
+
if (v.contents == 0) {
|
|
34
|
+
output = 1;
|
|
35
|
+
} else {
|
|
36
|
+
output = 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
mach.valueStack.push(ValueLib.newI32(output));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function signExtend(uint32 a) internal pure returns (uint64) {
|
|
43
|
+
if (a & (1 << 31) != 0) {
|
|
44
|
+
return uint64(a) | uint64(0xffffffff00000000);
|
|
45
|
+
}
|
|
46
|
+
return uint64(a);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function i64RelOp(
|
|
50
|
+
uint64 a,
|
|
51
|
+
uint64 b,
|
|
52
|
+
uint16 relop
|
|
53
|
+
) internal pure returns (bool) {
|
|
54
|
+
if (relop == Instructions.IRELOP_EQ) {
|
|
55
|
+
return (a == b);
|
|
56
|
+
} else if (relop == Instructions.IRELOP_NE) {
|
|
57
|
+
return (a != b);
|
|
58
|
+
} else if (relop == Instructions.IRELOP_LT_S) {
|
|
59
|
+
return (int64(a) < int64(b));
|
|
60
|
+
} else if (relop == Instructions.IRELOP_LT_U) {
|
|
61
|
+
return (a < b);
|
|
62
|
+
} else if (relop == Instructions.IRELOP_GT_S) {
|
|
63
|
+
return (int64(a) > int64(b));
|
|
64
|
+
} else if (relop == Instructions.IRELOP_GT_U) {
|
|
65
|
+
return (a > b);
|
|
66
|
+
} else if (relop == Instructions.IRELOP_LE_S) {
|
|
67
|
+
return (int64(a) <= int64(b));
|
|
68
|
+
} else if (relop == Instructions.IRELOP_LE_U) {
|
|
69
|
+
return (a <= b);
|
|
70
|
+
} else if (relop == Instructions.IRELOP_GE_S) {
|
|
71
|
+
return (int64(a) >= int64(b));
|
|
72
|
+
} else if (relop == Instructions.IRELOP_GE_U) {
|
|
73
|
+
return (a >= b);
|
|
74
|
+
} else {
|
|
75
|
+
revert("BAD IRELOP");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function executeI32RelOp(
|
|
80
|
+
Machine memory mach,
|
|
81
|
+
Module memory,
|
|
82
|
+
Instruction calldata inst,
|
|
83
|
+
bytes calldata
|
|
84
|
+
) internal pure {
|
|
85
|
+
uint32 b = mach.valueStack.pop().assumeI32();
|
|
86
|
+
uint32 a = mach.valueStack.pop().assumeI32();
|
|
87
|
+
|
|
88
|
+
uint16 relop = inst.opcode - Instructions.I32_RELOP_BASE;
|
|
89
|
+
uint64 a64;
|
|
90
|
+
uint64 b64;
|
|
91
|
+
|
|
92
|
+
if (
|
|
93
|
+
relop == Instructions.IRELOP_LT_S ||
|
|
94
|
+
relop == Instructions.IRELOP_GT_S ||
|
|
95
|
+
relop == Instructions.IRELOP_LE_S ||
|
|
96
|
+
relop == Instructions.IRELOP_GE_S
|
|
97
|
+
) {
|
|
98
|
+
a64 = signExtend(a);
|
|
99
|
+
b64 = signExtend(b);
|
|
100
|
+
} else {
|
|
101
|
+
a64 = uint64(a);
|
|
102
|
+
b64 = uint64(b);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
bool res = i64RelOp(a64, b64, relop);
|
|
106
|
+
|
|
107
|
+
mach.valueStack.push(ValueLib.newBoolean(res));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function executeI64RelOp(
|
|
111
|
+
Machine memory mach,
|
|
112
|
+
Module memory,
|
|
113
|
+
Instruction calldata inst,
|
|
114
|
+
bytes calldata
|
|
115
|
+
) internal pure {
|
|
116
|
+
uint64 b = mach.valueStack.pop().assumeI64();
|
|
117
|
+
uint64 a = mach.valueStack.pop().assumeI64();
|
|
118
|
+
|
|
119
|
+
uint16 relop = inst.opcode - Instructions.I64_RELOP_BASE;
|
|
120
|
+
|
|
121
|
+
bool res = i64RelOp(a, b, relop);
|
|
122
|
+
|
|
123
|
+
mach.valueStack.push(ValueLib.newBoolean(res));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function genericIUnOp(
|
|
127
|
+
uint64 a,
|
|
128
|
+
uint16 unop,
|
|
129
|
+
uint16 bits
|
|
130
|
+
) internal pure returns (uint32) {
|
|
131
|
+
require(bits == 32 || bits == 64, "WRONG USE OF genericUnOp");
|
|
132
|
+
if (unop == Instructions.IUNOP_CLZ) {
|
|
133
|
+
/* curbits is one-based to keep with unsigned mathematics */
|
|
134
|
+
uint32 curbit = bits;
|
|
135
|
+
while (curbit > 0 && (a & (1 << (curbit - 1)) == 0)) {
|
|
136
|
+
curbit -= 1;
|
|
137
|
+
}
|
|
138
|
+
return (bits - curbit);
|
|
139
|
+
} else if (unop == Instructions.IUNOP_CTZ) {
|
|
140
|
+
uint32 curbit = 0;
|
|
141
|
+
while (curbit < bits && ((a & (1 << curbit)) == 0)) {
|
|
142
|
+
curbit += 1;
|
|
143
|
+
}
|
|
144
|
+
return curbit;
|
|
145
|
+
} else if (unop == Instructions.IUNOP_POPCNT) {
|
|
146
|
+
uint32 curbit = 0;
|
|
147
|
+
uint32 res = 0;
|
|
148
|
+
while (curbit < bits) {
|
|
149
|
+
if ((a & (1 << curbit)) != 0) {
|
|
150
|
+
res += 1;
|
|
151
|
+
}
|
|
152
|
+
curbit++;
|
|
153
|
+
}
|
|
154
|
+
return res;
|
|
155
|
+
}
|
|
156
|
+
revert("BAD IUnOp");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function executeI32UnOp(
|
|
160
|
+
Machine memory mach,
|
|
161
|
+
Module memory,
|
|
162
|
+
Instruction calldata inst,
|
|
163
|
+
bytes calldata
|
|
164
|
+
) internal pure {
|
|
165
|
+
uint32 a = mach.valueStack.pop().assumeI32();
|
|
166
|
+
|
|
167
|
+
uint16 unop = inst.opcode - Instructions.I32_UNOP_BASE;
|
|
168
|
+
|
|
169
|
+
uint32 res = genericIUnOp(a, unop, 32);
|
|
170
|
+
|
|
171
|
+
mach.valueStack.push(ValueLib.newI32(res));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function executeI64UnOp(
|
|
175
|
+
Machine memory mach,
|
|
176
|
+
Module memory,
|
|
177
|
+
Instruction calldata inst,
|
|
178
|
+
bytes calldata
|
|
179
|
+
) internal pure {
|
|
180
|
+
uint64 a = mach.valueStack.pop().assumeI64();
|
|
181
|
+
|
|
182
|
+
uint16 unop = inst.opcode - Instructions.I64_UNOP_BASE;
|
|
183
|
+
|
|
184
|
+
uint64 res = uint64(genericIUnOp(a, unop, 64));
|
|
185
|
+
|
|
186
|
+
mach.valueStack.push(ValueLib.newI64(res));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function rotl32(uint32 a, uint32 b) internal pure returns (uint32) {
|
|
190
|
+
b %= 32;
|
|
191
|
+
return (a << b) | (a >> (32 - b));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function rotl64(uint64 a, uint64 b) internal pure returns (uint64) {
|
|
195
|
+
b %= 64;
|
|
196
|
+
return (a << b) | (a >> (64 - b));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function rotr32(uint32 a, uint32 b) internal pure returns (uint32) {
|
|
200
|
+
b %= 32;
|
|
201
|
+
return (a >> b) | (a << (32 - b));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function rotr64(uint64 a, uint64 b) internal pure returns (uint64) {
|
|
205
|
+
b %= 64;
|
|
206
|
+
return (a >> b) | (a << (64 - b));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function genericBinOp(
|
|
210
|
+
uint64 a,
|
|
211
|
+
uint64 b,
|
|
212
|
+
uint16 opcodeOffset
|
|
213
|
+
) internal pure returns (uint64) {
|
|
214
|
+
unchecked {
|
|
215
|
+
if (opcodeOffset == 0) {
|
|
216
|
+
// add
|
|
217
|
+
return a + b;
|
|
218
|
+
} else if (opcodeOffset == 1) {
|
|
219
|
+
// sub
|
|
220
|
+
return a - b;
|
|
221
|
+
} else if (opcodeOffset == 2) {
|
|
222
|
+
// mul
|
|
223
|
+
return a * b;
|
|
224
|
+
} else if (opcodeOffset == 4) {
|
|
225
|
+
// div_u
|
|
226
|
+
if (b == 0) {
|
|
227
|
+
return 0;
|
|
228
|
+
}
|
|
229
|
+
return a / b;
|
|
230
|
+
} else if (opcodeOffset == 6) {
|
|
231
|
+
// rem_u
|
|
232
|
+
if (b == 0) {
|
|
233
|
+
return 0;
|
|
234
|
+
}
|
|
235
|
+
return a % b;
|
|
236
|
+
} else if (opcodeOffset == 7) {
|
|
237
|
+
// and
|
|
238
|
+
return a & b;
|
|
239
|
+
} else if (opcodeOffset == 8) {
|
|
240
|
+
// or
|
|
241
|
+
return a | b;
|
|
242
|
+
} else if (opcodeOffset == 9) {
|
|
243
|
+
// xor
|
|
244
|
+
return a ^ b;
|
|
245
|
+
} else {
|
|
246
|
+
revert("INVALID_GENERIC_BIN_OP");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function executeI32BinOp(
|
|
252
|
+
Machine memory mach,
|
|
253
|
+
Module memory,
|
|
254
|
+
Instruction calldata inst,
|
|
255
|
+
bytes calldata
|
|
256
|
+
) internal pure {
|
|
257
|
+
uint32 b = mach.valueStack.pop().assumeI32();
|
|
258
|
+
uint32 a = mach.valueStack.pop().assumeI32();
|
|
259
|
+
uint32 res;
|
|
260
|
+
|
|
261
|
+
uint16 opcodeOffset = inst.opcode - Instructions.I32_ADD;
|
|
262
|
+
|
|
263
|
+
unchecked {
|
|
264
|
+
if (opcodeOffset == 3) {
|
|
265
|
+
// div_s
|
|
266
|
+
if (b == 0) {
|
|
267
|
+
res = 0;
|
|
268
|
+
} else {
|
|
269
|
+
res = uint32(int32(a) / int32(b));
|
|
270
|
+
}
|
|
271
|
+
} else if (opcodeOffset == 5) {
|
|
272
|
+
// rem_s
|
|
273
|
+
if (b == 0) {
|
|
274
|
+
res = 0;
|
|
275
|
+
} else {
|
|
276
|
+
res = uint32(int32(a) % int32(b));
|
|
277
|
+
}
|
|
278
|
+
} else if (opcodeOffset == 10) {
|
|
279
|
+
// shl
|
|
280
|
+
res = a << (b % 32);
|
|
281
|
+
} else if (opcodeOffset == 12) {
|
|
282
|
+
// shr_u
|
|
283
|
+
res = a >> (b % 32);
|
|
284
|
+
} else if (opcodeOffset == 11) {
|
|
285
|
+
// shr_s
|
|
286
|
+
res = uint32(int32(a) >> b);
|
|
287
|
+
} else if (opcodeOffset == 13) {
|
|
288
|
+
// rotl
|
|
289
|
+
res = rotl32(a, b);
|
|
290
|
+
} else if (opcodeOffset == 14) {
|
|
291
|
+
// rotr
|
|
292
|
+
res = rotr32(a, b);
|
|
293
|
+
} else {
|
|
294
|
+
res = uint32(genericBinOp(a, b, opcodeOffset));
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
mach.valueStack.push(ValueLib.newI32(res));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function executeI64BinOp(
|
|
302
|
+
Machine memory mach,
|
|
303
|
+
Module memory,
|
|
304
|
+
Instruction calldata inst,
|
|
305
|
+
bytes calldata
|
|
306
|
+
) internal pure {
|
|
307
|
+
uint64 b = mach.valueStack.pop().assumeI64();
|
|
308
|
+
uint64 a = mach.valueStack.pop().assumeI64();
|
|
309
|
+
uint64 res;
|
|
310
|
+
|
|
311
|
+
uint16 opcodeOffset = inst.opcode - Instructions.I64_ADD;
|
|
312
|
+
|
|
313
|
+
unchecked {
|
|
314
|
+
if (opcodeOffset == 3) {
|
|
315
|
+
// div_s
|
|
316
|
+
if (b == 0) {
|
|
317
|
+
res = 0;
|
|
318
|
+
} else {
|
|
319
|
+
res = uint64(int64(a) / int64(b));
|
|
320
|
+
}
|
|
321
|
+
} else if (opcodeOffset == 5) {
|
|
322
|
+
// rem_s
|
|
323
|
+
if (b == 0) {
|
|
324
|
+
res = 0;
|
|
325
|
+
} else {
|
|
326
|
+
res = uint64(int64(a) % int64(b));
|
|
327
|
+
}
|
|
328
|
+
} else if (opcodeOffset == 10) {
|
|
329
|
+
// shl
|
|
330
|
+
res = a << (b % 64);
|
|
331
|
+
} else if (opcodeOffset == 12) {
|
|
332
|
+
// shr_u
|
|
333
|
+
res = a >> (b % 64);
|
|
334
|
+
} else if (opcodeOffset == 11) {
|
|
335
|
+
// shr_s
|
|
336
|
+
res = uint64(int64(a) >> b);
|
|
337
|
+
} else if (opcodeOffset == 13) {
|
|
338
|
+
// rotl
|
|
339
|
+
res = rotl64(a, b);
|
|
340
|
+
} else if (opcodeOffset == 14) {
|
|
341
|
+
// rotr
|
|
342
|
+
res = rotr64(a, b);
|
|
343
|
+
} else {
|
|
344
|
+
res = genericBinOp(a, b, opcodeOffset);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
mach.valueStack.push(ValueLib.newI64(res));
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function executeI32WrapI64(
|
|
352
|
+
Machine memory mach,
|
|
353
|
+
Module memory,
|
|
354
|
+
Instruction calldata,
|
|
355
|
+
bytes calldata
|
|
356
|
+
) internal pure {
|
|
357
|
+
uint64 a = mach.valueStack.pop().assumeI64();
|
|
358
|
+
|
|
359
|
+
uint32 a32 = uint32(a);
|
|
360
|
+
|
|
361
|
+
mach.valueStack.push(ValueLib.newI32(a32));
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function executeI64ExtendI32(
|
|
365
|
+
Machine memory mach,
|
|
366
|
+
Module memory,
|
|
367
|
+
Instruction calldata inst,
|
|
368
|
+
bytes calldata
|
|
369
|
+
) internal pure {
|
|
370
|
+
uint32 a = mach.valueStack.pop().assumeI32();
|
|
371
|
+
|
|
372
|
+
uint64 a64;
|
|
373
|
+
|
|
374
|
+
if (inst.opcode == Instructions.I64_EXTEND_I32_S) {
|
|
375
|
+
a64 = signExtend(a);
|
|
376
|
+
} else {
|
|
377
|
+
a64 = uint64(a);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
mach.valueStack.push(ValueLib.newI64(a64));
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function executeExtendSameType(
|
|
384
|
+
Machine memory mach,
|
|
385
|
+
Module memory,
|
|
386
|
+
Instruction calldata inst,
|
|
387
|
+
bytes calldata
|
|
388
|
+
) internal pure {
|
|
389
|
+
ValueType ty;
|
|
390
|
+
uint8 sourceBits;
|
|
391
|
+
if (inst.opcode == Instructions.I32_EXTEND_8S) {
|
|
392
|
+
ty = ValueType.I32;
|
|
393
|
+
sourceBits = 8;
|
|
394
|
+
} else if (inst.opcode == Instructions.I32_EXTEND_16S) {
|
|
395
|
+
ty = ValueType.I32;
|
|
396
|
+
sourceBits = 16;
|
|
397
|
+
} else if (inst.opcode == Instructions.I64_EXTEND_8S) {
|
|
398
|
+
ty = ValueType.I64;
|
|
399
|
+
sourceBits = 8;
|
|
400
|
+
} else if (inst.opcode == Instructions.I64_EXTEND_16S) {
|
|
401
|
+
ty = ValueType.I64;
|
|
402
|
+
sourceBits = 16;
|
|
403
|
+
} else if (inst.opcode == Instructions.I64_EXTEND_32S) {
|
|
404
|
+
ty = ValueType.I64;
|
|
405
|
+
sourceBits = 32;
|
|
406
|
+
} else {
|
|
407
|
+
revert("INVALID_EXTEND_SAME_TYPE");
|
|
408
|
+
}
|
|
409
|
+
uint256 resultMask;
|
|
410
|
+
if (ty == ValueType.I32) {
|
|
411
|
+
resultMask = (1 << 32) - 1;
|
|
412
|
+
} else {
|
|
413
|
+
resultMask = (1 << 64) - 1;
|
|
414
|
+
}
|
|
415
|
+
Value memory val = mach.valueStack.pop();
|
|
416
|
+
require(val.valueType == ty, "BAD_EXTEND_SAME_TYPE_TYPE");
|
|
417
|
+
uint256 sourceMask = (1 << sourceBits) - 1;
|
|
418
|
+
val.contents &= sourceMask;
|
|
419
|
+
if (val.contents & (1 << (sourceBits - 1)) != 0) {
|
|
420
|
+
// Extend sign flag
|
|
421
|
+
val.contents |= resultMask & ~sourceMask;
|
|
422
|
+
}
|
|
423
|
+
mach.valueStack.push(val);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function executeReinterpret(
|
|
427
|
+
Machine memory mach,
|
|
428
|
+
Module memory,
|
|
429
|
+
Instruction calldata inst,
|
|
430
|
+
bytes calldata
|
|
431
|
+
) internal pure {
|
|
432
|
+
ValueType destTy;
|
|
433
|
+
ValueType sourceTy;
|
|
434
|
+
if (inst.opcode == Instructions.I32_REINTERPRET_F32) {
|
|
435
|
+
destTy = ValueType.I32;
|
|
436
|
+
sourceTy = ValueType.F32;
|
|
437
|
+
} else if (inst.opcode == Instructions.I64_REINTERPRET_F64) {
|
|
438
|
+
destTy = ValueType.I64;
|
|
439
|
+
sourceTy = ValueType.F64;
|
|
440
|
+
} else if (inst.opcode == Instructions.F32_REINTERPRET_I32) {
|
|
441
|
+
destTy = ValueType.F32;
|
|
442
|
+
sourceTy = ValueType.I32;
|
|
443
|
+
} else if (inst.opcode == Instructions.F64_REINTERPRET_I64) {
|
|
444
|
+
destTy = ValueType.F64;
|
|
445
|
+
sourceTy = ValueType.I64;
|
|
446
|
+
} else {
|
|
447
|
+
revert("INVALID_REINTERPRET");
|
|
448
|
+
}
|
|
449
|
+
Value memory val = mach.valueStack.pop();
|
|
450
|
+
require(val.valueType == sourceTy, "INVALID_REINTERPRET_TYPE");
|
|
451
|
+
val.valueType = destTy;
|
|
452
|
+
mach.valueStack.push(val);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
function executeOneStep(
|
|
456
|
+
ExecutionContext calldata,
|
|
457
|
+
Machine calldata startMach,
|
|
458
|
+
Module calldata startMod,
|
|
459
|
+
Instruction calldata inst,
|
|
460
|
+
bytes calldata proof
|
|
461
|
+
) external pure override returns (Machine memory mach, Module memory mod) {
|
|
462
|
+
mach = startMach;
|
|
463
|
+
mod = startMod;
|
|
464
|
+
|
|
465
|
+
uint16 opcode = inst.opcode;
|
|
466
|
+
|
|
467
|
+
function(Machine memory, Module memory, Instruction calldata, bytes calldata)
|
|
468
|
+
internal
|
|
469
|
+
pure impl;
|
|
470
|
+
if (opcode == Instructions.I32_EQZ || opcode == Instructions.I64_EQZ) {
|
|
471
|
+
impl = executeEqz;
|
|
472
|
+
} else if (
|
|
473
|
+
opcode >= Instructions.I32_RELOP_BASE &&
|
|
474
|
+
opcode <= Instructions.I32_RELOP_BASE + Instructions.IRELOP_LAST
|
|
475
|
+
) {
|
|
476
|
+
impl = executeI32RelOp;
|
|
477
|
+
} else if (
|
|
478
|
+
opcode >= Instructions.I32_UNOP_BASE &&
|
|
479
|
+
opcode <= Instructions.I32_UNOP_BASE + Instructions.IUNOP_LAST
|
|
480
|
+
) {
|
|
481
|
+
impl = executeI32UnOp;
|
|
482
|
+
} else if (opcode >= Instructions.I32_ADD && opcode <= Instructions.I32_ROTR) {
|
|
483
|
+
impl = executeI32BinOp;
|
|
484
|
+
} else if (
|
|
485
|
+
opcode >= Instructions.I64_RELOP_BASE &&
|
|
486
|
+
opcode <= Instructions.I64_RELOP_BASE + Instructions.IRELOP_LAST
|
|
487
|
+
) {
|
|
488
|
+
impl = executeI64RelOp;
|
|
489
|
+
} else if (
|
|
490
|
+
opcode >= Instructions.I64_UNOP_BASE &&
|
|
491
|
+
opcode <= Instructions.I64_UNOP_BASE + Instructions.IUNOP_LAST
|
|
492
|
+
) {
|
|
493
|
+
impl = executeI64UnOp;
|
|
494
|
+
} else if (opcode >= Instructions.I64_ADD && opcode <= Instructions.I64_ROTR) {
|
|
495
|
+
impl = executeI64BinOp;
|
|
496
|
+
} else if (opcode == Instructions.I32_WRAP_I64) {
|
|
497
|
+
impl = executeI32WrapI64;
|
|
498
|
+
} else if (
|
|
499
|
+
opcode == Instructions.I64_EXTEND_I32_S || opcode == Instructions.I64_EXTEND_I32_U
|
|
500
|
+
) {
|
|
501
|
+
impl = executeI64ExtendI32;
|
|
502
|
+
} else if (opcode >= Instructions.I32_EXTEND_8S && opcode <= Instructions.I64_EXTEND_32S) {
|
|
503
|
+
impl = executeExtendSameType;
|
|
504
|
+
} else if (
|
|
505
|
+
opcode >= Instructions.I32_REINTERPRET_F32 && opcode <= Instructions.F64_REINTERPRET_I64
|
|
506
|
+
) {
|
|
507
|
+
impl = executeReinterpret;
|
|
508
|
+
} else {
|
|
509
|
+
revert("INVALID_OPCODE");
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
impl(mach, mod, inst, proof);
|
|
513
|
+
}
|
|
514
|
+
}
|