Skip to content

Commit 6cb485f

Browse files
committed
---
yaml --- r: 50942 b: refs/heads/try c: df171e4 h: refs/heads/master v: v3
1 parent 84038ac commit 6cb485f

34 files changed

+1854
-1128
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 5f13e9ccc2e3328d4cd8ca49f84e6840dd998346
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: f7a2371c176663d59062ec5158f39faecba45768
5-
refs/heads/try: 057c40d5bd3dc700af7d99a2dfeba0fe6c2ba119
5+
refs/heads/try: df171e4b6898db92610bcccb22d996d361e16902
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/Makefile.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ $(foreach target,$(CFG_TARGET_TRIPLES),\
238238

239239
CORELIB_CRATE := $(S)src/libcore/core.rc
240240
CORELIB_INPUTS := $(wildcard $(addprefix $(S)src/libcore/, \
241-
core.rc *.rs */*.rs))
241+
core.rc *.rs */*.rs */*/*rs))
242242

243243
######################################################################
244244
# Standard library variables

branches/try/doc/tutorial-macros.md

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
# Introduction
44

55
Functions are the primary tool that programmers can use to build abstractions.
6-
Sometimes, however, programmers want to perform abstractions over things that are not
7-
runtime values. Macros provide a syntactic abstraction. For an example of how this
8-
can be useful, consider the following two code fragments, which both pattern-match
9-
on their input and return early in one case, and do nothing otherwise:
6+
Sometimes, however, programmers want to abstract over compile-time syntax
7+
rather than run-time values.
8+
Macros provide syntactic abstraction.
9+
For an example of how this can be useful, consider the following two code fragments,
10+
which both pattern-match on their input and both return early in one case,
11+
doing nothing otherwise:
1012

1113
~~~~
1214
# enum t { special_a(uint), special_b(uint) };
@@ -25,9 +27,10 @@ match input_2 {
2527
# }
2628
~~~~
2729

28-
This code could become tiresome if repeated many times. However, no function
29-
can capture its functionality to make it possible to rewrite the repetition
30-
away. Rust's macro system, however, can eliminate the repetition. Macros are
30+
This code could become tiresome if repeated many times.
31+
However, no function can capture its functionality to make it possible
32+
to abstract the repetition away.
33+
Rust's macro system, however, can eliminate the repetition. Macros are
3134
lightweight custom syntax extensions, themselves defined using the
3235
`macro_rules!` syntax extension. The following `early_return` macro captures
3336
the pattern in the above code:
@@ -37,7 +40,7 @@ the pattern in the above code:
3740
# fn f() -> uint {
3841
# let input_1 = special_a(0), input_2 = special_a(0);
3942
macro_rules! early_return(
40-
($inp:expr $sp:ident) => ( //invoke it like `(input_5 special_e)`
43+
($inp:expr $sp:ident) => ( // invoke it like `(input_5 special_e)`
4144
match $inp {
4245
$sp(x) => { return x; }
4346
_ => {}
@@ -93,10 +96,10 @@ that could be invoked like: `my_macro!(i->(( 2+2 )))`.
9396

9497
## Invocation location
9598

96-
A macro invocation may take the place of (and therefore expand to) either an
97-
expression, an item, or a statement. The Rust parser will parse the macro
98-
invocation as a "placeholder" for whichever of those three nonterminals is
99-
appropriate for the location.
99+
A macro invocation may take the place of (and therefore expand to)
100+
an expression, an item, or a statement.
101+
The Rust parser will parse the macro invocation as a "placeholder"
102+
for whichever of those three nonterminals is appropriate for the location.
100103

101104
At expansion time, the output of the macro will be parsed as whichever of the
102105
three nonterminals it stands in for. This means that a single macro might,
@@ -112,17 +115,19 @@ The right-hand side of the `=>` follows the same rules as the left-hand side,
112115
except that a `$` need only be followed by the name of the syntactic fragment
113116
to transcribe into the macro expansion; its type need not be repeated.
114117

115-
The right-hand side must be enclosed by delimiters, which are ignored by the
116-
transcriber (therefore `() => ((1,2,3))` is a macro that expands to a tuple
117-
expression, `() => (let $x=$val)` is a macro that expands to a statement, and
118-
`() => (1,2,3)` is a macro that expands to a syntax error).
118+
The right-hand side must be enclosed by delimiters, which the transcriber ignores.
119+
Therefore `() => ((1,2,3))` is a macro that expands to a tuple expression,
120+
`() => (let $x=$val)` is a macro that expands to a statement,
121+
and `() => (1,2,3)` is a macro that expands to a syntax error
122+
(since the transcriber interprets the parentheses on the right-hand-size as delimiters,
123+
and `1,2,3` is not a valid Rust expression on its own).
119124

120125
Except for permissibility of `$name` (and `$(...)*`, discussed below), the
121126
right-hand side of a macro definition is ordinary Rust syntax. In particular,
122127
macro invocations (including invocations of the macro currently being defined)
123128
are permitted in expression, statement, and item locations. However, nothing
124129
else about the code is examined or executed by the macro system; execution
125-
still has to wait until runtime.
130+
still has to wait until run-time.
126131

127132
## Interpolation location
128133

@@ -287,7 +292,6 @@ A macro may accept multiple different input grammars. The first one to
287292
successfully match the actual argument to a macro invocation is the one that
288293
"wins".
289294

290-
291295
In the case of the example above, we want to write a recursive macro to
292296
process the semicolon-terminated lines, one-by-one. So, we want the following
293297
input patterns:
@@ -369,19 +373,19 @@ return result + val;
369373
# }
370374
~~~~
371375

372-
This technique is applicable in many cases where transcribing a result "all
373-
at once" is not possible. It resembles ordinary functional programming in some
374-
respects, but it is important to recognize the differences.
376+
This technique applies to many cases where transcribing a result all at once is not possible.
377+
The resulting code resembles ordinary functional programming in some respects,
378+
but has some important differences from functional programming.
375379

376380
The first difference is important, but also easy to forget: the transcription
377381
(right-hand) side of a `macro_rules!` rule is literal syntax, which can only
378382
be executed at run-time. If a piece of transcription syntax does not itself
379383
appear inside another macro invocation, it will become part of the final
380384
program. If it is inside a macro invocation (for example, the recursive
381-
invocation of `biased_match_rec!`), it does have the opprotunity to affect
385+
invocation of `biased_match_rec!`), it does have the opportunity to affect
382386
transcription, but only through the process of attempted pattern matching.
383387

384-
The second difference is related: the evaluation order of macros feels
388+
The second, related, difference is that the evaluation order of macros feels
385389
"backwards" compared to ordinary programming. Given an invocation
386390
`m1!(m2!())`, the expander first expands `m1!`, giving it as input the literal
387391
syntax `m2!()`. If it transcribes its argument unchanged into an appropriate

branches/try/mk/tests.mk

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,21 +244,29 @@ $(foreach host,$(CFG_HOST_TRIPLES), \
244244

245245
define TEST_RUNNER
246246

247+
# If NO_REBUILD is set then break the dependencies on std so we can
248+
# test crates without rebuilding core and std first
249+
ifeq ($(NO_REBUILD),)
250+
STDTESTDEP_$(1)_$(2)_$(3) = $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB_$(2))
251+
else
252+
STDTESTDEP_$(1)_$(2)_$(3) =
253+
endif
254+
247255
$(3)/test/coretest.stage$(1)-$(2)$$(X_$(2)): \
248256
$$(CORELIB_CRATE) $$(CORELIB_INPUTS) \
249-
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB_$(2))
257+
$$(STDTESTDEP_$(1)_$(2)_$(3))
250258
@$$(call E, compile_and_link: $$@)
251259
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
252260

253261
$(3)/test/stdtest.stage$(1)-$(2)$$(X_$(2)): \
254262
$$(STDLIB_CRATE) $$(STDLIB_INPUTS) \
255-
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB_$(2))
263+
$$(STDTESTDEP_$(1)_$(2)_$(3))
256264
@$$(call E, compile_and_link: $$@)
257265
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
258266

259267
$(3)/test/syntaxtest.stage$(1)-$(2)$$(X_$(2)): \
260268
$$(LIBSYNTAX_CRATE) $$(LIBSYNTAX_INPUTS) \
261-
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB_$(2))
269+
$$(STDTESTDEP_$(1)_$(2)_$(3))
262270
@$$(call E, compile_and_link: $$@)
263271
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
264272

branches/try/src/compiletest/common.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ pub struct config {
6363
// Run tests using the JIT
6464
jit: bool,
6565

66+
// Run tests using the new runtime
67+
newrt: bool,
68+
6669
// Explain what's going on
6770
verbose: bool
6871

branches/try/src/compiletest/compiletest.rc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ pub fn parse_config(args: ~[~str]) -> config {
6161
getopts::optopt(~"runtool"), getopts::optopt(~"rustcflags"),
6262
getopts::optflag(~"verbose"),
6363
getopts::optopt(~"logfile"),
64-
getopts::optflag(~"jit")];
64+
getopts::optflag(~"jit"),
65+
getopts::optflag(~"newrt")];
6566

6667
fail_unless!(!args.is_empty());
6768
let args_ = vec::tail(args);
@@ -95,6 +96,7 @@ pub fn parse_config(args: ~[~str]) -> config {
9596
runtool: getopts::opt_maybe_str(matches, ~"runtool"),
9697
rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"),
9798
jit: getopts::opt_present(matches, ~"jit"),
99+
newrt: getopts::opt_present(matches, ~"newrt"),
98100
verbose: getopts::opt_present(matches, ~"verbose")
99101
}
100102
}
@@ -114,6 +116,7 @@ pub fn log_config(config: config) {
114116
logv(c, fmt!("runtool: %s", opt_str(config.runtool)));
115117
logv(c, fmt!("rustcflags: %s", opt_str(config.rustcflags)));
116118
logv(c, fmt!("jit: %b", config.jit));
119+
logv(c, fmt!("newrt: %b", config.newrt));
117120
logv(c, fmt!("verbose: %b", config.verbose));
118121
logv(c, fmt!("\n"));
119122
}

branches/try/src/compiletest/runtest.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,9 +484,17 @@ fn compile_test_(config: config, props: TestProps,
484484

485485
fn exec_compiled_test(config: config, props: TestProps,
486486
testfile: &Path) -> ProcRes {
487+
488+
// If testing the new runtime then set the RUST_NEWRT env var
489+
let env = if config.newrt {
490+
props.exec_env + ~[(~"RUST_NEWRT", ~"1")]
491+
} else {
492+
props.exec_env
493+
};
494+
487495
compose_and_run(config, testfile,
488496
make_run_args(config, props, testfile),
489-
props.exec_env,
497+
env,
490498
config.run_lib_path, None)
491499
}
492500

branches/try/src/libcore/rt/context.rs

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use option::*;
1112
use super::stack::StackSegment;
1213
use libc::c_void;
1314
use cast::{transmute, transmute_mut_unsafe,
@@ -16,17 +17,30 @@ use cast::{transmute, transmute_mut_unsafe,
1617
// XXX: Registers is boxed so that it is 16-byte aligned, for storing
1718
// SSE regs. It would be marginally better not to do this. In C++ we
1819
// use an attribute on a struct.
19-
pub struct Context(~Registers);
20+
// XXX: It would be nice to define regs as `~Option<Registers>` since
21+
// the registers are sometimes empty, but the discriminant would
22+
// then misalign the regs again.
23+
pub struct Context {
24+
/// The context entry point, saved here for later destruction
25+
start: Option<~~fn()>,
26+
/// Hold the registers while the task or scheduler is suspended
27+
regs: ~Registers
28+
}
2029

2130
pub impl Context {
2231
fn empty() -> Context {
23-
Context(new_regs())
32+
Context {
33+
start: None,
34+
regs: new_regs()
35+
}
2436
}
2537

2638
/// Create a new context that will resume execution by running ~fn()
27-
/// # Safety Note
28-
/// The `start` closure must remain valid for the life of the Task
29-
fn new(start: &~fn(), stack: &mut StackSegment) -> Context {
39+
fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
40+
// XXX: Putting main into a ~ so it's a thin pointer and can
41+
// be passed to the spawn function. Another unfortunate
42+
// allocation
43+
let start = ~start;
3044

3145
// The C-ABI function that is the task entry point
3246
extern fn task_start_wrapper(f: &~fn()) { (*f)() }
@@ -40,21 +54,29 @@ pub impl Context {
4054
// which we will then modify to call the given function when restored
4155
let mut regs = new_regs();
4256
unsafe {
43-
swap_registers(transmute_mut_region(&mut *regs),
44-
transmute_region(&*regs))
57+
swap_registers(transmute_mut_region(&mut *regs), transmute_region(&*regs))
4558
};
4659

4760
initialize_call_frame(&mut *regs, fp, argp, sp);
4861

49-
return Context(regs);
62+
return Context {
63+
start: Some(start),
64+
regs: regs
65+
}
5066
}
5167

68+
/* Switch contexts
69+
70+
Suspend the current execution context and resume another by
71+
saving the registers values of the executing thread to a Context
72+
then loading the registers from a previously saved Context.
73+
*/
5274
fn swap(out_context: &mut Context, in_context: &Context) {
5375
let out_regs: &mut Registers = match out_context {
54-
&Context(~ref mut r) => r
76+
&Context { regs: ~ref mut r, _ } => r
5577
};
5678
let in_regs: &Registers = match in_context {
57-
&Context(~ref r) => r
79+
&Context { regs: ~ref r, _ } => r
5880
};
5981

6082
unsafe { swap_registers(out_regs, in_regs) };
@@ -84,11 +106,10 @@ fn new_regs() -> ~Registers {
84106
}
85107

86108
#[cfg(target_arch = "x86")]
87-
fn initialize_call_frame(regs: &mut Registers,
88-
fptr: *c_void, arg: *c_void, sp: *mut uint) {
109+
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
89110

90111
let sp = align_down(sp);
91-
let sp = mut_offset(sp, -4); // XXX: -4 words? Needs this be done at all?
112+
let sp = mut_offset(sp, -4);
92113

93114
unsafe { *sp = arg as uint; }
94115
let sp = mut_offset(sp, -1);
@@ -108,8 +129,7 @@ type Registers = [uint * 22];
108129
fn new_regs() -> ~Registers { ~[0, .. 22] }
109130

110131
#[cfg(target_arch = "x86_64")]
111-
fn initialize_call_frame(regs: &mut Registers,
112-
fptr: *c_void, arg: *c_void, sp: *mut uint) {
132+
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
113133

114134
// Redefinitions from regs.h
115135
static RUSTRT_ARG0: uint = 3;
@@ -143,8 +163,7 @@ type Registers = [uint * 32];
143163
fn new_regs() -> ~Registers { ~[0, .. 32] }
144164

145165
#[cfg(target_arch = "arm")]
146-
fn initialize_call_frame(regs: &mut Registers,
147-
fptr: *c_void, arg: *c_void, sp: *mut uint) {
166+
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
148167
let sp = mut_offset(sp, -1);
149168

150169
// The final return address. 0 indicates the bottom of the stack
@@ -162,8 +181,7 @@ type Registers = [uint * 32];
162181
fn new_regs() -> ~Registers { ~[0, .. 32] }
163182

164183
#[cfg(target_arch = "mips")]
165-
fn initialize_call_frame(regs: &mut Registers,
166-
fptr: *c_void, arg: *c_void, sp: *mut uint) {
184+
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
167185
let sp = mut_offset(sp, -1);
168186

169187
// The final return address. 0 indicates the bottom of the stack
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use prelude::*;
12+
use super::super::sched::*;
13+
use super::super::rtio::*;
14+
use super::Stream;
15+
16+
pub struct FileStream;
17+
18+
pub impl FileStream {
19+
fn new(_path: Path) -> FileStream {
20+
fail!()
21+
}
22+
}
23+
24+
impl Stream for FileStream {
25+
fn read(&mut self, _buf: &mut [u8]) -> uint {
26+
fail!()
27+
}
28+
29+
fn eof(&mut self) -> bool {
30+
fail!()
31+
}
32+
33+
fn write(&mut self, _v: &const [u8]) {
34+
fail!()
35+
}
36+
}
37+
38+
#[test]
39+
#[ignore]
40+
fn super_simple_smoke_test_lets_go_read_some_files_and_have_a_good_time() {
41+
let message = "it's alright. have a good time";
42+
let filename = Path("test.txt");
43+
let mut outstream = FileStream::new(filename);
44+
outstream.write(message.to_bytes());
45+
}

0 commit comments

Comments
 (0)