Skip to content
Open
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
16 changes: 14 additions & 2 deletions src/shims/native_lib/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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() => {
Expand Down Expand Up @@ -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
Expand All @@ -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!(
Expand Down
4 changes: 4 additions & 0 deletions tests/native-lib/pass/scalar_arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand All @@ -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();
}
Expand Down
4 changes: 4 additions & 0 deletions tests/native-lib/scalar_arguments.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down