Skip to content

Commit 884d7f1

Browse files
committed
---
yaml --- r: 89791 b: refs/heads/master c: 88e383e h: refs/heads/master i: 89789: aba4040 89787: 5b3de15 89783: 47003b3 89775: 33f7092 89759: 89f7d60 89727: c3de7fe v: v3
1 parent a029d45 commit 884d7f1

File tree

339 files changed

+9369
-10651
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

339 files changed

+9369
-10651
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: e34834375db649a16d45c902f7f0209a44c7e42e
2+
refs/heads/master: 88e383ef1e702666159bdc899d81e30927479501
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a6d3e57dca68fde4effdda3e4ae2887aa535fcd6
55
refs/heads/try: b160761e35efcd1207112b3b782c06633cf441a8

trunk/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
*.cps
3131
*.log
3232
*.pdf
33+
*.epub
3334
*.html
3435
*.pg
3536
*.toc

trunk/Makefile.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ ifdef TRACE
125125
CFG_RUSTC_FLAGS += -Z trace
126126
endif
127127
ifndef DEBUG_BORROWS
128+
RUSTFLAGS_STAGE0 += -Z no-debug-borrows
128129
RUSTFLAGS_STAGE1 += -Z no-debug-borrows
129130
RUSTFLAGS_STAGE2 += -Z no-debug-borrows
130131
endif

trunk/doc/tutorial-ffi.md

Lines changed: 45 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ extern {
1919
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
2020
}
2121
22-
#[fixed_stack_segment]
2322
fn main() {
2423
let x = unsafe { snappy_max_compressed_length(100) };
25-
println(fmt!("max compressed length of a 100 byte buffer: %?", x));
24+
println!("max compressed length of a 100 byte buffer: {}", x);
2625
}
2726
~~~~
2827

@@ -36,11 +35,6 @@ interfaces that aren't thread-safe, and almost any function that takes a pointer
3635
valid for all possible inputs since the pointer could be dangling, and raw pointers fall outside of
3736
Rust's safe memory model.
3837

39-
Finally, the `#[fixed_stack_segment]` annotation that appears on
40-
`main()` instructs the Rust compiler that when `main()` executes, it
41-
should request a "very large" stack segment. More details on
42-
stack management can be found in the following sections.
43-
4438
When declaring the argument types to a foreign function, the Rust compiler will not check if the
4539
declaration is correct, so specifying it correctly is part of keeping the binding correct at
4640
runtime.
@@ -81,8 +75,6 @@ length is number of elements currently contained, and the capacity is the total
8175
the allocated memory. The length is less than or equal to the capacity.
8276

