Merge pull request #4650 from FranciscoTGouveia/f32/64-native-func-calls
Support `f32`/`f64` in native function calls
This commit is contained in:
commit
8fef16e2a6
3 changed files with 22 additions and 2 deletions
|
|
@ -8,10 +8,12 @@ use libffi::middle::Type as FfiType;
|
|||
use rustc_abi::{HasDataLayout, Size};
|
||||
use rustc_data_structures::either;
|
||||
use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout};
|
||||
use rustc_middle::ty::{self, IntTy, Ty, UintTy};
|
||||
use rustc_middle::ty::{self, FloatTy, IntTy, Ty, UintTy};
|
||||
use rustc_span::Symbol;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use self::helpers::ToSoft;
|
||||
|
||||
mod ffi;
|
||||
|
||||
#[cfg_attr(
|
||||
|
|
@ -138,6 +140,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
let x = unsafe { ffi::call::<usize>(fun, libffi_args) };
|
||||
Scalar::from_target_usize(x.try_into().unwrap(), this)
|
||||
}
|
||||
ty::Float(FloatTy::F32) => {
|
||||
let x = unsafe { ffi::call::<f32>(fun, libffi_args) };
|
||||
Scalar::from_f32(x.to_soft())
|
||||
}
|
||||
ty::Float(FloatTy::F64) => {
|
||||
let x = unsafe { ffi::call::<f64>(fun, libffi_args) };
|
||||
Scalar::from_f64(x.to_soft())
|
||||
}
|
||||
// Functions with no declared return type (i.e., the default return)
|
||||
// have the output_type `Tuple([])`.
|
||||
ty::Tuple(t_list) if (*t_list).deref().is_empty() => {
|
||||
|
|
@ -396,7 +406,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
/// Gets the matching libffi type for a given Ty.
|
||||
fn ty_to_ffitype(&self, layout: TyAndLayout<'tcx>) -> InterpResult<'tcx, FfiType> {
|
||||
use rustc_abi::{AddressSpace, BackendRepr, Integer, Primitive};
|
||||
use rustc_abi::{AddressSpace, BackendRepr, Float, Integer, Primitive};
|
||||
|
||||
// `BackendRepr::Scalar` is also a signal to pass this type as a scalar in the ABI. This
|
||||
// matches what codegen does. This does mean that we support some types whose ABI is not
|
||||
|
|
@ -413,6 +423,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
Primitive::Int(Integer::I16, /* signed */ false) => FfiType::u16(),
|
||||
Primitive::Int(Integer::I32, /* signed */ false) => FfiType::u32(),
|
||||
Primitive::Int(Integer::I64, /* signed */ false) => FfiType::u64(),
|
||||
Primitive::Float(Float::F32) => FfiType::f32(),
|
||||
Primitive::Float(Float::F64) => FfiType::f64(),
|
||||
Primitive::Pointer(AddressSpace::ZERO) => FfiType::pointer(),
|
||||
_ =>
|
||||
throw_unsup_format!(
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ extern "C" {
|
|||
) -> i32;
|
||||
fn add_short_to_long(x: i16, y: i64) -> i64;
|
||||
fn get_unsigned_int() -> u32;
|
||||
fn add_float(x: f32) -> f32;
|
||||
fn printer();
|
||||
}
|
||||
|
||||
|
|
@ -37,6 +38,9 @@ fn main() {
|
|||
// test function that returns -10 as an unsigned int
|
||||
assert_eq!(get_unsigned_int(), (-10i32) as u32);
|
||||
|
||||
// test function that adds 1.5 to a f32
|
||||
assert_eq!(add_float(1.0f32), 2.5f32);
|
||||
|
||||
// test void function that prints from C
|
||||
printer();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ EXPORT int64_t add_short_to_long(int16_t x, int64_t y) {
|
|||
return x + y;
|
||||
}
|
||||
|
||||
EXPORT float add_float(float x) {
|
||||
return x + 1.5f;
|
||||
}
|
||||
|
||||
// To test that functions not marked with EXPORT cannot be called by Miri.
|
||||
int32_t not_exported(void) {
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue