Skip to content

Commit b3fc3a1

Browse files
committed
bugc: add debug contexts to all remaining unmapped bytecodes
Thread remark/code contexts through all compiler-generated instructions that previously lacked debug info: - Free memory pointer initialization (remark) - Return value spill after call continuation (call expr source range) - STOP guard between main and user functions (remark) - Function prologue MSTORE for param storage (thread existing remark) - Function prologue return PC save sequence (thread existing remark) - Deployment wrapper CODECOPY+RETURN (remark) All 82 instructions across runtime and create programs now carry debug contexts (previously 22 were unmapped).
1 parent 8864511 commit b3fc3a1

File tree

3 files changed

+70
-23
lines changed

3 files changed

+70
-23
lines changed

packages/bugc/src/evmgen/generation/block.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ export function generate<S extends Stack>(
104104
predBlock.terminator.dest
105105
) {
106106
const destId = predBlock.terminator.dest;
107+
const spillDebug = predBlock.terminator.operationDebug;
107108
result = result.then(annotateTop(destId)).then((s) => {
108109
const allocation = s.memory.allocations[destId];
109110
if (!allocation) return s;
@@ -112,16 +113,25 @@ export function generate<S extends Stack>(
112113
...s,
113114
instructions: [
114115
...s.instructions,
115-
{ mnemonic: "DUP1" as const, opcode: 0x80 },
116+
{
117+
mnemonic: "DUP1" as const,
118+
opcode: 0x80,
119+
debug: spillDebug,
120+
},
116121
{
117122
mnemonic: "PUSH2" as const,
118123
opcode: 0x61,
119124
immediates: [
120125
(allocation.offset >> 8) & 0xff,
121126
allocation.offset & 0xff,
122127
],
128+
debug: spillDebug,
129+
},
130+
{
131+
mnemonic: "MSTORE" as const,
132+
opcode: 0x52,
133+
debug: spillDebug,
123134
},
124-
{ mnemonic: "MSTORE" as const, opcode: 0x52 },
125135
],
126136
};
127137
});
@@ -212,14 +222,22 @@ function initializeMemory<S extends Stack>(
212222
): Transition<S, S> {
213223
const { PUSHn, MSTORE } = operations;
214224

215-
return (
216-
pipe<S>()
217-
// Push the static offset value (the value to store)
218-
.then(PUSHn(BigInt(nextStaticOffset)), { as: "value" })
219-
// Push the free memory pointer location (0x40) (the offset)
220-
.then(PUSHn(BigInt(Memory.regions.FREE_MEMORY_POINTER)), { as: "offset" })
221-
// Store the initial free pointer (expects [value, offset] on stack)
222-
.then(MSTORE())
223-
.done()
224-
);
225+
const debug = {
226+
context: {
227+
remark: "initialize free memory pointer",
228+
},
229+
};
230+
231+
return pipe<S>()
232+
.then(PUSHn(BigInt(nextStaticOffset), { debug }), {
233+
as: "value",
234+
})
235+
.then(
236+
PUSHn(BigInt(Memory.regions.FREE_MEMORY_POINTER), {
237+
debug,
238+
}),
239+
{ as: "offset" },
240+
)
241+
.then(MSTORE({ debug }))
242+
.done();
225243
}

packages/bugc/src/evmgen/generation/function.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,11 @@ function generatePrologue<S extends Stack>(
104104
...currentState,
105105
instructions: [
106106
...currentState.instructions,
107-
{ mnemonic: "MSTORE", opcode: 0x52 },
107+
{
108+
mnemonic: "MSTORE",
109+
opcode: 0x52,
110+
debug: prologueDebug,
111+
},
108112
],
109113
};
110114
}
@@ -130,13 +134,22 @@ function generatePrologue<S extends Stack>(
130134
immediates: [0x60],
131135
debug: savePcDebug,
132136
},
133-
{ mnemonic: "MLOAD", opcode: 0x51 },
137+
{
138+
mnemonic: "MLOAD",
139+
opcode: 0x51,
140+
debug: savePcDebug,
141+
},
134142
{
135143
mnemonic: "PUSH2",
136144
opcode: 0x61,
137145
immediates: [highByte, lowByte],
146+
debug: savePcDebug,
147+
},
148+
{
149+
mnemonic: "MSTORE",
150+
opcode: 0x52,
151+
debug: savePcDebug,
138152
},
139-
{ mnemonic: "MSTORE", opcode: 0x52 },
140153
],
141154
};
142155
}

packages/bugc/src/evmgen/generation/module.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,17 @@ export function generate(
107107
// STOP (the isLastBlock optimization).
108108
const stopGuard: Evm.Instruction[] =
109109
patchedFunctions.length > 0
110-
? [{ mnemonic: "STOP" as const, opcode: 0x00 }]
110+
? [
111+
{
112+
mnemonic: "STOP" as const,
113+
opcode: 0x00,
114+
debug: {
115+
context: {
116+
remark: "guard: prevent fall-through into functions",
117+
},
118+
},
119+
},
120+
]
111121
: [];
112122
const stopGuardBytes: number[] = patchedFunctions.length > 0 ? [0x00] : [];
113123

@@ -243,13 +253,19 @@ function buildDeploymentInstructions(
243253
function deploymentTransition(runtimeOffset: bigint, runtimeLength: bigint) {
244254
const { PUSHn, CODECOPY, RETURN } = operations;
245255

256+
const debug = {
257+
context: {
258+
remark: "deployment: copy runtime bytecode and return",
259+
},
260+
};
261+
246262
return pipe()
247-
.then(PUSHn(runtimeLength), { as: "size" })
248-
.then(PUSHn(runtimeOffset), { as: "offset" })
249-
.then(PUSHn(0n), { as: "destOffset" })
250-
.then(CODECOPY())
251-
.then(PUSHn(runtimeLength), { as: "size" })
252-
.then(PUSHn(0n), { as: "offset" })
253-
.then(RETURN())
263+
.then(PUSHn(runtimeLength, { debug }), { as: "size" })
264+
.then(PUSHn(runtimeOffset, { debug }), { as: "offset" })
265+
.then(PUSHn(0n, { debug }), { as: "destOffset" })
266+
.then(CODECOPY({ debug }))
267+
.then(PUSHn(runtimeLength, { debug }), { as: "size" })
268+
.then(PUSHn(0n, { debug }), { as: "offset" })
269+
.then(RETURN({ debug }))
254270
.done();
255271
}

0 commit comments

Comments
 (0)