hardhat 2.22.11 → 2.22.13

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.
Files changed (94) hide show
  1. package/internal/hardhat-network/provider/provider.d.ts +2 -3
  2. package/internal/hardhat-network/provider/provider.d.ts.map +1 -1
  3. package/internal/hardhat-network/provider/provider.js +5 -19
  4. package/internal/hardhat-network/provider/provider.js.map +1 -1
  5. package/internal/hardhat-network/provider/return-data.d.ts +2 -15
  6. package/internal/hardhat-network/provider/return-data.d.ts.map +1 -1
  7. package/internal/hardhat-network/provider/return-data.js +2 -50
  8. package/internal/hardhat-network/provider/return-data.js.map +1 -1
  9. package/internal/hardhat-network/provider/vm/exit.d.ts +2 -20
  10. package/internal/hardhat-network/provider/vm/exit.d.ts.map +1 -1
  11. package/internal/hardhat-network/provider/vm/exit.js +3 -78
  12. package/internal/hardhat-network/provider/vm/exit.js.map +1 -1
  13. package/internal/hardhat-network/stack-traces/compiler-to-model.d.ts +2 -3
  14. package/internal/hardhat-network/stack-traces/compiler-to-model.d.ts.map +1 -1
  15. package/internal/hardhat-network/stack-traces/compiler-to-model.js +2 -351
  16. package/internal/hardhat-network/stack-traces/compiler-to-model.js.map +1 -1
  17. package/internal/hardhat-network/stack-traces/debug.d.ts +2 -7
  18. package/internal/hardhat-network/stack-traces/debug.d.ts.map +1 -1
  19. package/internal/hardhat-network/stack-traces/debug.js +3 -143
  20. package/internal/hardhat-network/stack-traces/debug.js.map +1 -1
  21. package/internal/hardhat-network/stack-traces/library-utils.d.ts +2 -11
  22. package/internal/hardhat-network/stack-traces/library-utils.d.ts.map +1 -1
  23. package/internal/hardhat-network/stack-traces/library-utils.js +3 -61
  24. package/internal/hardhat-network/stack-traces/library-utils.js.map +1 -1
  25. package/internal/hardhat-network/stack-traces/logger.d.ts.map +1 -1
  26. package/internal/hardhat-network/stack-traces/logger.js +0 -221
  27. package/internal/hardhat-network/stack-traces/logger.js.map +1 -1
  28. package/internal/hardhat-network/stack-traces/message-trace.d.ts +2 -51
  29. package/internal/hardhat-network/stack-traces/message-trace.d.ts.map +1 -1
  30. package/internal/hardhat-network/stack-traces/message-trace.js +0 -46
  31. package/internal/hardhat-network/stack-traces/message-trace.js.map +1 -1
  32. package/internal/hardhat-network/stack-traces/solidity-errors.d.ts.map +1 -1
  33. package/internal/hardhat-network/stack-traces/solidity-errors.js +58 -53
  34. package/internal/hardhat-network/stack-traces/solidity-errors.js.map +1 -1
  35. package/internal/hardhat-network/stack-traces/solidity-stack-trace.d.ts +4 -155
  36. package/internal/hardhat-network/stack-traces/solidity-stack-trace.d.ts.map +1 -1
  37. package/internal/hardhat-network/stack-traces/solidity-stack-trace.js +12 -37
  38. package/internal/hardhat-network/stack-traces/solidity-stack-trace.js.map +1 -1
  39. package/internal/hardhat-network/stack-traces/solidityTracer.d.ts +2 -13
  40. package/internal/hardhat-network/stack-traces/solidityTracer.d.ts.map +1 -1
  41. package/internal/hardhat-network/stack-traces/solidityTracer.js +2 -162
  42. package/internal/hardhat-network/stack-traces/solidityTracer.js.map +1 -1
  43. package/internal/hardhat-network/stack-traces/vm-trace-decoder.d.ts +4 -15
  44. package/internal/hardhat-network/stack-traces/vm-trace-decoder.d.ts.map +1 -1
  45. package/internal/hardhat-network/stack-traces/vm-trace-decoder.js +6 -70
  46. package/internal/hardhat-network/stack-traces/vm-trace-decoder.js.map +1 -1
  47. package/internal/hardhat-network/stack-traces/vm-tracer.d.ts +2 -19
  48. package/internal/hardhat-network/stack-traces/vm-tracer.d.ts.map +1 -1
  49. package/internal/hardhat-network/stack-traces/vm-tracer.js +3 -150
  50. package/internal/hardhat-network/stack-traces/vm-tracer.js.map +1 -1
  51. package/package.json +2 -2
  52. package/src/internal/hardhat-network/provider/provider.ts +11 -24
  53. package/src/internal/hardhat-network/provider/return-data.ts +5 -73
  54. package/src/internal/hardhat-network/provider/vm/exit.ts +4 -92
  55. package/src/internal/hardhat-network/stack-traces/compiler-to-model.ts +5 -697
  56. package/src/internal/hardhat-network/stack-traces/debug.ts +5 -218
  57. package/src/internal/hardhat-network/stack-traces/library-utils.ts +5 -90
  58. package/src/internal/hardhat-network/stack-traces/logger.ts +0 -221
  59. package/src/internal/hardhat-network/stack-traces/message-trace.ts +5 -122
  60. package/src/internal/hardhat-network/stack-traces/solidity-errors.ts +16 -15
  61. package/src/internal/hardhat-network/stack-traces/solidity-stack-trace.ts +83 -186
  62. package/src/internal/hardhat-network/stack-traces/solidityTracer.ts +5 -253
  63. package/src/internal/hardhat-network/stack-traces/vm-trace-decoder.ts +15 -108
  64. package/src/internal/hardhat-network/stack-traces/vm-tracer.ts +5 -206
  65. package/internal/hardhat-network/stack-traces/contracts-identifier.d.ts +0 -15
  66. package/internal/hardhat-network/stack-traces/contracts-identifier.d.ts.map +0 -1
  67. package/internal/hardhat-network/stack-traces/contracts-identifier.js +0 -166
  68. package/internal/hardhat-network/stack-traces/contracts-identifier.js.map +0 -1
  69. package/internal/hardhat-network/stack-traces/error-inferrer.d.ts +0 -85
  70. package/internal/hardhat-network/stack-traces/error-inferrer.d.ts.map +0 -1
  71. package/internal/hardhat-network/stack-traces/error-inferrer.js +0 -1168
  72. package/internal/hardhat-network/stack-traces/error-inferrer.js.map +0 -1
  73. package/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.d.ts +0 -24
  74. package/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.d.ts.map +0 -1
  75. package/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.js +0 -116
  76. package/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.js.map +0 -1
  77. package/internal/hardhat-network/stack-traces/model.d.ts +0 -140
  78. package/internal/hardhat-network/stack-traces/model.d.ts.map +0 -1
  79. package/internal/hardhat-network/stack-traces/model.js +0 -328
  80. package/internal/hardhat-network/stack-traces/model.js.map +0 -1
  81. package/internal/hardhat-network/stack-traces/opcodes.d.ts +0 -266
  82. package/internal/hardhat-network/stack-traces/opcodes.d.ts.map +0 -1
  83. package/internal/hardhat-network/stack-traces/opcodes.js +0 -320
  84. package/internal/hardhat-network/stack-traces/opcodes.js.map +0 -1
  85. package/internal/hardhat-network/stack-traces/source-maps.d.ts +0 -13
  86. package/internal/hardhat-network/stack-traces/source-maps.d.ts.map +0 -1
  87. package/internal/hardhat-network/stack-traces/source-maps.js +0 -106
  88. package/internal/hardhat-network/stack-traces/source-maps.js.map +0 -1
  89. package/src/internal/hardhat-network/stack-traces/contracts-identifier.ts +0 -235
  90. package/src/internal/hardhat-network/stack-traces/error-inferrer.ts +0 -1845
  91. package/src/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.ts +0 -163
  92. package/src/internal/hardhat-network/stack-traces/model.ts +0 -409
  93. package/src/internal/hardhat-network/stack-traces/opcodes.ts +0 -344
  94. package/src/internal/hardhat-network/stack-traces/source-maps.ts +0 -167
