Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions examples/jit-io-roundtrip.ilo
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-- Cross-engine I/O round-trip: write/read text and lines, parse JSONL,
-- and format/parse a timestamp. Pins that the Cranelift JIT helpers
-- jit_rd/jit_rdl/jit_wr/jit_wrl/jit_jpar/jit_rdjl/jit_dtfmt/jit_dtparse
-- agree with tree/VM on success, and that their type-error paths now
-- surface VmError::Type through JIT_RUNTIME_ERROR instead of silently
-- returning nil. (The type-error paths are unit-tested directly; this
-- file pins the happy paths so the examples harness exercises them on
-- every engine.)

text-roundtrip>t;w=wr!! "/tmp/ilo-jit-io-roundtrip-text.txt" "hello";rd!! "/tmp/ilo-jit-io-roundtrip-text.txt"

lines-roundtrip>n;w=wrl!! "/tmp/ilo-jit-io-roundtrip-lines.txt" ["a" "b" "c"];es=rdl!! "/tmp/ilo-jit-io-roundtrip-lines.txt";len es

jsonl-count>n;p="/tmp/ilo-jit-io-roundtrip.jsonl";w=wrl!! p ["{\"k\":1}" "{\"k\":2}"];es=rdjl p;len es

dt-format>t;dtfmt!! 0 "%Y-%m-%d"

dt-parse>n;dtparse!! "1970-01-01" "%Y-%m-%d"

-- run: text-roundtrip
-- out: hello

-- run: lines-roundtrip
-- out: 3

-- run: jsonl-count
-- out: 2

-- run: dt-format
-- out: 1970-01-01

