Skip to content
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

Use fibers on windows #8

Merged
merged 17 commits into from
Dec 10, 2018
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,9 @@ test = false
cfg-if = "0.1"
libc = "0.2"

[target.'cfg(windows)'.dependencies]
kernel32-sys = "0.2.2"
winapi = "0.2.8"

[build-dependencies]
cc = "1.0"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

A stack-growth library for Rust. Enables annotating fixed points in programs
where the stack may want to grow larger. Spills over to the heap if the stack
has it its limit.
has hit its limit.

This library is intended on helping implement recursive algorithms.

Expand Down
21 changes: 12 additions & 9 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::env;

fn main() {
let target = env::var("TARGET").unwrap();
let msvc = target.contains("msvc");

let mut cfg = cc::Build::new();

Expand All @@ -19,15 +18,19 @@ fn main() {
stacker: {}\n\n", target);
}

if target.starts_with("x86_64") {
cfg.file(if msvc {"src/arch/x86_64.asm"} else {"src/arch/x86_64.S"});
cfg.define("X86_64", None);
} else if target.contains("i686") {
cfg.file(if msvc {"src/arch/i686.asm"} else {"src/arch/i686.S"});
cfg.define("X86", None);
if target.contains("windows") {
cfg.file("src/arch/windows.c");
} else {
panic!("\n\nusing currently unsupported target triple with \
stacker: {}\n\n", target);
if target.starts_with("x86_64") {
cfg.file("src/arch/x86_64.S");
cfg.define("X86_64", None);
} else if target.contains("i686") {
cfg.file("src/arch/i686.S");
cfg.define("X86", None);
} else {
panic!("\n\nusing currently unsupported target triple with \
stacker: {}\n\n", target);
}
}

cfg.include("src/arch").compile("libstacker.a");
Expand Down
2 changes: 1 addition & 1 deletion src/arch/asm.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#if defined(APPLE) || (defined(WINDOWS) && defined(X86))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

32 bit Windows does use additional leading _, you'll have to revert this change.

#if defined(APPLE)
#define GLOBAL(name) .globl _ ## name; _ ## name
#else
#define GLOBAL(name) .globl name; name
Expand Down
17 changes: 8 additions & 9 deletions src/arch/i686.S
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@

.text

GLOBAL(__stacker_black_box):
ret

GLOBAL(__stacker_stack_pointer):
mov %esp, %eax
ret

#if defined(WINDOWS)
GLOBAL(__stacker_get_tib_32):
mov %fs:0x18, %eax
GLOBAL(__stacker_black_box):
ret
#endif

GLOBAL(__stacker_switch_stacks):
.cfi_startproc
push %ebp
.cfi_def_cfa_offset 8
.cfi_offset ebp, -8
mov %esp, %ebp
mov 8(%ebp), %esp // switch to our new stack
.cfi_def_cfa_register ebp
mov 16(%ebp), %esp // switch to our new stack
mov 12(%ebp), %eax // load function we're going to call
push 16(%ebp) // push argument to first function
push 8(%ebp) // push argument to first function
call *%eax // call our function pointer
mov %ebp, %esp // restore the old stack pointer
pop %ebp
ret
.cfi_endproc
33 changes: 0 additions & 33 deletions src/arch/i686.asm

This file was deleted.

30 changes: 30 additions & 0 deletions src/arch/windows.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <windows.h>

void __stacker_black_box() {}

PVOID __stacker_get_current_fiber() {
return GetCurrentFiber();
}

static size_t calc_stack_limit(size_t stack_low, size_t stack_guarantee) {
return stack_low +
max(stack_guarantee, sizeof(void *) == 4 ? 0x1000 : 0x2000) + // The guaranteed pages on a stack overflow
0x1000; // The guard page
}

// Fast paths for x86
// magic numbers are from https://en.wikipedia.org/wiki/Win32_Thread_Information_Block

#if defined(_M_X64)
size_t __stacker_get_stack_limit() {
return calc_stack_limit(__readgsqword(0x1478), // The base address of the stack. Referenced in GetCurrentThreadStackLimits
__readgsqword(0x1748)); // The guaranteed pages on a stack overflow. Referenced in SetThreadStackGuarantee
}
#endif

#ifdef _M_IX86
size_t __stacker_get_stack_limit() {
return calc_stack_limit(__readfsdword(0xE0C), // The base address of the stack. Referenced in GetCurrentThreadStackLimits
__readfsdword(0xF78)); // The guaranteed pages on a stack overflow. Referenced in SetThreadStackGuarantee
}
#endif
27 changes: 7 additions & 20 deletions src/arch/x86_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,20 @@

GLOBAL(__stacker_black_box):
ret

GLOBAL(__stacker_stack_pointer):
movq %rsp, %rax
ret

#if defined(WINDOWS)
#define ARG1 %rcx
#define ARG2 %rdx
#define ARG3 %r8
#else
#define ARG1 %rdi
#define ARG2 %rsi
#define ARG3 %rdx
#endif

#if defined(WINDOWS)
GLOBAL(__stacker_get_tib_64):
mov %gs:0x30, %rax
ret
#endif

GLOBAL(__stacker_switch_stacks):
.cfi_startproc
push %rbp
.cfi_def_cfa_offset 16
.cfi_offset rbp, -16
mov %rsp, %rbp
mov ARG1, %rsp // switch to our new stack
mov ARG3, ARG1 // move the data pointer to the first argument
call *ARG2 // call our function pointer
.cfi_def_cfa_register rbp
mov %rdx, %rsp // switch to our new stack
call *%rsi // call our function pointer, data argument in %rdi
mov %rbp, %rsp // restore the old stack pointer
pop %rbp
ret
.cfi_endproc
23 changes: 0 additions & 23 deletions src/arch/x86_64.asm

This file was deleted.

Loading