librustc: Make C functions unsafe

This commit is contained in:
Patrick Walton
2013-01-23 16:29:31 -08:00
parent e43cff6657
commit 163b97b7bb
43 changed files with 635 additions and 529 deletions

View File

@@ -280,17 +280,23 @@ extern mod rusti {
// I get link errors. This is a bug that needs investigated more. // I get link errors. This is a bug that needs investigated more.
#[doc(hidden)] #[doc(hidden)]
pub fn atomic_xchng_rel(dst: &mut int, src: int) -> int { pub fn atomic_xchng_rel(dst: &mut int, src: int) -> int {
unsafe {
rusti::atomic_xchg_rel(dst, src) rusti::atomic_xchg_rel(dst, src)
}
} }
#[doc(hidden)] #[doc(hidden)]
pub fn atomic_add_acq(dst: &mut int, src: int) -> int { pub fn atomic_add_acq(dst: &mut int, src: int) -> int {
unsafe {
rusti::atomic_xadd_acq(dst, src) rusti::atomic_xadd_acq(dst, src)
}
} }
#[doc(hidden)] #[doc(hidden)]
pub fn atomic_sub_rel(dst: &mut int, src: int) -> int { pub fn atomic_sub_rel(dst: &mut int, src: int) -> int {
unsafe {
rusti::atomic_xsub_rel(dst, src) rusti::atomic_xsub_rel(dst, src)
}
} }
#[doc(hidden)] #[doc(hidden)]

View File

@@ -93,8 +93,10 @@ type rust_port_id = uint;
type GlobalPtr = *libc::uintptr_t; type GlobalPtr = *libc::uintptr_t;
fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool { fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool {
unsafe {
let old = rusti::atomic_cxchg(address, oldval, newval); let old = rusti::atomic_cxchg(address, oldval, newval);
old == oldval old == oldval
}
} }
/** /**

View File

@@ -201,11 +201,13 @@ impl ReprVisitor {
#[inline(always)] #[inline(always)]
fn visit_ptr_inner(ptr: *c_void, inner: *TyDesc) -> bool { fn visit_ptr_inner(ptr: *c_void, inner: *TyDesc) -> bool {
unsafe {
let mut u = ReprVisitor(ptr, self.writer); let mut u = ReprVisitor(ptr, self.writer);
let v = reflect::MovePtrAdaptor(move u); let v = reflect::MovePtrAdaptor(move u);
visit_tydesc(inner, (move v) as @TyVisitor); visit_tydesc(inner, (move v) as @TyVisitor);
true true
} }
}
#[inline(always)] #[inline(always)]
fn write<T:Repr>() -> bool { fn write<T:Repr>() -> bool {
@@ -558,11 +560,13 @@ impl ReprVisitor : TyVisitor {
} }
pub fn write_repr<T>(writer: @Writer, object: &T) { pub fn write_repr<T>(writer: @Writer, object: &T) {
unsafe {
let ptr = ptr::to_unsafe_ptr(object) as *c_void; let ptr = ptr::to_unsafe_ptr(object) as *c_void;
let tydesc = intrinsic::get_tydesc::<T>(); let tydesc = intrinsic::get_tydesc::<T>();
let mut u = ReprVisitor(ptr, writer); let mut u = ReprVisitor(ptr, writer);
let v = reflect::MovePtrAdaptor(move u); let v = reflect::MovePtrAdaptor(move u);
visit_tydesc(tydesc, (move v) as @TyVisitor) visit_tydesc(tydesc, (move v) as @TyVisitor)
}
} }
#[test] #[test]

View File

@@ -571,23 +571,29 @@ pub fn try<T:Owned>(f: fn~() -> T) -> Result<T,()> {
pub fn yield() { pub fn yield() {
//! Yield control to the task scheduler //! Yield control to the task scheduler
unsafe {
let task_ = rt::rust_get_task(); let task_ = rt::rust_get_task();
let killed = rt::rust_task_yield(task_); let killed = rt::rust_task_yield(task_);
if killed && !failing() { if killed && !failing() {
fail ~"killed"; fail ~"killed";
} }
}
} }
pub fn failing() -> bool { pub fn failing() -> bool {
//! True if the running task has failed //! True if the running task has failed
unsafe {
rt::rust_task_is_unwinding(rt::rust_get_task()) rt::rust_task_is_unwinding(rt::rust_get_task())
}
} }
pub fn get_task() -> Task { pub fn get_task() -> Task {
//! Get a handle to the running task //! Get a handle to the running task
unsafe {
TaskHandle(rt::get_task_id()) TaskHandle(rt::get_task_id())
}
} }
/** /**
@@ -608,7 +614,11 @@ pub fn get_task() -> Task {
pub unsafe fn unkillable<U>(f: fn() -> U) -> U { pub unsafe fn unkillable<U>(f: fn() -> U) -> U {
struct AllowFailure { struct AllowFailure {
t: *rust_task, t: *rust_task,
drop { rt::rust_task_allow_kill(self.t); } drop {
unsafe {
rt::rust_task_allow_kill(self.t);
}
}
} }
fn AllowFailure(t: *rust_task) -> AllowFailure{ fn AllowFailure(t: *rust_task) -> AllowFailure{
@@ -617,17 +627,23 @@ pub unsafe fn unkillable<U>(f: fn() -> U) -> U {
} }
} }
unsafe {
let t = rt::rust_get_task(); let t = rt::rust_get_task();
let _allow_failure = AllowFailure(t); let _allow_failure = AllowFailure(t);
rt::rust_task_inhibit_kill(t); rt::rust_task_inhibit_kill(t);
f() f()
}
} }
/// The inverse of unkillable. Only ever to be used nested in unkillable(). /// The inverse of unkillable. Only ever to be used nested in unkillable().
pub unsafe fn rekillable<U>(f: fn() -> U) -> U { pub unsafe fn rekillable<U>(f: fn() -> U) -> U {
struct DisallowFailure { struct DisallowFailure {
t: *rust_task, t: *rust_task,
drop { rt::rust_task_inhibit_kill(self.t); } drop {
unsafe {
rt::rust_task_inhibit_kill(self.t);
}
}
} }
fn DisallowFailure(t: *rust_task) -> DisallowFailure { fn DisallowFailure(t: *rust_task) -> DisallowFailure {
@@ -636,10 +652,12 @@ pub unsafe fn rekillable<U>(f: fn() -> U) -> U {
} }
} }
unsafe {
let t = rt::rust_get_task(); let t = rt::rust_get_task();
let _allow_failure = DisallowFailure(t); let _allow_failure = DisallowFailure(t);
rt::rust_task_allow_kill(t); rt::rust_task_allow_kill(t);
f() f()
}
} }
/** /**
@@ -650,10 +668,12 @@ pub unsafe fn atomically<U>(f: fn() -> U) -> U {
struct DeferInterrupts { struct DeferInterrupts {
t: *rust_task, t: *rust_task,
drop { drop {
unsafe {
rt::rust_task_allow_yield(self.t); rt::rust_task_allow_yield(self.t);
rt::rust_task_allow_kill(self.t); rt::rust_task_allow_kill(self.t);
} }
} }
}
fn DeferInterrupts(t: *rust_task) -> DeferInterrupts { fn DeferInterrupts(t: *rust_task) -> DeferInterrupts {
DeferInterrupts { DeferInterrupts {
@@ -661,11 +681,13 @@ pub unsafe fn atomically<U>(f: fn() -> U) -> U {
} }
} }
unsafe {
let t = rt::rust_get_task(); let t = rt::rust_get_task();
let _interrupts = DeferInterrupts(t); let _interrupts = DeferInterrupts(t);
rt::rust_task_inhibit_kill(t); rt::rust_task_inhibit_kill(t);
rt::rust_task_inhibit_yield(t); rt::rust_task_inhibit_yield(t);
f() f()
}
} }
#[test] #[should_fail] #[ignore(cfg(windows))] #[test] #[should_fail] #[ignore(cfg(windows))]
@@ -908,9 +930,11 @@ fn test_spawn_sched() {
let ch = oldcomm::Chan(&po); let ch = oldcomm::Chan(&po);
fn f(i: int, ch: oldcomm::Chan<()>) { fn f(i: int, ch: oldcomm::Chan<()>) {
unsafe {
let parent_sched_id = rt::rust_get_sched_id(); let parent_sched_id = rt::rust_get_sched_id();
do spawn_sched(SingleThreaded) { do spawn_sched(SingleThreaded) {
unsafe {
let child_sched_id = rt::rust_get_sched_id(); let child_sched_id = rt::rust_get_sched_id();
assert parent_sched_id != child_sched_id; assert parent_sched_id != child_sched_id;
@@ -919,7 +943,9 @@ fn test_spawn_sched() {
} else { } else {
f(i - 1, ch); f(i - 1, ch);
} }
}
}; };
}
} }
f(10, ch); f(10, ch);
@@ -932,13 +958,17 @@ fn test_spawn_sched_childs_on_same_sched() {
let ch = oldcomm::Chan(&po); let ch = oldcomm::Chan(&po);
do spawn_sched(SingleThreaded) { do spawn_sched(SingleThreaded) {
unsafe {
let parent_sched_id = rt::rust_get_sched_id(); let parent_sched_id = rt::rust_get_sched_id();
do spawn { do spawn {
unsafe {
let child_sched_id = rt::rust_get_sched_id(); let child_sched_id = rt::rust_get_sched_id();
// This should be on the same scheduler // This should be on the same scheduler
assert parent_sched_id == child_sched_id; assert parent_sched_id == child_sched_id;
oldcomm::send(ch, ()); oldcomm::send(ch, ());
}
}; };
}
}; };
oldcomm::recv(po); oldcomm::recv(po);
@@ -1185,11 +1215,13 @@ fn test_sched_thread_per_core() {
let (port, chan) = pipes::stream(); let (port, chan) = pipes::stream();
do spawn_sched(ThreadPerCore) |move chan| { do spawn_sched(ThreadPerCore) |move chan| {
unsafe {
let cores = rt::rust_num_threads(); let cores = rt::rust_num_threads();
let reported_threads = rt::rust_sched_threads(); let reported_threads = rt::rust_sched_threads();
assert(cores as uint == reported_threads as uint); assert(cores as uint == reported_threads as uint);
chan.send(()); chan.send(());
} }
}
port.recv(); port.recv();
} }
@@ -1199,6 +1231,7 @@ fn test_spawn_thread_on_demand() {
let (port, chan) = pipes::stream(); let (port, chan) = pipes::stream();
do spawn_sched(ManualThreads(2)) |move chan| { do spawn_sched(ManualThreads(2)) |move chan| {
unsafe {
let max_threads = rt::rust_sched_threads(); let max_threads = rt::rust_sched_threads();
assert(max_threads as int == 2); assert(max_threads as int == 2);
let running_threads = rt::rust_sched_current_nonlazy_threads(); let running_threads = rt::rust_sched_current_nonlazy_threads();
@@ -1216,6 +1249,7 @@ fn test_spawn_thread_on_demand() {
port2.recv(); port2.recv();
chan.send(()); chan.send(());
} }
}
port.recv(); port.recv();
} }

View File

@@ -308,6 +308,7 @@ struct TCB {
notifier: Option<AutoNotify>, notifier: Option<AutoNotify>,
// Runs on task exit. // Runs on task exit.
drop { drop {
unsafe {
// If we are failing, the whole taskgroup needs to die. // If we are failing, the whole taskgroup needs to die.
if rt::rust_task_is_unwinding(self.me) { if rt::rust_task_is_unwinding(self.me) {
self.notifier.iter(|x| { x.failed = true; }); self.notifier.iter(|x| { x.failed = true; });
@@ -321,13 +322,15 @@ struct TCB {
leave_taskgroup(tg, self.me, true); leave_taskgroup(tg, self.me, true);
} }
} }
// It doesn't matter whether this happens before or after dealing with // It doesn't matter whether this happens before or after dealing
// our own taskgroup, so long as both happen before we die. We need to // with our own taskgroup, so long as both happen before we die.
// remove ourself from every ancestor we can, so no cleanup; no break. // We remove ourself from every ancestor we can, so no cleanup; no
// break.
for each_ancestor(&mut self.ancestors, None) |ancestor_group| { for each_ancestor(&mut self.ancestors, None) |ancestor_group| {
leave_taskgroup(ancestor_group, self.me, false); leave_taskgroup(ancestor_group, self.me, false);
}; };
} }
}
} }
fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList, fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList,
@@ -391,14 +394,16 @@ fn leave_taskgroup(state: TaskGroupInner, me: *rust_task,
// NB: Runs in destructor/post-exit context. Can't 'fail'. // NB: Runs in destructor/post-exit context. Can't 'fail'.
fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) { fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) {
unsafe {
// NB: We could do the killing iteration outside of the group arc, by // NB: We could do the killing iteration outside of the group arc, by
// having "let mut newstate" here, swapping inside, and iterating after. // having "let mut newstate" here, swapping inside, and iterating
// But that would let other exiting tasks fall-through and exit while we // after. But that would let other exiting tasks fall-through and exit
// were trying to kill them, causing potential use-after-free. A task's // while we were trying to kill them, causing potential
// presence in the arc guarantees it's alive only while we hold the lock, // use-after-free. A task's presence in the arc guarantees it's alive
// so if we're failing, all concurrently exiting tasks must wait for us. // only while we hold the lock, so if we're failing, all concurrently
// To do it differently, we'd have to use the runtime's task refcounting, // exiting tasks must wait for us. To do it differently, we'd have to
// but that could leave task structs around long after their task exited. // use the runtime's task refcounting, but that could leave task
// structs around long after their task exited.
let newstate = util::replace(state, None); let newstate = util::replace(state, None);
// Might already be None, if Somebody is failing simultaneously. // Might already be None, if Somebody is failing simultaneously.
// That's ok; only one task needs to do the dirty work. (Might also // That's ok; only one task needs to do the dirty work. (Might also
@@ -423,6 +428,7 @@ fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) {
// that the whole taskgroup is failing, to forbid new spawns. // that the whole taskgroup is failing, to forbid new spawns.
} }
// (note: multiple tasks may reach this point) // (note: multiple tasks may reach this point)
}
} }
// FIXME (#2912): Work around core-vs-coretest function duplication. Can't use // FIXME (#2912): Work around core-vs-coretest function duplication. Can't use
@@ -434,32 +440,32 @@ macro_rules! taskgroup_key (
fn gen_child_taskgroup(linked: bool, supervised: bool) fn gen_child_taskgroup(linked: bool, supervised: bool)
-> (TaskGroupArc, AncestorList, bool) { -> (TaskGroupArc, AncestorList, bool) {
unsafe {
let spawner = rt::rust_get_task(); let spawner = rt::rust_get_task();
/*######################################################################* /*##################################################################*
* Step 1. Get spawner's taskgroup info. * Step 1. Get spawner's taskgroup info.
*######################################################################*/ *##################################################################*/
let spawner_group = match unsafe { local_get(spawner, let spawner_group = match local_get(spawner, taskgroup_key!()) {
taskgroup_key!()) } {
None => { None => {
// Main task, doing first spawn ever. Lazily initialise here. // Main task, doing first spawn ever. Lazily initialise here.
let mut members = new_taskset(); let mut members = new_taskset();
taskset_insert(&mut members, spawner); taskset_insert(&mut members, spawner);
let tasks = let tasks =
private::exclusive(Some({ mut members: move members, private::exclusive(Some({
mut descendants: new_taskset() })); mut members: move members,
mut descendants: new_taskset()
}));
// Main task/group has no ancestors, no notifier, etc. // Main task/group has no ancestors, no notifier, etc.
let group = let group =
@TCB(spawner, move tasks, AncestorList(None), true, None); @TCB(spawner, move tasks, AncestorList(None), true, None);
unsafe {
local_set(spawner, taskgroup_key!(), group); local_set(spawner, taskgroup_key!(), group);
}
group group
} }
Some(group) => group Some(group) => group
}; };
/*######################################################################* /*##################################################################*
* Step 2. Process spawn options for child. * Step 2. Process spawn options for child.
*######################################################################*/ *##################################################################*/
return if linked { return if linked {
// Child is in the same group as spawner. // Child is in the same group as spawner.
let g = spawner_group.tasks.clone(); let g = spawner_group.tasks.clone();
@@ -469,14 +475,17 @@ fn gen_child_taskgroup(linked: bool, supervised: bool)
(move g, move a, spawner_group.is_main) (move g, move a, spawner_group.is_main)
} else { } else {
// Child is in a separate group from spawner. // Child is in a separate group from spawner.
let g = private::exclusive(Some({ mut members: new_taskset(), let g = private::exclusive(Some({
mut descendants: new_taskset() })); mut members: new_taskset(),
mut descendants: new_taskset()
}));
let a = if supervised { let a = if supervised {
// Child's ancestors start with the spawner. // Child's ancestors start with the spawner.
let old_ancestors = share_ancestors(&mut spawner_group.ancestors); let old_ancestors =
// FIXME(#3068) - The generation counter is only used for a debug share_ancestors(&mut spawner_group.ancestors);
// assertion, but initialising it requires locking a mutex. Hence // FIXME(#3068) - The generation counter is only used for a
// it should be enabled only in debug builds. // debug assertion, but initialising it requires locking a
// mutex. Hence it should be enabled only in debug builds.
let new_generation = let new_generation =
match *old_ancestors { match *old_ancestors {
Some(ref arc) => { Some(ref arc) => {
@@ -496,6 +505,7 @@ fn gen_child_taskgroup(linked: bool, supervised: bool)
}; };
(move g, move a, false) (move g, move a, false)
}; };
}
fn share_ancestors(ancestors: &mut AncestorList) -> AncestorList { fn share_ancestors(ancestors: &mut AncestorList) -> AncestorList {
// Appease the borrow-checker. Really this wants to be written as: // Appease the borrow-checker. Really this wants to be written as:
@@ -632,6 +642,7 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
} }
fn new_task_in_new_sched(opts: SchedOpts) -> *rust_task { fn new_task_in_new_sched(opts: SchedOpts) -> *rust_task {
unsafe {
if opts.foreign_stack_size != None { if opts.foreign_stack_size != None {
fail ~"foreign_stack_size scheduler option unimplemented"; fail ~"foreign_stack_size scheduler option unimplemented";
} }
@@ -658,6 +669,7 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
}; };
rt::rust_new_task_in_sched(sched_id) rt::rust_new_task_in_sched(sched_id)
} }
}
} }
#[test] #[test]

