rustc: Use an out pointer to return structs in x86 C ABI. #5347
This Adds a bunch of tests for passing and returning structs of various sizes to C. It fixes the struct return rules on unix, and on windows for structs of size > 8 bytes. Struct passing on unix for structs under a certain size appears to still be broken.
This commit is contained in:
parent
7cd681684f
commit
a5ddc00982
19 changed files with 397 additions and 91 deletions
|
@ -356,7 +356,6 @@ impl NativeHandle<*uvll::uv_write_t> for WriteRequest {
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore(reason = "ffi struct issues")]
|
|
||||||
fn connect_close() {
|
fn connect_close() {
|
||||||
do run_in_bare_thread() {
|
do run_in_bare_thread() {
|
||||||
let mut loop_ = Loop::new();
|
let mut loop_ = Loop::new();
|
||||||
|
@ -409,7 +408,6 @@ fn connect_read() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore(reason = "ffi struct issues")]
|
|
||||||
fn listen() {
|
fn listen() {
|
||||||
do run_in_bare_thread() {
|
do run_in_bare_thread() {
|
||||||
static MAX: int = 10;
|
static MAX: int = 10;
|
||||||
|
|
|
@ -125,27 +125,25 @@ pub enum RealPredicate {
|
||||||
RealPredicateTrue = 15,
|
RealPredicateTrue = 15,
|
||||||
}
|
}
|
||||||
|
|
||||||
// enum for the LLVM TypeKind type - must stay in sync with the def of
|
// The LLVM TypeKind type - must stay in sync with the def of
|
||||||
// LLVMTypeKind in llvm/include/llvm-c/Core.h
|
// LLVMTypeKind in llvm/include/llvm-c/Core.h
|
||||||
#[deriving(Eq)]
|
pub type TypeKind = u32;
|
||||||
pub enum TypeKind {
|
pub static Void: TypeKind = 0;
|
||||||
Void = 0,
|
pub static Half: TypeKind = 1;
|
||||||
Half = 1,
|
pub static Float: TypeKind = 2;
|
||||||
Float = 2,
|
pub static Double: TypeKind = 3;
|
||||||
Double = 3,
|
pub static X86_FP80: TypeKind = 4;
|
||||||
X86_FP80 = 4,
|
pub static FP128: TypeKind = 5;
|
||||||
FP128 = 5,
|
pub static PPC_FP128: TypeKind = 6;
|
||||||
PPC_FP128 = 6,
|
pub static Label: TypeKind = 7;
|
||||||
Label = 7,
|
pub static Integer: TypeKind = 8;
|
||||||
Integer = 8,
|
pub static Function: TypeKind = 9;
|
||||||
Function = 9,
|
pub static Struct: TypeKind = 10;
|
||||||
Struct = 10,
|
pub static Array: TypeKind = 11;
|
||||||
Array = 11,
|
pub static Pointer: TypeKind = 12;
|
||||||
Pointer = 12,
|
pub static Vector: TypeKind = 13;
|
||||||
Vector = 13,
|
pub static Metadata: TypeKind = 14;
|
||||||
Metadata = 14,
|
pub static X86_MMX: TypeKind = 15;
|
||||||
X86_MMX = 15
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum AtomicBinOp {
|
pub enum AtomicBinOp {
|
||||||
Xchg = 0,
|
Xchg = 0,
|
||||||
|
@ -1582,7 +1580,8 @@ pub fn type_to_str_inner(names: @TypeNames, +outer0: &[TypeRef], ty: TypeRef)
|
||||||
}
|
}
|
||||||
Vector => return @"Vector",
|
Vector => return @"Vector",
|
||||||
Metadata => return @"Metadata",
|
Metadata => return @"Metadata",
|
||||||
X86_MMX => return @"X86_MMAX"
|
X86_MMX => return @"X86_MMAX",
|
||||||
|
_ => fail!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,37 +180,3 @@ pub impl FnType {
|
||||||
Ret(bcx, llretval);
|
Ret(bcx, llretval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum LLVM_ABIInfo { LLVM_ABIInfo }
|
|
||||||
|
|
||||||
impl ABIInfo for LLVM_ABIInfo {
|
|
||||||
fn compute_info(&self,
|
|
||||||
atys: &[TypeRef],
|
|
||||||
rty: TypeRef,
|
|
||||||
_ret_def: bool) -> FnType {
|
|
||||||
let arg_tys = do atys.map |a| {
|
|
||||||
LLVMType { cast: false, ty: *a }
|
|
||||||
};
|
|
||||||
let ret_ty = LLVMType {
|
|
||||||
cast: false,
|
|
||||||
ty: rty
|
|
||||||
};
|
|
||||||
let attrs = do atys.map |_| {
|
|
||||||
option::None
|
|
||||||
};
|
|
||||||
let sret = false;
|
|
||||||
|
|
||||||
return FnType {
|
|
||||||
arg_tys: arg_tys,
|
|
||||||
ret_ty: ret_ty,
|
|
||||||
attrs: attrs,
|
|
||||||
sret: sret
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn llvm_abi_info() -> @ABIInfo {
|
|
||||||
return @LLVM_ABIInfo as @ABIInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -227,6 +227,6 @@ impl ABIInfo for MIPS_ABIInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mips_abi_info() -> @ABIInfo {
|
pub fn abi_info() -> @ABIInfo {
|
||||||
return @MIPS_ABIInfo as @ABIInfo;
|
return @MIPS_ABIInfo as @ABIInfo;
|
||||||
}
|
}
|
||||||
|
|
77
src/librustc/middle/trans/cabi_x86.rs
Normal file
77
src/librustc/middle/trans/cabi_x86.rs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
use driver::session::os_win32;
|
||||||
|
use core::option::*;
|
||||||
|
use lib::llvm::*;
|
||||||
|
use lib::llvm::llvm::*;
|
||||||
|
use super::cabi::*;
|
||||||
|
use super::common::*;
|
||||||
|
use super::machine::*;
|
||||||
|
|
||||||
|
struct X86_ABIInfo {
|
||||||
|
ccx: @CrateContext
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ABIInfo for X86_ABIInfo {
|
||||||
|
fn compute_info(&self,
|
||||||
|
atys: &[TypeRef],
|
||||||
|
rty: TypeRef,
|
||||||
|
ret_def: bool) -> FnType {
|
||||||
|
let mut arg_tys = do atys.map |a| {
|
||||||
|
LLVMType { cast: false, ty: *a }
|
||||||
|
};
|
||||||
|
let mut ret_ty = LLVMType {
|
||||||
|
cast: false,
|
||||||
|
ty: rty
|
||||||
|
};
|
||||||
|
let mut attrs = do atys.map |_| {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
// Rules for returning structs taken from
|
||||||
|
// http://www.angelcode.com/dev/callconv/callconv.html
|
||||||
|
let sret = {
|
||||||
|
let returning_a_struct = unsafe { LLVMGetTypeKind(rty) == Struct && ret_def };
|
||||||
|
let big_struct = if self.ccx.sess.targ_cfg.os != os_win32 {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
llsize_of_alloc(self.ccx, rty) > 8
|
||||||
|
};
|
||||||
|
returning_a_struct && big_struct
|
||||||
|
};
|
||||||
|
|
||||||
|
if sret {
|
||||||
|
let ret_ptr_ty = LLVMType {
|
||||||
|
cast: false,
|
||||||
|
ty: T_ptr(ret_ty.ty)
|
||||||
|
};
|
||||||
|
arg_tys = ~[ret_ptr_ty] + arg_tys;
|
||||||
|
attrs = ~[Some(StructRetAttribute)] + attrs;
|
||||||
|
ret_ty = LLVMType {
|
||||||
|
cast: false,
|
||||||
|
ty: T_void(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return FnType {
|
||||||
|
arg_tys: arg_tys,
|
||||||
|
ret_ty: ret_ty,
|
||||||
|
attrs: attrs,
|
||||||
|
sret: sret
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn abi_info(ccx: @CrateContext) -> @ABIInfo {
|
||||||
|
return @X86_ABIInfo {
|
||||||
|
ccx: ccx
|
||||||
|
} as @ABIInfo;
|
||||||
|
}
|
|
@ -410,6 +410,6 @@ impl ABIInfo for X86_64_ABIInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn x86_64_abi_info() -> @ABIInfo {
|
pub fn abi_info() -> @ABIInfo {
|
||||||
return @X86_64_ABIInfo as @ABIInfo;
|
return @X86_64_ABIInfo as @ABIInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,10 @@ use lib::llvm::{TypeRef, ValueRef};
|
||||||
use lib;
|
use lib;
|
||||||
use middle::trans::base::*;
|
use middle::trans::base::*;
|
||||||
use middle::trans::cabi;
|
use middle::trans::cabi;
|
||||||
use middle::trans::cabi_x86_64::*;
|
use middle::trans::cabi_x86;
|
||||||
|
use middle::trans::cabi_x86_64;
|
||||||
use middle::trans::cabi_arm;
|
use middle::trans::cabi_arm;
|
||||||
use middle::trans::cabi_mips::*;
|
use middle::trans::cabi_mips;
|
||||||
use middle::trans::build::*;
|
use middle::trans::build::*;
|
||||||
use middle::trans::callee::*;
|
use middle::trans::callee::*;
|
||||||
use middle::trans::common::*;
|
use middle::trans::common::*;
|
||||||
|
@ -42,12 +43,12 @@ use syntax::abi::{Architecture, X86, X86_64, Arm, Mips};
|
||||||
use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall,
|
use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall,
|
||||||
Cdecl, Aapcs, C};
|
Cdecl, Aapcs, C};
|
||||||
|
|
||||||
fn abi_info(arch: Architecture) -> @cabi::ABIInfo {
|
fn abi_info(ccx: @CrateContext) -> @cabi::ABIInfo {
|
||||||
return match arch {
|
return match ccx.sess.targ_cfg.arch {
|
||||||
X86_64 => x86_64_abi_info(),
|
X86 => cabi_x86::abi_info(ccx),
|
||||||
|
X86_64 => cabi_x86_64::abi_info(),
|
||||||
Arm => cabi_arm::abi_info(),
|
Arm => cabi_arm::abi_info(),
|
||||||
Mips => mips_abi_info(),
|
Mips => cabi_mips::abi_info(),
|
||||||
X86 => cabi::llvm_abi_info()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +113,7 @@ fn shim_types(ccx: @CrateContext, id: ast::node_id) -> ShimTypes {
|
||||||
!ty::type_is_bot(fn_sig.output) &&
|
!ty::type_is_bot(fn_sig.output) &&
|
||||||
!ty::type_is_nil(fn_sig.output);
|
!ty::type_is_nil(fn_sig.output);
|
||||||
let fn_ty =
|
let fn_ty =
|
||||||
abi_info(ccx.sess.targ_cfg.arch).compute_info(
|
abi_info(ccx).compute_info(
|
||||||
llsig.llarg_tys,
|
llsig.llarg_tys,
|
||||||
llsig.llret_ty,
|
llsig.llret_ty,
|
||||||
ret_def);
|
ret_def);
|
||||||
|
|
|
@ -69,6 +69,7 @@ pub mod middle {
|
||||||
pub mod tvec;
|
pub mod tvec;
|
||||||
pub mod meth;
|
pub mod meth;
|
||||||
pub mod cabi;
|
pub mod cabi;
|
||||||
|
pub mod cabi_x86;
|
||||||
pub mod cabi_x86_64;
|
pub mod cabi_x86_64;
|
||||||
pub mod cabi_arm;
|
pub mod cabi_arm;
|
||||||
pub mod cabi_mips;
|
pub mod cabi_mips;
|
||||||
|
|
|
@ -30,26 +30,6 @@ rust_dbg_extern_identity_u64(uint64_t u) {
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TwoU64s {
|
|
||||||
uint64_t one;
|
|
||||||
uint64_t two;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" CDECL TwoU64s
|
|
||||||
rust_dbg_extern_identity_TwoU64s(TwoU64s u) {
|
|
||||||
return u;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TwoDoubles {
|
|
||||||
double one;
|
|
||||||
double two;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" CDECL TwoDoubles
|
|
||||||
rust_dbg_extern_identity_TwoDoubles(TwoDoubles u) {
|
|
||||||
return u;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" CDECL double
|
extern "C" CDECL double
|
||||||
rust_dbg_extern_identity_double(double u) {
|
rust_dbg_extern_identity_double(double u) {
|
||||||
return u;
|
return u;
|
||||||
|
@ -103,3 +83,85 @@ rust_dbg_call(dbg_callback cb, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" CDECL void rust_dbg_do_nothing() { }
|
extern "C" CDECL void rust_dbg_do_nothing() { }
|
||||||
|
|
||||||
|
struct TwoU8s {
|
||||||
|
uint8_t one;
|
||||||
|
uint8_t two;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" CDECL TwoU8s
|
||||||
|
rust_dbg_extern_return_TwoU8s() {
|
||||||
|
struct TwoU8s s;
|
||||||
|
s.one = 10;
|
||||||
|
s.two = 20;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" CDECL TwoU8s
|
||||||
|
rust_dbg_extern_identity_TwoU8s(TwoU8s u) {
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TwoU16s {
|
||||||
|
uint16_t one;
|
||||||
|
uint16_t two;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" CDECL TwoU16s
|
||||||
|
rust_dbg_extern_return_TwoU16s() {
|
||||||
|
struct TwoU16s s;
|
||||||
|
s.one = 10;
|
||||||
|
s.two = 20;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" CDECL TwoU16s
|
||||||
|
rust_dbg_extern_identity_TwoU16s(TwoU16s u) {
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TwoU32s {
|
||||||
|
uint32_t one;
|
||||||
|
uint32_t two;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" CDECL TwoU32s
|
||||||
|
rust_dbg_extern_return_TwoU32s() {
|
||||||
|
struct TwoU32s s;
|
||||||
|
s.one = 10;
|
||||||
|
s.two = 20;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" CDECL TwoU32s
|
||||||
|
rust_dbg_extern_identity_TwoU32s(TwoU32s u) {
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TwoU64s {
|
||||||
|
uint64_t one;
|
||||||
|
uint64_t two;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" CDECL TwoU64s
|
||||||
|
rust_dbg_extern_return_TwoU64s() {
|
||||||
|
struct TwoU64s s;
|
||||||
|
s.one = 10;
|
||||||
|
s.two = 20;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" CDECL TwoU64s
|
||||||
|
rust_dbg_extern_identity_TwoU64s(TwoU64s u) {
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TwoDoubles {
|
||||||
|
double one;
|
||||||
|
double two;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" CDECL TwoDoubles
|
||||||
|
rust_dbg_extern_identity_TwoDoubles(TwoDoubles u) {
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
|
@ -198,8 +198,15 @@ rust_readdir
|
||||||
rust_opendir
|
rust_opendir
|
||||||
rust_dbg_extern_identity_u32
|
rust_dbg_extern_identity_u32
|
||||||
rust_dbg_extern_identity_u64
|
rust_dbg_extern_identity_u64
|
||||||
|
rust_dbg_extern_identity_TwoU8s
|
||||||
|
rust_dbg_extern_identity_TwoU16s
|
||||||
|
rust_dbg_extern_identity_TwoU32s
|
||||||
rust_dbg_extern_identity_TwoU64s
|
rust_dbg_extern_identity_TwoU64s
|
||||||
rust_dbg_extern_identity_TwoDoubles
|
rust_dbg_extern_identity_TwoDoubles
|
||||||
|
rust_dbg_extern_return_TwoU8s
|
||||||
|
rust_dbg_extern_return_TwoU16s
|
||||||
|
rust_dbg_extern_return_TwoU32s
|
||||||
|
rust_dbg_extern_return_TwoU64s
|
||||||
rust_dbg_extern_identity_double
|
rust_dbg_extern_identity_double
|
||||||
rust_dbg_extern_identity_u8
|
rust_dbg_extern_identity_u8
|
||||||
rust_get_rt_env
|
rust_get_rt_env
|
||||||
|
@ -214,4 +221,3 @@ rust_uv_free_ip6_addr
|
||||||
rust_call_nullary_fn
|
rust_call_nullary_fn
|
||||||
rust_initialize_global_state
|
rust_initialize_global_state
|
||||||
|
|
||||||
|
|
||||||
|
|
32
src/test/run-pass/extern-pass-TwoU16s.rs
Normal file
32
src/test/run-pass/extern-pass-TwoU16s.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// Test a foreign function that accepts and returns a struct
|
||||||
|
// by value.
|
||||||
|
|
||||||
|
// xfail-test #5744
|
||||||
|
|
||||||
|
#[deriving(Eq)]
|
||||||
|
struct TwoU16s {
|
||||||
|
one: u16, two: u16
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern {
|
||||||
|
pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
unsafe {
|
||||||
|
let x = TwoU16s {one: 22, two: 23};
|
||||||
|
let y = rust_dbg_extern_identity_TwoU16s(x);
|
||||||
|
assert!(x == y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
30
src/test/run-pass/extern-pass-TwoU32s.rs
Normal file
30
src/test/run-pass/extern-pass-TwoU32s.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// Test a foreign function that accepts and returns a struct
|
||||||
|
// by value.
|
||||||
|
|
||||||
|
#[deriving(Eq)]
|
||||||
|
struct TwoU32s {
|
||||||
|
one: u32, two: u32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern {
|
||||||
|
pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
unsafe {
|
||||||
|
let x = TwoU32s {one: 22, two: 23};
|
||||||
|
let y = rust_dbg_extern_identity_TwoU32s(x);
|
||||||
|
assert!(x == y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
// Test that we ignore modes when calling extern functions.
|
// Test that we ignore modes when calling extern functions.
|
||||||
|
|
||||||
// xfail-test --- broken on 32-bit ABIs! (#5347)
|
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
struct TwoU64s {
|
struct TwoU64s {
|
||||||
one: u64, two: u64
|
one: u64, two: u64
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
// Test a foreign function that accepts and returns a struct
|
// Test a foreign function that accepts and returns a struct
|
||||||
// by value.
|
// by value.
|
||||||
|
|
||||||
// xfail-test --- broken on 32-bit ABIs! (#5347)
|
// xfail-fast This works standalone on windows but not with check-fast. don't know why
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
struct TwoU64s {
|
struct TwoU64s {
|
||||||
|
|
32
src/test/run-pass/extern-pass-TwoU8s.rs
Normal file
32
src/test/run-pass/extern-pass-TwoU8s.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// Test a foreign function that accepts and returns a struct
|
||||||
|
// by value.
|
||||||
|
|
||||||
|
// xfail-test #5744
|
||||||
|
|
||||||
|
#[deriving(Eq)]
|
||||||
|
struct TwoU8s {
|
||||||
|
one: u8, two: u8
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern {
|
||||||
|
pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
unsafe {
|
||||||
|
let x = TwoU8s {one: 22, two: 23};
|
||||||
|
let y = rust_dbg_extern_identity_TwoU8s(x);
|
||||||
|
assert!(x == y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
27
src/test/run-pass/extern-return-TwoU16s.rs
Normal file
27
src/test/run-pass/extern-return-TwoU16s.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// xfail-win32 #5745
|
||||||
|
|
||||||
|
struct TwoU16s {
|
||||||
|
one: u16, two: u16
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern {
|
||||||
|
pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
unsafe {
|
||||||
|
let y = rust_dbg_extern_return_TwoU16s();
|
||||||
|
assert!(y.one == 10);
|
||||||
|
assert!(y.two == 20);
|
||||||
|
}
|
||||||
|
}
|
25
src/test/run-pass/extern-return-TwoU32s.rs
Normal file
25
src/test/run-pass/extern-return-TwoU32s.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
struct TwoU32s {
|
||||||
|
one: u32, two: u32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern {
|
||||||
|
pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
unsafe {
|
||||||
|
let y = rust_dbg_extern_return_TwoU32s();
|
||||||
|
assert!(y.one == 10);
|
||||||
|
assert!(y.two == 20);
|
||||||
|
}
|
||||||
|
}
|
25
src/test/run-pass/extern-return-TwoU64s.rs
Normal file
25
src/test/run-pass/extern-return-TwoU64s.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
struct TwoU64s {
|
||||||
|
one: u64, two: u64
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern {
|
||||||
|
pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
unsafe {
|
||||||
|
let y = rust_dbg_extern_return_TwoU64s();
|
||||||
|
assert!(y.one == 10);
|
||||||
|
assert!(y.two == 20);
|
||||||
|
}
|
||||||
|
}
|
27
src/test/run-pass/extern-return-TwoU8s.rs
Normal file
27
src/test/run-pass/extern-return-TwoU8s.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// xfail-win32 #5745
|
||||||
|
|
||||||
|
struct TwoU8s {
|
||||||
|
one: u8, two: u8
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern {
|
||||||
|
pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
unsafe {
|
||||||
|
let y = rust_dbg_extern_return_TwoU8s();
|
||||||
|
assert!(y.one == 10);
|
||||||
|
assert!(y.two == 20);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue