jit: preserve return types for recursive calls (#8499)

Assisted-by: Codex:5.6-sol
This commit is contained in:
Jeaeun Kim authored and GitHub committed 2026-08-12 16:24:44 +09:00
1 parent dc19be06f2
commit 980be72e4f
3 files changed
+44 -2

No files matched your search

+16 -2
View File
@@ -548,8 +548,22 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
match self.stack.pop().ok_or(JitCompileError::BadBytecode)? {
JitValue::FuncRef(reference) => {
let call = self.builder.ins().call(reference, &args);
let returns = self.builder.inst_results(call);
self.stack.push(JitValue::Int(returns[0]));
// The only callable reachable here is this function itself,
// so the result carries the declared return type - it is not
// always an Int. A function whose return type is still
// unknown has no return slot in the signature it was
// declared with, and there is nothing to type the result as.
let ret = match *self.builder.inst_results(call) {
[] => None,
[val] => Some(val),
_ => return Err(JitCompileError::NotSupported),
};
let val = match (self.sig.ret.clone(), ret) {
(Some(JitType::None), None) => JitValue::None,
(Some(ty), Some(val)) => JitValue::from_type_and_value(ty, val),
_ => return Err(JitCompileError::NotSupported),
};
self.stack.push(val);
Ok(())
}
+14
View File
@@ -202,4 +202,18 @@ mod tests {
assert_eq!(lte(false, 1), Ok(1));
assert_eq!(lte(true, 0), Ok(0));
}
#[test]
fn recursive_bool() {
let recursive_bool = jit_function! { recursive_bool(n: i64) -> bool => r##"
def recursive_bool(n: int) -> bool:
if n == 0:
return True
return not recursive_bool(n - 1)
"## };
assert_eq!(recursive_bool(0), Ok(true));
assert_eq!(recursive_bool(1), Ok(false));
assert_eq!(recursive_bool(4), Ok(true));
}
}
+14
View File
@@ -379,4 +379,18 @@ mod tests {
assert_eq!(float_lte(f64::NAN, f64::NAN), Ok(false));
assert_eq!(float_lte(f64::INFINITY, f64::NEG_INFINITY), Ok(false));
}
#[test]
fn recursive_float() {
let recursive_float = jit_function! { recursive_float(n: i64) -> f64 => r##"
def recursive_float(n: int) -> float:
if n == 0:
return 1.0
return recursive_float(n - 1) / 2.0
"## };
assert_eq!(recursive_float(0), Ok(1.0));
assert_eq!(recursive_float(1), Ok(0.5));
assert_eq!(recursive_float(4), Ok(0.0625));
}
}