Skip to content

Commit a393fb3

Browse files
committed
rt: Maintain stack ptrs correctly when returning from stack switches
1 parent 214cdd0 commit a393fb3

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

src/rt/rust_task.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ rust_task::call_on_c_stack(void *args, void *fn_ptr) {
231231
// Too expensive to check
232232
// I(thread, on_rust_stack());
233233

234+
uintptr_t prev_rust_sp = next_rust_sp;
234235
next_rust_sp = get_sp();
235236

236237
bool borrowed_a_c_stack = false;
@@ -251,6 +252,8 @@ rust_task::call_on_c_stack(void *args, void *fn_ptr) {
251252
if (borrowed_a_c_stack) {
252253
return_c_stack();
253254
}
255+
256+
next_rust_sp = prev_rust_sp;
254257
}
255258

256259
inline void
@@ -259,11 +262,14 @@ rust_task::call_on_rust_stack(void *args, void *fn_ptr) {
259262
// I(thread, !on_rust_stack());
260263
I(thread, next_rust_sp);
261264

265+
uintptr_t prev_c_sp = next_c_sp;
262266
next_c_sp = get_sp();
263267

264268
uintptr_t sp = sanitize_next_sp(next_rust_sp);
265269

266270
__morestack(args, fn_ptr, sp);
271+
272+
next_c_sp = prev_c_sp;
267273
}
268274

269275
inline void

src/test/run-pass/crust-call-deep2.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
native mod rustrt {
2+
fn rust_dbg_call(cb: *u8,
3+
data: ctypes::uintptr_t) -> ctypes::uintptr_t;
4+
}
5+
6+
crust fn cb(data: ctypes::uintptr_t) -> ctypes::uintptr_t {
7+
if data == 1u {
8+
data
9+
} else {
10+
count(data - 1u) + 1u
11+
}
12+
}
13+
14+
fn count(n: uint) -> uint {
15+
#debug("n = %?", n);
16+
rustrt::rust_dbg_call(cb, n)
17+
}
18+
19+
fn main() {
20+
// Make sure we're on a task with small Rust stacks (main currently
21+
// has a large stack)
22+
task::spawn {||
23+
let result = count(1000u);
24+
#debug("result = %?", result);
25+
assert result == 1000u;
26+
};
27+
}

src/test/run-pass/crust-call-scrub.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// This time we're testing repeatedly going up and down both stacks to
2+
// make sure the stack pointers are maintained properly in both
3+
// directions
4+
5+
native mod rustrt {
6+
fn rust_dbg_call(cb: *u8,
7+
data: ctypes::uintptr_t) -> ctypes::uintptr_t;
8+
}
9+
10+
crust fn cb(data: ctypes::uintptr_t) -> ctypes::uintptr_t {
11+
if data == 1u {
12+
data
13+
} else {
14+
count(data - 1u) + count(data - 1u)
15+
}
16+
}
17+
18+
fn count(n: uint) -> uint {
19+
#debug("n = %?", n);
20+
rustrt::rust_dbg_call(cb, n)
21+
}
22+
23+
fn main() {
24+
// Make sure we're on a task with small Rust stacks (main currently
25+
// has a large stack)
26+
task::spawn {||
27+
let result = count(12u);
28+
#debug("result = %?", result);
29+
assert result == 2048u;
30+
};
31+
}

0 commit comments

Comments
 (0)