Bytecode & VM: Making It Run

  • Connect each source statement to stack and scope effects.
  • Patch absolute jumps and preserve caller operands across function execution.
  • Distinguish a VM stack result from discarded source expression statements.
1 / 6

Readiness

  • Finish v2 parsing and name analysis.
  • Trace expression postfix instructions.
2 / 6

Worked reconstruction

Compile let x=3; while (x>1) { x=x-1; }:

0 PUSH_NUM 3       1 DEFINE_VAR x
2 LOAD x           3 PUSH_NUM 1       4 GT
5 JUMP_IF_FALSE 13
6 ENTER_SCOPE      7 LOAD x           8 PUSH_NUM 1
9 SUB             10 STORE x        11 EXIT_SCOPE
12 JUMP 2

A target of 13 is the legal one-past-end exit in this code slice. At x=3 and x=2 the test consumes two numeric operands and produces true; the conditional jump consumes that boolean. Each body returns to the same stack height and exits its scope. At x=1 the jump exits. The final operand stack is empty, so Run returns nil. Changing the back edge from 2 to 0 would reset x forever.

3 / 6

Diagnose before implementing

A while loop leaves one condition value on the stack after every test, and a program ending in f(); unexpectedly returns f’s result. Identify the two missing stack effects.

4 / 6

Independent transfer

Replace the worked loop body with a nested block containing a shadowing declaration. Trace which x each LOAD/STORE sees and verify the outer loop still progresses. Independently hand-author bytecode computing 17-5 to test right-then-left pops.

5 / 6

Carry forward

Carry an executable Bytecode object into BC1 serialization. Preserve the instruction-index trace as a comparison point after decoding.

6 / 6
←/→ or click edges to navigate · ? help · N notes · F fullscreen