Skip to content

Fix i686 struct returning in some scenarios #5726

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
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
3 changes: 2 additions & 1 deletion mk/rt.mk
Original file line number Diff line number Diff line change
@@ -76,7 +76,8 @@ RUNTIME_CXXS_$(1) := \
rt/boxed_region.cpp \
rt/arch/$$(HOST_$(1))/context.cpp \
rt/arch/$$(HOST_$(1))/gpr.cpp \
rt/rust_android_dummy.cpp
rt/rust_android_dummy.cpp \
rt/rust_test_helpers.cpp

RUNTIME_CS_$(1) := rt/linenoise/linenoise.c rt/linenoise/utf8.c

2 changes: 0 additions & 2 deletions src/libcore/rt/uv/net.rs
Original file line number Diff line number Diff line change
@@ -356,7 +356,6 @@ impl NativeHandle<*uvll::uv_write_t> for WriteRequest {


#[test]
#[ignore(reason = "ffi struct issues")]
fn connect_close() {
do run_in_bare_thread() {
let mut loop_ = Loop::new();
@@ -409,7 +408,6 @@ fn connect_read() {
}

#[test]
#[ignore(reason = "ffi struct issues")]
fn listen() {
do run_in_bare_thread() {
static MAX: int = 10;
41 changes: 20 additions & 21 deletions src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
@@ -125,27 +125,25 @@ pub enum RealPredicate {
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
#[deriving(Eq)]
pub enum TypeKind {
Void = 0,
Half = 1,
Float = 2,
Double = 3,
X86_FP80 = 4,
FP128 = 5,
PPC_FP128 = 6,
Label = 7,
Integer = 8,
Function = 9,
Struct = 10,
Array = 11,
Pointer = 12,
Vector = 13,
Metadata = 14,
X86_MMX = 15
}
pub type TypeKind = u32;
pub static Void: TypeKind = 0;
pub static Half: TypeKind = 1;
pub static Float: TypeKind = 2;
pub static Double: TypeKind = 3;
pub static X86_FP80: TypeKind = 4;
pub static FP128: TypeKind = 5;
pub static PPC_FP128: TypeKind = 6;
pub static Label: TypeKind = 7;
pub static Integer: TypeKind = 8;
pub static Function: TypeKind = 9;
pub static Struct: TypeKind = 10;
pub static Array: TypeKind = 11;
pub static Pointer: TypeKind = 12;
pub static Vector: TypeKind = 13;
pub static Metadata: TypeKind = 14;
pub static X86_MMX: TypeKind = 15;

pub enum AtomicBinOp {
Xchg = 0,
@@ -1582,7 +1580,8 @@ pub fn type_to_str_inner(names: @TypeNames, +outer0: &[TypeRef], ty: TypeRef)
}
Vector => return @"Vector",
Metadata => return @"Metadata",
X86_MMX => return @"X86_MMAX"
X86_MMX => return @"X86_MMAX",
_ => fail!()
}
}
}
34 changes: 0 additions & 34 deletions src/librustc/middle/trans/cabi.rs
Original file line number Diff line number Diff line change
@@ -180,37 +180,3 @@ pub impl FnType {
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;
}


2 changes: 1 addition & 1 deletion src/librustc/middle/trans/cabi_mips.rs
Original file line number Diff line number Diff line change
@@ -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;
}
77 changes: 77 additions & 0 deletions src/librustc/middle/trans/cabi_x86.rs
Original file line number Diff line number Diff line change
@@ -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;
}
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/cabi_x86_64.rs
Original file line number Diff line number Diff line change
@@ -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;
}
17 changes: 9 additions & 8 deletions src/librustc/middle/trans/foreign.rs
Original file line number Diff line number Diff line change
@@ -16,9 +16,10 @@ use lib::llvm::{TypeRef, ValueRef};
use lib;
use middle::trans::base::*;
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_mips::*;
use middle::trans::cabi_mips;
use middle::trans::build::*;
use middle::trans::callee::*;
use middle::trans::common::*;
@@ -42,12 +43,12 @@ use syntax::abi::{Architecture, X86, X86_64, Arm, Mips};
use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall,
Cdecl, Aapcs, C};

fn abi_info(arch: Architecture) -> @cabi::ABIInfo {
return match arch {
X86_64 => x86_64_abi_info(),
fn abi_info(ccx: @CrateContext) -> @cabi::ABIInfo {
return match ccx.sess.targ_cfg.arch {
X86 => cabi_x86::abi_info(ccx),
X86_64 => cabi_x86_64::abi_info(),
Arm => cabi_arm::abi_info(),
Mips => mips_abi_info(),
X86 => cabi::llvm_abi_info()
Mips => cabi_mips::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_nil(fn_sig.output);
let fn_ty =
abi_info(ccx.sess.targ_cfg.arch).compute_info(
abi_info(ccx).compute_info(
llsig.llarg_tys,
llsig.llret_ty,
ret_def);
1 change: 1 addition & 0 deletions src/librustc/rustc.rc
Original file line number Diff line number Diff line change
@@ -69,6 +69,7 @@ pub mod middle {
pub mod tvec;
pub mod meth;
pub mod cabi;
pub mod cabi_x86;
pub mod cabi_x86_64;
pub mod cabi_arm;
pub mod cabi_mips;
86 changes: 0 additions & 86 deletions src/rt/rust_builtin.cpp
Original file line number Diff line number Diff line change
@@ -589,50 +589,6 @@ rust_log_console_off() {
log_console_off(task->kernel->env);
}

extern "C" CDECL lock_and_signal *
rust_dbg_lock_create() {
return new lock_and_signal();
}

extern "C" CDECL void
rust_dbg_lock_destroy(lock_and_signal *lock) {
assert(lock);
delete lock;
}

extern "C" CDECL void
rust_dbg_lock_lock(lock_and_signal *lock) {
assert(lock);
lock->lock();
}

extern "C" CDECL void
rust_dbg_lock_unlock(lock_and_signal *lock) {
assert(lock);
lock->unlock();
}

extern "C" CDECL void
rust_dbg_lock_wait(lock_and_signal *lock) {
assert(lock);
lock->wait();
}

extern "C" CDECL void
rust_dbg_lock_signal(lock_and_signal *lock) {
assert(lock);
lock->signal();
}

typedef void *(*dbg_callback)(void*);

extern "C" CDECL void *
rust_dbg_call(dbg_callback cb, void *data) {
return cb(data);
}

extern "C" CDECL void rust_dbg_do_nothing() { }

extern "C" CDECL void
rust_dbg_breakpoint() {
BREAKPOINT_AWESOME;
@@ -844,48 +800,6 @@ rust_readdir() {

#endif

// These functions are used in the unit tests for C ABI calls.

extern "C" CDECL uint32_t
rust_dbg_extern_identity_u32(uint32_t u) {
return u;
}

extern "C" CDECL uint64_t
rust_dbg_extern_identity_u64(uint64_t 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
rust_dbg_extern_identity_double(double u) {
return u;
}

extern "C" CDECL char
rust_dbg_extern_identity_u8(char u) {
return u;
}

extern "C" rust_env*
rust_get_rt_env() {
rust_task *task = rust_get_current_task();
Loading