Merge branch 'master' of github.com:graydon/rust

This commit is contained in:
Niko Matsakis 2011-12-06 14:02:32 -08:00
commit 39b1657b2c
97 changed files with 674 additions and 114 deletions

View File

@ -104,6 +104,7 @@ endif
CFG_RUNTIME :=$(call CFG_LIB_NAME,rustrt)
CFG_RUSTLLVM :=$(call CFG_LIB_NAME,rustllvm)
CFG_CORELIB :=$(call CFG_LIB_NAME,core)
CFG_STDLIB :=$(call CFG_LIB_NAME,ruststd)
CFG_LIBRUSTC :=$(call CFG_LIB_NAME,rustc)
@ -144,9 +145,9 @@ else
endif
ifeq ($(CFG_NATURALDOCS),)
$(info cfg: no naturaldocs found, omitting doc/std/index.html)
$(info cfg: no naturaldocs found, omitting library doc build)
else
DOCS += doc/std/index.html
DOCS += doc/core/index.html doc/std/index.html
endif
ifdef CFG_DISABLE_DOCS
@ -183,12 +184,21 @@ GENERATED :=
%:: s.%
%:: SCCS/s.%
######################################################################
# Core library variables
######################################################################
CORELIB_CRATE := $(S)src/libcore/core.rc
CORELIB_INPUTS := $(wildcard $(addprefix $(S)src/libcore/, \
core.rc *.rs */*.rs))
######################################################################
# Standard library variables
######################################################################
STDLIB_CRATE := $(S)src/lib/std.rc
STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/lib/,*.rc *.rs */*.rs))
STDLIB_CRATE := $(S)src/libstd/std.rc
STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/libstd/, \
std.rc *.rs */*.rs))
######################################################################
# rustc crate variables
@ -268,13 +278,21 @@ TROOT$(1)_T_$(2)_H_$(3) = $$(HLIB$(1)_H_$(3))/rustc/$(2)
TBIN$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/bin
TLIB$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/lib
# The name of the standard library used by rustc
# The name of the core and standard libraries used by rustc
ifdef CFG_DISABLE_SHAREDSTD
HCORELIB_DEFAULT$(1)_H_$(3) = \
$$(HLIB$(1)_H_$(3))/libcore.rlib
TCORELIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
$$(TLIB$(1)_T_$(2)_H_$(3))/libcore.rlib
HSTDLIB_DEFAULT$(1)_H_$(3) = \
$$(HLIB$(1)_H_$(3))/libstd.rlib
TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
$$(TLIB$(1)_T_$(2)_H_$(3))/libstd.rlib
else
HCORELIB_DEFAULT$(1)_H_$(3) = \
$$(HLIB$(1)_H_$(3))/$(CFG_CORELIB)
TCORELIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_CORELIB)
HSTDLIB_DEFAULT$(1)_H_$(3) = \
$$(HLIB$(1)_H_$(3))/$(CFG_STDLIB)
TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
@ -286,6 +304,7 @@ HSREQ$(1)_H_$(3) = \
$$(HBIN$(1)_H_$(3))/rustc$$(X) \
$$(HLIB$(1)_H_$(3))/$$(CFG_RUNTIME) \
$$(HLIB$(1)_H_$(3))/$$(CFG_RUSTLLVM) \
$$(HCORELIB_DEFAULT$(1)_H_$(3)) \
$$(HSTDLIB_DEFAULT$(1)_H_$(3)) \
$$(MKFILE_DEPS)
@ -299,6 +318,7 @@ TSREQ$(1)_T_$(2)_H_$(3) = \
# Prerequisites for complete stageN targets
SREQ$(1)_T_$(2)_H_$(3) = \
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_CORELIB) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB)
ifeq ($(1),0)

4
configure vendored
View File

@ -355,8 +355,8 @@ fi
step_msg "making directories"
for i in \
doc doc/std \
nd nd/std \
doc doc/core doc/std \
nd nd/core nd/std \
dl tmp
do
make_dir $i

View File

@ -120,6 +120,7 @@ Language: Rust
Block Comment: /* */
Package Separator: ::
Function Prototype Enders: ; {
Predicate Prototype Enders: ; {
Type Prototype Enders: ; }
Class Prototype Enders: {
Variant Prototype Enders: ;

8
doc/lib.css Normal file
View File

@ -0,0 +1,8 @@
/*
Custom styles for the library docs generated by naturaldocs
*/
p {
text-indent: 0;
margin-bottom: 1em;
}

View File

@ -1,8 +0,0 @@
/*
Custom styles for the standard library docs generated by naturaldocs
*/
p {
text-indent: 0;
margin-bottom: 1em;
}

View File

@ -46,6 +46,7 @@ PKG_FILES = \
$(PKG_3RDPARTY)) \
$(PKG_UV) \
$(COMPILER_INPUTS) \
$(CORELIB_INPUTS) \
$(STDLIB_INPUTS) \
$(ALL_TEST_INPUTS) \
$(FUZZER_CRATE) \

View File

@ -29,19 +29,25 @@ docsnap: doc/rust.pdf
@$(call E, snap: doc/rust-$(shell date +"%Y-%m-%d")-snap.pdf)
$(Q)mv $< doc/rust-$(shell date +"%Y-%m-%d")-snap.pdf
doc/std/index.html: nd/std/Languages.txt nd/std/Topics.txt nd/std/std.css \
$(STDLIB_CRATE) $(STDLIB_INPUTS)
@$(call E, naturaldocs: $@)
naturaldocs -i $(S)src/lib -o HTML doc/std -p nd/std -r -s Default std
define libdoc
doc/$(1)/index.html: nd/$(1)/Languages.txt nd/$(1)/Topics.txt \
nd/$(1)/lib.css $(2)
@$$(call E, naturaldocs: $$@)
naturaldocs -i $(S)src/lib$(1) -o HTML doc/$(1) -p nd/$(1) -r -s Default lib
nd/std/Languages.txt: $(S)doc/Languages.txt
@$(call E, cp: $@)
$(Q)cp $< $@
nd/$(1)/Languages.txt: $(S)doc/Languages.txt
@$$(call E, cp: $$@)
$(Q)cp $$< $$@
nd/std/Topics.txt: $(S)doc/Topics.txt
@$(call E, cp: $@)
$(Q)cp $< $@
nd/$(1)/Topics.txt: $(S)doc/Topics.txt
@$$(call E, cp: $$@)
$(Q)cp $$< $$@
nd/std/std.css: $(S)doc/std.css
@$(call E, cp: $@)
$(Q)cp $< $@
nd/$(1)/lib.css: $(S)doc/lib.css
@$$(call E, cp: $$@)
$(Q)cp $$< $$@
endef
$(eval $(call libdoc,core,$(CORELIB_CRATE) $(CORELIB_INPUTS)))
$(eval $(call libdoc,std,$(STDLIB_CRATE) $(STDLIB_INPUTS)))

View File

@ -15,6 +15,7 @@ $$(HBIN$(2)_H_$(4))/rustc$$(X): \
$$(TBIN$(1)_T_$(4)_H_$(3))/rustc$$(X) \
$$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME) \
$$(HLIB$(2)_H_$(4))/$$(CFG_RUSTLLVM) \
$$(HCORELIB_DEFAULT$(2)_H_$(4)) \
$$(HSTDLIB_DEFAULT$(2)_H_$(4))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
@ -25,6 +26,7 @@ $$(HLIB$(2)_H_$(4))/$$(CFG_LIBRUSTC): \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTC) \
$$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME) \
$$(HLIB$(2)_H_$(4))/$$(CFG_RUSTLLVM) \
$$(HCORELIB_DEFAULT$(2)_H_$(3)) \
$$(HSTDLIB_DEFAULT$(2)_H_$(3))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
@ -34,14 +36,28 @@ $$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME): \
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB$(2)_H_$(4))/$$(CFG_CORELIB): \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_CORELIB) \
$$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME)
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB$(2)_H_$(4))/$$(CFG_STDLIB): \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_STDLIB) \
$$(HLIB$(2)_H_$(4))/$$(CFG_CORELIB) \
$$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME)
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB$(2)_H_$(4))/libcore.rlib: \
$$(TLIB$(1)_T_$(4)_H_$(3))/libcore.rlib \
$$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME)
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB$(2)_H_$(4))/libstd.rlib: \
$$(TLIB$(1)_T_$(4)_H_$(3))/libstd.rlib \
$$(HLIB$(2)_H_$(4))/libcore.rlib \
$$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME)
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@