@@ -1,163 +0,0 @@
1
- /**
2
- * This file includes Solidity tracing heuristics for solc starting with version
3
- * 0.6.9.
4
- *
5
- * This solc version introduced a significant change to how sourcemaps are
6
- * handled for inline yul/internal functions. These were mapped to the
7
- * unmapped/-1 file before, which lead to many unmapped reverts. Now, they are
8
- * mapped to the part of the Solidity source that lead to their inlining.
9
- *
10
- * This change is a very positive change, as errors would point to the correct
11
- * line by default. The only problem is that we used to rely very heavily on
12
- * unmapped reverts to decide when our error detection heuristics were to be
13
- * run. In fact, this heuristics were first introduced because of unmapped
14
- * reverts.
15
- *
16
- * Instead of synthetically completing stack traces when unmapped reverts occur,
17
- * we now start from complete stack traces and adjust them if we can provide
18
- * more meaningful errors.
19
- */
20
-
21
- import semver from "semver";
22
-
23
- import {
24
- DecodedEvmMessageTrace,
25
- isDecodedCallTrace,
26
- isDecodedCreateTrace,
27
- isEvmStep,
28
- } from "./message-trace";
29
- import { Opcode } from "./opcodes";
30
- import {
31
- SolidityStackTrace,
32
- StackTraceEntryType,
33
- } from "./solidity-stack-trace";
34
-
35
- const FIRST_SOLC_VERSION_WITH_MAPPED_SMALL_INTERNAL_FUNCTIONS = "0.6.9";
36
-
37
- export function stackTraceMayRequireAdjustments(
38
- stackTrace: SolidityStackTrace,
39
- decodedTrace: DecodedEvmMessageTrace
40
- ): boolean {
41
- if (stackTrace.length === 0) {
42
- return false;
43
- }
44
-
45
- const lastFrame = stackTrace[stackTrace.length - 1];
46
-
47
- return (
48
- lastFrame.type === StackTraceEntryType.REVERT_ERROR &&
49
- !lastFrame.isInvalidOpcodeError &&
50
- lastFrame.message.isEmpty() &&
51
- semver.gte(
52
- decodedTrace.bytecode.compilerVersion,
53
- FIRST_SOLC_VERSION_WITH_MAPPED_SMALL_INTERNAL_FUNCTIONS
54
- )
55
- );
56
- }
57
-
58
- export function adjustStackTrace(
59
- stackTrace: SolidityStackTrace,
60
- decodedTrace: DecodedEvmMessageTrace
61
- ): SolidityStackTrace {
62
- const start = stackTrace.slice(0, -1);
63
- const [revert] = stackTrace.slice(-1);
64
-
65
- if (isNonContractAccountCalledError(decodedTrace)) {
66
- return [
67
- ...start,
68
- {
69
- type: StackTraceEntryType.NONCONTRACT_ACCOUNT_CALLED_ERROR,
70
- sourceReference: revert.sourceReference!,
71
- },
72
- ];
73
- }
74
-
75
- if (isConstructorInvalidParamsError(decodedTrace)) {
76
- return [
77
- ...start,
78
- {
79
- type: StackTraceEntryType.INVALID_PARAMS_ERROR,
80
- sourceReference: revert.sourceReference!,
81
- },
82
- ];
83
- }
84
-
85
- if (isCallInvalidParamsError(decodedTrace)) {
86
- return [
87
- ...start,
88
- {
89
- type: StackTraceEntryType.INVALID_PARAMS_ERROR,
90
- sourceReference: revert.sourceReference!,
91
- },
92
- ];
93
- }
94
-
95
- return stackTrace;
96
- }
97
-
98
- function isNonContractAccountCalledError(
99
- decodedTrace: DecodedEvmMessageTrace
100
- ): boolean {
101
- return matchOpcodes(decodedTrace, -9, [
102
- Opcode.EXTCODESIZE,
103
- Opcode.ISZERO,
104
- Opcode.DUP1,
105
- Opcode.ISZERO,
106
- ]);
107
- }
108
-
109
- function isConstructorInvalidParamsError(decodedTrace: DecodedEvmMessageTrace) {
110
- if (!isDecodedCreateTrace(decodedTrace)) {
111
- return false;
112
- }
113
-
114
- return (
115
- matchOpcodes(decodedTrace, -20, [Opcode.CODESIZE]) &&
116
- matchOpcodes(decodedTrace, -15, [Opcode.CODECOPY]) &&
117
- matchOpcodes(decodedTrace, -7, [Opcode.LT, Opcode.ISZERO])
118
- );
119
- }
120
-
121
- function isCallInvalidParamsError(decodedTrace: DecodedEvmMessageTrace) {
122
- if (!isDecodedCallTrace(decodedTrace)) {
123
- return false;
124
- }
125
-
126
- return (
127
- matchOpcodes(decodedTrace, -11, [Opcode.CALLDATASIZE]) &&
128
- matchOpcodes(decodedTrace, -7, [Opcode.LT, Opcode.ISZERO])
129
- );
130
- }
131
-
132
- function matchOpcode(
133
- decodedTrace: DecodedEvmMessageTrace,
134
- stepIndex: number,
135
- opcode: Opcode
136
- ): boolean {
137
- const [step] = decodedTrace.steps.slice(stepIndex, stepIndex + 1);
138
-
139
- if (step === undefined || !isEvmStep(step)) {
140
- return false;
141
- }
142
-
143
- const instruction = decodedTrace.bytecode.getInstruction(step.pc);
144
-
145
- return instruction.opcode === opcode;
146
- }
147
-
148
- function matchOpcodes(
149
- decodedTrace: DecodedEvmMessageTrace,
150
- firstStepIndex: number,
151
- opcodes: Opcode[]
152
- ): boolean {
153
- let index = firstStepIndex;
154
- for (const opcode of opcodes) {
155
- if (!matchOpcode(decodedTrace, index, opcode)) {
156
- return false;
157
- }
158
-
159
- index += 1;
160
- }
161
-
162
- return true;
163
- }
@@ -1,409 +0,0 @@
1
- import { bytesToHex as bufferToHex } from "@nomicfoundation/ethereumjs-util";
2
-
3
- import { AbiHelpers } from "../../util/abi-helpers";
4
-
5
- import { Opcode } from "./opcodes";
6
-
7
- /* eslint-disable @nomicfoundation/hardhat-internal-rules/only-hardhat-error */
8
-
9
- export enum JumpType {
10
- NOT_JUMP,
11
- INTO_FUNCTION,
12
- OUTOF_FUNCTION,
13
- INTERNAL_JUMP,
14
- }
15
-
16
- export enum ContractType {
17
- CONTRACT,
18
- LIBRARY,
19
- }
20
-
21
- export enum ContractFunctionType {
22
- CONSTRUCTOR,
23
- FUNCTION,
24
- FALLBACK,
25
- RECEIVE,
26
- GETTER,
27
- MODIFIER,
28
- FREE_FUNCTION,
29
- }
30
-
31
- export enum ContractFunctionVisibility {
32
- PRIVATE,
33
- INTERNAL,
34
- PUBLIC,
35
- EXTERNAL,
36
- }
37
-
38
- export class SourceFile {
39
- public readonly contracts: Contract[] = [];
40
- public readonly functions: ContractFunction[] = [];
41
-
42
- constructor(
43
- public readonly sourceName: string,
44
- public readonly content: string
45
- ) {}
46
-
47
- public addContract(contract: Contract) {
48
- if (contract.location.file !== this) {
49
- throw new Error("Trying to add a contract from another file");
50
- }
51
-
52
- this.contracts.push(contract);
53
- }
54
-
55
- public addFunction(func: ContractFunction) {
56
- if (func.location.file !== this) {
57
- throw new Error("Trying to add a function from another file");
58
- }
59
-
60
- this.functions.push(func);
61
- }
62
-
63
- public getContainingFunction(
64
- location: SourceLocation
65
- ): ContractFunction | undefined {
66
- // TODO: Optimize this with a binary search or an internal tree
67
-
68
- for (const func of this.functions) {
69
- if (func.location.contains(location)) {
70
- return func;
71
- }
72
- }
73
-
74
- return undefined;
75
- }
76
- }
77
-
78
- export class SourceLocation {
79
- private _line: number | undefined;
80
-
81
- constructor(
82
- public readonly file: SourceFile,
83
- public readonly offset: number,
84
- public readonly length: number
85
- ) {}
86
-
87
- public getStartingLineNumber(): number {
88
- if (this._line === undefined) {
89
- this._line = 1;
90
-
91
- for (const c of this.file.content.slice(0, this.offset)) {
92
- if (c === "\n") {
93
- this._line += 1;
94
- }
95
- }
96
- }
97
-
98
- return this._line;
99
- }
100
-
101
- public getContainingFunction(): ContractFunction | undefined {
102
- return this.file.getContainingFunction(this);
103
- }
104
-
105
- public contains(other: SourceLocation) {
106
- if (this.file !== other.file) {
107
- return false;
108
- }
109
-
110
- if (other.offset < this.offset) {
111
- return false;
112
- }
113
-
114
- return other.offset + other.length <= this.offset + this.length;
115
- }
116
-
117
- public equals(other: SourceLocation) {
118
- return (
119
- this.file === other.file &&
120
- this.offset === other.offset &&
121
- this.length === other.length
122
- );
123
- }
124
- }
125
-
126
- export class Contract {
127
- public readonly localFunctions: ContractFunction[] = [];
128
- public readonly customErrors: CustomError[] = [];
129
-
130
- private _constructor: ContractFunction | undefined;
131
- private _fallback: ContractFunction | undefined;
132
- private _receive: ContractFunction | undefined;
133
- private readonly _selectorHexToFunction: Map<string, ContractFunction> =
134
- new Map();
135
-
136
- constructor(
137
- public readonly name: string,
138
- public readonly type: ContractType,
139
- public readonly location: SourceLocation
140
- ) {}
141
-
142
- public get constructorFunction(): ContractFunction | undefined {
143
- return this._constructor;
144
- }
145
-
146
- public get fallback(): ContractFunction | undefined {
147
- return this._fallback;
148
- }
149
-
150
- public get receive(): ContractFunction | undefined {
151
- return this._receive;
152
- }
153
-
154
- public addLocalFunction(func: ContractFunction) {
155
- if (func.contract !== this) {
156
- throw new Error("Function isn't local");
157
- }
158
-
159
- if (
160
- func.visibility === ContractFunctionVisibility.PUBLIC ||
161
- func.visibility === ContractFunctionVisibility.EXTERNAL
162
- ) {
163
- if (
164
- func.type === ContractFunctionType.FUNCTION ||
165
- func.type === ContractFunctionType.GETTER
166
- ) {
167
- this._selectorHexToFunction.set(bufferToHex(func.selector!), func);
168
- } else if (func.type === ContractFunctionType.CONSTRUCTOR) {
169
- this._constructor = func;
170
- } else if (func.type === ContractFunctionType.FALLBACK) {
171
- this._fallback = func;
172
- } else if (func.type === ContractFunctionType.RECEIVE) {
173
- this._receive = func;
174
- }
175
- }
176
-
177
- this.localFunctions.push(func);
178
- }
179
-
180
- public addCustomError(customError: CustomError) {
181
- this.customErrors.push(customError);
182
- }
183
-
184
- public addNextLinearizedBaseContract(baseContract: Contract) {
185
- if (this._fallback === undefined && baseContract._fallback !== undefined) {
186
- this._fallback = baseContract._fallback;
187
- }
188
- if (this._receive === undefined && baseContract._receive !== undefined) {
189
- this._receive = baseContract._receive;
190
- }
191
-
192
- for (const baseContractFunction of baseContract.localFunctions) {
193
- if (
194
- baseContractFunction.type !== ContractFunctionType.GETTER &&
195
- baseContractFunction.type !== ContractFunctionType.FUNCTION
196
- ) {
197
- continue;
198
- }
199
-
200
- if (
201
- baseContractFunction.visibility !== ContractFunctionVisibility.PUBLIC &&
202
- baseContractFunction.visibility !== ContractFunctionVisibility.EXTERNAL
203
- ) {
204
- continue;
205
- }
206
-
207
- const selectorHex = bufferToHex(baseContractFunction.selector!);
208
- if (!this._selectorHexToFunction.has(selectorHex)) {
209
- this._selectorHexToFunction.set(selectorHex, baseContractFunction);
210
- }
211
- }
212
- }
213
-
214
- public getFunctionFromSelector(
215
- selector: Uint8Array
216
- ): ContractFunction | undefined {
217
- return this._selectorHexToFunction.get(bufferToHex(selector));
218
- }
219
-
220
- /**
221
- * We compute selectors manually, which is particularly hard. We do this
222
- * because we need to map selectors to AST nodes, and it seems easier to start
223
- * from the AST node. This is surprisingly super hard: things like inherited
224
- * enums, structs and ABIv2 complicate it.
225
- *
226
- * As we know that that can fail, we run a heuristic that tries to correct
227
- * incorrect selectors. What it does is checking the `evm.methodIdentifiers`
228
- * compiler output, and detect missing selectors. Then we take those and
229
- * find contract functions with the same name. If there are multiple of those
230
- * we can't do anything. If there is a single one, it must have an incorrect
231
- * selector, so we update it with the `evm.methodIdentifiers`'s value.
232
- */
233
- public correctSelector(functionName: string, selector: Buffer): boolean {
234
- const functions = Array.from(this._selectorHexToFunction.values()).filter(
235
- (cf) => cf.name === functionName
236
- );
237
-
238
- if (functions.length !== 1) {
239
- return false;
240
- }
241
-
242
- const functionToCorrect = functions[0];
243
-
244
- if (functionToCorrect.selector !== undefined) {
245
- this._selectorHexToFunction.delete(
246
- bufferToHex(functionToCorrect.selector)
247
- );
248
- }
249
-
250
- functionToCorrect.selector = selector;
251
- this._selectorHexToFunction.set(bufferToHex(selector), functionToCorrect);
252
- return true;
253
- }
254
- }
255
-
256
- export class ContractFunction {
257
- constructor(
258
- public readonly name: string,
259
- public readonly type: ContractFunctionType,
260
- public readonly location: SourceLocation,
261
- public readonly contract?: Contract,
262
- public readonly visibility?: ContractFunctionVisibility,
263
- public readonly isPayable?: boolean,
264
- public selector?: Uint8Array,
265
- public readonly paramTypes?: any[]
266
- ) {
267
- if (contract !== undefined && !contract.location.contains(location)) {
268
- throw new Error("Incompatible contract and function location");
269
- }
270
- }
271
-
272
- public isValidCalldata(calldata: Uint8Array): boolean {
273
- if (this.paramTypes === undefined) {
274
- // if we don't know the param types, we just assume that the call is valid
275
- return true;
276
- }
277
-
278
- return AbiHelpers.isValidCalldata(this.paramTypes, calldata);
279
- }
280
- }
281
-
282
- export class CustomError {
283
- /**
284
- * Return a CustomError from the given ABI information: the name
285
- * of the error and its inputs. Returns undefined if it can't build
286
- * the CustomError.
287
- */
288
- public static fromABI(name: string, inputs: any[]): CustomError | undefined {
289
- const selector = AbiHelpers.computeSelector(name, inputs);
290
-
291
- if (selector !== undefined) {
292
- return new CustomError(selector, name, inputs);
293
- }
294
- }
295
-
296
- private constructor(
297
- public readonly selector: Uint8Array,
298
- public readonly name: string,
299
- public readonly paramTypes: any[]
300
- ) {}
301
- }
302
-
303
- export class Instruction {
304
- constructor(
305
- public readonly pc: number,
306
- public readonly opcode: Opcode,
307
- public readonly jumpType: JumpType,
308
- public readonly pushData?: Buffer,
309
- public readonly location?: SourceLocation
310
- ) {}
311
-
312
- /**
313
- * Checks equality with another Instruction.
314
- */
315
- public equals(other: Instruction): boolean {
316
- if (this.pc !== other.pc) {
317
- return false;
318
- }
319
-
320
- if (this.opcode !== other.opcode) {
321
- return false;
322
- }
323
-
324
- if (this.jumpType !== other.jumpType) {
325
- return false;
326
- }
327
-
328
- if (this.pushData !== undefined) {
329
- if (other.pushData === undefined) {
330
- return false;
331
- }
332
-
333
- if (!this.pushData.equals(other.pushData)) {
334
- return false;
335
- }
336
- } else if (other.pushData !== undefined) {
337
- return false;
338
- }
339
-
340
- if (this.location !== undefined) {
341
- if (other.location === undefined) {
342
- return false;
343
- }
344
-
345
- if (!this.location.equals(other.location)) {
346
- return false;
347
- }
348
- } else if (other.location !== undefined) {
349
- return false;
350
- }
351
-
352
- return true;
353
- }
354
- }
355
-
356
- interface ImmutableReference {
357
- start: number;
358
- length: number;
359
- }
360
-
361
- export class Bytecode {
362
- private readonly _pcToInstruction: Map<number, Instruction> = new Map();
363
-
364
- constructor(
365
- public readonly contract: Contract,
366
- public readonly isDeployment: boolean,
367
- public readonly normalizedCode: Buffer,
368
- public readonly instructions: Instruction[],
369
- public readonly libraryAddressPositions: number[],
370
- public readonly immutableReferences: ImmutableReference[],
371
- public readonly compilerVersion: string
372
- ) {
373
- for (const inst of instructions) {
374
- this._pcToInstruction.set(inst.pc, inst);
375
- }
376
- }
377
-
378
- public getInstruction(pc: number): Instruction {
379
- const inst = this._pcToInstruction.get(pc);
380
-
381
- if (inst === undefined) {
382
- throw new Error(`There's no instruction at pc ${pc}`);
383
- }
384
-
385
- return inst;
386
- }
387
-
388
- public hasInstruction(pc: number): boolean {
389
- return this._pcToInstruction.has(pc);
390
- }
391
-
392
- /**
393
- * Checks equality with another Bytecode.
394
- */
395
- public equals(other: Bytecode): boolean {
396
- if (this._pcToInstruction.size !== other._pcToInstruction.size) {
397
- return false;
398
- }
399
-
400
- for (const [key, val] of this._pcToInstruction) {
401
- const otherVal = other._pcToInstruction.get(key);
402
- if (otherVal === undefined || !val.equals(otherVal)) {
403
- return false;
404
- }
405
- }
406
-
407
- return true;
408
- }
409
- }