v5 Capstone: Full Pipeline
- 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.
1 / 6
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.
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?
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 the multi-module BC2 baseline into v6. The runtime and linker remain useful; new static contracts reject additional source programs before those stages run.