Exercise 1: Hand-Computing a Backpatched Jump — Possible Solution ==================================================================== THE DISASSEMBLY ------------------------------ 0000 OP_CONSTANT 0 '1.0' 0002 OP_CONSTANT 1 '2.0' 0004 OP_LESS 0005 OP_JUMP_IF_FALSE 3 -> offset 11 0008 OP_CONSTANT 2 '100.0' 0010 OP_PRINT 0011 OP_RETURN HAND COMPUTATION ------------------------------ emit_jump(OP_JUMP_IF_FALSE) runs immediately after the condition (1 < 2) has been compiled, i.e. after offset 4 (OP_LESS, 1 byte). It writes: offset 5: OP_JUMP_IF_FALSE (1 byte) offset 6: 0xff (placeholder high byte) offset 7: 0xff (placeholder low byte) returning jump_pos = len(code) - 2 = 8 - 2 = 6. The then-branch (print 100;) then compiles: offset 8: OP_CONSTANT (1 byte) offset 9: constant index 2 (1 byte) offset 10: OP_PRINT (1 byte) At the point patch_jump(6) runs, len(chunk.code) == 11 (offsets 0 through 10 have been written; OP_RETURN hasn't been appended yet -- that happens after compile_program's own loop finishes). offset = len(chunk.code) - jump_pos - 2 = 11 - 6 - 2 = 3 chunk.code[6] = (3 >> 8) & 0xFF = 0 chunk.code[7] = 3 & 0xFF = 3 RESULT ------------------------------ Matches the disassembly exactly: jump distance 3, and the reported target offset is 11 (offset 5 + 3 header bytes for OP_JUMP_IF_FALSE itself + 3 = 11) -- which is exactly where OP_RETURN sits, i.e. exactly past the then-branch, confirming the jump correctly skips the print when the condition is false. WHY THIS WORKS AS AN ANSWER ------------------------------ The "+2" in patch_jump's own offset formula exists because the distance needs to be measured from the END of the jump instruction (after its own 2 operand bytes), not from where the opcode byte itself sits -- the VM's own ip has already advanced past both operand bytes by the time it applies the offset. Getting this off by one in either direction is the single easiest way to introduce a bug in a backpatching compiler, which is exactly why disassembling and independently recomputing the expected value, as this exercise does, is worth doing by hand at least once rather than trusting the code was written correctly on the first try.