libgreen: use FFI-safe types

This commit is contained in:
Corey Richardson
2014-08-14 15:49:26 -04:00
parent 2dc2ac1e6b
commit cf5d28083d
4 changed files with 45 additions and 31 deletions

View File

@@ -40,6 +40,7 @@
#[experimental] #[experimental]
#[simd] #[simd]
#[deriving(Show)] #[deriving(Show)]
#[repr(C)]
pub struct i8x16(pub i8, pub i8, pub i8, pub i8, pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8,
pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8,
@@ -48,22 +49,26 @@ pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
#[experimental] #[experimental]
#[simd] #[simd]
#[deriving(Show)] #[deriving(Show)]
#[repr(C)]
pub struct i16x8(pub i16, pub i16, pub i16, pub i16, pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
pub i16, pub i16, pub i16, pub i16); pub i16, pub i16, pub i16, pub i16);
#[experimental] #[experimental]
#[simd] #[simd]
#[deriving(Show)] #[deriving(Show)]
#[repr(C)]
pub struct i32x4(pub i32, pub i32, pub i32, pub i32); pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
#[experimental] #[experimental]
#[simd] #[simd]
#[deriving(Show)] #[deriving(Show)]
#[repr(C)]
pub struct i64x2(pub i64, pub i64); pub struct i64x2(pub i64, pub i64);
#[experimental] #[experimental]
#[simd] #[simd]
#[deriving(Show)] #[deriving(Show)]
#[repr(C)]
pub struct u8x16(pub u8, pub u8, pub u8, pub u8, pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
@@ -72,25 +77,30 @@ pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
#[experimental] #[experimental]
#[simd] #[simd]
#[deriving(Show)] #[deriving(Show)]
#[repr(C)]
pub struct u16x8(pub u16, pub u16, pub u16, pub u16, pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
pub u16, pub u16, pub u16, pub u16); pub u16, pub u16, pub u16, pub u16);
#[experimental] #[experimental]
#[simd] #[simd]
#[deriving(Show)] #[deriving(Show)]
#[repr(C)]
pub struct u32x4(pub u32, pub u32, pub u32, pub u32); pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
#[experimental] #[experimental]
#[simd] #[simd]
#[deriving(Show)] #[deriving(Show)]
#[repr(C)]
pub struct u64x2(pub u64, pub u64); pub struct u64x2(pub u64, pub u64);
#[experimental] #[experimental]
#[simd] #[simd]
#[deriving(Show)] #[deriving(Show)]
#[repr(C)]
pub struct f32x4(pub f32, pub f32, pub f32, pub f32); pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
#[experimental] #[experimental]
#[simd] #[simd]
#[deriving(Show)] #[deriving(Show)]
#[repr(C)]
pub struct f64x2(pub f64, pub f64); pub struct f64x2(pub f64, pub f64);

View File