View File

@ -33,6 +33,7 @@ PTL$(1)$(2) = $$(PTR$(1)$(2))/lib
install-target-$(1)-host-$(2): $$(SREQ$$(ISTAGE)_T_$(1)_H_$(2))
$$(Q)mkdir -p $$(PTL$(1)$(2))
$$(Q)$$(call INSTALL,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(CFG_RUNTIME))
$$(Q)$$(call INSTALL,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(CFG_CORELIB))
$$(Q)$$(call INSTALL,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(CFG_STDLIB))
$$(Q)$$(call INSTALL,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),intrinsics.bc)
$$(Q)$$(call INSTALL,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),libmorestack.a)
@ -61,6 +62,7 @@ install-host: $(SREQ$(ISTAGE)_T_$(CFG_HOST_TRIPLE)_H_$(CFG_HOST_TRIPLE))
$(Q)mkdir -p $(PREFIX_ROOT)/share/man/man1
$(Q)$(call INSTALL,$(HB),$(PHB),rustc$(X))
$(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_RUNTIME))
$(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_CORELIB))
$(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_STDLIB))
$(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_RUSTLLVM))
$(Q)$(call INSTALL,$(S)/man, \

View File

@ -17,8 +17,8 @@ CFG_GCCISH_LINK_FLAGS :=
# embedded into the executable, so use a no-op command.
CFG_DSYMUTIL := true
ifneq ($(CFG_VALGRIND),)
CFG_GCCISH_CFLAGS += -DHAVE_VALGRIND
ifeq ($(CFG_VALGRIND),)
CFG_GCCISH_CFLAGS += -DNVALGRIND
endif
ifneq ($(findstring freebsd,$(CFG_OSTYPE)),)

View File

@ -2,7 +2,8 @@
ifdef PPFILES
PP_INPUTS_FILTERED := $(wildcard $(PPFILES))
else
PP_INPUTS = $(wildcard $(addprefix $(S)src/lib/,*.rs */*.rs)) \
PP_INPUTS = $(wildcard $(addprefix $(S)src/libcore/,*.rs */*.rs)) \
$(wildcard $(addprefix $(S)src/libstd/,*.rs */*.rs)) \
$(wildcard $(addprefix $(S)src/comp/,*.rs */*.rs */*/*.rs)) \
$(wildcard $(S)src/test/*/*.rs \
$(S)src/test/*/*/*.rs) \

View File

@ -125,7 +125,7 @@ else
endif
RUNTIME_DEF_$(1) := rt/rustrt$$(CFG_DEF_SUFFIX)
RUNTIME_INCS_$(1) := -I $$(S)src/rt/isaac -I $$(S)src/rt/uthash \
RUNTIME_INCS_$(1) := -I $$(S)src/rt -I $$(S)src/rt/isaac -I $$(S)src/rt/uthash \
-I $$(S)src/rt/arch/$$(HOST_$(1)) \
-I $$(S)src/libuv/include
RUNTIME_OBJS_$(1) := $$(RUNTIME_CS_$(1):rt/%.cpp=rt/$(1)/%.o) \

View File

@ -13,6 +13,10 @@ $(HLIB0_H_$(CFG_HOST_TRIPLE))/$(CFG_RUNTIME): \
$(HBIN0_H_$(CFG_HOST_TRIPLE))/rustc$(X)
$(Q)touch $@
$(HLIB0_H_$(CFG_HOST_TRIPLE))/$(CFG_CORELIB): \
$(HBIN0_H_$(CFG_HOST_TRIPLE))/rustc$(X)
$(Q)touch $@
$(HLIB0_H_$(CFG_HOST_TRIPLE))/$(CFG_STDLIB): \
$(HBIN0_H_$(CFG_HOST_TRIPLE))/rustc$(X)
$(Q)touch $@
@ -38,6 +42,11 @@ $$(HLIB0_H_$(1))/$$(CFG_RUNTIME): \
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB0_H_$(1))/$(CFG_CORELIB): \
$$(TLIB$(2)_T_$(1)_H_$(3))/$$(CFG_CORELIB)
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB0_H_$(1))/$(CFG_STDLIB): \
$$(TLIB$(2)_T_$(1)_H_$(3))/$$(CFG_STDLIB)
@$$(call E, cp: $$@)

