diff --git a/src/arch.rs b/src/arch.rs index a484e98..e07fc8e 100644 --- a/src/arch.rs +++ b/src/arch.rs @@ -9,10 +9,6 @@ extern "C" { pub fn bootstrap(); #[link_name = "lwt_swapcontext"] pub fn swapcontext(save: *mut Registers, restore: *mut Registers); - #[link_name = "lwt_get_sp_limit"] - pub fn get_sp_limit() -> *const u8; - #[link_name = "lwt_set_sp_limit"] - pub fn set_sp_limit(limit: *const u8); #[link_name = "lwt_abort"] pub fn abort() -> !; } @@ -77,6 +73,22 @@ pub fn initialise_call_frame(stack: &mut Stack, init: uintptr_t, args: &[uintptr regs } +// Rust stores a stack limit at [fs:0x70]. These two functions set and retrieve +// the limit. They're marked as #[inline(always)] so that they can be used in +// situations where the stack limit is invalid. + +#[inline(always)] +pub unsafe fn get_sp_limit() -> *const u8 { + let limit; + asm!("movq %fs:0x70, $0" : "=r"(limit) ::: "volatile"); + limit +} + +#[inline(always)] +pub unsafe fn set_sp_limit(limit: *const u8) { + asm!("movq $0, %fs:0x70" :: "r"(limit) :: "volatile"); +} + #[inline] fn align_down_mut(sp: *mut T, n: uint) -> *mut T { let sp = (sp as uint) & !(n - 1); diff --git a/src/arch.s b/src/arch.s index a360fca..8afa2da 100644 --- a/src/arch.s +++ b/src/arch.s @@ -91,22 +91,6 @@ lwt_bootstrap: mov r8, r15 jmp rbx - -;; Rust stores a stack limit at [fs:0x70]. These two functions set and retrieve -;; the limit. They could alternatively be implemented as #[inline(always)] Rust -;; functions, with inline assembly, but I prefer keeping all the assembly-land -;; stuff in here. - -global lwt_set_sp_limit -lwt_set_sp_limit: - mov [fs:0x70], rdi - ret - -global lwt_get_sp_limit -lwt_get_sp_limit: - mov rax, [fs:0x70] - ret - global lwt_abort lwt_abort: ;; when a context is created for a native thread, it should only be switched diff --git a/src/lib.rs b/src/lib.rs index c908701..270ce20 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(default_type_params, macro_rules, phase, globs)] +#![feature(default_type_params, macro_rules, phase, globs, asm)] #![no_std] #[phase(plugin, link)]