v5 Capstone: Full Pipeline
Work through examples, try the reasoning yourself, then put it into practice.
View SlidesBefore you start
- Complete v5 module parsing, dynamic semantics, compilation, and relocation.
What you will practice
- Trace multi-module initialization through BC2 and a fresh VM.
- Test relocation with control flow in a later module.
- Separate name/export validity from dynamic call checks.
In this lesson
Lesson
3 min readv5 Capstone: Full Pipeline
The integration path now adds real separate compilation and linking:
Lex → Parse → Analyze → CompileModules → Link → Encode → Decode → NewVM().Run
CompileModules and Encode return artifacts directly. Link, Decode, and Run can return errors. Analyze still returns diagnostic strings, not static type annotations; v5 is dynamically typed.
Worked reconstruction
module util { export fn add(a,b){ return a+b; } }
module main {
import util as u;
let total=0;
for (let i=0; i<3; i=i+1) { total=u.add(total,i); }
if (total!=3) { 1/0; }
}
util's initializer constructs and exports a closure. main's initializer loads that export map, then runs a loop. Both modules started with local function IDs and local Main instruction coordinates. Link shifts main's Main jump operands by util's initializer length, while preserving function-local jumps. Decode reconstructs the merged artifact. The VM initializes util before main, and the assertion proves total reached 3. Normal completion returns nil.
A straight-line main might pass with a broken linker because no Main jump uses the missing offset. This program is deliberately a transfer test combining v4 control flow with v5 separate compilation.
First-failure discipline
Malformed syntax fails before module resolution. Unknown imports, inaccessible exports, invalid loop transfers, and name errors fail analysis. The linker also validates its independent artifact inputs, but source rejected by Analyze should never reach it. Imported-member call arity remains a runtime check in v5; do not replace examples with v6 typed function syntax or promise v6 errors.
Encode and Decode form the BC2 transport boundary. A round trip supplements independent instruction/relocation tests; it cannot prove that both sides did not preserve the same wrong address. Execute only the decoded object with a fresh VM, and return earlier errors without fallback execution.
Integration gate
Keep a library closure, a later initializer branch/loop, an unknown export, and repeated Link on saved artifacts. Add a declaration whose value export can differ from a later mutation of its captured environment. Explain the observed module semantics before moving to static types.
Debugging lab
A v5 program with two modules works until a for loop is added to main. The same loop works in implicit-main mode. Which boundary is the strongest first suspect and which two offsets should be inspected?
Compare your diagnosis after attempting the lab
Inspect Link: multi-module Main concatenation relocates instruction addresses, while implicit main starts at offset zero. Check Main-length relocation separately from function-count relocation; correct closure IDs do not prove correct branches.
Transfer task
Add a second library importing the first, then put a nested closure and a while loop in the final module. Assert a numeric result through a conditional failure and compare repeated runs and repeated linking of the saved module artifacts.
Carry forward
Carry the multi-module BC2 baseline into v6. The runtime and linker remain useful; new static contracts reject additional source programs before those stages run.
Build compile-and-run-v5. Keep a before/after trace of one failing test. Use the checkpoint to diagnose specific skills; passing it does not replace implementing and testing the artifact.
Practice sequence
Use the order below for a guided path, or choose an item to revisit. A pass records a successful attempt; try a fresh example later to check what you can reconstruct.
- Step 1
Compile and Run v5 (Capstone)
- Step 2
v5 Capstone: Full Pipeline Checkpoint
Predict fresh artifacts, diagnose a broken invariant, and test a version boundary. Select one answer per multiple-choice question; numeric responses use the stated integer format. Use review links to revisit the relevant representation, then attempt the independent transfer task.