View File

@ -22,8 +22,15 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a: \
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_CORELIB): \
$$(CORELIB_CRATE) $$(CORELIB_INPUTS) \
$$(TSREQ$(1)_T_$(2)_H_$(3))
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) --lib -o $$@ $$<
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB): \
$$(STDLIB_CRATE) $$(STDLIB_INPUTS) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_CORELIB) \
$$(TSREQ$(1)_T_$(2)_H_$(3))
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) --lib -o $$@ $$<

View File

@ -87,6 +87,8 @@ tidy:
$(wildcard $(S)src/etc/*.py) \
$(COMPILER_CRATE) \
$(COMPILER_INPUTS) \
$(CORELIB_CRATE) \
$(CORELIB_INPUTS) \
$(STDLIB_CRATE) \
$(STDLIB_INPUTS) \
$(COMPILETEST_CRATE) \
@ -475,4 +477,4 @@ endef
$(foreach stage,$(STAGES), \
$(eval $(call DEF_CHECK_FOR_STAGE,$(stage))))
check-fast: check-fast-H-$(CFG_HOST_TRIPLE)
check-fast: check-fast-H-$(CFG_HOST_TRIPLE)

View File

@ -19,6 +19,7 @@ define TOOLS_STAGE_N
$$(TBIN$(1)_T_$(4)_H_$(3))/fuzzer$$(X): \
$$(FUZZER_CRATE) $$(FUZZER_INPUTS) \
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_CORELIB) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_STDLIB) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTC)
@$$(call E, compile_and_link: $$@)
@ -37,6 +38,7 @@ $$(HBIN$(2)_H_$(4))/fuzzer$$(X): \
$$(TBIN$(1)_T_$(4)_H_$(3))/compiletest$$(X): \
$$(COMPILETEST_CRATE) $$(COMPILETEST_INPUTS) \
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_CORELIB) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_STDLIB)
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$<
@ -50,6 +52,7 @@ $$(HBIN$(2)_H_$(4))/compiletest$$(X): \
$$(TBIN$(1)_T_$(4)_H_$(3))/cargo$$(X): \
$$(CARGO_CRATE) $$(CARGO_INPUTS) \
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_CORELIB) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_STDLIB) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTC)
@$$(call E, compile_and_link: $$@)

View File

@ -260,7 +260,7 @@ options:
--pretty [type] pretty-print the input instead of compiling
--ls list the symbols defined by a crate file
-L <path> add a directory to the library search path
--noverify suppress LLVM verification step (slight speedup)
--no-verify suppress LLVM verification step (slight speedup)
--parse-only parse only; do not compile, assemble, or link
--no-trans run all passes except translation; no output
-g produce debug info
@ -362,7 +362,7 @@ fn build_session_options(match: getopts::match)
} else if opt_present(match, "emit-llvm") {
link::output_type_bitcode
} else { link::output_type_exe };
let verify = !opt_present(match, "noverify");
let verify = !opt_present(match, "no-verify");
let save_temps = opt_present(match, "save-temps");
let debuginfo = opt_present(match, "g");
let stats = opt_present(match, "stats");
@ -463,7 +463,7 @@ fn opts() -> [getopts::opt] {
optflag("c"), optopt("o"), optflag("g"), optflag("save-temps"),
optopt("sysroot"), optopt("target"), optflag("stats"),
optflag("time-passes"), optflag("time-llvm-passes"),
optflag("noverify"),
optflag("no-verify"),
optmulti("cfg"), optflag("test"),
optflag("lib"), optflag("static"), optflag("gc"),
optflag("stack-growth"),

View File

@ -1,42 +0,0 @@
/*
Module: ctypes
Definitions useful for C interop
*/
type c_int = i32;
type c_uint = u32;
type void = int; // Not really the same as C
type long = int;
type unsigned = u32;
type ulong = uint;
type intptr_t = uint;
type uintptr_t = uint;
type uint32_t = u32;
// machine type equivalents of rust int, uint, float
#[cfg(target_arch="x86")]
type m_int = i32;
#[cfg(target_arch="x86_64")]
type m_int = i64;
#[cfg(target_arch="x86")]
type m_uint = u32;
#[cfg(target_arch="x86_64")]
type m_uint = u64;
// This *must* match with "import m_float = fXX" in std::math per arch
type m_float = f64;
type size_t = uint;
type ssize_t = int;
type off_t = uint;
type fd_t = i32; // not actually a C type, but should be.
type pid_t = i32;
// enum is implementation-defined, but is 32-bits in practice
type enum = u32;

17
src/libcore/core.rc Normal file
View File

@ -0,0 +1,17 @@
#[link(name = "core",
vers = "0.1",
uuid = "c70c24a7-5551-4f73-8e37-380b11d80be8",
url = "http://rust-lang.org/src/core")];
#[comment = "The Rust core library"];
#[license = "BSD"];
// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:

