use cranelift::prelude::*;
use cranelift_codegen::ir::BlockArg;
use cranelift_jit::{JITBuilder, JITModule};
use cranelift_module::{Linkage, Module};
#[test]
fn tier_a_pure_function_add() {
println!("\n=== Tier A: Pure function (add) ===\n");
let source = "pub fn add(a: i32, b: i32) -> i32 { a + b }";
let item: syn::ItemFn = syn::parse_str(source).expect("failed to parse");
println!(
"Parsed: fn {}({} params) -> i32",
item.sig.ident,
item.sig.inputs.len()
);
let mut flag_builder = settings::builder();
flag_builder.set("use_colocated_libcalls", "false").unwrap();
flag_builder.set("is_pic", "false").unwrap();
let isa_builder = cranelift_native::builder().expect("host ISA");
let isa = isa_builder
.finish(settings::Flags::new(flag_builder))
.expect("ISA");
let builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
let mut module = JITModule::new(builder);
let mut sig = module.make_signature();
sig.params.push(AbiParam::new(types::I64));
sig.params.push(AbiParam::new(types::I64));
sig.returns.push(AbiParam::new(types::I64));
let func_id = module
.declare_function("add", Linkage::Local, &sig)
.expect("declare");
let mut ctx = module.make_context();
ctx.func.signature = sig;
let mut func_ctx = FunctionBuilderContext::new();
{
let mut builder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
let entry = builder.create_block();
builder.append_block_params_for_function_params(entry);
builder.switch_to_block(entry);
builder.seal_block(entry);
let a = builder.block_params(entry)[0];
let b = builder.block_params(entry)[1];
let result = builder.ins().iadd(a, b);
builder.ins().return_(&[result]);
builder.finalize();
}
module.define_function(func_id, &mut ctx).expect("define");
module.clear_context(&mut ctx);
module.finalize_definitions().expect("finalize");
let code_ptr = module.get_finalized_function(func_id);
let add_fn: fn(i64, i64) -> i64 = unsafe { std::mem::transmute(code_ptr) };
let result = add_fn(2, 3);
println!("add(2, 3) = {result}");
assert_eq!(result, 5, "Tier A: add(2, 3) should equal 5");
assert_eq!(add_fn(0, 0), 0);
assert_eq!(add_fn(-1, 1), 0);
assert_eq!(add_fn(100, 200), 300);
println!("TIER A: PASS ✓");
}
#[test]
fn tier_a_pure_function_multiply() {
println!("\n=== Tier A bonus: Pure function (multiply) ===\n");
let source = "pub fn multiply(a: i32, b: i32) -> i32 { a * b }";
let _item: syn::ItemFn = syn::parse_str(source).expect("parse");
let mut flag_builder = settings::builder();
flag_builder.set("use_colocated_libcalls", "false").unwrap();
flag_builder.set("is_pic", "false").unwrap();
let isa = cranelift_native::builder()
.unwrap()
.finish(settings::Flags::new(flag_builder))
.unwrap();
let builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
let mut module = JITModule::new(builder);
let mut sig = module.make_signature();
sig.params.push(AbiParam::new(types::I64));
sig.params.push(AbiParam::new(types::I64));
sig.returns.push(AbiParam::new(types::I64));
let func_id = module
.declare_function("multiply", Linkage::Local, &sig)
.unwrap();
let mut ctx = module.make_context();
ctx.func.signature = sig;
let mut func_ctx = FunctionBuilderContext::new();
{
let mut b = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
let entry = b.create_block();
b.append_block_params_for_function_params(entry);
b.switch_to_block(entry);
b.seal_block(entry);
let a = b.block_params(entry)[0];
let bv = b.block_params(entry)[1];
let result = b.ins().imul(a, bv);
b.ins().return_(&[result]);
b.finalize();
}
module.define_function(func_id, &mut ctx).unwrap();
module.clear_context(&mut ctx);
module.finalize_definitions().unwrap();
let code_ptr = module.get_finalized_function(func_id);
let mul_fn: fn(i64, i64) -> i64 = unsafe { std::mem::transmute(code_ptr) };
assert_eq!(mul_fn(3, 4), 12);
assert_eq!(mul_fn(0, 100), 0);
assert_eq!(mul_fn(-2, 5), -10);
println!("TIER A BONUS (multiply): PASS ✓");
}
#[test]
fn tier_a_conditional_max() {
println!("\n=== Tier A: Conditional (max) ===\n");
let source = "pub fn max(a: i32, b: i32) -> i32 { if a > b { a } else { b } }";
let _item: syn::ItemFn = syn::parse_str(source).expect("parse");
let mut flag_builder = settings::builder();
flag_builder.set("use_colocated_libcalls", "false").unwrap();
flag_builder.set("is_pic", "false").unwrap();
let isa = cranelift_native::builder()
.unwrap()
.finish(settings::Flags::new(flag_builder))
.unwrap();
let builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
let mut module = JITModule::new(builder);
let mut sig = module.make_signature();
sig.params.push(AbiParam::new(types::I64));
sig.params.push(AbiParam::new(types::I64));
sig.returns.push(AbiParam::new(types::I64));
let func_id = module
.declare_function("max", Linkage::Local, &sig)
.unwrap();
let mut ctx = module.make_context();
ctx.func.signature = sig;
let mut func_ctx = FunctionBuilderContext::new();
{
let mut b = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
let entry = b.create_block();
let then_block = b.create_block();
let else_block = b.create_block();
let merge_block = b.create_block();
b.append_block_params_for_function_params(entry);
b.append_block_param(merge_block, types::I64);
b.switch_to_block(entry);
let a = b.block_params(entry)[0];
let bv = b.block_params(entry)[1];
let cmp = b.ins().icmp(IntCC::SignedGreaterThan, a, bv);
b.ins().brif(cmp, then_block, &[], else_block, &[]);
b.switch_to_block(then_block);
b.seal_block(then_block);
b.ins().jump(merge_block, &[BlockArg::Value(a)]);
b.switch_to_block(else_block);
b.seal_block(else_block);
b.ins().jump(merge_block, &[BlockArg::Value(bv)]);
b.switch_to_block(merge_block);
b.seal_block(merge_block);
b.seal_block(entry);
let result = b.block_params(merge_block)[0];
b.ins().return_(&[result]);
b.finalize();
}
module.define_function(func_id, &mut ctx).unwrap();
module.clear_context(&mut ctx);
module.finalize_definitions().unwrap();
let code_ptr = module.get_finalized_function(func_id);
let max_fn: fn(i64, i64) -> i64 = unsafe { std::mem::transmute(code_ptr) };
assert_eq!(max_fn(5, 3), 5);
assert_eq!(max_fn(3, 5), 5);
assert_eq!(max_fn(7, 7), 7);
assert_eq!(max_fn(-1, -5), -1);
println!("TIER A CONDITIONAL (max): PASS ✓");
}
#[test]
fn tier_b_flattened_struct_operations() {
println!("\n=== Tier B: Struct-like data via flattened params ===\n");
let mut flag_builder = settings::builder();
flag_builder.set("use_colocated_libcalls", "false").unwrap();
flag_builder.set("is_pic", "false").unwrap();
let isa = cranelift_native::builder()
.unwrap()
.finish(settings::Flags::new(flag_builder))
.unwrap();
let builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
let mut module = JITModule::new(builder);
let mut sig = module.make_signature();
for _ in 0..4 {
sig.params.push(AbiParam::new(types::I64));
}
sig.returns.push(AbiParam::new(types::I64));
let func_id = module
.declare_function("distance_sq", Linkage::Local, &sig)
.unwrap();
let mut ctx = module.make_context();
ctx.func.signature = sig;
let mut func_ctx = FunctionBuilderContext::new();
{
let mut b = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
let entry = b.create_block();
b.append_block_params_for_function_params(entry);
b.switch_to_block(entry);
b.seal_block(entry);
let px = b.block_params(entry)[0];
let py = b.block_params(entry)[1];
let qx = b.block_params(entry)[2];
let qy = b.block_params(entry)[3];
let dx = b.ins().isub(px, qx);
let dy = b.ins().isub(py, qy);
let dx2 = b.ins().imul(dx, dx);
let dy2 = b.ins().imul(dy, dy);
let result = b.ins().iadd(dx2, dy2);
b.ins().return_(&[result]);
b.finalize();
}
module.define_function(func_id, &mut ctx).unwrap();
module.clear_context(&mut ctx);
module.finalize_definitions().unwrap();
let code_ptr = module.get_finalized_function(func_id);
let dist_fn: fn(i64, i64, i64, i64) -> i64 = unsafe { std::mem::transmute(code_ptr) };
assert_eq!(dist_fn(0, 0, 3, 4), 25);
assert_eq!(dist_fn(1, 1, 1, 1), 0);
assert_eq!(dist_fn(0, 0, 1, 0), 1);
println!("TIER B FLATTENED STRUCT (distance_sq): PASS ✓");
}
#[test]
fn tier_b_cross_function_call() {
println!("\n=== Tier B: Cross-function call (simulating cross-module import) ===\n");
let mut flag_builder = settings::builder();
flag_builder.set("use_colocated_libcalls", "false").unwrap();
flag_builder.set("is_pic", "false").unwrap();
let isa = cranelift_native::builder()
.unwrap()
.finish(settings::Flags::new(flag_builder))
.unwrap();
let builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
let mut module = JITModule::new(builder);
let mut sig1 = module.make_signature();
sig1.params.push(AbiParam::new(types::I64));
sig1.returns.push(AbiParam::new(types::I64));
let double_id = module
.declare_function("double", Linkage::Local, &sig1)
.unwrap();
let mut sig2 = module.make_signature();
sig2.params.push(AbiParam::new(types::I64));
sig2.returns.push(AbiParam::new(types::I64));
let quad_id = module
.declare_function("quadruple", Linkage::Local, &sig2)
.unwrap();
{
let mut ctx = module.make_context();
ctx.func.signature = sig1;
let mut func_ctx = FunctionBuilderContext::new();
let mut b = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
let entry = b.create_block();
b.append_block_params_for_function_params(entry);
b.switch_to_block(entry);
b.seal_block(entry);
let x = b.block_params(entry)[0];
let two = b.ins().iconst(types::I64, 2);
let result = b.ins().imul(x, two);
b.ins().return_(&[result]);
b.finalize();
module.define_function(double_id, &mut ctx).unwrap();
}
{
let mut ctx = module.make_context();
ctx.func.signature = sig2;
let mut func_ctx = FunctionBuilderContext::new();
let mut b = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
let entry = b.create_block();
b.append_block_params_for_function_params(entry);
b.switch_to_block(entry);
b.seal_block(entry);
let x = b.block_params(entry)[0];
let double_ref = module.declare_func_in_func(double_id, b.func);
let call1 = b.ins().call(double_ref, &[x]);
let intermediate = b.inst_results(call1)[0];
let call2 = b.ins().call(double_ref, &[intermediate]);
let result = b.inst_results(call2)[0];
b.ins().return_(&[result]);
b.finalize();
module.define_function(quad_id, &mut ctx).unwrap();
}
module.finalize_definitions().unwrap();
let quad_ptr = module.get_finalized_function(quad_id);
let quadruple: fn(i64) -> i64 = unsafe { std::mem::transmute(quad_ptr) };
assert_eq!(quadruple(5), 20);
assert_eq!(quadruple(0), 0);
assert_eq!(quadruple(-3), -12);
println!("TIER B CROSS-FUNCTION CALL (quadruple): PASS ✓");
}
#[test]
fn tier_c_nontrivial_computation_pattern() {
println!("\n=== Tier C: NuSy-like computation pattern ===\n");
let mut flag_builder = settings::builder();
flag_builder.set("use_colocated_libcalls", "false").unwrap();
flag_builder.set("is_pic", "false").unwrap();
let isa = cranelift_native::builder()
.unwrap()
.finish(settings::Flags::new(flag_builder))
.unwrap();
let builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
let mut module = JITModule::new(builder);
let mut sig_score = module.make_signature();
sig_score.params.push(AbiParam::new(types::F64));
sig_score.params.push(AbiParam::new(types::F64));
sig_score.returns.push(AbiParam::new(types::F64));
let score_id = module
.declare_function("schema_match_score", Linkage::Local, &sig_score)
.unwrap();
let mut sig_dec = module.make_signature();
sig_dec.params.push(AbiParam::new(types::F64));
sig_dec.returns.push(AbiParam::new(types::I64));
let dec_id = module
.declare_function("schema_decision", Linkage::Local, &sig_dec)
.unwrap();
{
let mut ctx = module.make_context();
ctx.func.signature = sig_score;
let mut func_ctx = FunctionBuilderContext::new();
let mut b = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
let entry = b.create_block();
b.append_block_params_for_function_params(entry);
b.switch_to_block(entry);
b.seal_block(entry);
let fractal = b.block_params(entry)[0];
let coverage = b.block_params(entry)[1];
let w1 = b.ins().f64const(0.7);
let w2 = b.ins().f64const(0.3);
let term1 = b.ins().fmul(w1, fractal);
let term2 = b.ins().fmul(w2, coverage);
let score = b.ins().fadd(term1, term2);
b.ins().return_(&[score]);
b.finalize();
module.define_function(score_id, &mut ctx).unwrap();
}
{
let mut ctx = module.make_context();
ctx.func.signature = sig_dec;
let mut func_ctx = FunctionBuilderContext::new();
let mut b = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
let entry = b.create_block();
let assimilate_block = b.create_block();
let check_low = b.create_block();
let accommodate_block = b.create_block();
let standard_block = b.create_block();
b.append_block_params_for_function_params(entry);
b.switch_to_block(entry);
let score = b.block_params(entry)[0];
let high_threshold = b.ins().f64const(0.7);
let is_high = b.ins().fcmp(FloatCC::GreaterThan, score, high_threshold);
b.ins().brif(is_high, assimilate_block, &[], check_low, &[]);
b.switch_to_block(assimilate_block);
b.seal_block(assimilate_block);
let zero = b.ins().iconst(types::I64, 0); b.ins().return_(&[zero]);
b.switch_to_block(check_low);
b.seal_block(check_low);
let low_threshold = b.ins().f64const(0.3);
let is_low = b.ins().fcmp(FloatCC::LessThan, score, low_threshold);
b.ins()
.brif(is_low, accommodate_block, &[], standard_block, &[]);
b.switch_to_block(accommodate_block);
b.seal_block(accommodate_block);
let two = b.ins().iconst(types::I64, 2); b.ins().return_(&[two]);
b.switch_to_block(standard_block);
b.seal_block(standard_block);
b.seal_block(entry);
let one = b.ins().iconst(types::I64, 1); b.ins().return_(&[one]);
b.finalize();
module.define_function(dec_id, &mut ctx).unwrap();
}
module.finalize_definitions().unwrap();
let score_fn: fn(f64, f64) -> f64 =
unsafe { std::mem::transmute(module.get_finalized_function(score_id)) };
let decision_fn: fn(f64) -> i64 =
unsafe { std::mem::transmute(module.get_finalized_function(dec_id)) };
let s1 = score_fn(1.0, 1.0); assert!((s1 - 1.0).abs() < 1e-10, "expected 1.0, got {s1}");
let s2 = score_fn(0.0, 0.0); assert!((s2).abs() < 1e-10, "expected 0.0, got {s2}");
let s3 = score_fn(0.5, 0.5); assert!((s3 - 0.5).abs() < 1e-10, "expected 0.5, got {s3}");
assert_eq!(decision_fn(0.9), 0, "high score → assimilate (0)");
assert_eq!(decision_fn(0.5), 1, "mid score → standard (1)");
assert_eq!(decision_fn(0.1), 2, "low score → accommodate (2)");
let score = score_fn(0.9, 0.8); assert!((score - 0.87).abs() < 1e-10);
assert_eq!(decision_fn(score), 0, "high schema match → assimilate");
let score2 = score_fn(0.1, 0.1); assert_eq!(decision_fn(score2), 2, "low schema match → accommodate");
println!("TIER C COMPUTATION PATTERN (schema_match): PASS ✓");
println!();
println!("=== Tier C Assessment ===");
println!("Cranelift CAN handle the computational patterns of NuSy functions:");
println!(" - Multi-parameter arithmetic (weighted sums)");
println!(" - Floating-point operations (f64)");
println!(" - Multi-branch conditionals (if/else/else)");
println!(" - Cross-function calls (composition)");
println!();
println!("Cranelift CANNOT handle (without a Rust frontend):");
println!(" - Rust type system (structs, enums, traits, generics)");
println!(" - Borrow checking / lifetime analysis");
println!(" - Monomorphization of generic functions");
println!(" - Standard library calls (String, Vec, HashMap, etc.)");
println!(" - Pattern matching on enums");
println!();
println!("VERDICT: Tier C PARTIAL PASS");
println!(" Cranelift works for hot-path numerical functions (signal assessors,");
println!(" scoring, fusion weights). NOT viable as a general Rust compiler.");
println!(" Recommendation: HYBRID approach — Cranelift for hot-path DSL functions,");
println!(" materialization (Path B) for full crate compilation.");
}
#[test]
fn spike_summary() {
println!("\n========================================");
println!("EX-3108: Cranelift/WASM JIT Spike Results");
println!("========================================\n");
println!("Tier A (pure functions): PASS");
println!(" - add, multiply, max (conditional)");
println!(" - syn parses, Cranelift compiles, JIT executes correctly\n");
println!("Tier B (struct-like + cross-module): PASS");
println!(" - Flattened struct operations (distance_sq)");
println!(" - Cross-function calls (quadruple = double(double(x)))");
println!(" - Simulates cross-module imports via multi-function JIT\n");
println!("Tier C (real NuSy complexity): PARTIAL PASS");
println!(" - Computational PATTERNS work (weighted sums, branches, f64)");
println!(" - Rust TYPE SYSTEM does not (no structs, traits, generics)");
println!(" - Cranelift is a code generator, not a Rust compiler\n");
println!("RECOMMENDATION: Hybrid approach for V13");
println!(" - Path A (Cranelift): Hot-path numerical functions (assessors, scoring)");
println!(" - Path B (materialization): Full crate compilation");
println!(" - Content-addressed cache bridges both (EX-3091, already done)\n");
}