auto merge of #12248 : alexcrichton/rust/rollup, r=alexcrichton
This passed `make check` locally, so hopefully it passes on bors!
This commit is contained in:
commit
94d453e459
@ -125,10 +125,7 @@ ifdef TRACE
|
||||
CFG_RUSTC_FLAGS += -Z trace
|
||||
endif
|
||||
ifdef CFG_DISABLE_RPATH
|
||||
# NOTE: make this CFG_RUSTC_FLAGS after stage0 snapshot
|
||||
RUSTFLAGS_STAGE1 += -C no-rpath
|
||||
RUSTFLAGS_STAGE2 += -C no-rpath
|
||||
RUSTFLAGS_STAGE3 += -C no-rpath
|
||||
CFG_RUSTC_FLAGS += -C no-rpath
|
||||
endif
|
||||
|
||||
# The executables crated during this compilation process have no need to include
|
||||
@ -140,8 +137,7 @@ endif
|
||||
# snapshot will be generated with a statically linked rustc so we only have to
|
||||
# worry about the distribution of one file (with its native dynamic
|
||||
# dependencies)
|
||||
#
|
||||
# NOTE: after a snapshot (stage0), put this on stage0 as well
|
||||
RUSTFLAGS_STAGE0 += -C prefer-dynamic
|
||||
RUSTFLAGS_STAGE1 += -C prefer-dynamic
|
||||
|
||||
# platform-specific auto-configuration
|
||||
|
@ -12,7 +12,7 @@ PKG_ICO = $(S)src/etc/pkg/rust-logo.ico
|
||||
PKG_EXE = $(PKG_DIR)-install.exe
|
||||
endif
|
||||
|
||||
PKG_GITMODULES := $(S)src/libuv $(S)src/llvm $(S)src/gyp
|
||||
PKG_GITMODULES := $(S)src/libuv $(S)src/llvm $(S)src/gyp $(S)src/compiler-rt
|
||||
|
||||
PKG_FILES := \
|
||||
$(S)COPYRIGHT \
|
||||
|
34
mk/tests.mk
34
mk/tests.mk
@ -333,21 +333,22 @@ $(foreach host,$(CFG_HOST), \
|
||||
|
||||
define TEST_RUNNER
|
||||
|
||||
# If NO_REBUILD is set then break the dependencies on extra so we can
|
||||
# test crates without rebuilding std and extra first
|
||||
# If NO_REBUILD is set then break the dependencies on everything but
|
||||
# the source files so we can test crates without rebuilding any of the
|
||||
# parent crates.
|
||||
ifeq ($(NO_REBUILD),)
|
||||
STDTESTDEP_$(1)_$(2)_$(3)_$(4) = $$(SREQ$(1)_T_$(2)_H_$(3)) \
|
||||
TESTDEP_$(1)_$(2)_$(3)_$(4) = $$(SREQ$(1)_T_$(2)_H_$(3)) \
|
||||
$$(foreach crate,$$(TARGET_CRATES),\
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(crate))
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(crate)) \
|
||||
$$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4))
|
||||
else
|
||||
STDTESTDEP_$(1)_$(2)_$(3)_$(4) =
|
||||
TESTDEP_$(1)_$(2)_$(3)_$(4) = $$(RSINPUTS_$(4))
|
||||
endif
|
||||
|
||||
$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)): CFG_COMPILER = $(2)
|
||||
$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)): \
|
||||
$$(CRATEFILE_$(4)) \
|
||||
$$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \
|
||||
$$(STDTESTDEP_$(1)_$(2)_$(3)_$(4))
|
||||
$$(CRATEFILE_$(4)) \
|
||||
$$(TESTDEP_$(1)_$(2)_$(3)_$(4))
|
||||
@$$(call E, oxidize: $$@)
|
||||
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test \
|
||||
-L "$$(RT_OUTPUT_DIR_$(2))" \
|
||||
@ -684,13 +685,22 @@ $(foreach host,$(CFG_HOST), \
|
||||
|
||||
define DEF_CRATE_DOC_TEST
|
||||
|
||||
# If NO_REBUILD is set then break the dependencies on everything but
|
||||
# the source files so we can test crate documentation without
|
||||
# rebuilding any of the parent crates.
|
||||
ifeq ($(NO_REBUILD),)
|
||||
DOCTESTDEP_$(1)_$(2)_$(3)_$(4) = \
|
||||
$$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
|
||||
$$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \
|
||||
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3))
|
||||
else
|
||||
DOCTESTDEP_$(1)_$(2)_$(3)_$(4) = $$(RSINPUTS_$(4))
|
||||
endif
|
||||
|
||||
check-stage$(1)-T-$(2)-H-$(3)-doc-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4))
|
||||
|
||||
ifeq ($(2),$$(CFG_BUILD))
|
||||
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): \
|
||||
$$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
|
||||
$$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \
|
||||
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3))
|
||||
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): $$(DOCTESTDEP_$(1)_$(2)_$(3)_$(4))
|
||||
@$$(call E, run doc-$(4) [$(2)])
|
||||
$$(Q)$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) --test \
|
||||
$$(CRATEFILE_$(4)) --test-args "$$(TESTARGS)" && touch $$@
|
||||
|
@ -195,7 +195,7 @@ impl<T: Send> Unique<T> {
|
||||
pub fn new(value: T) -> Unique<T> {
|
||||
unsafe {
|
||||
let ptr = malloc(std::mem::size_of::<T>() as size_t) as *mut T;
|
||||
assert!(!ptr::is_null(ptr));
|
||||
assert!(!ptr.is_null());
|
||||
// `*ptr` is uninitialized, and `*ptr = value` would attempt to destroy it
|
||||
// move_val_init moves a value into this memory without
|
||||
// attempting to drop the original value.
|
||||
|
@ -1725,14 +1725,17 @@ mod bar {
|
||||
pub type int8_t = i8;
|
||||
~~~~
|
||||
|
||||
> **Note:** In future versions of Rust, user-provided extensions to the compiler will be able to interpret attributes.
|
||||
> When this facility is provided, the compiler will distinguish between language-reserved and user-available attributes.
|
||||
> **Note:** In future versions of Rust, user-provided extensions to the compiler
|
||||
> will be able to interpret attributes. When this facility is provided, the
|
||||
> compiler will distinguish between language-reserved and user-available
|
||||
> attributes.
|
||||
|
||||
At present, only the Rust compiler interprets attributes, so all attribute
|
||||
names are effectively reserved. Some significant attributes include:
|
||||
At present, only the Rust compiler interprets attributes, so all attribute names
|
||||
are effectively reserved. Some significant attributes include:
|
||||
|
||||
* The `doc` attribute, for documenting code in-place.
|
||||
* The `cfg` attribute, for conditional-compilation by build-configuration.
|
||||
* The `cfg` attribute, for conditional-compilation by build-configuration (see
|
||||
[Conditional compilation](#conditional-compilation)).
|
||||
* The `crate_id` attribute, for describing the package ID of a crate.
|
||||
* The `lang` attribute, for custom definitions of traits and functions that are
|
||||
known to the Rust compiler (see [Language items](#language-items)).
|
||||
@ -1740,16 +1743,77 @@ names are effectively reserved. Some significant attributes include:
|
||||
* The `test` attribute, for marking functions as unit tests.
|
||||
* The `allow`, `warn`, `forbid`, and `deny` attributes, for
|
||||
controlling lint checks (see [Lint check attributes](#lint-check-attributes)).
|
||||
* The `deriving` attribute, for automatically generating
|
||||
implementations of certain traits.
|
||||
* The `deriving` attribute, for automatically generating implementations of
|
||||
certain traits.
|
||||
* The `inline` attribute, for expanding functions at caller location (see
|
||||
[Inline attributes](#inline-attributes)).
|
||||
* The `static_assert` attribute, for asserting that a static bool is true at compiletime
|
||||
* The `thread_local` attribute, for defining a `static mut` as a thread-local. Note that this is
|
||||
only a low-level building block, and is not local to a *task*, nor does it provide safety.
|
||||
* The `static_assert` attribute, for asserting that a static bool is true at
|
||||
compiletime.
|
||||
* The `thread_local` attribute, for defining a `static mut` as a thread-local.
|
||||
Note that this is only a low-level building block, and is not local to a
|
||||
*task*, nor does it provide safety.
|
||||
|
||||
Other attributes may be added or removed during development of the language.
|
||||
|
||||
### Conditional compilation
|
||||
|
||||
Sometimes one wants to have different compiler outputs from the same code,
|
||||
depending on build target, such as targeted operating system, or to enable
|
||||
release builds.
|
||||
|
||||
There are two kinds of configuration options, one that is either defined or not
|
||||
(`#[cfg(foo)]`), and the other that contains a string that can be checked
|
||||
against (`#[cfg(bar = "baz")]` (currently only compiler-defined configuration
|
||||
options can have the latter form).
|
||||
|
||||
~~~~
|
||||
// The function is only included in the build when compiling for OSX
|
||||
#[cfg(target_os = "macos")]
|
||||
fn macos_only() {
|
||||
// ...
|
||||
}
|
||||
|
||||
// This function is only included when either foo or bar is defined
|
||||
#[cfg(foo)]
|
||||
#[cfg(bar)]
|
||||
fn needs_foo_or_bar() {
|
||||
// ...
|
||||
}
|
||||
|
||||
// This function is only included when compiling for a unixish OS with a 32-bit
|
||||
// architecture
|
||||
#[cfg(unix, target_word_size = "32")]
|
||||
fn on_32bit_unix() {
|
||||
// ...
|
||||
}
|
||||
~~~~
|
||||
|
||||
This illustrates some conditional compilation can be achieved using the
|
||||
`#[cfg(...)]` attribute. Note that `#[cfg(foo, bar)]` is a condition that needs
|
||||
both `foo` and `bar` to be defined while `#[cfg(foo)] #[cfg(bar)]` only needs
|
||||
one of `foo` and `bar` to be defined (this resembles in the disjunctive normal
|
||||
form). Additionally, one can reverse a condition by enclosing it in a
|
||||
`not(...)`, like e. g. `#[cfg(not(target_os = "win32"))]`.
|
||||
|
||||
To pass a configuration option which triggers a `#[cfg(identifier)]` one can use
|
||||
`rustc --cfg identifier`. In addition to that, the following configurations are
|
||||
pre-defined by the compiler:
|
||||
|
||||
* `target_arch = "..."`. Target CPU architecture, such as `"x86"`, `"x86_64"`
|
||||
`"mips"`, or `"arm"`.
|
||||
* `target_endian = "..."`. Endianness of the target CPU, either `"little"` or
|
||||
`"big"`.
|
||||
* `target_family = "..."`. Operating system family of the target, e. g.
|
||||
`"unix"` or `"windows"`. The value of this configuration option is defined as
|
||||
a configuration itself, like `unix` or `windows`.
|
||||
* `target_os = "..."`. Operating system of the target, examples include
|
||||
`"win32"`, `"macos"`, `"linux"`, `"android"` or `"freebsd"`.
|
||||
* `target_word_size = "..."`. Target word size in bits. This is set to `"32"`
|
||||
for 32-bit CPU targets, and likewise set to `"64"` for 64-bit CPU targets.
|
||||
* `test`. Only set in test builds (`rustc --test`).
|
||||
* `unix`. See `target_family`.
|
||||
* `windows`. See `target_family`.
|
||||
|
||||
### Lint check attributes
|
||||
|
||||
A lint check names a potentially undesirable coding pattern, such as
|
||||
|
@ -34,7 +34,6 @@ use std::cast;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::mem;
|
||||
use std::num;
|
||||
use std::ptr;
|
||||
use std::kinds::marker;
|
||||
use std::rc::Rc;
|
||||
use std::rt::global_heap;
|
||||
@ -144,7 +143,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
|
||||
let fill = chunk.fill.get();
|
||||
|
||||
while idx < fill {
|
||||
let tydesc_data: *uint = transmute(ptr::offset(buf, idx as int));
|
||||
let tydesc_data: *uint = transmute(buf.offset(idx as int));
|
||||
let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
|
||||
let (size, align) = ((*tydesc).size, (*tydesc).align);
|
||||
|
||||
@ -155,7 +154,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
|
||||
//debug!("freeing object: idx = {}, size = {}, align = {}, done = {}",
|
||||
// start, size, align, is_done);
|
||||
if is_done {
|
||||
((*tydesc).drop_glue)(ptr::offset(buf, start as int) as *i8);
|
||||
((*tydesc).drop_glue)(buf.offset(start as int) as *i8);
|
||||
}
|
||||
|
||||
// Find where the next tydesc lives
|
||||
@ -261,7 +260,7 @@ impl Arena {
|
||||
// start, n_bytes, align, head.fill);
|
||||
|
||||
let buf = self.head.as_ptr();
|
||||
return (ptr::offset(buf, tydesc_start as int), ptr::offset(buf, start as int));
|
||||
return (buf.offset(tydesc_start as int), buf.offset(start as int));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ impl <T> CVec<T> {
|
||||
pub fn get<'a>(&'a self, ofs: uint) -> &'a T {
|
||||
assert!(ofs < self.len);
|
||||
unsafe {
|
||||
&*ptr::mut_offset(self.base, ofs as int)
|
||||
&*self.base.offset(ofs as int)
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ impl <T> CVec<T> {
|
||||
pub fn get_mut<'a>(&'a mut self, ofs: uint) -> &'a mut T {
|
||||
assert!(ofs < self.len);
|
||||
unsafe {
|
||||
&mut *ptr::mut_offset(self.base, ofs as int)
|
||||
&mut *self.base.offset(ofs as int)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,20 +35,10 @@ Rust extras are part of the standard Rust distribution.
|
||||
#[deny(missing_doc)];
|
||||
|
||||
extern mod sync;
|
||||
#[cfg(not(stage0))]
|
||||
extern mod serialize;
|
||||
|
||||
extern mod collections;
|
||||
|
||||
#[cfg(stage0)]
|
||||
pub mod serialize {
|
||||
#[allow(missing_doc)];
|
||||
// Temp re-export until after a snapshot
|
||||
extern mod serialize = "serialize";
|
||||
pub use self::serialize::{Encoder, Decoder, Encodable, Decodable,
|
||||
EncoderHelpers, DecoderHelpers};
|
||||
}
|
||||
|
||||
// Utility modules
|
||||
|
||||
pub mod c_vec;
|
||||
@ -59,11 +49,9 @@ pub mod url;
|
||||
pub mod json;
|
||||
pub mod tempfile;
|
||||
pub mod time;
|
||||
pub mod base64;
|
||||
pub mod workcache;
|
||||
pub mod enum_set;
|
||||
pub mod stats;
|
||||
pub mod hex;
|
||||
|
||||
#[cfg(unicode)]
|
||||
mod unicode;
|
||||
|
@ -784,11 +784,12 @@ impl BigUint {
|
||||
if n_bits == 0 || self.data.is_empty() { return (*self).clone(); }
|
||||
|
||||
let mut borrow = 0;
|
||||
let mut shifted = ~[];
|
||||
let mut shifted_rev = vec::with_capacity(self.data.len());
|
||||
for elem in self.data.rev_iter() {
|
||||
shifted = ~[(*elem >> n_bits) | borrow] + shifted;
|
||||
shifted_rev.push((*elem >> n_bits) | borrow);
|
||||
borrow = *elem << (BigDigit::bits - n_bits);
|
||||
}
|
||||
let shifted = { shifted_rev.reverse(); shifted_rev };
|
||||
return BigUint::new(shifted);
|
||||
}
|
||||
|
||||
@ -2637,4 +2638,15 @@ mod bench {
|
||||
fib.to_str();
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn shr(bh: &mut BenchHarness) {
|
||||
let n = { let one : BigUint = One::one(); one << 1000 };
|
||||
bh.iter(|| {
|
||||
let mut m = n.clone();
|
||||
for _ in range(0, 10) {
|
||||
m = m >> 1;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ use std::run;
|
||||
use std::str;
|
||||
use std::io;
|
||||
use std::io::fs;
|
||||
use extra::hex::ToHex;
|
||||
use serialize::hex::ToHex;
|
||||
use extra::tempfile::TempDir;
|
||||
use syntax::abi;
|
||||
use syntax::ast;
|
||||
|
@ -30,7 +30,6 @@ use std::io;
|
||||
use std::num;
|
||||
use std::option;
|
||||
use std::os::consts::{macos, freebsd, linux, android, win32};
|
||||
use std::ptr;
|
||||
use std::str;
|
||||
use std::vec;
|
||||
use flate;
|
||||
@ -340,7 +339,7 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Option<MetadataBlob> {
|
||||
});
|
||||
if !version_ok { return None; }
|
||||
|
||||
let cvbuf1 = ptr::offset(cvbuf, vlen as int);
|
||||
let cvbuf1 = cvbuf.offset(vlen as int);
|
||||
debug!("inflating {} bytes of compressed metadata",
|
||||
csz - vlen);
|
||||
vec::raw::buf_as_slice(cvbuf1, csz-vlen, |bytes| {
|
||||
|
@ -21,7 +21,6 @@ use std::cast;
|
||||
use std::hashmap::HashMap;
|
||||
use std::libc::{c_uint, c_ulonglong, c_char};
|
||||
use syntax::codemap::Span;
|
||||
use std::ptr::is_not_null;
|
||||
|
||||
pub struct Builder<'a> {
|
||||
llbuilder: BuilderRef,
|
||||
@ -492,7 +491,7 @@ impl<'a> Builder<'a> {
|
||||
debug!("Store {} -> {}",
|
||||
self.ccx.tn.val_to_str(val),
|
||||
self.ccx.tn.val_to_str(ptr));
|
||||
assert!(is_not_null(self.llbuilder));
|
||||
assert!(self.llbuilder.is_not_null());
|
||||
self.count_insn("store");
|
||||
unsafe {
|
||||
llvm::LLVMBuildStore(self.llbuilder, val, ptr);
|
||||
@ -503,7 +502,7 @@ impl<'a> Builder<'a> {
|
||||
debug!("Store {} -> {}",
|
||||
self.ccx.tn.val_to_str(val),
|
||||
self.ccx.tn.val_to_str(ptr));
|
||||
assert!(is_not_null(self.llbuilder));
|
||||
assert!(self.llbuilder.is_not_null());
|
||||
self.count_insn("store.volatile");
|
||||
unsafe {
|
||||
let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
|
||||
|
@ -3035,6 +3035,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
if type_is_c_like_enum(fcx, expr.span, t_e) && t_1_is_trivial {
|
||||
// casts from C-like enums are allowed
|
||||
} else if t_1_is_char {
|
||||
let te = fcx.infcx().resolve_type_vars_if_possible(te);
|
||||
if ty::get(te).sty != ty::ty_uint(ast::TyU8) {
|
||||
fcx.type_error_message(expr.span, |actual| {
|
||||
format!("only `u8` can be cast as `char`, not `{}`", actual)
|
||||
|
@ -16,7 +16,7 @@ use std::iter::range_step;
|
||||
use std::num::Zero;
|
||||
use std::vec;
|
||||
use std::vec::bytes::{MutableByteVector, copy_memory};
|
||||
use extra::hex::ToHex;
|
||||
use serialize::hex::ToHex;
|
||||
|
||||
/// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian
|
||||
/// format.
|
||||
@ -529,7 +529,7 @@ mod tests {
|
||||
use std::vec;
|
||||
use std::rand::isaac::IsaacRng;
|
||||
use std::rand::Rng;
|
||||
use extra::hex::FromHex;
|
||||
use serialize::hex::FromHex;
|
||||
|
||||
// A normal addition - no overflow occurs
|
||||
#[test]
|
||||
|
@ -342,7 +342,9 @@ impl Clean<Item> for ast::Method {
|
||||
_ => self.decl.inputs.slice_from(1)
|
||||
};
|
||||
let decl = FnDecl {
|
||||
inputs: inputs.iter().map(|x| x.clean()).collect(),
|
||||
inputs: Arguments {
|
||||
values: inputs.iter().map(|x| x.clean()).collect(),
|
||||
},
|
||||
output: (self.decl.output.clean()),
|
||||
cf: self.decl.cf.clean(),
|
||||
attrs: ~[]
|
||||
@ -378,7 +380,9 @@ impl Clean<Item> for ast::TypeMethod {
|
||||
_ => self.decl.inputs.slice_from(1)
|
||||
};
|
||||
let decl = FnDecl {
|
||||
inputs: inputs.iter().map(|x| x.clean()).collect(),
|
||||
inputs: Arguments {
|
||||
values: inputs.iter().map(|x| x.clean()).collect(),
|
||||
},
|
||||
output: (self.decl.output.clean()),
|
||||
cf: self.decl.cf.clean(),
|
||||
attrs: ~[]
|
||||
@ -472,16 +476,23 @@ impl Clean<ClosureDecl> for ast::ClosureTy {
|
||||
|
||||
#[deriving(Clone, Encodable, Decodable)]
|
||||
pub struct FnDecl {
|
||||
inputs: ~[Argument],
|
||||
inputs: Arguments,
|
||||
output: Type,
|
||||
cf: RetStyle,
|
||||
attrs: ~[Attribute]
|
||||
}
|
||||
|
||||
#[deriving(Clone, Encodable, Decodable)]
|
||||
pub struct Arguments {
|
||||
values: ~[Argument],
|
||||
}
|
||||
|
||||
impl Clean<FnDecl> for ast::FnDecl {
|
||||
fn clean(&self) -> FnDecl {
|
||||
FnDecl {
|
||||
inputs: self.inputs.iter().map(|x| x.clean()).collect(),
|
||||
inputs: Arguments {
|
||||
values: self.inputs.iter().map(|x| x.clean()).collect(),
|
||||
},
|
||||
output: (self.output.clean()),
|
||||
cf: self.cf.clean(),
|
||||
attrs: ~[]
|
||||
|
@ -404,6 +404,19 @@ impl fmt::Show for clean::Type {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::Arguments {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for (i, input) in self.values.iter().enumerate() {
|
||||
if i > 0 { if_ok!(write!(f.buf, ", ")); }
|
||||
if input.name.len() > 0 {
|
||||
if_ok!(write!(f.buf, "{}: ", input.name));
|
||||
}
|
||||
if_ok!(write!(f.buf, "{}", input.type_));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::FnDecl {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}",
|
||||
@ -413,20 +426,6 @@ impl fmt::Show for clean::FnDecl {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for ~[clean::Argument] {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut args = ~"";
|
||||
for (i, input) in self.iter().enumerate() {
|
||||
if i > 0 { args.push_str(", "); }
|
||||
if input.name.len() > 0 {
|
||||
args.push_str(format!("{}: ", input.name));
|
||||
}
|
||||
args.push_str(format!("{}", input.type_));
|
||||
}
|
||||
f.buf.write(args.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for Method<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Method(selfty, d) = *self;
|
||||
@ -448,7 +447,7 @@ impl<'a> fmt::Show for Method<'a> {
|
||||
args.push_str("&self");
|
||||
}
|
||||
}
|
||||
for (i, input) in d.inputs.iter().enumerate() {
|
||||
for (i, input) in d.inputs.values.iter().enumerate() {
|
||||
if i > 0 || args.len() > 0 { args.push_str(", "); }
|
||||
if input.name.len() > 0 {
|
||||
args.push_str(format!("{}: ", input.name));
|
||||
|
@ -426,7 +426,7 @@ mod test {
|
||||
unsafe {
|
||||
let base = transmute::<*u8, *mut u8>(buf.base);
|
||||
(*base) = 1;
|
||||
(*ptr::mut_offset(base, 1)) = 2;
|
||||
(*base.offset(1)) = 2;
|
||||
}
|
||||
|
||||
assert!(slice[0] == 1);
|
||||
|
@ -63,8 +63,8 @@ impl<'a> ToBase64 for &'a [u8] {
|
||||
* # Example
|
||||
*
|
||||
* ```rust
|
||||
* extern mod extra;
|
||||
* use extra::base64::{ToBase64, STANDARD};
|
||||
* extern mod serialize;
|
||||
* use serialize::base64::{ToBase64, STANDARD};
|
||||
*
|
||||
* fn main () {
|
||||
* let str = [52,32].to_base64(STANDARD);
|
||||
@ -189,8 +189,8 @@ impl<'a> FromBase64 for &'a str {
|
||||
* This converts a string literal to base64 and back.
|
||||
*
|
||||
* ```rust
|
||||
* extern mod extra;
|
||||
* use extra::base64::{ToBase64, FromBase64, STANDARD};
|
||||
* extern mod serialize;
|
||||
* use serialize::base64::{ToBase64, FromBase64, STANDARD};
|
||||
* use std::str;
|
||||
*
|
||||
* fn main () {
|
||||
@ -261,8 +261,8 @@ impl<'a> FromBase64 for &'a str {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use test::BenchHarness;
|
||||
use base64::*;
|
||||
use extra::test::BenchHarness;
|
||||
use base64::{Config, FromBase64, ToBase64, STANDARD, URL_SAFE};
|
||||
|
||||
#[test]
|
||||
fn test_to_base64_basic() {
|
@ -131,7 +131,6 @@ pub mod reader {
|
||||
}
|
||||
|
||||
pub fn vuint_at(data: &[u8], start: uint) -> Res {
|
||||
use std::ptr::offset;
|
||||
use std::mem::from_be32;
|
||||
|
||||
if data.len() - start < 4 {
|
||||
@ -163,7 +162,7 @@ pub mod reader {
|
||||
|
||||
unsafe {
|
||||
let (ptr, _): (*u8, uint) = transmute(data);
|
||||
let ptr = offset(ptr, start as int);
|
||||
let ptr = ptr.offset(start as int);
|
||||
let ptr: *i32 = transmute(ptr);
|
||||
let val = from_be32(*ptr) as u32;
|
||||
|
||||
|
@ -28,7 +28,8 @@ impl<'a> ToHex for &'a [u8] {
|
||||
* # Example
|
||||
*
|
||||
* ```rust
|
||||
* use extra::hex::ToHex;
|
||||
* extern mod serialize;
|
||||
* use serialize::hex::ToHex;
|
||||
*
|
||||
* fn main () {
|
||||
* let str = [52,32].to_hex();
|
||||
@ -88,7 +89,8 @@ impl<'a> FromHex for &'a str {
|
||||
* This converts a string literal to hexadecimal and back.
|
||||
*
|
||||
* ```rust
|
||||
* use extra::hex::{FromHex, ToHex};
|
||||
* extern mod serialize;
|
||||
* use serialize::hex::{FromHex, ToHex};
|
||||
* use std::str;
|
||||
*
|
||||
* fn main () {
|
||||
@ -137,8 +139,8 @@ impl<'a> FromHex for &'a str {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use test::BenchHarness;
|
||||
use hex::*;
|
||||
use extra::test::BenchHarness;
|
||||
use hex::{FromHex, ToHex};
|
||||
|
||||
#[test]
|
||||
pub fn test_to_hex() {
|
@ -30,4 +30,8 @@ pub use self::serialize::{Decoder, Encoder, Decodable, Encodable,
|
||||
DecoderHelpers, EncoderHelpers};
|
||||
|
||||
mod serialize;
|
||||
|
||||
pub mod base64;
|
||||
pub mod ebml;
|
||||
pub mod hex;
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
//! extension traits (`*Ext`) for the full details.
|
||||
|
||||
use cast::transmute;
|
||||
use fmt;
|
||||
use option::{Option, Some, None};
|
||||
use result::{Result, Ok, Err};
|
||||
use to_str::ToStr;
|
||||
@ -158,6 +159,18 @@ impl<'a> ToStr for &'a Any {
|
||||
fn to_str(&self) -> ~str { ~"&Any" }
|
||||
}
|
||||
|
||||
impl fmt::Show for ~Any {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.pad("~Any")
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for &'a Any {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.pad("&Any")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use prelude::*;
|
||||
@ -377,4 +390,17 @@ mod tests {
|
||||
assert!(a.move::<~Test>().is_err());
|
||||
assert!(b.move::<~uint>().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
let a = ~8u as ~Any;
|
||||
let b = ~Test as ~Any;
|
||||
assert_eq!(format!("{}", a), ~"~Any");
|
||||
assert_eq!(format!("{}", b), ~"~Any");
|
||||
|
||||
let a = &8u as &Any;
|
||||
let b = &Test as &Any;
|
||||
assert_eq!(format!("{}", a), ~"&Any");
|
||||
assert_eq!(format!("{}", b), ~"&Any");
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ use str::StrSlice;
|
||||
use str::OwnedStr;
|
||||
use container::Container;
|
||||
use cast;
|
||||
use fmt;
|
||||
use iter::Iterator;
|
||||
use vec::{ImmutableVector, MutableVector, Vector};
|
||||
use to_bytes::IterBytes;
|
||||
@ -134,6 +135,12 @@ impl ToStr for Ascii {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for Ascii {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
(self.chr as char).fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for converting into an ascii type.
|
||||
pub trait AsciiCast<T> {
|
||||
/// Convert to an ascii type, fail on non-ASCII input.
|
||||
@ -698,5 +705,9 @@ mod tests {
|
||||
assert_eq!(s, ~"t");
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
let c = Ascii { chr: 't' as u8 };
|
||||
assert_eq!(format!("{}", c), ~"t");
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ impl<'a> ToCStr for &'a [u8] {
|
||||
let buf = malloc_raw(self_len + 1);
|
||||
|
||||
ptr::copy_memory(buf, self.as_ptr(), self_len);
|
||||
*ptr::mut_offset(buf, self_len as int) = 0;
|
||||
*buf.offset(self_len as int) = 0;
|
||||
|
||||
CString::new(buf as *libc::c_char, true)
|
||||
}
|
||||
@ -368,7 +368,7 @@ impl<'a> Iterator<libc::c_char> for CChars<'a> {
|
||||
if ch == 0 {
|
||||
None
|
||||
} else {
|
||||
self.ptr = unsafe { ptr::offset(self.ptr, 1) };
|
||||
self.ptr = unsafe { self.ptr.offset(1) };
|
||||
Some(ch)
|
||||
}
|
||||
}
|
||||
@ -429,18 +429,18 @@ mod tests {
|
||||
fn test_str_to_c_str() {
|
||||
"".to_c_str().with_ref(|buf| {
|
||||
unsafe {
|
||||
assert_eq!(*ptr::offset(buf, 0), 0);
|
||||
assert_eq!(*buf.offset(0), 0);
|
||||
}
|
||||
});
|
||||
|
||||
"hello".to_c_str().with_ref(|buf| {
|
||||
unsafe {
|
||||
assert_eq!(*ptr::offset(buf, 0), 'h' as libc::c_char);
|
||||
assert_eq!(*ptr::offset(buf, 1), 'e' as libc::c_char);
|
||||
assert_eq!(*ptr::offset(buf, 2), 'l' as libc::c_char);
|
||||
assert_eq!(*ptr::offset(buf, 3), 'l' as libc::c_char);
|
||||
assert_eq!(*ptr::offset(buf, 4), 'o' as libc::c_char);
|
||||
assert_eq!(*ptr::offset(buf, 5), 0);
|
||||
assert_eq!(*buf.offset(0), 'h' as libc::c_char);
|
||||
assert_eq!(*buf.offset(1), 'e' as libc::c_char);
|
||||
assert_eq!(*buf.offset(2), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(3), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(4), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(5), 0);
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -450,28 +450,28 @@ mod tests {
|
||||
let b: &[u8] = [];
|
||||
b.to_c_str().with_ref(|buf| {
|
||||
unsafe {
|
||||
assert_eq!(*ptr::offset(buf, 0), 0);
|
||||
assert_eq!(*buf.offset(0), 0);
|
||||
}
|
||||
});
|
||||
|
||||
let _ = bytes!("hello").to_c_str().with_ref(|buf| {
|
||||
unsafe {
|
||||
assert_eq!(*ptr::offset(buf, 0), 'h' as libc::c_char);
|
||||
assert_eq!(*ptr::offset(buf, 1), 'e' as libc::c_char);
|
||||
assert_eq!(*ptr::offset(buf, 2), 'l' as libc::c_char);
|
||||
assert_eq!(*ptr::offset(buf, 3), 'l' as libc::c_char);
|
||||
assert_eq!(*ptr::offset(buf, 4), 'o' as libc::c_char);
|
||||
assert_eq!(*ptr::offset(buf, 5), 0);
|
||||
assert_eq!(*buf.offset(0), 'h' as libc::c_char);
|
||||
assert_eq!(*buf.offset(1), 'e' as libc::c_char);
|
||||
assert_eq!(*buf.offset(2), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(3), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(4), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(5), 0);
|
||||
}
|
||||
});
|
||||
|
||||
let _ = bytes!("foo", 0xff).to_c_str().with_ref(|buf| {
|
||||
unsafe {
|
||||
assert_eq!(*ptr::offset(buf, 0), 'f' as libc::c_char);
|
||||
assert_eq!(*ptr::offset(buf, 1), 'o' as libc::c_char);
|
||||
assert_eq!(*ptr::offset(buf, 2), 'o' as libc::c_char);
|
||||
assert_eq!(*ptr::offset(buf, 3), 0xff as i8);
|
||||
assert_eq!(*ptr::offset(buf, 4), 0);
|
||||
assert_eq!(*buf.offset(0), 'f' as libc::c_char);
|
||||
assert_eq!(*buf.offset(1), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(2), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(3), 0xff as i8);
|
||||
assert_eq!(*buf.offset(4), 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -634,7 +634,6 @@ mod bench {
|
||||
use extra::test::BenchHarness;
|
||||
use libc;
|
||||
use prelude::*;
|
||||
use ptr;
|
||||
|
||||
#[inline]
|
||||
fn check(s: &str, c_str: *libc::c_char) {
|
||||
@ -642,8 +641,8 @@ mod bench {
|
||||
for i in range(0, s.len()) {
|
||||
unsafe {
|
||||
assert_eq!(
|
||||
*ptr::offset(s_buf, i as int) as libc::c_char,
|
||||
*ptr::offset(c_str, i as int));
|
||||
*s_buf.offset(i as int) as libc::c_char,
|
||||
*c_str.offset(i as int));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,53 +57,6 @@ fn debug_mem() -> bool {
|
||||
}
|
||||
|
||||
/// Destroys all managed memory (i.e. @ boxes) held by the current task.
|
||||
#[cfg(stage0)]
|
||||
pub unsafe fn annihilate() {
|
||||
use rt::local_heap::local_free;
|
||||
|
||||
let mut n_total_boxes = 0u;
|
||||
|
||||
// Pass 1: Make all boxes immortal.
|
||||
//
|
||||
// In this pass, nothing gets freed, so it does not matter whether
|
||||
// we read the next field before or after the callback.
|
||||
each_live_alloc(true, |alloc| {
|
||||
n_total_boxes += 1;
|
||||
(*alloc).ref_count = RC_IMMORTAL;
|
||||
true
|
||||
});
|
||||
|
||||
// Pass 2: Drop all boxes.
|
||||
//
|
||||
// In this pass, unique-managed boxes may get freed, but not
|
||||
// managed boxes, so we must read the `next` field *after* the
|
||||
// callback, as the original value may have been freed.
|
||||
each_live_alloc(false, |alloc| {
|
||||
let tydesc = (*alloc).type_desc;
|
||||
let data = &(*alloc).data as *();
|
||||
((*tydesc).drop_glue)(data as *i8);
|
||||
true
|
||||
});
|
||||
|
||||
// Pass 3: Free all boxes.
|
||||
//
|
||||
// In this pass, managed boxes may get freed (but not
|
||||
// unique-managed boxes, though I think that none of those are
|
||||
// left), so we must read the `next` field before, since it will
|
||||
// not be valid after.
|
||||
each_live_alloc(true, |alloc| {
|
||||
local_free(alloc as *u8);
|
||||
true
|
||||
});
|
||||
|
||||
if debug_mem() {
|
||||
// We do logging here w/o allocation.
|
||||
debug!("total boxes annihilated: {}", n_total_boxes);
|
||||
}
|
||||
}
|
||||
|
||||
/// Destroys all managed memory (i.e. @ boxes) held by the current task.
|
||||
#[cfg(not(stage0))]
|
||||
pub unsafe fn annihilate() {
|
||||
use rt::local_heap::local_free;
|
||||
|
||||
|
@ -60,21 +60,17 @@ use uint;
|
||||
|
||||
macro_rules! select {
|
||||
(
|
||||
$name1:pat = $port1:ident.$meth1:ident() => $code1:expr,
|
||||
$($name:pat = $port:ident.$meth:ident() => $code:expr),*
|
||||
$($name:pat = $port:ident.$meth:ident() => $code:expr),+
|
||||
) => ({
|
||||
use std::comm::Select;
|
||||
let sel = Select::new();
|
||||
let mut $port1 = sel.handle(&$port1);
|
||||
$( let mut $port = sel.handle(&$port); )*
|
||||
$( let mut $port = sel.handle(&$port); )+
|
||||
unsafe {
|
||||
$port1.add();
|
||||
$( $port.add(); )*
|
||||
$( $port.add(); )+
|
||||
}
|
||||
let ret = sel.wait();
|
||||
if ret == $port1.id { let $name1 = $port1.$meth1(); $code1 }
|
||||
$( else if ret == $port.id { let $name = $port.$meth(); $code } )*
|
||||
else { unreachable!() }
|
||||
$( if ret == $port.id() { let $name = $port.$meth(); $code } else )+
|
||||
{ unreachable!() }
|
||||
})
|
||||
}
|
||||
|
||||
@ -94,7 +90,7 @@ pub struct Select {
|
||||
pub struct Handle<'port, T> {
|
||||
/// The ID of this handle, used to compare against the return value of
|
||||
/// `Select::wait()`
|
||||
id: uint,
|
||||
priv id: uint,
|
||||
priv selector: &'port Select,
|
||||
priv next: *mut Handle<'static, ()>,
|
||||
priv prev: *mut Handle<'static, ()>,
|
||||
@ -150,11 +146,16 @@ impl Select {
|
||||
|
||||
/// Waits for an event on this port set. The returned valus is *not* and
|
||||
/// index, but rather an id. This id can be queried against any active
|
||||
/// `Handle` structures (each one has a public `id` field). The handle with
|
||||
/// `Handle` structures (each one has an `id` method). The handle with
|
||||
/// the matching `id` will have some sort of event available on it. The
|
||||
/// event could either be that data is available or the corresponding
|
||||
/// channel has been closed.
|
||||
pub fn wait(&self) -> uint {
|
||||
self.wait2(false)
|
||||
}
|
||||
|
||||
/// Helper method for skipping the preflight checks during testing
|
||||
fn wait2(&self, do_preflight_checks: bool) -> uint {
|
||||
// Note that this is currently an inefficient implementation. We in
|
||||
// theory have knowledge about all ports in the set ahead of time, so
|
||||
// this method shouldn't really have to iterate over all of them yet
|
||||
@ -179,7 +180,7 @@ impl Select {
|
||||
let mut amt = 0;
|
||||
for p in self.iter() {
|
||||
amt += 1;
|
||||
if (*p).packet.can_recv() {
|
||||
if do_preflight_checks && (*p).packet.can_recv() {
|
||||
return (*p).id;
|
||||
}
|
||||
}
|
||||
@ -242,6 +243,10 @@ impl Select {
|
||||
}
|
||||
|
||||
impl<'port, T: Send> Handle<'port, T> {
|
||||
/// Retrieve the id of this handle.
|
||||
#[inline]
|
||||
pub fn id(&self) -> uint { self.id }
|
||||
|
||||
/// Receive a value on the underlying port. Has the same semantics as
|
||||
/// `Port.recv`
|
||||
pub fn recv(&mut self) -> T { self.port.recv() }
|
||||
@ -355,7 +360,7 @@ mod test {
|
||||
)
|
||||
drop(c2);
|
||||
select! (
|
||||
bar = p2.recv_opt() => { assert_eq!(bar, None); },
|
||||
bar = p2.recv_opt() => { assert_eq!(bar, None); }
|
||||
)
|
||||
})
|
||||
|
||||
@ -507,7 +512,7 @@ mod test {
|
||||
let (p2, c2) = Chan::<()>::new();
|
||||
let (p, c) = Chan::new();
|
||||
spawn(proc() {
|
||||
let mut s = Select::new();
|
||||
let s = Select::new();
|
||||
let mut h1 = s.handle(&p1);
|
||||
let mut h2 = s.handle(&p2);
|
||||
unsafe { h2.add(); }
|
||||
@ -521,4 +526,91 @@ mod test {
|
||||
c2.send(());
|
||||
p.recv();
|
||||
})
|
||||
|
||||
test!(fn preflight1() {
|
||||
let (p, c) = Chan::new();
|
||||
c.send(());
|
||||
select!(
|
||||
() = p.recv() => {}
|
||||
)
|
||||
})
|
||||
|
||||
test!(fn preflight2() {
|
||||
let (p, c) = Chan::new();
|
||||
c.send(());
|
||||
c.send(());
|
||||
select!(
|
||||
() = p.recv() => {}
|
||||
)
|
||||
})
|
||||
|
||||
test!(fn preflight3() {
|
||||
let (p, c) = Chan::new();
|
||||
drop(c.clone());
|
||||
c.send(());
|
||||
select!(
|
||||
() = p.recv() => {}
|
||||
)
|
||||
})
|
||||
|
||||
test!(fn preflight4() {
|
||||
let (p, c) = Chan::new();
|
||||
c.send(());
|
||||
let s = Select::new();
|
||||
let mut h = s.handle(&p);
|
||||
unsafe { h.add(); }
|
||||
assert_eq!(s.wait2(false), h.id);
|
||||
})
|
||||
|
||||
test!(fn preflight5() {
|
||||
let (p, c) = Chan::new();
|
||||
c.send(());
|
||||
c.send(());
|
||||
let s = Select::new();
|
||||
let mut h = s.handle(&p);
|
||||
unsafe { h.add(); }
|
||||
assert_eq!(s.wait2(false), h.id);
|
||||
})
|
||||
|
||||
test!(fn preflight6() {
|
||||
let (p, c) = Chan::new();
|
||||
drop(c.clone());
|
||||
c.send(());
|
||||
let s = Select::new();
|
||||
let mut h = s.handle(&p);
|
||||
unsafe { h.add(); }
|
||||
assert_eq!(s.wait2(false), h.id);
|
||||
})
|
||||
|
||||
test!(fn preflight7() {
|
||||
let (p, c) = Chan::<()>::new();
|
||||
drop(c);
|
||||
let s = Select::new();
|
||||
let mut h = s.handle(&p);
|
||||
unsafe { h.add(); }
|
||||
assert_eq!(s.wait2(false), h.id);
|
||||
})
|
||||
|
||||
test!(fn preflight8() {
|
||||
let (p, c) = Chan::new();
|
||||
c.send(());
|
||||
drop(c);
|
||||
p.recv();
|
||||
let s = Select::new();
|
||||
let mut h = s.handle(&p);
|
||||
unsafe { h.add(); }
|
||||
assert_eq!(s.wait2(false), h.id);
|
||||
})
|
||||
|
||||
test!(fn preflight9() {
|
||||
let (p, c) = Chan::new();
|
||||
drop(c.clone());
|
||||
c.send(());
|
||||
drop(c);
|
||||
p.recv();
|
||||
let s = Select::new();
|
||||
let mut h = s.handle(&p);
|
||||
unsafe { h.add(); }
|
||||
assert_eq!(s.wait2(false), h.id);
|
||||
})
|
||||
}
|
||||
|
@ -398,6 +398,17 @@ impl<T: Send> Packet<T> {
|
||||
cnt == DISCONNECTED || cnt - self.steals > 0
|
||||
}
|
||||
|
||||
// increment the count on the channel (used for selection)
|
||||
fn bump(&mut self, amt: int) -> int {
|
||||
match self.cnt.fetch_add(amt, atomics::SeqCst) {
|
||||
DISCONNECTED => {
|
||||
self.cnt.store(DISCONNECTED, atomics::SeqCst);
|
||||
DISCONNECTED
|
||||
}
|
||||
n => n
|
||||
}
|
||||
}
|
||||
|
||||
// Inserts the blocked task for selection on this port, returning it back if
|
||||
// the port already has data on it.
|
||||
//
|
||||
@ -408,8 +419,8 @@ impl<T: Send> Packet<T> {
|
||||
match self.decrement(task) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(task) => {
|
||||
let prev = self.cnt.fetch_add(1, atomics::SeqCst);
|
||||
assert!(prev >= 0);
|
||||
let prev = self.bump(1);
|
||||
assert!(prev == DISCONNECTED || prev >= 0);
|
||||
return Err(task);
|
||||
}
|
||||
}
|
||||
@ -440,11 +451,10 @@ impl<T: Send> Packet<T> {
|
||||
let cnt = self.cnt.load(atomics::SeqCst);
|
||||
if cnt < 0 && cnt != DISCONNECTED {-cnt} else {0}
|
||||
};
|
||||
let prev = self.cnt.fetch_add(steals + 1, atomics::SeqCst);
|
||||
let prev = self.bump(steals + 1);
|
||||
|
||||
if prev == DISCONNECTED {
|
||||
assert_eq!(self.to_wake.load(atomics::SeqCst), 0);
|
||||
self.cnt.store(DISCONNECTED, atomics::SeqCst);
|
||||
true
|
||||
} else {
|
||||
let cur = prev + steals + 1;
|
||||
|
@ -333,6 +333,17 @@ impl<T: Send> Packet<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// increment the count on the channel (used for selection)
|
||||
fn bump(&mut self, amt: int) -> int {
|
||||
match self.cnt.fetch_add(amt, atomics::SeqCst) {
|
||||
DISCONNECTED => {
|
||||
self.cnt.store(DISCONNECTED, atomics::SeqCst);
|
||||
DISCONNECTED
|
||||
}
|
||||
n => n
|
||||
}
|
||||
}
|
||||
|
||||
// Attempts to start selecting on this port. Like a oneshot, this can fail
|
||||
// immediately because of an upgrade.
|
||||
pub fn start_selection(&mut self, task: BlockedTask) -> SelectionResult<T> {
|
||||
@ -351,8 +362,8 @@ impl<T: Send> Packet<T> {
|
||||
};
|
||||
// Undo our decrement above, and we should be guaranteed that the
|
||||
// previous value is positive because we're not going to sleep
|
||||
let prev = self.cnt.fetch_add(1, atomics::SeqCst);
|
||||
assert!(prev >= 0);
|
||||
let prev = self.bump(1);
|
||||
assert!(prev == DISCONNECTED || prev >= 0);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -384,13 +395,12 @@ impl<T: Send> Packet<T> {
|
||||
// and in the stream case we can have at most one steal, so just assume
|
||||
// that we had one steal.
|
||||
let steals = 1;
|
||||
let prev = self.cnt.fetch_add(steals + 1, atomics::SeqCst);
|
||||
let prev = self.bump(steals + 1);
|
||||
|
||||
// If we were previously disconnected, then we know for sure that there
|
||||
// is no task in to_wake, so just keep going
|
||||
let has_data = if prev == DISCONNECTED {
|
||||
assert_eq!(self.to_wake.load(atomics::SeqCst), 0);
|
||||
self.cnt.store(DISCONNECTED, atomics::SeqCst);
|
||||
true // there is data, that data is that we're disconnected
|
||||
} else {
|
||||
let cur = prev + steals + 1;
|
||||
|
@ -56,6 +56,7 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
|
||||
use clone::Clone;
|
||||
use cmp::{Eq, Equiv};
|
||||
use default::Default;
|
||||
#[cfg(not(stage0))] use fmt;
|
||||
use hash::Hash;
|
||||
use iter;
|
||||
use iter::{Iterator, FromIterator, Extendable};
|
||||
@ -65,6 +66,7 @@ use num;
|
||||
use option::{None, Option, Some};
|
||||
use rand::Rng;
|
||||
use rand;
|
||||
#[cfg(not(stage0))] use result::{Ok, Err};
|
||||
use vec::{ImmutableVector, MutableVector, OwnedVector, Items, MutItems};
|
||||
use vec_ng;
|
||||
use vec_ng::Vec;
|
||||
@ -595,6 +597,23 @@ impl<K:Hash + Eq + Clone,V:Clone> Clone for HashMap<K,V> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for HashMap<A, B> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if_ok!(write!(f.buf, r"\{"))
|
||||
let mut first = true;
|
||||
for (key, value) in self.iter() {
|
||||
if first {
|
||||
first = false;
|
||||
} else {
|
||||
if_ok!(write!(f.buf, ", "));
|
||||
}
|
||||
if_ok!(write!(f.buf, "{}: {}", *key, *value));
|
||||
}
|
||||
write!(f.buf, r"\}")
|
||||
}
|
||||
}
|
||||
|
||||
/// HashMap iterator
|
||||
#[deriving(Clone)]
|
||||
pub struct Entries<'a, K, V> {
|
||||
@ -857,6 +876,23 @@ impl<T:Hash + Eq + Clone> Clone for HashSet<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
impl<A: fmt::Show + Hash + Eq> fmt::Show for HashSet<A> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if_ok!(write!(f.buf, r"\{"))
|
||||
let mut first = true;
|
||||
for x in self.iter() {
|
||||
if first {
|
||||
first = false;
|
||||
} else {
|
||||
if_ok!(write!(f.buf, ", "));
|
||||
}
|
||||
if_ok!(write!(f.buf, "{}", *x));
|
||||
}
|
||||
write!(f.buf, r"\}")
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq + Hash> FromIterator<K> for HashSet<K> {
|
||||
fn from_iterator<T: Iterator<K>>(iter: &mut T) -> HashSet<K> {
|
||||
let (lower, _) = iter.size_hint();
|
||||
@ -890,6 +926,7 @@ pub type SetAlgebraItems<'a, T> =
|
||||
mod test_map {
|
||||
use prelude::*;
|
||||
use super::*;
|
||||
use fmt;
|
||||
|
||||
#[test]
|
||||
fn test_create_capacity_zero() {
|
||||
@ -1121,6 +1158,30 @@ mod test_map {
|
||||
assert_eq!(map.find(&k), Some(&v));
|
||||
}
|
||||
}
|
||||
|
||||
struct ShowableStruct {
|
||||
value: int,
|
||||
}
|
||||
|
||||
impl fmt::Show for ShowableStruct {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f.buf, r"s{}", self.value)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
let mut table: HashMap<int, ShowableStruct> = HashMap::new();
|
||||
let empty: HashMap<int, ShowableStruct> = HashMap::new();
|
||||
|
||||
table.insert(3, ShowableStruct { value: 4 });
|
||||
table.insert(1, ShowableStruct { value: 2 });
|
||||
|
||||
let table_str = format!("{}", table);
|
||||
|
||||
assert!(table_str == ~"{1: s2, 3: s4}" || table_str == ~"{3: s4, 1: s2}");
|
||||
assert_eq!(format!("{}", empty), ~"{}");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -1346,4 +1407,18 @@ mod test_set {
|
||||
|
||||
assert_eq!(s1, s2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
let mut set: HashSet<int> = HashSet::new();
|
||||
let empty: HashSet<int> = HashSet::new();
|
||||
|
||||
set.insert(1);
|
||||
set.insert(2);
|
||||
|
||||
let set_str = format!("{}", set);
|
||||
|
||||
assert!(set_str == ~"{1, 2}" || set_str == ~"{2, 1}");
|
||||
assert_eq!(format!("{}", empty), ~"{}");
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ use iter::Iterator;
|
||||
use option::Option;
|
||||
use io::Reader;
|
||||
use vec::{OwnedVector, ImmutableVector};
|
||||
use ptr::RawPtr;
|
||||
|
||||
/// An iterator that reads a single byte on each iteration,
|
||||
/// until `.read_byte()` returns `None`.
|
||||
@ -104,7 +105,7 @@ pub fn u64_from_be_bytes(data: &[u8],
|
||||
start: uint,
|
||||
size: uint)
|
||||
-> u64 {
|
||||
use ptr::{copy_nonoverlapping_memory, offset, mut_offset};
|
||||
use ptr::{copy_nonoverlapping_memory};
|
||||
use mem::from_be64;
|
||||
use vec::MutableVector;
|
||||
|
||||
@ -116,9 +117,9 @@ pub fn u64_from_be_bytes(data: &[u8],
|
||||
|
||||
let mut buf = [0u8, ..8];
|
||||
unsafe {
|
||||
let ptr = offset(data.as_ptr(), start as int);
|
||||
let ptr = data.as_ptr().offset(start as int);
|
||||
let out = buf.as_mut_ptr();
|
||||
copy_nonoverlapping_memory(mut_offset(out, (8 - size) as int), ptr, size);
|
||||
copy_nonoverlapping_memory(out.offset((8 - size) as int), ptr, size);
|
||||
from_be64(*(out as *i64)) as u64
|
||||
}
|
||||
}
|
||||
|
@ -145,16 +145,18 @@ macro_rules! format(
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! write(
|
||||
($dst:expr, $($arg:tt)*) => (
|
||||
format_args!(|args| { ::std::fmt::write($dst, args) }, $($arg)*)
|
||||
)
|
||||
($dst:expr, $($arg:tt)*) => ({
|
||||
let dst: &mut ::std::io::Writer = $dst;
|
||||
format_args!(|args| { ::std::fmt::write(dst, args) }, $($arg)*)
|
||||
})
|
||||
)
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! writeln(
|
||||
($dst:expr, $($arg:tt)*) => (
|
||||
format_args!(|args| { ::std::fmt::writeln($dst, args) }, $($arg)*)
|
||||
)
|
||||
($dst:expr, $($arg:tt)*) => ({
|
||||
let dst: &mut ::std::io::Writer = $dst;
|
||||
format_args!(|args| { ::std::fmt::writeln(dst, args) }, $($arg)*)
|
||||
})
|
||||
)
|
||||
|
||||
#[macro_export]
|
||||
|
@ -21,23 +21,6 @@ use unstable::intrinsics;
|
||||
|
||||
#[cfg(not(test))] use cmp::{Eq, Ord};
|
||||
|
||||
/// Calculate the offset from a pointer.
|
||||
/// The `count` argument is in units of T; e.g. a `count` of 3
|
||||
/// represents a pointer offset of `3 * sizeof::<T>()` bytes.
|
||||
#[inline]
|
||||
pub unsafe fn offset<T>(ptr: *T, count: int) -> *T {
|
||||
intrinsics::offset(ptr, count)
|
||||
}
|
||||
|
||||
/// Calculate the offset from a mut pointer. The count *must* be in bounds or
|
||||
/// otherwise the loads of this address are undefined.
|
||||
/// The `count` argument is in units of T; e.g. a `count` of 3
|
||||
/// represents a pointer offset of `3 * sizeof::<T>()` bytes.
|
||||
#[inline]
|
||||
pub unsafe fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
|
||||
intrinsics::offset(ptr as *T, count) as *mut T
|
||||
}
|
||||
|
||||
/// Return the offset of the first null pointer in `buf`.
|
||||
#[inline]
|
||||
pub unsafe fn buf_len<T>(buf: **T) -> uint {
|
||||
@ -63,7 +46,7 @@ impl<T> Clone for *mut T {
|
||||
pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
|
||||
let mut i = 0;
|
||||
loop {
|
||||
if f(&(*offset(buf, i as int))) { return i; }
|
||||
if f(&(*buf.offset(i as int))) { return i; }
|
||||
else { i += 1; }
|
||||
}
|
||||
}
|
||||
@ -76,14 +59,6 @@ pub fn null<T>() -> *T { 0 as *T }
|
||||
#[inline]
|
||||
pub fn mut_null<T>() -> *mut T { 0 as *mut T }
|
||||
|
||||
/// Returns true if the pointer is equal to the null pointer.
|
||||
#[inline]
|
||||
pub fn is_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_null() }
|
||||
|
||||
/// Returns true if the pointer is not equal to the null pointer.
|
||||
#[inline]
|
||||
pub fn is_not_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_not_null() }
|
||||
|
||||
/**
|
||||
* Copies data from one location to another.
|
||||
*
|
||||
@ -206,7 +181,7 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
|
||||
}
|
||||
//let start_ptr = *arr;
|
||||
for e in range(0, len) {
|
||||
let n = offset(arr, e as int);
|
||||
let n = arr.offset(e as int);
|
||||
cb(*n);
|
||||
}
|
||||
debug!("array_each_with_len: after iterate");
|
||||
@ -278,7 +253,7 @@ impl<T> RawPtr<T> for *T {
|
||||
/// Calculates the offset from a pointer. The offset *must* be in-bounds of
|
||||
/// the object, or one-byte-past-the-end.
|
||||
#[inline]
|
||||
unsafe fn offset(self, count: int) -> *T { offset(self, count) }
|
||||
unsafe fn offset(self, count: int) -> *T { intrinsics::offset(self, count) }
|
||||
}
|
||||
|
||||
/// Extension methods for mutable pointers
|
||||
@ -323,7 +298,7 @@ impl<T> RawPtr<T> for *mut T {
|
||||
/// This method should be preferred over `offset` when the guarantee can be
|
||||
/// satisfied, to enable better optimization.
|
||||
#[inline]
|
||||
unsafe fn offset(self, count: int) -> *mut T { mut_offset(self, count) }
|
||||
unsafe fn offset(self, count: int) -> *mut T { intrinsics::offset(self as *T, count) as *mut T }
|
||||
}
|
||||
|
||||
// Equality for pointers
|
||||
@ -478,14 +453,14 @@ pub mod ptr_tests {
|
||||
let v0 = ~[32000u16, 32001u16, 32002u16];
|
||||
let mut v1 = ~[0u16, 0u16, 0u16];
|
||||
|
||||
copy_memory(mut_offset(v1.as_mut_ptr(), 1),
|
||||
offset(v0.as_ptr(), 1), 1);
|
||||
copy_memory(v1.as_mut_ptr().offset(1),
|
||||
v0.as_ptr().offset(1), 1);
|
||||
assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16));
|
||||
copy_memory(v1.as_mut_ptr(),
|
||||
offset(v0.as_ptr(), 2), 1);
|
||||
v0.as_ptr().offset(2), 1);
|
||||
assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
|
||||
v1[2] == 0u16));
|
||||
copy_memory(mut_offset(v1.as_mut_ptr(), 2),
|
||||
copy_memory(v1.as_mut_ptr().offset(2),
|
||||
v0.as_ptr(), 1u);
|
||||
assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
|
||||
v1[2] == 32000u16));
|
||||
@ -525,7 +500,7 @@ pub mod ptr_tests {
|
||||
assert!(p.is_null());
|
||||
assert!(!p.is_not_null());
|
||||
|
||||
let q = unsafe { offset(p, 1) };
|
||||
let q = unsafe { p.offset(1) };
|
||||
assert!(!q.is_null());
|
||||
assert!(q.is_not_null());
|
||||
|
||||
|
@ -441,11 +441,4 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
||||
self.align_to::<&'static u8>();
|
||||
true
|
||||
}
|
||||
|
||||
// NOTE Remove after next snapshot.
|
||||
#[cfg(stage0)]
|
||||
fn visit_type(&mut self) -> bool {
|
||||
if ! self.inner.visit_type() { return false; }
|
||||
true
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ use io;
|
||||
use iter::Iterator;
|
||||
use option::{Some, None, Option};
|
||||
use ptr;
|
||||
use ptr::RawPtr;
|
||||
use reflect;
|
||||
use reflect::{MovePtr, align};
|
||||
use result::{Ok, Err};
|
||||
@ -221,7 +222,7 @@ impl<'a> ReprVisitor<'a> {
|
||||
if_ok!(self, self.writer.write(", ".as_bytes()));
|
||||
}
|
||||
self.visit_ptr_inner(p as *u8, inner);
|
||||
p = align(unsafe { ptr::offset(p, sz as int) as uint }, al) as *u8;
|
||||
p = align(unsafe { p.offset(sz as int) as uint }, al) as *u8;
|
||||
left -= dec;
|
||||
}
|
||||
if_ok!(self, self.writer.write([']' as u8]));
|
||||
@ -601,10 +602,6 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
||||
|
||||
fn visit_param(&mut self, _i: uint) -> bool { true }
|
||||
fn visit_self(&mut self) -> bool { true }
|
||||
|
||||
// NOTE Remove after next snapshot.
|
||||
#[cfg(stage0)]
|
||||
fn visit_type(&mut self) -> bool { true }
|
||||
}
|
||||
|
||||
pub fn write_repr<T>(writer: &mut io::Writer, object: &T) -> io::IoResult<()> {
|
||||
|
@ -10,8 +10,6 @@
|
||||
|
||||
use libc::{c_void, size_t, free, malloc, realloc};
|
||||
use ptr::{RawPtr, mut_null};
|
||||
#[cfg(stage0)]
|
||||
use unstable::intrinsics::TyDesc;
|
||||
use unstable::intrinsics::abort;
|
||||
use unstable::raw;
|
||||
use mem::size_of;
|
||||
@ -75,15 +73,7 @@ pub unsafe fn exchange_malloc(size: uint) -> *u8 {
|
||||
}
|
||||
|
||||
// FIXME: #7496
|
||||
#[cfg(not(test), stage0)]
|
||||
#[lang="closure_exchange_malloc"]
|
||||
#[inline]
|
||||
pub unsafe fn closure_exchange_malloc_(td: *u8, size: uint) -> *u8 {
|
||||
closure_exchange_malloc(td, size)
|
||||
}
|
||||
|
||||
// FIXME: #7496
|
||||
#[cfg(not(test), not(stage0))]
|
||||
#[cfg(not(test))]
|
||||
#[lang="closure_exchange_malloc"]
|
||||
#[inline]
|
||||
pub unsafe fn closure_exchange_malloc_(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
|
||||
@ -91,24 +81,6 @@ pub unsafe fn closure_exchange_malloc_(drop_glue: fn(*mut u8), size: uint, align
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(stage0)]
|
||||
pub unsafe fn closure_exchange_malloc(td: *u8, size: uint) -> *u8 {
|
||||
let td = td as *TyDesc;
|
||||
let size = size;
|
||||
|
||||
assert!(td.is_not_null());
|
||||
|
||||
let total_size = get_box_size(size, (*td).align);
|
||||
let p = malloc_raw(total_size);
|
||||
|
||||
let alloc = p as *mut raw::Box<()>;
|
||||
(*alloc).type_desc = td;
|
||||
|
||||
alloc as *u8
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(stage0))]
|
||||
pub unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
|
||||
let total_size = get_box_size(size, align);
|
||||
let p = malloc_raw(total_size);
|
||||
|
@ -21,8 +21,6 @@ use rt::env;
|
||||
use rt::global_heap;
|
||||
use rt::local::Local;
|
||||
use rt::task::Task;
|
||||
#[cfg(stage0)]
|
||||
use unstable::intrinsics::TyDesc;
|
||||
use unstable::raw;
|
||||
use vec::ImmutableVector;
|
||||
|
||||
@ -61,29 +59,6 @@ impl LocalHeap {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(stage0)]
|
||||
pub fn alloc(&mut self, td: *TyDesc, size: uint) -> *mut Box {
|
||||
let total_size = global_heap::get_box_size(size, unsafe { (*td).align });
|
||||
let alloc = self.memory_region.malloc(total_size);
|
||||
{
|
||||
// Make sure that we can't use `mybox` outside of this scope
|
||||
let mybox: &mut Box = unsafe { cast::transmute(alloc) };
|
||||
// Clear out this box, and move it to the front of the live
|
||||
// allocations list
|
||||
mybox.type_desc = td;
|
||||
mybox.ref_count = 1;
|
||||
mybox.prev = ptr::mut_null();
|
||||
mybox.next = self.live_allocs;
|
||||
if !self.live_allocs.is_null() {
|
||||
unsafe { (*self.live_allocs).prev = alloc; }
|
||||
}
|
||||
self.live_allocs = alloc;
|
||||
}
|
||||
return alloc;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(stage0))]
|
||||
pub fn alloc(&mut self, drop_glue: fn(*mut u8), size: uint, align: uint) -> *mut Box {
|
||||
let total_size = global_heap::get_box_size(size, align);
|
||||
let alloc = self.memory_region.malloc(total_size);
|
||||
@ -126,41 +101,6 @@ impl LocalHeap {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(stage0)]
|
||||
pub fn free(&mut self, alloc: *mut Box) {
|
||||
{
|
||||
// Make sure that we can't use `mybox` outside of this scope
|
||||
let mybox: &mut Box = unsafe { cast::transmute(alloc) };
|
||||
assert!(!mybox.type_desc.is_null());
|
||||
|
||||
// Unlink it from the linked list
|
||||
if !mybox.prev.is_null() {
|
||||
unsafe { (*mybox.prev).next = mybox.next; }
|
||||
}
|
||||
if !mybox.next.is_null() {
|
||||
unsafe { (*mybox.next).prev = mybox.prev; }
|
||||
}
|
||||
if self.live_allocs == alloc {
|
||||
self.live_allocs = mybox.next;
|
||||
}
|
||||
|
||||
// Destroy the box memory-wise
|
||||
if self.poison_on_free {
|
||||
unsafe {
|
||||
let ptr: *mut u8 = cast::transmute(&mybox.data);
|
||||
ptr::set_memory(ptr, 0xab, (*mybox.type_desc).size);
|
||||
}
|
||||
}
|
||||
mybox.prev = ptr::mut_null();
|
||||
mybox.next = ptr::mut_null();
|
||||
mybox.type_desc = ptr::null();
|
||||
}
|
||||
|
||||
self.memory_region.free(alloc);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(stage0))]
|
||||
pub fn free(&mut self, alloc: *mut Box) {
|
||||
{
|
||||
// Make sure that we can't use `mybox` outside of this scope
|
||||
@ -339,20 +279,6 @@ impl Drop for MemoryRegion {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(stage0)]
|
||||
pub unsafe fn local_malloc(td: *u8, size: uint) -> *u8 {
|
||||
// FIXME: Unsafe borrow for speed. Lame.
|
||||
let task: Option<*mut Task> = Local::try_unsafe_borrow();
|
||||
match task {
|
||||
Some(task) => {
|
||||
(*task).heap.alloc(td as *TyDesc, size) as *u8
|
||||
}
|
||||
None => rtabort!("local malloc outside of task")
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(stage0))]
|
||||
pub unsafe fn local_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
|
||||
// FIXME: Unsafe borrow for speed. Lame.
|
||||
let task: Option<*mut Task> = Local::try_unsafe_borrow();
|
||||
|
@ -1242,7 +1242,7 @@ pub mod raw {
|
||||
let mut i = 0;
|
||||
while *curr != 0 {
|
||||
i += 1;
|
||||
curr = ptr::offset(buf, i);
|
||||
curr = buf.offset(i);
|
||||
}
|
||||
from_buf_len(buf as *u8, i as uint)
|
||||
}
|
||||
@ -1272,7 +1272,7 @@ pub mod raw {
|
||||
let mut len = 0u;
|
||||
while *curr != 0u8 {
|
||||
len += 1u;
|
||||
curr = ptr::offset(s, len as int);
|
||||
curr = s.offset(len as int);
|
||||
}
|
||||
let v = Slice { data: s, len: len };
|
||||
assert!(is_utf8(::cast::transmute(v)));
|
||||
@ -2921,7 +2921,6 @@ impl Default for ~str {
|
||||
mod tests {
|
||||
use iter::AdditiveIterator;
|
||||
use prelude::*;
|
||||
use ptr;
|
||||
use str::*;
|
||||
|
||||
#[test]
|
||||
@ -3549,11 +3548,11 @@ mod tests {
|
||||
fn test_as_ptr() {
|
||||
let buf = "hello".as_ptr();
|
||||
unsafe {
|
||||
assert_eq!(*ptr::offset(buf, 0), 'h' as u8);
|
||||
assert_eq!(*ptr::offset(buf, 1), 'e' as u8);
|
||||
assert_eq!(*ptr::offset(buf, 2), 'l' as u8);
|
||||
assert_eq!(*ptr::offset(buf, 3), 'l' as u8);
|
||||
assert_eq!(*ptr::offset(buf, 4), 'o' as u8);
|
||||
assert_eq!(*buf.offset(0), 'h' as u8);
|
||||
assert_eq!(*buf.offset(1), 'e' as u8);
|
||||
assert_eq!(*buf.offset(2), 'l' as u8);
|
||||
assert_eq!(*buf.offset(3), 'l' as u8);
|
||||
assert_eq!(*buf.offset(4), 'o' as u8);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4164,6 +4163,7 @@ mod tests {
|
||||
assert_eq!(s.len(), 5);
|
||||
assert_eq!(s.as_slice(), "abcde");
|
||||
assert_eq!(s.to_str(), ~"abcde");
|
||||
assert_eq!(format!("{}", s), ~"abcde");
|
||||
assert!(s.lt(&Owned(~"bcdef")));
|
||||
assert_eq!(Slice(""), Default::default());
|
||||
|
||||
@ -4171,6 +4171,7 @@ mod tests {
|
||||
assert_eq!(o.len(), 5);
|
||||
assert_eq!(o.as_slice(), "abcde");
|
||||
assert_eq!(o.to_str(), ~"abcde");
|
||||
assert_eq!(format!("{}", o), ~"abcde");
|
||||
assert!(o.lt(&Slice("bcdef")));
|
||||
assert_eq!(Owned(~""), Default::default());
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
use default::Default;
|
||||
#[cfg(not(test))]
|
||||
use cmp::{Eq, Equal, Ord, Ordering, TotalEq, TotalOrd};
|
||||
use fmt;
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl Eq for () {
|
||||
@ -46,3 +47,9 @@ impl Default for () {
|
||||
#[inline]
|
||||
fn default() -> () { () }
|
||||
}
|
||||
|
||||
impl fmt::Show for () {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.pad("()")
|
||||
}
|
||||
}
|
||||
|
@ -160,10 +160,6 @@ pub trait TyVisitor {
|
||||
fn visit_trait(&mut self, name: &str) -> bool;
|
||||
fn visit_param(&mut self, i: uint) -> bool;
|
||||
fn visit_self(&mut self) -> bool;
|
||||
|
||||
// NOTE Remove after next snapshot.
|
||||
#[cfg(stage0)]
|
||||
fn visit_type(&mut self) -> bool;
|
||||
}
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
|
@ -27,14 +27,6 @@ pub fn fail_bounds_check(file: *u8, line: uint, index: uint, len: uint) -> ! {
|
||||
}
|
||||
|
||||
#[lang="malloc"]
|
||||
#[cfg(stage0)]
|
||||
#[inline]
|
||||
pub unsafe fn local_malloc(td: *u8, size: uint) -> *u8 {
|
||||
::rt::local_heap::local_malloc(td, size)
|
||||
}
|
||||
|
||||
#[lang="malloc"]
|
||||
#[cfg(not(stage0))]
|
||||
#[inline]
|
||||
pub unsafe fn local_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
|
||||
::rt::local_heap::local_malloc(drop_glue, size, align)
|
||||
|
@ -9,21 +9,8 @@
|
||||
// except according to those terms.
|
||||
|
||||
use cast;
|
||||
#[cfg(stage0)]
|
||||
use unstable::intrinsics::TyDesc;
|
||||
|
||||
/// The representation of a Rust managed box
|
||||
#[cfg(stage0)]
|
||||
pub struct Box<T> {
|
||||
ref_count: uint,
|
||||
type_desc: *TyDesc,
|
||||
prev: *mut Box<T>,
|
||||
next: *mut Box<T>,
|
||||
data: T
|
||||
}
|
||||
|
||||
/// The representation of a Rust managed box
|
||||
#[cfg(not(stage0))]
|
||||
pub struct Box<T> {
|
||||
ref_count: uint,
|
||||
drop_glue: fn(ptr: *mut u8),
|
||||
|
@ -108,6 +108,7 @@ use container::{Container, Mutable};
|
||||
use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater};
|
||||
use cmp;
|
||||
use default::Default;
|
||||
#[cfg(not(stage0))] use fmt;
|
||||
use iter::*;
|
||||
use num::{Integer, CheckedAdd, Saturating, checked_next_power_of_two};
|
||||
use option::{None, Option, Some};
|
||||
@ -115,6 +116,7 @@ use ptr::to_unsafe_ptr;
|
||||
use ptr;
|
||||
use ptr::RawPtr;
|
||||
use rt::global_heap::{malloc_raw, realloc_raw, exchange_free};
|
||||
#[cfg(not(stage0))] use result::{Ok, Err};
|
||||
use mem;
|
||||
use mem::size_of;
|
||||
use kinds::marker;
|
||||
@ -137,7 +139,7 @@ pub fn from_fn<T>(n_elts: uint, op: |uint| -> T) -> ~[T] {
|
||||
&mut i, (),
|
||||
|i, ()| while *i < n_elts {
|
||||
mem::move_val_init(
|
||||
&mut(*ptr::mut_offset(p, *i as int)),
|
||||
&mut(*p.offset(*i as int)),
|
||||
op(*i));
|
||||
*i += 1u;
|
||||
},
|
||||
@ -165,7 +167,7 @@ pub fn from_elem<T:Clone>(n_elts: uint, t: T) -> ~[T] {
|
||||
&mut i, (),
|
||||
|i, ()| while *i < n_elts {
|
||||
mem::move_val_init(
|
||||
&mut(*ptr::mut_offset(p, *i as int)),
|
||||
&mut(*p.offset(*i as int)),
|
||||
t.clone());
|
||||
*i += 1u;
|
||||
},
|
||||
@ -1495,7 +1497,7 @@ impl<T> OwnedVector<T> for ~[T] {
|
||||
let fill = (**repr).fill;
|
||||
(**repr).fill += mem::nonzero_size_of::<T>();
|
||||
let p = to_unsafe_ptr(&((**repr).data));
|
||||
let p = ptr::offset(p, fill as int) as *mut T;
|
||||
let p = p.offset(fill as int) as *mut T;
|
||||
mem::move_val_init(&mut(*p), t);
|
||||
}
|
||||
}
|
||||
@ -1509,7 +1511,7 @@ impl<T> OwnedVector<T> for ~[T] {
|
||||
unsafe { // Note: infallible.
|
||||
let self_p = self.as_mut_ptr();
|
||||
let rhs_p = rhs.as_ptr();
|
||||
ptr::copy_memory(ptr::mut_offset(self_p, self_len as int), rhs_p, rhs_len);
|
||||
ptr::copy_memory(self_p.offset(self_len as int), rhs_p, rhs_len);
|
||||
self.set_len(new_len);
|
||||
rhs.set_len(0);
|
||||
}
|
||||
@ -1796,11 +1798,11 @@ impl<T:Eq> OwnedEqVector<T> for ~[T] {
|
||||
let mut w = 1;
|
||||
|
||||
while r < ln {
|
||||
let p_r = ptr::mut_offset(p, r as int);
|
||||
let p_wm1 = ptr::mut_offset(p, (w - 1) as int);
|
||||
let p_r = p.offset(r as int);
|
||||
let p_wm1 = p.offset((w - 1) as int);
|
||||
if *p_r != *p_wm1 {
|
||||
if r != w {
|
||||
let p_w = ptr::mut_offset(p_wm1, 1);
|
||||
let p_w = p_wm1.offset(1);
|
||||
mem::swap(&mut *p_r, &mut *p_w);
|
||||
}
|
||||
w += 1;
|
||||
@ -2383,7 +2385,7 @@ impl<'a,T> MutableVector<'a, T> for &'a mut [T] {
|
||||
|
||||
#[inline]
|
||||
unsafe fn unsafe_mut_ref(self, index: uint) -> &'a mut T {
|
||||
cast::transmute(ptr::mut_offset(self.repr().data as *mut T, index as int))
|
||||
cast::transmute((self.repr().data as *mut T).offset(index as int))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -2484,6 +2486,7 @@ pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
|
||||
pub mod raw {
|
||||
use cast;
|
||||
use ptr;
|
||||
use ptr::RawPtr;
|
||||
use vec::{with_capacity, MutableVector, OwnedVector};
|
||||
use unstable::raw::Slice;
|
||||
|
||||
@ -2542,7 +2545,7 @@ pub mod raw {
|
||||
pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> *T {
|
||||
if slice.len == 0 { fail!("shift on empty slice"); }
|
||||
let head: *T = slice.data;
|
||||
slice.data = ptr::offset(slice.data, 1);
|
||||
slice.data = slice.data.offset(1);
|
||||
slice.len -= 1;
|
||||
head
|
||||
}
|
||||
@ -2554,7 +2557,7 @@ pub mod raw {
|
||||
*/
|
||||
pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> *T {
|
||||
if slice.len == 0 { fail!("pop on empty slice"); }
|
||||
let tail: *T = ptr::offset(slice.data, (slice.len - 1) as int);
|
||||
let tail: *T = slice.data.offset((slice.len - 1) as int);
|
||||
slice.len -= 1;
|
||||
tail
|
||||
}
|
||||
@ -2640,6 +2643,30 @@ impl<A: DeepClone> DeepClone for ~[A] {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
impl<'a, T: fmt::Show> fmt::Show for &'a [T] {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if_ok!(write!(f.buf, "["));
|
||||
let mut is_first = true;
|
||||
for x in self.iter() {
|
||||
if is_first {
|
||||
is_first = false;
|
||||
} else {
|
||||
if_ok!(write!(f.buf, ", "));
|
||||
}
|
||||
if_ok!(write!(f.buf, "{}", *x))
|
||||
}
|
||||
write!(f.buf, "]")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
impl<T: fmt::Show> fmt::Show for ~[T] {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.as_slice().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
// This works because every lifetime is a sub-lifetime of 'static
|
||||
impl<'a, A> Default for &'a [A] {
|
||||
fn default() -> &'a [A] { &'a [] }
|
||||
@ -4049,6 +4076,22 @@ mod tests {
|
||||
assert_eq!(values, [1,4,3,2,5]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
macro_rules! test_show_vec(
|
||||
($x:expr, $x_str:expr) => ({
|
||||
let (x, x_str) = ($x, $x_str);
|
||||
assert_eq!(format!("{}", x), x_str);
|
||||
assert_eq!(format!("{}", x.as_slice()), x_str);
|
||||
})
|
||||
)
|
||||
let empty: ~[int] = ~[];
|
||||
test_show_vec!(empty, ~"[]");
|
||||
test_show_vec!(~[1], ~"[1]");
|
||||
test_show_vec!(~[1, 2, 3], ~"[1, 2, 3]");
|
||||
test_show_vec!(~[~[], ~[1u], ~[1u, 1u]], ~"[[], [1], [1, 1]]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_default() {
|
||||
use default::Default;
|
||||
|
@ -22,7 +22,8 @@ use cast::{forget, transmute};
|
||||
use rt::global_heap::{malloc_raw, realloc_raw};
|
||||
use vec::{ImmutableVector, Items, MutableVector};
|
||||
use unstable::raw::Slice;
|
||||
use ptr::{offset, read_ptr};
|
||||
use ptr::read_ptr;
|
||||
use ptr::RawPtr;
|
||||
use libc::{free, c_void};
|
||||
|
||||
pub struct Vec<T> {
|
||||
@ -135,7 +136,7 @@ impl<T> Vec<T> {
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let end = offset(self.ptr as *T, self.len as int) as *mut T;
|
||||
let end = (self.ptr as *T).offset(self.len as int) as *mut T;
|
||||
move_val_init(&mut *end, value);
|
||||
self.len += 1;
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ use parse::token::{InternedString, intern, str_to_ident};
|
||||
use util::small_vector::SmallVector;
|
||||
|
||||
use std::hashmap::HashMap;
|
||||
use std::unstable::dynamic_lib::DynamicLibrary;
|
||||
|
||||
// new-style macro! tt code:
|
||||
//
|
||||
@ -143,8 +142,6 @@ pub struct BlockInfo {
|
||||
macros_escape : bool,
|
||||
// what are the pending renames?
|
||||
pending_renames : RenameList,
|
||||
// references for crates loaded in this scope
|
||||
macro_crates: ~[DynamicLibrary],
|
||||
}
|
||||
|
||||
impl BlockInfo {
|
||||
@ -152,7 +149,6 @@ impl BlockInfo {
|
||||
BlockInfo {
|
||||
macros_escape: false,
|
||||
pending_renames: ~[],
|
||||
macro_crates: ~[],
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -551,10 +547,6 @@ impl SyntaxEnv {
|
||||
self.find_escape_frame().map.insert(k, v);
|
||||
}
|
||||
|
||||
pub fn insert_macro_crate(&mut self, lib: DynamicLibrary) {
|
||||
self.find_escape_frame().info.macro_crates.push(lib);
|
||||
}
|
||||
|
||||
pub fn info<'a>(&'a mut self) -> &'a mut BlockInfo {
|
||||
&mut self.chain[self.chain.len()-1].info
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
@ -28,6 +28,7 @@ use visit;
|
||||
use visit::Visitor;
|
||||
use util::small_vector::SmallVector;
|
||||
|
||||
use std::cast;
|
||||
use std::vec;
|
||||
use std::unstable::dynamic_lib::DynamicLibrary;
|
||||
use std::os;
|
||||
@ -469,9 +470,12 @@ fn load_extern_macros(crate: &ast::ViewItem, fld: &mut MacroExpander) {
|
||||
};
|
||||
fld.extsbox.insert(name, extension);
|
||||
});
|
||||
}
|
||||
|
||||
fld.extsbox.insert_macro_crate(lib);
|
||||
// Intentionally leak the dynamic library. We can't ever unload it
|
||||
// since the library can do things that will outlive the expansion
|
||||
// phase (e.g. make an @-box cycle or launch a task).
|
||||
cast::forget(lib);
|
||||
}
|
||||
}
|
||||
|
||||
// expand a stmt
|
||||
|
@ -1,3 +1,11 @@
|
||||
S 2014-02-12 c62f6ce
|
||||
freebsd-x86_64 737a423c5f803119ff5a692eac432fa9d0c595a8
|
||||
linux-i386 a7e90e27e8b6a3fa79ddc15f0ed217ccbade875d
|
||||
linux-x86_64 8f5fdf9f07b2afbc55d8d8c06c60aeb532b5ea83
|
||||
macos-i386 57bb225f45bc57fef4c34552a2d5814ab4913087
|
||||
macos-x86_64 d37b62478aa1c1dd1babb19d1df494d2aaf59c4c
|
||||
winnt-i386 2c5c5f7228140cd79f120201805504a9e07ad245
|
||||
|
||||
S 2014-02-03 346d378
|
||||
freebsd-x86_64 d369c1a83a2be6eb42bd0e550a1adc38ffed0804
|
||||
linux-i386 a6d4ab441f5b285d7aecbb940fa733526b413f34
|
||||
|
35
src/test/auxiliary/macro_crate_outlive_expansion_phase.rs
Normal file
35
src/test/auxiliary/macro_crate_outlive_expansion_phase.rs
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// force-host
|
||||
|
||||
#[feature(macro_registrar)];
|
||||
|
||||
extern mod syntax;
|
||||
|
||||
use std::any::Any;
|
||||
use std::local_data;
|
||||
use syntax::ast::Name;
|
||||
use syntax::ext::base::SyntaxExtension;
|
||||
|
||||
struct Foo {
|
||||
foo: int
|
||||
}
|
||||
|
||||
impl Drop for Foo {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
#[macro_registrar]
|
||||
pub fn registrar(_: |Name, SyntaxExtension|) {
|
||||
local_data_key!(foo: ~Any);
|
||||
local_data::set(foo, ~Foo { foo: 10 } as ~Any);
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:macro_crate_outlive_expansion_phase.rs
|
||||
// ignore-stage1
|
||||
// ignore-fast
|
||||
// ignore-android
|
||||
|
||||
#[feature(phase)];
|
||||
|
||||
#[phase(syntax)]
|
||||
extern mod macro_crate_outlive_expansion_phase;
|
||||
|
||||
pub fn main() {}
|
28
src/test/run-pass/colorful-write-macros.rs
Normal file
28
src/test/run-pass/colorful-write-macros.rs
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[allow(unused_must_use, dead_code)];
|
||||
|
||||
use std::io::MemWriter;
|
||||
|
||||
struct Foo<'a> {
|
||||
writer: &'a mut Writer,
|
||||
other: &'a str,
|
||||
}
|
||||
|
||||
fn borrowing_writer_from_struct_and_formatting_struct_field(foo: Foo) {
|
||||
write!(foo.writer, "{}", foo.other);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let mut w = MemWriter::new();
|
||||
write!(&mut w as &mut Writer, "");
|
||||
write!(&mut w, ""); // should coerce
|
||||
}
|
13
src/test/run-pass/issue-9918.rs
Normal file
13
src/test/run-pass/issue-9918.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn main() {
|
||||
assert_eq!((0 + 0u8) as char, '\0');
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user