1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Regression tests for the default engine flip: bytecode register VM is the
// default execution path, Cranelift JIT is opt-in via `--jit`. Tree
// interpreter remains the canonical-semantics fallback for any program the VM
// rejects.
//
// Pre-flip: default tried Cranelift JIT first then fell back to the VM on
// every NotEligible bailout, paying compile-and-bail cost on programs that
// touch any opcode the JIT can't yet handle (OP_WINDOW_VIEW pre-#386,
// OP_LEN_HAS_K_COUNT, OP_MAKE_CLOSURE for Phase 2 captures pre-#385). After
// the flip, default goes straight to the VM; agents opt into the JIT
// explicitly for hot numeric loops.
//
// What we assert:
// 1. `ilo file.ilo` (default) and `ilo file.ilo --vm` produce
// identical stdout for a VM-supported workload.
// 2. `ilo file.ilo --jit` runs the workload and produces correct output
// (the JIT opt-in flag works).
// 3. Default invocation of a JIT-eligible workload completes WITHOUT a
// JIT-fallback breadcrumb on stderr (proves we're using the VM
// directly, not JIT-then-fallback).
use std::process::Command;
fn ilo() -> Command {
Command::new(env!("CARGO_BIN_EXE_ilo"))
}
fn run_args(args: &[&str]) -> (String, String, i32) {
let out = ilo().args(args).output().expect("failed to run ilo");
(
String::from_utf8_lossy(&out.stdout).trim().to_string(),
String::from_utf8_lossy(&out.stderr).to_string(),
out.status.code().unwrap_or(-1),
)
}
// A VM-supported numeric workload (Cranelift-eligible too — used to assert
// parity between default and `--vm`).
const NUMERIC_SRC: &str = "main x:n>n;y=*x 2;+y 1";
// A modern workload that exercises OP_WINDOW_VIEW (post-#386 Cranelift can
// JIT this, but historically bailed). Used to assert "no breadcrumb" on the
// default path — proves we are not even *attempting* the JIT.
const WINDOW_SRC: &str = "main>n;xs=[1,2,3,4,5];ws=window 3 xs;len ws";
// Modern workload exercising OP_LEN_HAS_K_COUNT (the fused len-of-filter
// peephole from #346). Tree/VM both run it; default must run it without a
// JIT breadcrumb.
const LEN_HAS_K_SRC: &str = "f x:n>b;>x 2\nmain>n;xs=[1,2,3,4,5];len (flt f xs)";
#[test]
fn default_matches_run_vm_numeric() {
let (default_out, _, default_code) = run_args(&[NUMERIC_SRC, "main", "7"]);
let (vm_out, _, vm_code) = run_args(&["--vm", NUMERIC_SRC, "main", "7"]);
assert_eq!(default_code, 0, "default exit");
assert_eq!(vm_code, 0, "--vm exit");
assert_eq!(default_out, "15");
assert_eq!(default_out, vm_out, "default vs --vm parity");
}
#[test]
fn jit_flag_runs_numeric() {
let (out, _, code) = run_args(&["--jit", NUMERIC_SRC, "main", "7"]);
assert_eq!(code, 0, "--jit exit");
assert_eq!(out, "15");
}
#[test]
fn default_does_not_emit_jit_fallback_breadcrumb_on_window() {
// OP_WINDOW_VIEW workload. If the default were still JIT-first, this
// would either succeed via the post-#386 JIT path or fall back through
// the NotEligible arm. Either way, on the new VM-direct default we must
// observe no `[ilo:jit-fallback]` breadcrumb because the JIT is never
// invoked at all.
let (out, stderr, code) = run_args(&[WINDOW_SRC, "main"]);
assert_eq!(code, 0, "exit, stderr={stderr}");
assert_eq!(out, "3");
assert!(
!stderr.contains("[ilo:jit-fallback]"),
"default path must not invoke JIT, stderr={stderr:?}",
);
}
#[test]
fn default_does_not_emit_jit_fallback_breadcrumb_on_len_has() {
let (out, stderr, code) = run_args(&[LEN_HAS_K_SRC, "main"]);
assert_eq!(code, 0, "exit, stderr={stderr}");
assert_eq!(out, "3");
assert!(
!stderr.contains("[ilo:jit-fallback]"),
"default path must not invoke JIT, stderr={stderr:?}",
);
}
#[test]
fn default_matches_run_vm_on_window() {
let (default_out, _, default_code) = run_args(&[WINDOW_SRC, "main"]);
let (vm_out, _, vm_code) = run_args(&["--vm", WINDOW_SRC, "main"]);
assert_eq!(default_code, 0);
assert_eq!(vm_code, 0);
assert_eq!(default_out, vm_out, "default and --vm must agree");
}