libgreen: use FFI-safe types
This commit is contained in:
parent
2dc2ac1e6b
commit
cf5d28083d
@ -40,6 +40,7 @@
|
||||
#[experimental]
|
||||
#[simd]
|
||||
#[deriving(Show)]
|
||||
#[repr(C)]
|
||||
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,
|
||||
@ -48,22 +49,26 @@ pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
|
||||
#[experimental]
|
||||
#[simd]
|
||||
#[deriving(Show)]
|
||||
#[repr(C)]
|
||||
pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
|
||||
pub i16, pub i16, pub i16, pub i16);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
#[deriving(Show)]
|
||||
#[repr(C)]
|
||||
pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
#[deriving(Show)]
|
||||
#[repr(C)]
|
||||
pub struct i64x2(pub i64, pub i64);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
#[deriving(Show)]
|
||||
#[repr(C)]
|
||||
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,
|
||||
@ -72,25 +77,30 @@ pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
|
||||
#[experimental]
|
||||
#[simd]
|
||||
#[deriving(Show)]
|
||||
#[repr(C)]
|
||||
pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
|
||||
pub u16, pub u16, pub u16, pub u16);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
#[deriving(Show)]
|
||||
#[repr(C)]
|
||||
pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
#[deriving(Show)]
|
||||
#[repr(C)]
|
||||
pub struct u64x2(pub u64, pub u64);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
#[deriving(Show)]
|
||||
#[repr(C)]
|
||||
pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
#[deriving(Show)]
|
||||
#[repr(C)]
|
||||
pub struct f64x2(pub f64, pub f64);
|
||||
|
@ -15,6 +15,7 @@ use std::rt::stack;
|
||||
use std::raw;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::simd;
|
||||
use libc;
|
||||
|
||||
// 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
|
||||
@ -69,7 +70,7 @@ impl Context {
|
||||
// overflow). Additionally, their coroutine stacks are listed as being
|
||||
// zero-length, so that's how we detect what's what here.
|
||||
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
|
||||
} else {
|
||||
Some((stack_base as uint, sp as uint))
|
||||
@ -165,16 +166,16 @@ fn new_regs() -> Box<Registers> {
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
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
|
||||
// plus some offsetting to figure out what the actual stack should be.
|
||||
let sp = align_down(sp);
|
||||
let sp = mut_offset(sp, -4);
|
||||
|
||||
unsafe { *mut_offset(sp, 2) = procedure.env as uint };
|
||||
unsafe { *mut_offset(sp, 1) = procedure.code as uint };
|
||||
unsafe { *mut_offset(sp, 0) = arg as uint };
|
||||
unsafe { *mut_offset(sp, 2) = procedure.env as libc::uintptr_t };
|
||||
unsafe { *mut_offset(sp, 1) = procedure.code as libc::uintptr_t };
|
||||
unsafe { *mut_offset(sp, 0) = arg as libc::uintptr_t };
|
||||
let sp = mut_offset(sp, -1);
|
||||
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
|
||||
// register context must be larger.
|
||||
#[cfg(windows, target_arch = "x86_64")]
|
||||
#[repr(C)]
|
||||
struct Registers {
|
||||
gpr:[uint, ..14],
|
||||
gpr:[libc::uintptr_t, ..14],
|
||||
_xmm:[simd::u32x4, ..10]
|
||||
}
|
||||
#[cfg(not(windows), target_arch = "x86_64")]
|
||||
#[repr(C)]
|
||||
struct Registers {
|
||||
gpr:[uint, ..10],
|
||||
gpr:[libc::uintptr_t, ..10],
|
||||
_xmm:[simd::u32x4, ..6]
|
||||
}
|
||||
|
||||
@ -234,30 +237,30 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
|
||||
unsafe { *sp = 0; }
|
||||
|
||||
rtdebug!("creating call frame");
|
||||
rtdebug!("fptr {:#x}", fptr as uint);
|
||||
rtdebug!("fptr {:#x}", fptr as libc::uintptr_t);
|
||||
rtdebug!("arg {:#x}", arg);
|
||||
rtdebug!("sp {}", sp);
|
||||
|
||||
// These registers are frobbed by rust_bootstrap_green_task into the right
|
||||
// location so we can invoke the "real init function", `fptr`.
|
||||
regs.gpr[RUSTRT_R12] = arg as uint;
|
||||
regs.gpr[RUSTRT_R13] = procedure.code as uint;
|
||||
regs.gpr[RUSTRT_R14] = procedure.env as uint;
|
||||
regs.gpr[RUSTRT_R15] = fptr as uint;
|
||||
regs.gpr[RUSTRT_R12] = arg as libc::uintptr_t;
|
||||
regs.gpr[RUSTRT_R13] = procedure.code as libc::uintptr_t;
|
||||
regs.gpr[RUSTRT_R14] = procedure.env as libc::uintptr_t;
|
||||
regs.gpr[RUSTRT_R15] = fptr as libc::uintptr_t;
|
||||
|
||||
// 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
|
||||
// arguments to the right place. We have the small trampoline code inside of
|
||||
// rust_bootstrap_green_task to do that.
|
||||
regs.gpr[RUSTRT_RSP] = sp as uint;
|
||||
regs.gpr[RUSTRT_IP] = rust_bootstrap_green_task as uint;
|
||||
regs.gpr[RUSTRT_RSP] = sp as libc::uintptr_t;
|
||||
regs.gpr[RUSTRT_IP] = rust_bootstrap_green_task as libc::uintptr_t;
|
||||
|
||||
// Last base pointer on the stack should be 0
|
||||
regs.gpr[RUSTRT_RBP] = 0;
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
type Registers = [uint, ..32];
|
||||
type Registers = [libc::uintptr_t, ..32];
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
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
|
||||
// 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
|
||||
regs[0] = arg as uint; // r0
|
||||
regs[3] = procedure.code as uint; // r3
|
||||
regs[4] = procedure.env as uint; // r4
|
||||
regs[5] = fptr as uint; // r5
|
||||
regs[13] = sp as uint; // #52 sp, r13
|
||||
regs[14] = rust_bootstrap_green_task as uint; // #56 pc, r14 --> lr
|
||||
regs[0] = arg as libc::uintptr_t; // r0
|
||||
regs[3] = procedure.code as libc::uintptr_t; // r3
|
||||
regs[4] = procedure.env as libc::uintptr_t; // r4
|
||||
regs[5] = fptr as libc::uintptr_t; // r5
|
||||
regs[13] = sp as libc::uintptr_t; // #52 sp, r13
|
||||
regs[14] = rust_bootstrap_green_task as libc::uintptr_t; // #56 pc, r14 --> lr
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "mips")]
|
||||
#[cfg(target_arch = "mipsel")]
|
||||
type Registers = [uint, ..32];
|
||||
type Registers = [libc::uintptr_t, ..32];
|
||||
|
||||
#[cfg(target_arch = "mips")]
|
||||
#[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
|
||||
unsafe { *sp = 0; }
|
||||
|
||||
regs[4] = arg as uint;
|
||||
regs[5] = procedure.code as uint;
|
||||
regs[6] = procedure.env as uint;
|
||||
regs[29] = sp as uint;
|
||||
regs[25] = fptr as uint;
|
||||
regs[31] = fptr as uint;
|
||||
regs[4] = arg as libc::uintptr_t;
|
||||
regs[5] = procedure.code as libc::uintptr_t;
|
||||
regs[6] = procedure.env as libc::uintptr_t;
|
||||
regs[29] = sp as libc::uintptr_t;
|
||||
regs[25] = fptr as libc::uintptr_t;
|
||||
regs[31] = fptr as libc::uintptr_t;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ impl Stack {
|
||||
|
||||
// FIXME: Using the FFI to call a C macro. Slow
|
||||
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;
|
||||
}
|
||||
|
@ -107,13 +107,14 @@ mod select {
|
||||
#[cfg(target_os = "linux")]
|
||||
mod select {
|
||||
use std::uint;
|
||||
use libc;
|
||||
|
||||
pub static FD_SETSIZE: uint = 1024;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct fd_set {
|
||||
// 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) {
|
||||
|
Loading…
Reference in New Issue
Block a user