@@ -15,6 +15,7 @@ use std::rt::stack;
use std::raw; use std::raw;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use std::simd; use std::simd;
use libc;
// FIXME #7761: Registers is boxed so that it is 16-byte aligned, for storing // FIXME #7761: Registers is boxed so that it is 16-byte aligned, for storing
// SSE regs. It would be marginally better not to do this. In C++ we // SSE regs. It would be marginally better not to do this. In C++ we
@@ -69,7 +70,7 @@ impl Context {
// overflow). Additionally, their coroutine stacks are listed as being // overflow). Additionally, their coroutine stacks are listed as being
// zero-length, so that's how we detect what's what here. // zero-length, so that's how we detect what's what here.
let stack_base: *const uint = stack.start(); let stack_base: *const uint = stack.start();
let bounds = if sp as uint == stack_base as uint { let bounds = if sp as libc::uintptr_t == stack_base as libc::uintptr_t {
None None
} else { } else {
Some((stack_base as uint, sp as uint)) Some((stack_base as uint, sp as uint))
@@ -165,16 +166,16 @@ fn new_regs() -> Box<Registers> {
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]
fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint, fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
procedure: raw::Procedure, sp: *mut uint) { procedure: raw::Procedure, sp: *mut libc::uintptr_t) {
// x86 has interesting stack alignment requirements, so do some alignment // x86 has interesting stack alignment requirements, so do some alignment
// plus some offsetting to figure out what the actual stack should be. // plus some offsetting to figure out what the actual stack should be.
let sp = align_down(sp); let sp = align_down(sp);
let sp = mut_offset(sp, -4); let sp = mut_offset(sp, -4);
unsafe { *mut_offset(sp, 2) = procedure.env as uint }; unsafe { *mut_offset(sp, 2) = procedure.env as libc::uintptr_t };
unsafe { *mut_offset(sp, 1) = procedure.code as uint }; unsafe { *mut_offset(sp, 1) = procedure.code as libc::uintptr_t };
unsafe { *mut_offset(sp, 0) = arg as uint }; unsafe { *mut_offset(sp, 0) = arg as libc::uintptr_t };
let sp = mut_offset(sp, -1); let sp = mut_offset(sp, -1);
unsafe { *sp = 0 }; // The final return address unsafe { *sp = 0 }; // The final return address
@@ -188,13 +189,15 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
// windows requires saving more registers (both general and XMM), so the windows // windows requires saving more registers (both general and XMM), so the windows
// register context must be larger. // register context must be larger.
#[cfg(windows, target_arch = "x86_64")] #[cfg(windows, target_arch = "x86_64")]
#[repr(C)]
struct Registers { struct Registers {
gpr:[uint, ..14], gpr:[libc::uintptr_t, ..14],
_xmm:[simd::u32x4, ..10] _xmm:[simd::u32x4, ..10]
} }
#[cfg(not(windows), target_arch = "x86_64")] #[cfg(not(windows), target_arch = "x86_64")]
#[repr(C)]
struct Registers { struct Registers {
gpr:[uint, ..10], gpr:[libc::uintptr_t, ..10],
_xmm:[simd::u32x4, ..6] _xmm:[simd::u32x4, ..6]
} }
@@ -234,30 +237,30 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
unsafe { *sp = 0; } unsafe { *sp = 0; }
rtdebug!("creating call frame"); rtdebug!("creating call frame");
rtdebug!("fptr {:#x}", fptr as uint); rtdebug!("fptr {:#x}", fptr as libc::uintptr_t);
rtdebug!("arg {:#x}", arg); rtdebug!("arg {:#x}", arg);
rtdebug!("sp {}", sp); rtdebug!("sp {}", sp);
// These registers are frobbed by rust_bootstrap_green_task into the right // These registers are frobbed by rust_bootstrap_green_task into the right
// location so we can invoke the "real init function", `fptr`. // location so we can invoke the "real init function", `fptr`.
regs.gpr[RUSTRT_R12] = arg as uint; regs.gpr[RUSTRT_R12] = arg as libc::uintptr_t;
regs.gpr[RUSTRT_R13] = procedure.code as uint; regs.gpr[RUSTRT_R13] = procedure.code as libc::uintptr_t;
regs.gpr[RUSTRT_R14] = procedure.env as uint; regs.gpr[RUSTRT_R14] = procedure.env as libc::uintptr_t;
regs.gpr[RUSTRT_R15] = fptr as uint; regs.gpr[RUSTRT_R15] = fptr as libc::uintptr_t;
// These registers are picked up by the regular context switch paths. These // These registers are picked up by the regular context switch paths. These
// will put us in "mostly the right context" except for frobbing all the // will put us in "mostly the right context" except for frobbing all the
// arguments to the right place. We have the small trampoline code inside of // arguments to the right place. We have the small trampoline code inside of
// rust_bootstrap_green_task to do that. // rust_bootstrap_green_task to do that.
regs.gpr[RUSTRT_RSP] = sp as uint; regs.gpr[RUSTRT_RSP] = sp as libc::uintptr_t;
regs.gpr[RUSTRT_IP] = rust_bootstrap_green_task as uint; regs.gpr[RUSTRT_IP] = rust_bootstrap_green_task as libc::uintptr_t;
// Last base pointer on the stack should be 0 // Last base pointer on the stack should be 0
regs.gpr[RUSTRT_RBP] = 0; regs.gpr[RUSTRT_RBP] = 0;
} }
#[cfg(target_arch = "arm")] #[cfg(target_arch = "arm")]
type Registers = [uint, ..32]; type Registers = [libc::uintptr_t, ..32];
#[cfg(target_arch = "arm")] #[cfg(target_arch = "arm")]
fn new_regs() -> Box<Registers> { box {[0, .. 32]} } fn new_regs() -> Box<Registers> { box {[0, .. 32]} }
@@ -277,17 +280,17 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
// ARM uses the same technique as x86_64 to have a landing pad for the start // ARM uses the same technique as x86_64 to have a landing pad for the start
// of all new green tasks. Neither r1/r2 are saved on a context switch, so // of all new green tasks. Neither r1/r2 are saved on a context switch, so
// the shim will copy r3/r4 into r1/r2 and then execute the function in r5 // the shim will copy r3/r4 into r1/r2 and then execute the function in r5
regs[0] = arg as uint; // r0 regs[0] = arg as libc::uintptr_t; // r0
regs[3] = procedure.code as uint; // r3 regs[3] = procedure.code as libc::uintptr_t; // r3
regs[4] = procedure.env as uint; // r4 regs[4] = procedure.env as libc::uintptr_t; // r4
regs[5] = fptr as uint; // r5 regs[5] = fptr as libc::uintptr_t; // r5
regs[13] = sp as uint; // #52 sp, r13 regs[13] = sp as libc::uintptr_t; // #52 sp, r13
regs[14] = rust_bootstrap_green_task as uint; // #56 pc, r14 --> lr regs[14] = rust_bootstrap_green_task as libc::uintptr_t; // #56 pc, r14 --> lr
} }
#[cfg(target_arch = "mips")] #[cfg(target_arch = "mips")]
#[cfg(target_arch = "mipsel")] #[cfg(target_arch = "mipsel")]
type Registers = [uint, ..32]; type Registers = [libc::uintptr_t, ..32];
#[cfg(target_arch = "mips")] #[cfg(target_arch = "mips")]
#[cfg(target_arch = "mipsel")] #[cfg(target_arch = "mipsel")]
@@ -304,16 +307,16 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
// The final return address. 0 indicates the bottom of the stack // The final return address. 0 indicates the bottom of the stack
unsafe { *sp = 0; } unsafe { *sp = 0; }
regs[4] = arg as uint; regs[4] = arg as libc::uintptr_t;
regs[5] = procedure.code as uint; regs[5] = procedure.code as libc::uintptr_t;
regs[6] = procedure.env as uint; regs[6] = procedure.env as libc::uintptr_t;
regs[29] = sp as uint; regs[29] = sp as libc::uintptr_t;
regs[25] = fptr as uint; regs[25] = fptr as libc::uintptr_t;
regs[31] = fptr as uint; regs[31] = fptr as libc::uintptr_t;
} }
fn align_down(sp: *mut uint) -> *mut uint { fn align_down(sp: *mut uint) -> *mut uint {
let sp = (sp as uint) & !(16 - 1); let sp = (sp as libc::uintptr_t) & !(16 - 1);
sp as *mut uint sp as *mut uint
} }

View File

@@ -68,7 +68,7 @@ impl Stack {
// FIXME: Using the FFI to call a C macro. Slow // FIXME: Using the FFI to call a C macro. Slow
stk.valgrind_id = unsafe { stk.valgrind_id = unsafe {
rust_valgrind_stack_register(stk.start(), stk.end()) rust_valgrind_stack_register(stk.start() as *const libc::uintptr_t, stk.end() as *const libc::uintptr_t)
}; };
return stk; return stk;
} }

View File

@@ -107,13 +107,14 @@ mod select {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
mod select { mod select {
use std::uint; use std::uint;
use libc;
pub static FD_SETSIZE: uint = 1024; pub static FD_SETSIZE: uint = 1024;
#[repr(C)] #[repr(C)]
pub struct fd_set { pub struct fd_set {
// FIXME: shouldn't this be a c_ulong? // FIXME: shouldn't this be a c_ulong?
fds_bits: [uint, ..(FD_SETSIZE / uint::BITS)] fds_bits: [libc::uintptr_t, ..(FD_SETSIZE / uint::BITS)]
} }
pub fn fd_set(set: &mut fd_set, fd: i32) { pub fn fd_set(set: &mut fd_set, fd: i32) {