View File

@@ -19,8 +19,10 @@ mod intrinsic {
// FIXME (#3727): remove this when the interface has settled and the // FIXME (#3727): remove this when the interface has settled and the
// version in sys is no longer present. // version in sys is no longer present.
pub fn get_tydesc<T>() -> *TyDesc { pub fn get_tydesc<T>() -> *TyDesc {
unsafe {
rusti::get_tydesc::<T>() as *TyDesc rusti::get_tydesc::<T>() as *TyDesc
} }
}
pub enum TyDesc = { pub enum TyDesc = {
size: uint, size: uint,

View File

@@ -56,6 +56,7 @@ use syntax::ast::{type_value_ns, ty_param_bound, unnamed_field};
use syntax::ast::{variant, view_item, view_item_export, view_item_import}; use syntax::ast::{variant, view_item, view_item_export, view_item_import};
use syntax::ast::{view_item_use, view_path_glob, view_path_list}; use syntax::ast::{view_item_use, view_path_glob, view_path_list};
use syntax::ast::{view_path_simple, visibility, anonymous, named, not}; use syntax::ast::{view_path_simple, visibility, anonymous, named, not};
use syntax::ast::{unsafe_fn};
use syntax::ast_util::{def_id_of_def, dummy_sp, local_def}; use syntax::ast_util::{def_id_of_def, dummy_sp, local_def};
use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method}; use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
use syntax::ast_util::{Privacy, Public, Private, visibility_to_privacy}; use syntax::ast_util::{Privacy, Public, Private, visibility_to_privacy};
@@ -1643,8 +1644,8 @@ impl Resolver {
foreign_item.span); foreign_item.span);
match /*bad*/copy foreign_item.node { match /*bad*/copy foreign_item.node {
foreign_item_fn(_, purity, type_parameters) => { foreign_item_fn(_, _, type_parameters) => {
let def = def_fn(local_def(foreign_item.id), purity); let def = def_fn(local_def(foreign_item.id), unsafe_fn);
(*name_bindings).define_value(Public, def, foreign_item.span); (*name_bindings).define_value(Public, def, foreign_item.span);
do self.with_type_parameter_rib do self.with_type_parameter_rib

View File

@@ -3342,7 +3342,7 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
} }
}; };
let fty = ty::mk_fn(tcx, FnTyBase { let fty = ty::mk_fn(tcx, FnTyBase {
meta: FnMeta {purity: ast::impure_fn, meta: FnMeta {purity: ast::unsafe_fn,
proto: ast::ProtoBare, proto: ast::ProtoBare,
onceness: ast::Many, onceness: ast::Many,
region: ty::re_static, region: ty::re_static,

View File

@@ -889,9 +889,8 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item) fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item)
-> ty::ty_param_bounds_and_ty { -> ty::ty_param_bounds_and_ty {
match /*bad*/copy it.node { match /*bad*/copy it.node {
ast::foreign_item_fn(fn_decl, purity, params) => { ast::foreign_item_fn(fn_decl, _, params) => {
return ty_of_foreign_fn_decl(ccx, fn_decl, purity, params, return ty_of_foreign_fn_decl(ccx, fn_decl, params, local_def(it.id));
local_def(it.id));
} }
ast::foreign_item_const(t) => { ast::foreign_item_const(t) => {
let rb = in_binding_rscope(empty_rscope); let rb = in_binding_rscope(empty_rscope);
@@ -962,7 +961,6 @@ fn ty_param_bounds(ccx: @crate_ctxt,
fn ty_of_foreign_fn_decl(ccx: @crate_ctxt, fn ty_of_foreign_fn_decl(ccx: @crate_ctxt,
decl: ast::fn_decl, decl: ast::fn_decl,
purity: ast::purity,
+ty_params: ~[ast::ty_param], +ty_params: ~[ast::ty_param],
def_id: ast::def_id) -> ty::ty_param_bounds_and_ty { def_id: ast::def_id) -> ty::ty_param_bounds_and_ty {
let bounds = ty_param_bounds(ccx, ty_params); let bounds = ty_param_bounds(ccx, ty_params);
@@ -971,7 +969,7 @@ fn ty_of_foreign_fn_decl(ccx: @crate_ctxt,
let output_ty = ast_ty_to_ty(ccx, rb, decl.output); let output_ty = ast_ty_to_ty(ccx, rb, decl.output);
let t_fn = ty::mk_fn(ccx.tcx, FnTyBase { let t_fn = ty::mk_fn(ccx.tcx, FnTyBase {
meta: FnMeta {purity: purity, meta: FnMeta {purity: ast::unsafe_fn,
onceness: ast::Many, onceness: ast::Many,
proto: ast::ProtoBare, proto: ast::ProtoBare,
bounds: @~[], bounds: @~[],

View File

@@ -254,9 +254,13 @@ impl &Arena {
// The external interface // The external interface
#[inline(always)] #[inline(always)]
fn alloc<T>(op: fn() -> T) -> &self/T { fn alloc<T>(op: fn() -> T) -> &self/T {
unsafe {
if !rusti::needs_drop::<T>() { if !rusti::needs_drop::<T>() {
self.alloc_pod(op) self.alloc_pod(op)
} else { self.alloc_nonpod(op) } } else {
self.alloc_nonpod(op)
}
}
} }
} }

View File

@@ -31,5 +31,7 @@ extern mod rusti {
#[inline(always)] #[inline(always)]
fn atomic_xchg(dst: &mut int, src: int) -> int { fn atomic_xchg(dst: &mut int, src: int) -> int {
unsafe {
rusti::atomic_xchg(dst, src) rusti::atomic_xchg(dst, src)
}
} }

View File

@@ -21,8 +21,10 @@ extern mod rustrt {
} }
fn fact(n: uint) -> uint { fn fact(n: uint) -> uint {
unsafe {
debug!("n = %?", n); debug!("n = %?", n);
rustrt::rust_dbg_call(cb, n) rustrt::rust_dbg_call(cb, n)
}
} }
extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {

View File

@@ -30,7 +30,9 @@ pub enum port<T: Owned> {
/// Constructs a port /// Constructs a port
pub fn port<T: Owned>() -> port<T> { pub fn port<T: Owned>() -> port<T> {
unsafe {
port_t(@port_ptr(rustrt::new_port(sys::size_of::<T>() as size_t))) port_t(@port_ptr(rustrt::new_port(sys::size_of::<T>() as size_t)))
}
} }
struct port_ptr<T:Owned> { struct port_ptr<T:Owned> {
@@ -75,6 +77,7 @@ pub fn recv<T: Owned>(p: port<T>) -> T { recv_((**p).po) }
/// Receive on a raw port pointer /// Receive on a raw port pointer
pub fn recv_<T: Owned>(p: *rust_port) -> T { pub fn recv_<T: Owned>(p: *rust_port) -> T {
unsafe {
let yield = 0; let yield = 0;
let yieldp = ptr::addr_of(&yield); let yieldp = ptr::addr_of(&yield);
let mut res; let mut res;
@@ -90,6 +93,7 @@ pub fn recv_<T: Owned>(p: *rust_port) -> T {
task::yield(); task::yield();
} }
move res move res
}
} }

View File

@@ -27,8 +27,10 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
} }
fn count(n: uint) -> uint { fn count(n: uint) -> uint {
unsafe {
task::yield(); task::yield();
rustrt::rust_dbg_call(cb, n) rustrt::rust_dbg_call(cb, n)
}
} }
fn main() { fn main() {

View File

@@ -26,9 +26,11 @@ fn getbig_call_c_and_fail(i: int) {
if i != 0 { if i != 0 {
getbig_call_c_and_fail(i - 1); getbig_call_c_and_fail(i - 1);
} else { } else {
unsafe {
rustrt::last_os_error(); rustrt::last_os_error();
fail; fail;
} }
}
} }
struct and_then_get_big_again { struct and_then_get_big_again {

View File

@@ -15,5 +15,7 @@ extern {
} }
fn main() { fn main() {
last_os_error(); unsafe {
let _ = last_os_error();
}
} }

View File

@@ -15,5 +15,7 @@ extern mod rustrt {
} }
fn main() { fn main() {
unsafe {
let _foo = rustrt::get_task_id; let _foo = rustrt::get_task_id;
}
} }

View File

@@ -19,15 +19,17 @@ extern mod libc {
} }
fn atol(s: ~str) -> int { fn atol(s: ~str) -> int {
return str::as_buf(s, { |x, _len| libc::atol(x) }); return str::as_buf(s, { |x, _len| unsafe { libc::atol(x) } });
} }
fn atoll(s: ~str) -> i64 { fn atoll(s: ~str) -> i64 {
return str::as_buf(s, { |x, _len| libc::atoll(x) }); return str::as_buf(s, { |x, _len| unsafe { libc::atoll(x) } });
} }
fn main() { fn main() {
unsafe {
assert atol(~"1024") * 10 == atol(~"10240"); assert atol(~"1024") * 10 == atol(~"10240");
assert (atoll(~"11111111111111111") * 10i64) assert (atoll(~"11111111111111111") * 10i64)
== atoll(~"111111111111111110"); == atoll(~"111111111111111110");
}
} }

View File

@@ -23,8 +23,10 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
} }
fn count(n: uint) -> uint { fn count(n: uint) -> uint {
unsafe {
debug!("n = %?", n); debug!("n = %?", n);
rustrt::rust_dbg_call(cb, n) rustrt::rust_dbg_call(cb, n)
}
} }
fn main() { fn main() {

View File

@@ -23,8 +23,10 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
} }
fn count(n: uint) -> uint { fn count(n: uint) -> uint {
unsafe {
debug!("n = %?", n); debug!("n = %?", n);
rustrt::rust_dbg_call(cb, n) rustrt::rust_dbg_call(cb, n)
}
} }
fn main() { fn main() {

View File

@@ -27,8 +27,10 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
} }
fn count(n: uint) -> uint { fn count(n: uint) -> uint {
unsafe {
debug!("n = %?", n); debug!("n = %?", n);
rustrt::rust_dbg_call(cb, n) rustrt::rust_dbg_call(cb, n)
}
} }
fn main() { fn main() {

View File

@@ -23,8 +23,10 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
} }
fn fact(n: uint) -> uint { fn fact(n: uint) -> uint {
unsafe {
debug!("n = %?", n); debug!("n = %?", n);
rustrt::rust_dbg_call(cb, n) rustrt::rust_dbg_call(cb, n)
}
} }
fn main() { fn main() {

View File

@@ -14,8 +14,10 @@
extern mod externcallback(vers = "0.1"); extern mod externcallback(vers = "0.1");
fn fact(n: uint) -> uint { fn fact(n: uint) -> uint {
unsafe {
debug!("n = %?", n); debug!("n = %?", n);
externcallback::rustrt::rust_dbg_call(externcallback::cb, n) externcallback::rustrt::rust_dbg_call(externcallback::cb, n)
}
} }
fn main() { fn main() {

View File

@@ -27,7 +27,9 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
} }
fn count(n: uint) -> uint { fn count(n: uint) -> uint {
unsafe {
rustrt::rust_dbg_call(cb, n) rustrt::rust_dbg_call(cb, n)
}
} }
fn main() { fn main() {

View File

@@ -23,8 +23,10 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
} }
fn count(n: uint) -> uint { fn count(n: uint) -> uint {
unsafe {
task::yield(); task::yield();
rustrt::rust_dbg_call(cb, n) rustrt::rust_dbg_call(cb, n)
}
} }
fn main() { fn main() {

View File

@@ -26,6 +26,8 @@ extern mod rustrt2 {
} }
fn main() { fn main() {
unsafe {
rustrt1::last_os_error(); rustrt1::last_os_error();
rustrt2::last_os_error(); rustrt2::last_os_error();
}
} }

View File

@@ -16,5 +16,7 @@ extern mod rustrt {
} }
fn main() { fn main() {
unsafe {
rustrt::get_task_id(); rustrt::get_task_id();
}
} }

View File

@@ -23,22 +23,28 @@ extern mod rusti {
mod m { mod m {
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]
pub fn main() { pub fn main() {
unsafe {
assert ::rusti::pref_align_of::<u64>() == 8u; assert ::rusti::pref_align_of::<u64>() == 8u;
assert ::rusti::min_align_of::<u64>() == 4u; assert ::rusti::min_align_of::<u64>() == 4u;
} }
}
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub fn main() { pub fn main() {
unsafe {
assert ::rusti::pref_align_of::<u64>() == 8u; assert ::rusti::pref_align_of::<u64>() == 8u;
assert ::rusti::min_align_of::<u64>() == 8u; assert ::rusti::min_align_of::<u64>() == 8u;
} }
}
} }
#[cfg(target_os = "win32")] #[cfg(target_os = "win32")]
mod m { mod m {
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]
pub fn main() { pub fn main() {
unsafe {
assert ::rusti::pref_align_of::<u64>() == 8u; assert ::rusti::pref_align_of::<u64>() == 8u;
assert ::rusti::min_align_of::<u64>() == 8u; assert ::rusti::min_align_of::<u64>() == 8u;
} }
}
} }

View File

@@ -15,7 +15,9 @@ extern mod cci_intrinsic;
use cci_intrinsic::atomic_xchg; use cci_intrinsic::atomic_xchg;
fn main() { fn main() {
unsafe {
let mut x = 1; let mut x = 1;
atomic_xchg(&mut x, 5); atomic_xchg(&mut x, 5);
assert x == 5; assert x == 5;
}
} }

View File

@@ -29,6 +29,7 @@ extern mod rusti {
} }
fn main() { fn main() {
unsafe {
let x = ~mut 1; let x = ~mut 1;
assert rusti::atomic_cxchg(x, 1, 2) == 1; assert rusti::atomic_cxchg(x, 1, 2) == 1;
@@ -58,4 +59,5 @@ fn main() {
assert rusti::atomic_xsub_acq(x, 1) == 2; assert rusti::atomic_xsub_acq(x, 1) == 2;
assert rusti::atomic_xsub_rel(x, 1) == 1; assert rusti::atomic_xsub_rel(x, 1) == 1;
assert *x == 0; assert *x == 0;
}
} }

View File

@@ -17,7 +17,9 @@ extern mod rusti {
} }
fn main() { fn main() {
unsafe {
do rusti::frame_address |addr| { do rusti::frame_address |addr| {
assert addr.is_not_null(); assert addr.is_not_null();
} }
}
} }

View File

@@ -10,14 +10,15 @@
#[abi = "rust-intrinsic"] #[abi = "rust-intrinsic"]
extern mod rusti { extern mod rusti {
#[legacy_exports]; pub fn move_val_init<T>(dst: &mut T, -src: T);
fn move_val_init<T>(dst: &mut T, -src: T); pub fn move_val<T>(dst: &mut T, -src: T);
fn move_val<T>(dst: &mut T, -src: T);
} }
fn main() { fn main() {
unsafe {
let mut x = @1; let mut x = @1;
let mut y = @2; let mut y = @2;
rusti::move_val(&mut y, move x); rusti::move_val(&mut y, move x);
assert *y == 1; assert *y == 1;
}
} }

View File

@@ -35,7 +35,7 @@ extern mod rusti {
} }
fn main() { fn main() {
unsafe {
use rusti::*; use rusti::*;
assert(ctpop8(0i8) == 0i8); assert(ctpop8(0i8) == 0i8);
@@ -116,5 +116,5 @@ fn main() {
assert(bswap16(0x0A0Bi16) == 0x0B0Ai16); assert(bswap16(0x0A0Bi16) == 0x0B0Ai16);
assert(bswap32(0x0ABBCC0Di32) == 0x0DCCBB0Ai32); assert(bswap32(0x0ABBCC0Di32) == 0x0DCCBB0Ai32);
assert(bswap64(0x0122334455667708i64) == 0x0877665544332201i64); assert(bswap64(0x0122334455667708i64) == 0x0877665544332201i64);
}
} }

View File

@@ -49,7 +49,7 @@ extern mod rusti {
} }
fn main() { fn main() {
unsafe {
use rusti::*; use rusti::*;
assert(sqrtf32(64f32).fuzzy_eq(&8f32)); assert(sqrtf32(64f32).fuzzy_eq(&8f32));
@@ -100,5 +100,6 @@ fn main() {
// undefined reference to llvm.trunc.f32/64 // undefined reference to llvm.trunc.f32/64
//assert(truncf32(0.1f32) == 0.0f32); //assert(truncf32(0.1f32) == 0.0f32);
//assert(truncf64(-0.1f64) == 0.0f64); //assert(truncf64(-0.1f64) == 0.0f64);
}
} }

View File

@@ -21,7 +21,9 @@ fn to_c_int(v: &mut int) -> &mut c_int {
} }
fn lgamma(n: c_double, value: &mut int) -> c_double { fn lgamma(n: c_double, value: &mut int) -> c_double {
unsafe {
return m::lgamma(n, to_c_int(value)); return m::lgamma(n, to_c_int(value));
}
} }
#[link_name = "m"] #[link_name = "m"]

View File

@@ -1,27 +0,0 @@
// Copyright 2012 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.
/*
A reduced test case for Issue #506, provided by Rob Arnold.
Testing spawning foreign functions
*/
extern mod std;
#[abi = "cdecl"]
extern mod rustrt {
#[legacy_exports];
fn rust_dbg_do_nothing();
}
fn main() {
task::spawn(rustrt::rust_dbg_do_nothing);
}

View File

@@ -16,7 +16,9 @@ extern mod rusti {
} }
fn main() { fn main() {
unsafe {
let addr = rusti::morestack_addr(); let addr = rusti::morestack_addr();
assert addr.is_not_null(); assert addr.is_not_null();
error!("%?", addr); error!("%?", addr);
}
} }

View File

@@ -23,18 +23,19 @@ extern mod rustrt {
fn rust_get_task(); fn rust_get_task();
} }
fn calllink01() { rustrt::rust_get_sched_id(); } fn calllink01() { unsafe { rustrt::rust_get_sched_id(); } }
fn calllink02() { rustrt::last_os_error(); } fn calllink02() { unsafe { rustrt::last_os_error(); } }
fn calllink03() { rustrt::rust_getcwd(); } fn calllink03() { unsafe { rustrt::rust_getcwd(); } }
fn calllink08() { rustrt::get_task_id(); } fn calllink08() { unsafe { rustrt::get_task_id(); } }
fn calllink09() { rustrt::rust_sched_threads(); } fn calllink09() { unsafe { rustrt::rust_sched_threads(); } }
fn calllink10() { rustrt::rust_get_task(); } fn calllink10() { unsafe { rustrt::rust_get_task(); } }
fn runtest(f: fn~(), frame_backoff: u32) { fn runtest(f: fn~(), frame_backoff: u32) {
runtest2(f, frame_backoff, 0 as *u8); runtest2(f, frame_backoff, 0 as *u8);
} }
fn runtest2(f: fn~(), frame_backoff: u32, last_stk: *u8) -> u32 { fn runtest2(f: fn~(), frame_backoff: u32, last_stk: *u8) -> u32 {
unsafe {
let curr_stk = rustrt::debug_get_stk_seg(); let curr_stk = rustrt::debug_get_stk_seg();
if (last_stk != curr_stk && last_stk != 0 as *u8) { if (last_stk != curr_stk && last_stk != 0 as *u8) {
// We switched stacks, go back and try to hit the dynamic linker // We switched stacks, go back and try to hit the dynamic linker
@@ -50,6 +51,7 @@ fn runtest2(f: fn~(), frame_backoff: u32, last_stk: *u8) -> u32 {
0u32 0u32
} }
} }
}
} }
fn main() { fn main() {

View File

@@ -45,7 +45,7 @@ mod m {
} }
fn main() { fn main() {
unsafe {
let x = {c8: 22u8, t: {c64: 44u32}}; let x = {c8: 22u8, t: {c64: 44u32}};
// Send it through the shape code // Send it through the shape code
@@ -63,4 +63,5 @@ fn main() {
assert sys::size_of::<outer>() == m::size(); assert sys::size_of::<outer>() == m::size();
assert y == ~"{c8: 22, t: {c64: 44}}"; assert y == ~"{c8: 22, t: {c64: 44}}";
}
} }

View File

@@ -62,7 +62,7 @@ mod m {
} }
fn main() { fn main() {
unsafe {
let x = {c8: 22u8, t: {c64: 44u64}}; let x = {c8: 22u8, t: {c64: 44u64}};
// Send it through the shape code // Send it through the shape code
@@ -80,4 +80,5 @@ fn main() {
assert sys::size_of::<outer>() == m::m::size(); assert sys::size_of::<outer>() == m::m::size();
assert y == ~"{c8: 22, t: {c64: 44}}"; assert y == ~"{c8: 22, t: {c64: 44}}";
}
} }

View File

@@ -483,11 +483,13 @@ impl my_visitor {
} }
fn visit_inner(inner: *TyDesc) -> bool { fn visit_inner(inner: *TyDesc) -> bool {
unsafe {
let u = my_visitor(*self); let u = my_visitor(*self);
let v = ptr_visit_adaptor({inner: u}); let v = ptr_visit_adaptor({inner: u});
visit_tydesc(inner, v as TyVisitor); visit_tydesc(inner, v as TyVisitor);
true true
} }
}
} }
impl my_visitor: movable_ptr { impl my_visitor: movable_ptr {
@@ -621,6 +623,7 @@ fn get_tydesc_for<T>(&&_t: T) -> *TyDesc {
} }
fn main() { fn main() {
unsafe {
let r = (1,2,3,true,false,{x:5,y:4,z:3}); let r = (1,2,3,true,false,{x:5,y:4,z:3});
let p = ptr::addr_of(&r) as *c_void; let p = ptr::addr_of(&r) as *c_void;
let u = my_visitor(@{mut ptr1: p, let u = my_visitor(@{mut ptr1: p,
@@ -637,5 +640,8 @@ fn main() {
io::println(fmt!("val: %s", *s)); io::println(fmt!("val: %s", *s));
} }
error!("%?", copy u.vals); error!("%?", copy u.vals);
assert u.vals == ~[~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3"]; assert u.vals == ~[
~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3"
];
}
} }

View File

@@ -36,11 +36,13 @@ fn main() {
let new_task_id = rustrt::rust_new_task_in_sched(new_sched_id); let new_task_id = rustrt::rust_new_task_in_sched(new_sched_id);
assert !new_task_id.is_null(); assert !new_task_id.is_null();
let f = fn~() { let f = fn~() {
unsafe {
let child_sched_id = rustrt::rust_get_sched_id(); let child_sched_id = rustrt::rust_get_sched_id();
error!("child_sched_id %?", child_sched_id); error!("child_sched_id %?", child_sched_id);
assert child_sched_id != parent_sched_id; assert child_sched_id != parent_sched_id;
assert child_sched_id == new_sched_id; assert child_sched_id == new_sched_id;
oldcomm::send(ch, ()); oldcomm::send(ch, ());
}
}; };
let fptr = cast::reinterpret_cast(&ptr::addr_of(&f)); let fptr = cast::reinterpret_cast(&ptr::addr_of(&f));
rustrt::start_task(new_task_id, fptr); rustrt::start_task(new_task_id, fptr);

View File

@@ -19,6 +19,7 @@ extern mod rustrt {
} }
fn test1() { fn test1() {
unsafe {
let q = { a: 0xaaaa_aaaa_aaaa_aaaa_u64, let q = { a: 0xaaaa_aaaa_aaaa_aaaa_u64,
b: 0xbbbb_bbbb_bbbb_bbbb_u64, b: 0xbbbb_bbbb_bbbb_bbbb_u64,
c: 0xcccc_cccc_cccc_cccc_u64, c: 0xcccc_cccc_cccc_cccc_u64,
@@ -32,10 +33,12 @@ fn test1() {
assert qq.b == q.d - 1u64; assert qq.b == q.d - 1u64;
assert qq.c == q.a + 1u64; assert qq.c == q.a + 1u64;
assert qq.d == q.b - 1u64; assert qq.d == q.b - 1u64;
}
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn test2() { fn test2() {
unsafe {
let f = { a: 1.234567890e-15_f64, let f = { a: 1.234567890e-15_f64,
b: 0b_1010_1010_u8, b: 0b_1010_1010_u8,
c: 1.0987654321e-15_f64 }; c: 1.0987654321e-15_f64 };
@@ -46,6 +49,7 @@ fn test2() {
assert ff.a == f.c + 1.0f64; assert ff.a == f.c + 1.0f64;
assert ff.b == 0xff_u8; assert ff.b == 0xff_u8;
assert ff.c == f.a - 1.0f64; assert ff.c == f.a - 1.0f64;
}
} }
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]