8377
~~~~ {.xfail-test}
84-
#[fixed_stack_segment]
85-
#[inline(never)]
8678
pub fn validate_compressed_buffer(src: &[u8]) -> bool {
8779
unsafe {
8880
snappy_validate_compressed_buffer(vec::raw::to_ptr(src), src.len() as size_t) == 0
@@ -94,36 +86,6 @@ The `validate_compressed_buffer` wrapper above makes use of an `unsafe` block, b
9486
guarantee that calling it is safe for all inputs by leaving off `unsafe` from the function
9587
signature.
9688

97-
The `validate_compressed_buffer` wrapper is also annotated with two
98-
attributes `#[fixed_stack_segment]` and `#[inline(never)]`. The
99-
purpose of these attributes is to guarantee that there will be
100-
sufficient stack for the C function to execute. This is necessary
101-
because Rust, unlike C, does not assume that the stack is allocated in
102-
one continuous chunk. Instead, we rely on a *segmented stack* scheme,
103-
in which the stack grows and shrinks as necessary. C code, however,
104-
expects one large stack, and so callers of C functions must request a
105-
large stack segment to ensure that the C routine will not run off the
106-
end of the stack.
107-
108-
The compiler includes a lint mode that will report an error if you
109-
call a C function without a `#[fixed_stack_segment]` attribute. More
110-
details on the lint mode are given in a later section.
111-
112-
You may be wondering why we include a `#[inline(never)]` directive.
113-
This directive informs the compiler never to inline this function.
114-
While not strictly necessary, it is usually a good idea to use an
115-
`#[inline(never)]` directive in concert with `#[fixed_stack_segment]`.
116-
The reason is that if a fn annotated with `fixed_stack_segment` is
117-
inlined, then its caller also inherits the `fixed_stack_segment`
118-
annotation. This means that rather than requesting a large stack
119-
segment only for the duration of the call into C, the large stack
120-
segment would be used for the entire duration of the caller. This is
121-
not necessarily *bad* -- it can for example be more efficient,
122-
particularly if `validate_compressed_buffer()` is called multiple
123-
times in a row -- but it does work against the purpose of the
124-
segmented stack scheme, which is to keep stacks small and thus
125-
conserve address space.
126-
12789
The `snappy_compress` and `snappy_uncompress` functions are more complex, since a buffer has to be
12890
allocated to hold the output too.
12991

@@ -134,8 +96,6 @@ the true length after compression for setting the length.
13496

13597
~~~~ {.xfail-test}
13698
pub fn compress(src: &[u8]) -> ~[u8] {
137-
#[fixed_stack_segment]; #[inline(never)];
138-
13999
unsafe {
140100
let srclen = src.len() as size_t;
141101
let psrc = vec::raw::to_ptr(src);
@@ -156,8 +116,6 @@ format and `snappy_uncompressed_length` will retrieve the exact buffer size requ
156116

157117
~~~~ {.xfail-test}
158118
pub fn uncompress(src: &[u8]) -> Option<~[u8]> {
159-
#[fixed_stack_segment]; #[inline(never)];
160-
161119
unsafe {
162120
let srclen = src.len() as size_t;
163121
let psrc = vec::raw::to_ptr(src);
@@ -181,98 +139,28 @@ pub fn uncompress(src: &[u8]) -> Option<~[u8]> {
181139
For reference, the examples used here are also available as an [library on
182140
GitHub](https://github.com/thestinger/rust-snappy).
183141

184-
# Automatic wrappers
185-
186-
Sometimes writing Rust wrappers can be quite tedious. For example, if
187-
function does not take any pointer arguments, often there is no need
188-
for translating types. In such cases, it is usually still a good idea
189-
to have a Rust wrapper so as to manage the segmented stacks, but you
190-
can take advantage of the (standard) `externfn!` macro to remove some
191-
of the tedium.
192-
193-
In the initial section, we showed an extern block that added a call
194-
to a specific snappy API:
195-
196-
~~~~ {.xfail-test}
197-
use std::libc::size_t;
198-
199-
#[link_args = "-lsnappy"]
200-
extern {
201-
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
202-
}
203-
204-
#[fixed_stack_segment]
205-
fn main() {
206-
let x = unsafe { snappy_max_compressed_length(100) };
207-
println(fmt!("max compressed length of a 100 byte buffer: %?", x));
208-
}
209-
~~~~
210-
211-
To avoid the need to create a wrapper fn for `snappy_max_compressed_length()`,
212-
and also to avoid the need to think about `#[fixed_stack_segment]`, we
213-
could simply use the `externfn!` macro instead, as shown here:
214-
215-
~~~~ {.xfail-test}
216-
use std::libc::size_t;
217-
218-
externfn!(#[link_args = "-lsnappy"]
219-
fn snappy_max_compressed_length(source_length: size_t) -> size_t)
220-
221-
fn main() {
222-
let x = unsafe { snappy_max_compressed_length(100) };
223-
println(fmt!("max compressed length of a 100 byte buffer: %?", x));
224-
}
225-
~~~~
226-
227-
As you can see from the example, `externfn!` replaces the extern block
228-
entirely. After macro expansion, it will create something like this:
229-
230-
~~~~ {.xfail-test}
231-
use std::libc::size_t;
232-
233-
// Automatically generated by
234-
// externfn!(#[link_args = "-lsnappy"]
235-
// fn snappy_max_compressed_length(source_length: size_t) -> size_t)
236-
unsafe fn snappy_max_compressed_length(source_length: size_t) -> size_t {
237-
#[fixed_stack_segment]; #[inline(never)];
238-
return snappy_max_compressed_length(source_length);
239-
240-
#[link_args = "-lsnappy"]
241-
extern {
242-
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
243-
}
244-
}
245-
246-
fn main() {
247-
let x = unsafe { snappy_max_compressed_length(100) };
248-
println(fmt!("max compressed length of a 100 byte buffer: %?", x));
249-
}
250-
~~~~
251-
252-
# Segmented stacks and the linter
253-
254-
By default, whenever you invoke a non-Rust fn, the `cstack` lint will
255-
check that one of the following conditions holds:
256-
257-
1. The call occurs inside of a fn that has been annotated with
258-
`#[fixed_stack_segment]`;
259-
2. The call occurs inside of an `extern fn`;
260-
3. The call occurs within a stack closure created by some other
261-
safe fn.
262-
263-
All of these conditions ensure that you are running on a large stack
264-
segment. However, they are sometimes too strict. If your application
265-
will be making many calls into C, it is often beneficial to promote
266-
the `#[fixed_stack_segment]` attribute higher up the call chain. For
267-
example, the Rust compiler actually labels main itself as requiring a
268-
`#[fixed_stack_segment]`. In such cases, the linter is just an
269-
annoyance, because all C calls that occur from within the Rust
270-
compiler are made on a large stack. Another situation where this
271-
frequently occurs is on a 64-bit architecture, where large stacks are
272-
the default. In cases, you can disable the linter by including a
273-
`#[allow(cstack)]` directive somewhere, which permits violations of
274-
the "cstack" rules given above (you can also use `#[warn(cstack)]` to
275-
convert the errors into warnings, if you prefer).
142+
# Stack management
143+
144+
Rust tasks by default run on a "large stack". This is actually implemented as a
145+
reserving a large segment of the address space and then lazily mapping in pages
146+
as they are needed. When calling an external C function, the code is invoked on
147+
the same stack as the rust stack. This means that there is no extra
148+
stack-switching mechanism in place because it is assumed that the large stack
149+
for the rust task is plenty for the C function to have.
150+
151+
A planned future improvement (net yet implemented at the time of this writing)
152+
is to have a guard page at the end of every rust stack. No rust function will
153+
hit this guard page (due to rust's usage of LLVM's __morestack). The intention
154+
for this unmapped page is to prevent infinite recursion in C from overflowing
155+
onto other rust stacks. If the guard page is hit, then the process will be
156+
terminated with a message saying that the guard page was hit.
157+
158+
For normal external function usage, this all means that there shouldn't be any
159+
need for any extra effort on a user's perspective. The C stack naturally
160+
interleaves with the rust stack, and it's "large enough" for both to
161+
interoperate. If, however, it is determined that a larger stack is necessary,
162+
there are appropriate functions in the task spawning API to control the size of
163+
the stack of the task which is spawned.
276164

277165
# Destructors
278166

@@ -296,9 +184,6 @@ pub struct Unique<T> {
296184
297185
impl<T: Send> Unique<T> {
298186
pub fn new(value: T) -> Unique<T> {
299-
#[fixed_stack_segment];
300-
#[inline(never)];
301-
302187
unsafe {
303188
let ptr = malloc(std::mem::size_of::<T>() as size_t) as *mut T;
304189
assert!(!ptr::is_null(ptr));
@@ -322,9 +207,6 @@ impl<T: Send> Unique<T> {
322207
#[unsafe_destructor]
323208
impl<T: Send> Drop for Unique<T> {
324209
fn drop(&mut self) {
325-
#[fixed_stack_segment];
326-
#[inline(never)];
327-
328210
unsafe {
329211
let x = intrinsics::init(); // dummy value to swap in
330212
// moving the object out is needed to call the destructor
@@ -384,8 +266,8 @@ extern {
384266
}
385267
386268
fn main() {
387-
println(fmt!("You have readline version %d installed.",
388-
rl_readline_version as int));
269+
println!("You have readline version {} installed.",
270+
rl_readline_version as int);
389271
}
390272
~~~
391273

@@ -418,15 +300,32 @@ calling foreign functions. Some foreign functions, most notably the Windows API,
418300
conventions. Rust provides a way to tell the compiler which convention to use:
419301

420302
~~~~
421-
#[cfg(target_os = "win32")]
303+
#[cfg(target_os = "win32", target_arch = "x86")]
422304
#[link_name = "kernel32"]
423305
extern "stdcall" {
424306
fn SetEnvironmentVariableA(n: *u8, v: *u8) -> int;
425307
}
426308
~~~~
427309

428-
This applies to the entire `extern` block, and must be either `"cdecl"` or
429-
`"stdcall"`. The compiler may eventually support other calling conventions.
310+
This applies to the entire `extern` block. The list of supported ABI constraints
311+
are:
312+
313+
* `stdcall`
314+
* `aapcs`
315+
* `cdecl`
316+
* `fastcall`
317+
* `Rust`
318+
* `rust-intrinsic`
319+
* `system`
320+
* `C`
321+
322+
Most of the abis in this list are self-explanatory, but the `system` abi may
323+
seem a little odd. This constraint selects whatever the appropriate ABI is for
324+
interoperating with the target's libraries. For example, on win32 with a x86
325+
architecture, this means that the abi used would be `stdcall`. On x86_64,
326+
however, windows uses the `C` calling convention, so `C` would be used. This
327+
means that in our previous example, we could have used `extern "system" { ... }`
328+
to define a block for all windows systems, not just x86 ones.
430329

431330
# Interoperability with foreign code
432331

trunk/mk/clean.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ clean-misc:
5353
$(Q)rm -Rf tmp/*
5454
$(Q)rm -Rf rust-stage0-*.tar.bz2 $(PKG_NAME)-*.tar.gz dist
5555
$(Q)rm -Rf $(foreach ext, \
56-
html aux cp fn ky log pdf pg toc tp vr cps, \
56+
html aux cp fn ky log pdf pg toc tp vr cps epub, \
5757
$(wildcard doc/*.$(ext)))
5858
$(Q)find doc/std doc/extra -mindepth 1 | xargs rm -Rf
5959
$(Q)rm -Rf doc/version.md

trunk/mk/docs.mk

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,20 @@ doc/rust.tex: rust.md doc/version.md
6464
--from=markdown --to=latex \
6565
--output=$@
6666

67+
DOCS += doc/rust.epub
68+
doc/rust.epub: rust.md doc/version_info.html doc/rust.css doc/manual.inc
69+
@$(call E, pandoc: $@)
70+
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
71+
"$(CFG_PANDOC)" \
72+
--standalone --toc \
73+
--section-divs \
74+
--number-sections \
75+
--from=markdown --to=epub \
76+
--css=rust.css --include-in-header=doc/manual.inc \
77+
--include-before-body=doc/version_info.html \
78+
--output=$@
79+
80+
6781
DOCS += doc/tutorial.tex
6882
doc/tutorial.tex: tutorial.md doc/version.md
6983
@$(call E, pandoc: $@)
@@ -98,6 +112,17 @@ doc/tutorial.html: tutorial.md doc/version_info.html doc/rust.css
98112
--include-before-body=doc/version_info.html \
99113
--output=$@
100114

115+
DOCS += doc/tutorial.epub
116+
doc/tutorial.epub: tutorial.md doc/version_info.html doc/rust.css
117+
@$(call E, pandoc: $@)
118+
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
119+
$(CFG_PANDOC) --standalone --toc \
120+
--section-divs --number-sections \
121+
--from=markdown --to=epub --css=rust.css \
122+
--include-before-body=doc/version_info.html \
123+
--output=$@
124+
125+
101126
DOCS_L10N += doc/l10n/ja/tutorial.html
102127
doc/l10n/ja/tutorial.html: doc/l10n/ja/tutorial.md doc/version_info.html doc/rust.css
103128
@$(call E, pandoc: $@)

trunk/mk/rt.mk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ LIBUV_MAKEFILE_$(1) := $$(CFG_BUILD_DIR)$$(RT_OUTPUT_DIR_$(1))/libuv/Makefile
207207

208208
$$(LIBUV_MAKEFILE_$(1)): $$(LIBUV_DEPS)
209209
(cd $(S)src/libuv/ && \
210-
$$(CFG_PYTHON) ./gyp_uv -f make -Dtarget_arch=$$(LIBUV_ARCH_$(1)) \
210+
$$(CFG_PYTHON) ./gyp_uv.py -f make -Dtarget_arch=$$(LIBUV_ARCH_$(1)) \
211211
-D ninja \
212212
-DOS=$$(LIBUV_OSTYPE_$(1)) \
213213
-Goutput_dir=$$(@D) --generator-output $$(@D))
@@ -218,7 +218,7 @@ $$(LIBUV_MAKEFILE_$(1)): $$(LIBUV_DEPS)
218218
ifdef CFG_WINDOWSY_$(1)
219219
$$(LIBUV_LIB_$(1)): $$(LIBUV_DEPS)
220220
$$(Q)$$(MAKE) -C $$(S)src/libuv -f Makefile.mingw \
221-
CFLAGS="$$(CFG_GCCISH_CFLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1))) $$(SNAP_DEFINES)" \
221+
CC="$$(CC) $$(CFG_GCCISH_CFLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1))) $$(SNAP_DEFINES)" \
222222
AR="$$(AR_$(1))" \
223223
V=$$(VERBOSE)
224224
$$(Q)cp $$(S)src/libuv/libuv.a $$@

0 commit comments

Comments
 (0)