-- run: dt-parse
-- out: 0
48 changes: 32 additions & 16 deletions src/vm/compile_cranelift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@ fn declare_all_helpers(module: &mut ObjectModule) -> HelperFuncs {
listget: declare_helper(module, "jit_listget", 2, 1),
jpth: declare_helper(module, "jit_jpth", 2, 1),
jdmp: declare_helper(module, "jit_jdmp", 1, 1),
jpar: declare_helper(module, "jit_jpar", 1, 1),
rdjl: declare_helper(module, "jit_rdjl", 1, 1),
jpar: declare_helper(module, "jit_jpar", 2, 1),
rdjl: declare_helper(module, "jit_rdjl", 2, 1),
call: declare_helper(module, "jit_call", 4, 1),
// Type predicates
isnum: declare_helper(module, "jit_isnum", 1, 1),
Expand Down Expand Up @@ -338,17 +338,17 @@ fn declare_all_helpers(module: &mut ObjectModule) -> HelperFuncs {
partition: declare_helper(module, "jit_partition", 2, 1),
frq: declare_helper(module, "jit_frq", 1, 1),
// File I/O
rd: declare_helper(module, "jit_rd", 1, 1),
rdl: declare_helper(module, "jit_rdl", 1, 1),
wr: declare_helper(module, "jit_wr", 2, 1),
wrl: declare_helper(module, "jit_wrl", 2, 1),
rd: declare_helper(module, "jit_rd", 2, 1),
rdl: declare_helper(module, "jit_rdl", 2, 1),
wr: declare_helper(module, "jit_wr", 3, 1),
wrl: declare_helper(module, "jit_wrl", 3, 1),
// HTTP
post: declare_helper(module, "jit_post", 2, 1),
geth: declare_helper(module, "jit_geth", 2, 1),
posth: declare_helper(module, "jit_posth", 3, 1),
getmany: declare_helper(module, "jit_getmany", 1, 1),
dtfmt: declare_helper(module, "jit_dtfmt", 2, 1),
dtparse: declare_helper(module, "jit_dtparse", 2, 1),
dtfmt: declare_helper(module, "jit_dtfmt", 3, 1),
dtparse: declare_helper(module, "jit_dtparse", 3, 1),
call_builtin_tree: declare_helper(module, "jit_call_builtin_tree", 3, 1),
call_dyn: declare_helper(module, "jit_call_dyn", 3, 1),
panic_unwrap: declare_helper(module, "jit_panic_unwrap", 1, 1),
Expand Down Expand Up @@ -3378,31 +3378,39 @@ fn compile_function_body(
}
OP_JPAR => {
let bv = builder.use_var(vars[b_idx]);
let span_bits = super::jit_cranelift::pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.jpar);
let call_inst = builder.ins().call(fref, &[bv]);
let call_inst = builder.ins().call(fref, &[bv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
OP_RDJL => {
let bv = builder.use_var(vars[b_idx]);
let span_bits = super::jit_cranelift::pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.rdjl);
let call_inst = builder.ins().call(fref, &[bv]);
let call_inst = builder.ins().call(fref, &[bv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
OP_DTFMT => {
let bv = builder.use_var(vars[b_idx]);
let cv = builder.use_var(vars[c_idx]);
let span_bits = super::jit_cranelift::pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.dtfmt);
let call_inst = builder.ins().call(fref, &[bv, cv]);
let call_inst = builder.ins().call(fref, &[bv, cv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
OP_DTPARSE => {
let bv = builder.use_var(vars[b_idx]);
let cv = builder.use_var(vars[c_idx]);
let span_bits = super::jit_cranelift::pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.dtparse);
let call_inst = builder.ins().call(fref, &[bv, cv]);
let call_inst = builder.ins().call(fref, &[bv, cv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
Expand Down Expand Up @@ -3612,31 +3620,39 @@ fn compile_function_body(
// ── File I/O ──
OP_RD => {
let bv = builder.use_var(vars[b_idx]);
let span_bits = super::jit_cranelift::pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.rd);
let call_inst = builder.ins().call(fref, &[bv]);
let call_inst = builder.ins().call(fref, &[bv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
OP_RDL => {
let bv = builder.use_var(vars[b_idx]);
let span_bits = super::jit_cranelift::pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.rdl);
let call_inst = builder.ins().call(fref, &[bv]);
let call_inst = builder.ins().call(fref, &[bv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
OP_WR => {
let bv = builder.use_var(vars[b_idx]);
let cv = builder.use_var(vars[c_idx]);
let span_bits = super::jit_cranelift::pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.wr);
let call_inst = builder.ins().call(fref, &[bv, cv]);
let call_inst = builder.ins().call(fref, &[bv, cv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
OP_WRL => {
let bv = builder.use_var(vars[b_idx]);
let cv = builder.use_var(vars[c_idx]);
let span_bits = super::jit_cranelift::pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.wrl);
let call_inst = builder.ins().call(fref, &[bv, cv]);
let call_inst = builder.ins().call(fref, &[bv, cv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
Expand Down
48 changes: 32 additions & 16 deletions src/vm/jit_cranelift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,8 +482,8 @@ fn declare_all_helpers(module: &mut JITModule) -> HelperFuncs {
listget: declare_helper(module, "jit_listget", 2, 1),
jpth: declare_helper(module, "jit_jpth", 2, 1),
jdmp: declare_helper(module, "jit_jdmp", 1, 1),
jpar: declare_helper(module, "jit_jpar", 1, 1),
rdjl: declare_helper(module, "jit_rdjl", 1, 1),
jpar: declare_helper(module, "jit_jpar", 2, 1),
rdjl: declare_helper(module, "jit_rdjl", 2, 1),
call: declare_helper(module, "jit_call", 4, 1),
// Type predicates
isnum: declare_helper(module, "jit_isnum", 1, 1),
Expand Down Expand Up @@ -515,10 +515,10 @@ fn declare_all_helpers(module: &mut JITModule) -> HelperFuncs {
partition: declare_helper(module, "jit_partition", 2, 1),
frq: declare_helper(module, "jit_frq", 1, 1),
// File I/O
rd: declare_helper(module, "jit_rd", 1, 1),
rdl: declare_helper(module, "jit_rdl", 1, 1),
wr: declare_helper(module, "jit_wr", 2, 1),
wrl: declare_helper(module, "jit_wrl", 2, 1),
rd: declare_helper(module, "jit_rd", 2, 1),
rdl: declare_helper(module, "jit_rdl", 2, 1),
wr: declare_helper(module, "jit_wr", 3, 1),
wrl: declare_helper(module, "jit_wrl", 3, 1),
// HTTP
post: declare_helper(module, "jit_post", 2, 1),
geth: declare_helper(module, "jit_geth", 2, 1),
Expand All @@ -528,8 +528,8 @@ fn declare_all_helpers(module: &mut JITModule) -> HelperFuncs {
solve: declare_helper(module, "jit_solve", 3, 1),
inv: declare_helper(module, "jit_inv", 2, 1),
det: declare_helper(module, "jit_det", 2, 1),
dtfmt: declare_helper(module, "jit_dtfmt", 2, 1),
dtparse: declare_helper(module, "jit_dtparse", 2, 1),
dtfmt: declare_helper(module, "jit_dtfmt", 3, 1),
dtparse: declare_helper(module, "jit_dtparse", 3, 1),
call_builtin_tree: declare_helper(module, "jit_call_builtin_tree", 3, 1),
call_dyn: declare_helper(module, "jit_call_dyn", 3, 1),
}
Expand Down Expand Up @@ -3957,31 +3957,39 @@ fn compile_function_body(
}
OP_JPAR => {
let bv = builder.use_var(vars[b_idx]);
let span_bits = pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.jpar);
let call_inst = builder.ins().call(fref, &[bv]);
let call_inst = builder.ins().call(fref, &[bv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
OP_RDJL => {
let bv = builder.use_var(vars[b_idx]);
let span_bits = pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.rdjl);
let call_inst = builder.ins().call(fref, &[bv]);
let call_inst = builder.ins().call(fref, &[bv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
OP_DTFMT => {
let bv = builder.use_var(vars[b_idx]);
let cv = builder.use_var(vars[c_idx]);
let span_bits = pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.dtfmt);
let call_inst = builder.ins().call(fref, &[bv, cv]);
let call_inst = builder.ins().call(fref, &[bv, cv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
OP_DTPARSE => {
let bv = builder.use_var(vars[b_idx]);
let cv = builder.use_var(vars[c_idx]);
let span_bits = pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.dtparse);
let call_inst = builder.ins().call(fref, &[bv, cv]);
let call_inst = builder.ins().call(fref, &[bv, cv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
Expand Down Expand Up @@ -4188,31 +4196,39 @@ fn compile_function_body(
// ── File I/O ──
OP_RD => {
let bv = builder.use_var(vars[b_idx]);
let span_bits = pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.rd);
let call_inst = builder.ins().call(fref, &[bv]);
let call_inst = builder.ins().call(fref, &[bv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
OP_RDL => {
let bv = builder.use_var(vars[b_idx]);
let span_bits = pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.rdl);
let call_inst = builder.ins().call(fref, &[bv]);
let call_inst = builder.ins().call(fref, &[bv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
OP_WR => {
let bv = builder.use_var(vars[b_idx]);
let cv = builder.use_var(vars[c_idx]);
let span_bits = pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.wr);
let call_inst = builder.ins().call(fref, &[bv, cv]);
let call_inst = builder.ins().call(fref, &[bv, cv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
OP_WRL => {
let bv = builder.use_var(vars[b_idx]);
let cv = builder.use_var(vars[c_idx]);
let span_bits = pack_span_bits(chunk.spans[ip]);
let span_arg = builder.ins().iconst(I64, span_bits);
let fref = get_func_ref(&mut builder, module, helpers.wrl);
let call_inst = builder.ins().call(fref, &[bv, cv]);
let call_inst = builder.ins().call(fref, &[bv, cv, span_arg]);
let result = builder.inst_results(call_inst)[0];
builder.def_var(vars[a_idx], result);
}
Expand Down
Loading
Loading