View File

@ -57,6 +57,16 @@ resource dtor_res(dtor: option::t<fn@()>) {
Section: Introduction forms
*/
/*
Function: create
Create a c_vec::t from a native buffer with a given size.
Parameters:
base - A native pointer to a buffer
size - The number of elements in the buffer
*/
unsafe fn create<T>(base: *mutable T, size: uint) -> t<T> {
ret t({base: base,
size: size,
@ -64,6 +74,19 @@ unsafe fn create<T>(base: *mutable T, size: uint) -> t<T> {
});
}
/*
Function: create_with_dtor
Create a c_vec::t from a native buffer, with a given size,
and a function to run upon destruction.
Parameters:
base - A native pointer to a buffer
size - The number of elements in the buffer
dtor - A function to run when the value is destructed, useful
for freeing the buffer, etc.
*/
unsafe fn create_with_dtor<T>(base: *mutable T, size: uint, dtor: fn@())
-> t<T> {
ret t({base: base,
@ -76,11 +99,29 @@ unsafe fn create_with_dtor<T>(base: *mutable T, size: uint, dtor: fn@())
Section: Operations
*/
/*
Function: get
Retrieves an element at a given index
Failure:
If `ofs` is greater or equal to the length of the vector
*/
fn get<copy T>(t: t<T>, ofs: uint) -> T {
assert ofs < (*t).size;
ret unsafe { *ptr::mut_offset((*t).base, ofs) };
}
/*
Function: set
Sets the value of an element at a given index
Failure:
If `ofs` is greater or equal to the length of the vector
*/
fn set<copy T>(t: t<T>, ofs: uint, v: T) {
assert ofs < (*t).size;
unsafe { *ptr::mut_offset((*t).base, ofs) = v };
@ -90,10 +131,21 @@ fn set<copy T>(t: t<T>, ofs: uint, v: T) {
Section: Elimination forms
*/
// FIXME: Rename to len
/*
Function: size
Returns the length of the vector
*/
fn size<T>(t: t<T>) -> uint {
ret (*t).size;
}
/*
Function: ptr
Returns a pointer to the first element of the vector
*/
unsafe fn ptr<T>(t: t<T>) -> *mutable T {
ret (*t).base;
}

146
src/libstd/ctypes.rs Normal file
View File

@ -0,0 +1,146 @@
/*
Module: ctypes
Definitions useful for C interop
*/
/*
FIXME: Add a test that uses some native code to verify these sizes,
which are not obviously correct for all potential platforms.
*/
/*
Type: c_int
A signed integer with the same size as a C `int`
*/
type c_int = i32;
/*
Type: c_uint
An unsigned integer with the same size as a C `unsigned int`
*/
type c_uint = u32;
/*
Type: long
A signed integer with the same size as a C `long`
*/
type long = int;
/*
Type: unsigned
An unsigned integer with the same size as a C `unsigned int`
*/
type unsigned = u32;
/*
Type: ulong
An unsigned integer with the same size as a C `unsigned long`
*/
type ulong = uint;
/*
Type: intptr_t
A signed integer with the same size as a pointer. This is
guaranteed to always be the same type as a Rust `int`
*/
type intptr_t = uint; // FIXME: int
/*
Type: uintptr_t
An unsigned integer with the same size as a pointer. This is
guaranteed to always be the same type as a Rust `uint`.
*/
type uintptr_t = uint;
type uint32_t = u32;
/*
Type: void
A type, a pointer to which can be used as C `void *`
Note that this does not directly correspond to the C `void` type,
which is an incomplete type. Using pointers to this type
when interoperating with C void pointers can help in documentation.
*/
type void = int;
// machine type equivalents of rust int, uint, float
/*
Type: m_int
FIXME: What C type does this represent?
*/
#[cfg(target_arch="x86")]
type m_int = i32;
#[cfg(target_arch="x86_64")]
type m_int = i64;
/*
Type: m_uint
FIXME: What C type does this represent?
*/
#[cfg(target_arch="x86")]
type m_uint = u32;
#[cfg(target_arch="x86_64")]
type m_uint = u64;
// This *must* match with "import m_float = fXX" in std::math per arch
/*
Type: m_float
FIXME: What C type does this represent?
*/
type m_float = f64;
/*
Type: size_t
An unsigned integer corresponding to the C `size_t`
*/
type size_t = uint;
/*
Type: ssize_t
A signed integer correpsonding to the C `ssize_t`
*/
type ssize_t = int;
/*
Type: off_t
An unsigned integer corresponding to the C `off_t`
*/
type off_t = uint;
/*
Type: fd_t
A type that can be used for C file descriptors
*/
type fd_t = i32; // not actually a C type, but should be.
/*
Type: pid_t
A type for representing process ID's, corresponding to C `pid_t`
*/
type pid_t = i32;
// enum is implementation-defined, but is 32-bits in practice
/*
Type: enum
An unsigned integer with the same size as a C enum
*/
type enum = u32;

View File

@ -253,25 +253,18 @@ fn pow_uint_to_uint_as_float(x: uint, pow: uint) -> float {
}
/**
* Section: Constants
*/
//TODO: Once this is possible, replace the body of these functions
//by an actual constant.
/* Const: NaN */
const NaN: float = 0./0.;
/* Predicate: isNaN */
pure fn isNaN(f: float) -> bool { f != f }
/* Const: infinity */
const infinity: float = 1./0.;
/* Const: neg_infinity */
const neg_infinity: float = -1./0.;
/* Predicate: isNaN */
pure fn isNaN(f: float) -> bool { f != f }
/* Function: add */
pure fn add(x: float, y: float) -> float { ret x + y; }

View File

@ -1,3 +1,9 @@
/*
Module: io
Basic input/output
*/
import ctypes::fd_t;
import ctypes::c_int;

View File

@ -23,6 +23,9 @@ import ctypes::c_int;
import m_float = math_f64;
// FIXME replace with redirect to m_float::consts::FOO as soon as it works
/*
Module: consts
*/
mod consts {
/*
Const: pi

View File

@ -17,6 +17,7 @@ export
export consts;
/* Module: consts */
mod consts {
/*

View File

@ -17,6 +17,7 @@ export
export consts;
/* Module: consts */
mod consts {
/*

View File

@ -174,7 +174,8 @@ fn byte_len_range(s: str, byte_offset: uint, char_len: uint) -> uint {
/*
Function: bytes
Converts a string to a vector of bytes
Converts a string to a vector of bytes. The result vector is not
null-terminated.
*/
fn bytes(s: str) -> [u8] unsafe {
let v = unsafe::reinterpret_cast(s);

View File

@ -9,6 +9,9 @@ import option;
import option::{none, some};
import rand;
/*
Function: mkdtemp
*/
fn mkdtemp(prefix: str, suffix: str) -> option::t<str> {
let r = rand::mk_rng();
let i = 0u;

View File

@ -7,7 +7,7 @@
#include <inttypes.h>
#include <stdint.h>
#include "../../memcheck.h"
#include "vg/memcheck.h"
template<typename T>
T align_down(T sp)
@ -51,9 +51,7 @@ public:
uint32_t bot = regs.esp;
uint32_t top = align_down(bot - nbytes);
#ifdef HAVE_VALGRIND
(void)VALGRIND_MAKE_MEM_UNDEFINED(top - 4, bot - top + 4);
#endif
return reinterpret_cast<void *>(top);
}

View File

@ -75,11 +75,12 @@ MORESTACK:
// The arguments to rust_new_stack2
movl 40(%esp),%eax // Size of stack arguments
movl %eax,16(%esp)
movl %eax,20(%esp)
leal 48(%esp),%eax // Address of stack arguments
movl %eax,12(%esp)
movl %eax,16(%esp)
movl 36(%esp),%eax // The amount of stack needed
movl %eax,8(%esp)
movl %eax,12(%esp)
movl $0, 8(%esp) // Out pointer
#ifdef __APPLE__
call 1f
@ -97,7 +98,7 @@ MORESTACK:
movl 32(%esp),%edx // Grab the return pointer.
inc %edx // Skip past the ret instruction in the parent fn
movl %eax,%esp // Switch stacks.
movl 8(%esp),%esp // Switch stacks.
call *%edx // Re-enter the function that called us.
// Now the function that called us has returned, so we need to delete the

View File

@ -8,9 +8,7 @@
#include <stdint.h>
#include <xmmintrin.h>
#ifdef HAVE_VALGRIND
#include <valgrind/memcheck.h>
#endif
#include "vg/memcheck.h"
template<typename T>
T align_down(T sp)
@ -51,9 +49,7 @@ public:
uint64_t bot = regs.data[RUSTRT_RSP];
uint64_t top = align_down(bot - nbytes);
#ifdef HAVE_VALGRIND
(void)VALGRIND_MAKE_MEM_UNDEFINED(top - 4, bot - top + 4);
#endif
return reinterpret_cast<void *>(top);
}

View File

@ -81,9 +81,12 @@ MORESTACK:
movq %rbp, %rcx
addq $24, %rcx // Base pointer, return address x2
pushq $0 // Alignment
pushq %r11 // Size of stack arguments
pushq %rcx // Address of stack arguments
pushq %r10 // The amount of stack needed
pushq $0 // Out pointer
movq UPCALL_NEW_STACK@GOTPCREL(%rip), %rsi
movq %rsp, %rdi
@ -95,7 +98,8 @@ MORESTACK:
#endif
// Pop the new_stack_args struct
addq $24, %rsp
popq %rax
addq $32, %rsp
// Pop the saved arguments
popq %r9

View File

@ -273,6 +273,12 @@ debug_ptrcast(type_desc *from_ty,
return ptr;
}
extern "C" CDECL void *
debug_get_stk_seg() {
rust_task *task = rust_scheduler::get_task();
return task->stk;
}
extern "C" CDECL rust_vec*
rust_list_files(rust_str *path) {
rust_task *task = rust_scheduler::get_task();

View File

@ -2,8 +2,8 @@
#include "rust_internal.h"
#include "rust_cc.h"
#include "valgrind.h"
#include "memcheck.h"
#include "vg/valgrind.h"
#include "vg/memcheck.h"
#ifndef __WIN32__
#include <execinfo.h>
@ -131,6 +131,9 @@ rust_task::~rust_task()
// (ref_count == 1 && this == sched->root_task));
// Delete all the stacks. There may be more than one if the task failed
// FIXME: This is not correct. During unwinding we need to delete
// the stacks and record the stack limit, otherwise the stack
// stack is corrupted when destructors are running.
while (stk != NULL) {
del_stk(this, stk);
}

View File

@ -1,5 +1,5 @@
#include "rust_internal.h"
#include "valgrind.h"
#include "vg/valgrind.h"
// The mechanism in this file is very crude; every domain (thread) spawns its
// own secondary timer thread, and that timer thread *never idles*. It

View File

@ -209,28 +209,48 @@ upcall_dynastack_free(void *ptr) {
return rust_scheduler::get_task()->dynastack.free(ptr);
}
extern "C" void record_sp(void *limit);
/**
* Allocates |nbytes| bytes in the C stack and returns a pointer to the start
* of the allocated space.
* Switch to the C stack and call the given function, passing a single pointer
* argument.
*/
extern "C" CDECL void
upcall_call_shim_on_c_stack(void *args, void *fn_ptr) {
rust_scheduler *sched = rust_scheduler::get_task()->sched;
sched->c_context.call_shim_on_c_stack(args, fn_ptr);
rust_task *task = rust_scheduler::get_task();
// FIXME (1226) - The shim functions generated by rustc contain the
// morestack prologue, so we need to let them know they have enough
// stack.
record_sp(0);
rust_scheduler *sched = task->sched;
try {
sched->c_context.call_shim_on_c_stack(args, fn_ptr);
} catch (...) {
task = rust_scheduler::get_task();
task->record_stack_limit();
throw;
}
task = rust_scheduler::get_task();
task->record_stack_limit();
}
struct rust_new_stack2_args {
size_t stk_sz;
void *args_addr;
size_t args_sz;
void *new_stack;
size_t stk_sz;
void *args_addr;
size_t args_sz;
};
// A new stack function suitable for calling through
// upcall_call_shim_on_c_stack
extern "C" CDECL void *
extern "C" CDECL void
upcall_new_stack(struct rust_new_stack2_args *args) {
rust_task *task = rust_scheduler::get_task();
return task->new_stack(args->stk_sz, args->args_addr, args->args_sz);
args->new_stack = task->new_stack(args->stk_sz,
args->args_addr,
args->args_sz);
}
extern "C" CDECL void

View File

@ -8,6 +8,7 @@ del_port
debug_ptrcast
debug_tag
debug_tydesc
debug_get_stk_seg
do_gc
drop_task
get_port_id

View File

@ -0,0 +1,41 @@
// xfail-test
// error-pattern:explicit failure
// compile-flags:--stack-growth
// This time we're testing that the stack limits are restored
// correctly after calling into the C stack and unwinding.
// See the hack in upcall_call_shim_on_c_stack where it messes
// with the stack limit.
use std;
native mod rustrt {
fn set_min_stack(size: uint);
fn pin_task();
}
fn getbig_call_c_and_fail(i: int) {
if i != 0 {
getbig_call_c_and_fail(i - 1);
} else {
rustrt::pin_task();
fail;
}
}
resource and_then_get_big_again(_i: ()) {
fn getbig(i: int) {
if i != 0 {
getbig(i - 1);
}
}
getbig(10000);
}
fn main() {
rustrt::set_min_stack(256u);
std::task::spawn((), fn (&&_i: ()) {
let r = and_then_get_big_again(());
getbig_call_c_and_fail(10000);
});
}

View File

@ -0,0 +1,34 @@
// xfail-test
// error-pattern:explicit failure
// compile-flags:--stack-growth
// Just testing unwinding
use std;
native mod rustrt {
fn set_min_stack(size: uint);
}
fn getbig_and_fail(&&i: int) {
let r = and_then_get_big_again(@0);
if i != 0 {
getbig_and_fail(i - 1);
} else {
fail;
}
}
resource and_then_get_big_again(_i: @int) {
fn getbig(i: int) {
if i != 0 {
getbig(i - 1);
}
}
getbig(1000);
}
fn main() {
rustrt::set_min_stack(256u);
std::task::spawn(1000, getbig_and_fail);
}

View File

@ -0,0 +1,100 @@
// xfail-test
// compile-flags:--stack-growth
// This is testing for stack frames greater than 256 bytes,
// for which function prologues are generated differently
type biggy = {
a00: u64,
a01: u64,
a02: u64,
a03: u64,
a04: u64,
a05: u64,
a06: u64,
a07: u64,
a08: u64,
a09: u64,
a10: u64,
a11: u64,
a12: u64,
a13: u64,
a14: u64,
a15: u64,
a16: u64,
a17: u64,
a18: u64,
a19: u64,
a20: u64,
a21: u64,
a22: u64,
a23: u64,
a24: u64,
a25: u64,
a26: u64,
a27: u64,
a28: u64,
a29: u64,
a30: u64,
a31: u64,
a32: u64,
a33: u64,
a34: u64,
a35: u64,
a36: u64,
a37: u64,
a38: u64,
a39: u64,
};
fn getbig(i: biggy) {
if i.a00 != 0u64 {
getbig({a00: i.a00 - 1u64 with i});
}
}
fn main() {
getbig({
a00: 100000u64,
a01: 100000u64,
a02: 100000u64,
a03: 100000u64,
a04: 100000u64,
a05: 100000u64,
a06: 100000u64,
a07: 100000u64,
a08: 100000u64,
a09: 100000u64,
a10: 100000u64,
a11: 100000u64,
a12: 100000u64,
a13: 100000u64,
a14: 100000u64,
a15: 100000u64,
a16: 100000u64,
a17: 100000u64,
a18: 100000u64,
a19: 100000u64,
a20: 100000u64,
a21: 100000u64,
a22: 100000u64,
a23: 100000u64,
a24: 100000u64,
a25: 100000u64,
a26: 100000u64,
a27: 100000u64,
a28: 100000u64,
a29: 100000u64,
a30: 100000u64,
a31: 100000u64,
a32: 100000u64,
a33: 100000u64,
a34: 100000u64,
a35: 100000u64,
a36: 100000u64,
a37: 100000u64,
a38: 100000u64,
a39: 100000u64,
});
}

View File

@ -0,0 +1,26 @@
// xfail-test
// compile-flags:--stack-growth
// This test will call __morestack with various minimum stack sizes
use std;
import std::task;
native mod rustrt {
fn set_min_stack(size: uint);
}
fn getbig(&&i: int) {
if i != 0 {
getbig(i - 1);
}
}
fn main() {
let sz = 400u;
while sz < 500u {
rustrt::set_min_stack(sz);
task::join(task::spawn_joinable(200, getbig));
sz += 1u;
}
}

View File

@ -0,0 +1,81 @@
// xfail-test
// compile-flags:--stack-growth
// This test attempts to force the dynamic linker to resolve
// external symbols as close to the red zone as possible.
use std;
import std::task;
import std::rand;
native mod rustrt {
fn set_min_stack(size: uint);
fn debug_get_stk_seg() -> *u8;
fn unsupervise();
fn last_os_error() -> str;
fn rust_getcwd() -> str;
fn refcount(box: @int);
fn do_gc();
fn pin_task();
fn unpin_task();
fn get_task_id();
fn sched_threads();
fn rust_get_task();
}
fn calllink01() { rustrt::unsupervise(); }
fn calllink02() { rustrt::last_os_error(); }
fn calllink03() { rustrt::rust_getcwd(); }
fn calllink04() { rustrt::refcount(@0); }
fn calllink05() { rustrt::do_gc(); }
fn calllink06() { rustrt::pin_task(); }
fn calllink07() { rustrt::unpin_task(); }
fn calllink08() { rustrt::get_task_id(); }
fn calllink09() { rustrt::sched_threads(); }
fn calllink10() { rustrt::rust_get_task(); }
fn runtest(&&args:(fn(), u32)) {
let (f, frame_backoff) = args;
runtest2(f, frame_backoff, 0 as *u8);
}
fn runtest2(f: fn(), frame_backoff: u32, last_stk: *u8) -> u32 {
let curr_stk = rustrt::debug_get_stk_seg();
if (last_stk != curr_stk && last_stk != 0 as *u8) {
// We switched stacks, go back and try to hit the dynamic linker
frame_backoff
} else {
let frame_backoff = runtest2(f, frame_backoff, curr_stk);
if frame_backoff > 1u32 {
frame_backoff - 1u32
} else if frame_backoff == 1u32 {
f();
0u32
} else {
0u32
}
}
}
fn main() {
let fns = [
calllink01,
calllink02,
calllink03,
calllink04,
calllink05,
calllink06,
calllink07,
calllink08,
calllink09,
calllink10
];
let rng = rand::mk_rng();
for f in fns {
let sz = rng.next() % 256u32 + 256u32;
let frame_backoff = rng.next() % 10u32 + 1u32;
rustrt::set_min_stack(sz as uint);
task::join(task::spawn_joinable((f, frame_backoff), runtest));
}
}