mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
jit: preserve return types for recursive calls (#8499)
Assisted-by: Codex:5.6-sol
This commit is contained in:
1 parent
643039de94
commit
9de06ccdb3
3 files changed
+44
-2
No files matched your search
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user