about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-01-11 21:01:42 -0800
committerPatrick Walton <pcwalton@mimiga.net>2013-01-17 11:50:20 -0800
commitf405e41d7a43ebd7fdd0fcd90f6e0542a5a6ccf6 (patch)
tree62e7e079cb5998e833ec950e9525330a1dc1e9e8 /src/libcore
parent8bde2c1d6533bf693dbb6ae8105bb082ad0ff0fe (diff)
downloadrust-f405e41d7a43ebd7fdd0fcd90f6e0542a5a6ccf6.tar.gz
rust-f405e41d7a43ebd7fdd0fcd90f6e0542a5a6ccf6.zip
librustc: Implement write guards for borrowing `@mut` to `&` or `&mut`. r=nmatsakis
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/at_vec.rs4
-rw-r--r--src/libcore/core.rc2
-rw-r--r--src/libcore/managed.rs2
-rw-r--r--src/libcore/rt.rs39
-rw-r--r--src/libcore/str.rs16
-rw-r--r--src/libcore/task/spawn.rs8
-rw-r--r--src/libcore/vec.rs24
7 files changed, 68 insertions, 27 deletions
diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs
index 1b6ac13ceab..1d964edd537 100644
--- a/src/libcore/at_vec.rs
+++ b/src/libcore/at_vec.rs
@@ -216,7 +216,7 @@ pub mod raw {
     }
 
     pub unsafe fn push_slow<T>(v: &mut @[const T], initval: T) {
-        reserve_at_least(v, v.len() + 1u);
+        reserve_at_least(&mut *v, v.len() + 1u);
         push_fast(v, move initval);
     }
 
@@ -234,7 +234,7 @@ pub mod raw {
     pub unsafe fn reserve<T>(v: &mut @[const T], n: uint) {
         // Only make the (slow) call into the runtime if we have to
         if capacity(*v) < n {
-            let ptr: **VecRepr = transmute(copy v);
+            let ptr: **VecRepr = transmute(v);
             rustrt::vec_reserve_shared_actual(sys::get_type_desc::<T>(),
                                               ptr, n as libc::size_t);
         }
diff --git a/src/libcore/core.rc b/src/libcore/core.rc
index 81b9077fb3e..b800564b8e1 100644
--- a/src/libcore/core.rc
+++ b/src/libcore/core.rc
@@ -95,8 +95,8 @@ pub mod at_vec;
 pub mod str;
 
 pub mod ptr;
-pub mod managed;
 pub mod owned;
+pub mod managed;
 
 
 /* Core language traits */
diff --git a/src/libcore/managed.rs b/src/libcore/managed.rs
index 8395526276c..32fc5f527b7 100644
--- a/src/libcore/managed.rs
+++ b/src/libcore/managed.rs
@@ -14,7 +14,9 @@
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+use cast::transmute;
 use cmp::{Eq, Ord};
+use managed::raw::BoxRepr;
 use prelude::*;
 use ptr;
 
diff --git a/src/libcore/rt.rs b/src/libcore/rt.rs
index e0eb2fcfd83..c5268e2d4ed 100644
--- a/src/libcore/rt.rs
+++ b/src/libcore/rt.rs
@@ -15,7 +15,9 @@
 #[forbid(deprecated_pattern)];
 //! Runtime calls emitted by the compiler.
 
+use cast::transmute;
 use libc::{c_char, c_void, size_t, uintptr_t};
+use managed::raw::BoxRepr;
 use str;
 use sys;
 
@@ -24,6 +26,11 @@ use gc::{cleanup_stack_for_failure, gc, Word};
 #[allow(non_camel_case_types)]
 pub type rust_task = c_void;
 
+#[cfg(target_word_size = "32")]
+const FROZEN_BIT: uint = 0x80000000;
+#[cfg(target_word_size = "64")]
+const FROZEN_BIT: uint = 0x8000000000000000;
+
 extern mod rustrt {
     #[rust_stack]
     unsafe fn rust_upcall_exchange_malloc(td: *c_char, size: uintptr_t)
@@ -56,6 +63,15 @@ pub unsafe fn rt_fail_bounds_check(file: *c_char, line: size_t,
     }
 }
 
+pub unsafe fn rt_fail_borrowed() {
+    let msg = "borrowed";
+    do str::as_buf(msg) |msg_p, _| {
+        do str::as_buf("???") |file_p, _| {
+            rt_fail_(msg_p as *c_char, file_p as *c_char, 0);
+        }
+    }
+}
+
 #[rt(exchange_malloc)]
 #[lang="exchange_malloc"]
 pub unsafe fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
@@ -86,6 +102,29 @@ pub unsafe fn rt_free(ptr: *c_char) {
     rustrt::rust_upcall_free(ptr);
 }
 
+#[lang="borrow_as_imm"]
+#[inline(always)]
+pub unsafe fn borrow_as_imm(a: *u8) {
+    let a: *mut BoxRepr = transmute(a);
+    (*a).header.ref_count |= FROZEN_BIT;
+}
+
+#[lang="return_to_mut"]
+#[inline(always)]
+pub unsafe fn return_to_mut(a: *u8) {
+    let a: *mut BoxRepr = transmute(a);
+    (*a).header.ref_count &= !FROZEN_BIT;
+}
+
+#[lang="check_not_borrowed"]
+#[inline(always)]
+pub unsafe fn check_not_borrowed(a: *u8) {
+    let a: *mut BoxRepr = transmute(a);
+    if ((*a).header.ref_count & FROZEN_BIT) != 0 {
+        rt_fail_borrowed();
+    }
+}
+
 // Local Variables:
 // mode: rust;
 // fill-column: 78;
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index f32dc746e12..d1c85d6482d 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -80,7 +80,7 @@ pub fn push_char(s: &mut ~str, ch: char) {
         else { 6u };
         let len = len(*s);
         let new_len = len + nb;
-        reserve_at_least(s, new_len);
+        reserve_at_least(&mut *s, new_len);
         let off = len;
         do as_buf(*s) |buf, _len| {
             let buf: *mut u8 = ::cast::reinterpret_cast(&buf);
@@ -164,7 +164,7 @@ pub fn push_str_no_overallocate(lhs: &mut ~str, rhs: &str) {
     unsafe {
         let llen = lhs.len();
         let rlen = rhs.len();
-        reserve(lhs, llen + rlen);
+        reserve(&mut *lhs, llen + rlen);
         do as_buf(*lhs) |lbuf, _llen| {
             do as_buf(rhs) |rbuf, _rlen| {
                 let dst = ptr::offset(lbuf, llen);
@@ -181,7 +181,7 @@ pub fn push_str(lhs: &mut ~str, rhs: &str) {
     unsafe {
         let llen = lhs.len();
         let rlen = rhs.len();
-        reserve_at_least(lhs, llen + rlen);
+        reserve_at_least(&mut *lhs, llen + rlen);
         do as_buf(*lhs) |lbuf, _llen| {
             do as_buf(rhs) |rbuf, _rlen| {
                 let dst = ptr::offset(lbuf, llen);
@@ -2056,18 +2056,18 @@ pub mod raw {
 
     /// Appends a byte to a string. (Not UTF-8 safe).
     pub unsafe fn push_byte(s: &mut ~str, b: u8) {
-        reserve_at_least(s, s.len() + 1);
+        reserve_at_least(&mut *s, s.len() + 1);
         do as_buf(*s) |buf, len| {
             let buf: *mut u8 = ::cast::reinterpret_cast(&buf);
             *ptr::mut_offset(buf, len) = b;
         }
-        set_len(s, s.len() + 1);
+        set_len(&mut *s, s.len() + 1);
     }
 
     /// Appends a vector of bytes to a string. (Not UTF-8 safe).
     unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) {
-        reserve_at_least(s, s.len() + bytes.len());
-        for vec::each(bytes) |byte| { push_byte(s, *byte); }
+        reserve_at_least(&mut *s, s.len() + bytes.len());
+        for vec::each(bytes) |byte| { push_byte(&mut *s, *byte); }
     }
 
     /// Removes the last byte from a string and returns it. (Not UTF-8 safe).
@@ -2090,7 +2090,7 @@ pub mod raw {
 
     /// Sets the length of the string and adds the null terminator
     pub unsafe fn set_len(v: &mut ~str, new_len: uint) {
-        let v: **vec::raw::VecRepr = cast::transmute(copy v);
+        let v: **vec::raw::VecRepr = cast::transmute(v);
         let repr: *vec::raw::VecRepr = *v;
         (*repr).unboxed.fill = new_len + 1u;
         let null = ptr::mut_offset(ptr::mut_addr_of(&((*repr).unboxed.data)),
diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs
index 1c5531303e1..28bbeaad35b 100644
--- a/src/libcore/task/spawn.rs
+++ b/src/libcore/task/spawn.rs
@@ -187,7 +187,7 @@ fn each_ancestor(list:        &mut AncestorList,
                 forward_blk:     fn(TaskGroupInner) -> bool,
                 last_generation: uint) -> bool {
         // Need to swap the list out to use it, to appease borrowck.
-        let tmp_list = util::replace(list, AncestorList(None));
+        let tmp_list = util::replace(&mut *list, AncestorList(None));
         let (coalesce_this, early_break) =
             iterate(&tmp_list, bail_opt, forward_blk, last_generation);
         // What should our next ancestor end up being?
@@ -289,7 +289,7 @@ fn each_ancestor(list:        &mut AncestorList,
         fn with_parent_tg<U>(parent_group: &mut Option<TaskGroupArc>,
                              blk: fn(TaskGroupInner) -> U) -> U {
             // If this trips, more likely the problem is 'blk' failed inside.
-            let tmp_arc = option::swap_unwrap(parent_group);
+            let tmp_arc = option::swap_unwrap(&mut *parent_group);
             let result = do access_group(&tmp_arc) |tg_opt| { blk(tg_opt) };
             *parent_group = move Some(move tmp_arc);
             move result
@@ -363,7 +363,7 @@ fn AutoNotify(chan: Chan<TaskResult>) -> AutoNotify {
 
 fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task,
                            is_member: bool) -> bool {
-    let newstate = util::replace(state, None);
+    let newstate = util::replace(&mut *state, None);
     // If 'None', the group was failing. Can't enlist.
     if newstate.is_some() {
         let group = option::unwrap(move newstate);
@@ -379,7 +379,7 @@ fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task,
 // NB: Runs in destructor/post-exit context. Can't 'fail'.
 fn leave_taskgroup(state: TaskGroupInner, me: *rust_task,
                        is_member: bool) {
-    let newstate = util::replace(state, None);
+    let newstate = util::replace(&mut *state, None);
     // If 'None', already failing and we've already gotten a kill signal.
     if newstate.is_some() {
         let group = option::unwrap(move newstate);
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index 49a0e5b2109..1caf569e77d 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -472,7 +472,7 @@ pub fn shift<T>(v: &mut ~[T]) -> T unsafe {
     assert capacity(v) >= ln;
     // Pretend like we have the original length so we can use
     // the vector copy_memory to overwrite the hole we just made
-    raw::set_len(v, ln);
+    raw::set_len(&mut *v, ln);
 
     // Memcopy the head element (the one we want) to the location we just
     // popped. For the moment it unsafely exists at both the head and last
@@ -487,7 +487,7 @@ pub fn shift<T>(v: &mut ~[T]) -> T unsafe {
     raw::copy_memory(init_slice, tail_slice, next_ln);
 
     // Set the new length. Now the vector is back to normal
-    raw::set_len(v, next_ln);
+    raw::set_len(&mut *v, next_ln);
 
     // Swap out the element we want from the end
     let vp = raw::to_mut_ptr(*v);
@@ -592,7 +592,7 @@ pub fn swap_remove<T>(v: &mut ~[T], index: uint) -> T {
 #[inline(always)]
 pub fn push<T>(v: &mut ~[T], initval: T) {
     unsafe {
-        let repr: **raw::VecRepr = ::cast::transmute(copy v);
+        let repr: **raw::VecRepr = ::cast::transmute(&mut *v);
         let fill = (**repr).unboxed.fill;
         if (**repr).unboxed.alloc > fill {
             push_fast(v, initval);
@@ -616,30 +616,30 @@ unsafe fn push_fast<T>(v: &mut ~[T], initval: T) {
 
 #[inline(never)]
 fn push_slow<T>(v: &mut ~[T], initval: T) {
-    reserve_at_least(v, v.len() + 1u);
+    reserve_at_least(&mut *v, v.len() + 1u);
     unsafe { push_fast(v, initval) }
 }
 
 #[inline(always)]
 pub fn push_all<T: Copy>(v: &mut ~[T], rhs: &[const T]) {
-    reserve(v, v.len() + rhs.len());
+    reserve(&mut *v, v.len() + rhs.len());
 
     for uint::range(0u, rhs.len()) |i| {
-        push(v, unsafe { raw::get(rhs, i) })
+        push(&mut *v, unsafe { raw::get(rhs, i) })
     }
 }
 
 #[inline(always)]
 pub fn push_all_move<T>(v: &mut ~[T], rhs: ~[T]) {
     let mut rhs = rhs; // FIXME(#3488)
-    reserve(v, v.len() + rhs.len());
+    reserve(&mut *v, v.len() + rhs.len());
     unsafe {
         do as_mut_buf(rhs) |p, len| {
             for uint::range(0, len) |i| {
                 // FIXME #4204 Should be rusti::uninit() - don't need to zero
                 let mut x = rusti::init();
                 x <-> *ptr::mut_offset(p, i);
-                push(v, x);
+                push(&mut *v, x);
             }
         }
         raw::set_len(&mut rhs, 0);
@@ -657,7 +657,7 @@ pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
                 let mut dropped = rusti::init();
                 dropped <-> *ptr::mut_offset(p, i);
             }
-            raw::set_len(v, newlen);
+            raw::set_len(&mut *v, newlen);
         }
     }
 }
@@ -731,7 +731,7 @@ pub pure fn append_mut<T: Copy>(lhs: ~[mut T], rhs: &[const T]) -> ~[mut T] {
  * * initval - The value for the new elements
  */
 pub fn grow<T: Copy>(v: &mut ~[T], n: uint, initval: &T) {
-    reserve_at_least(v, v.len() + n);
+    reserve_at_least(&mut *v, v.len() + n);
     let mut i: uint = 0u;
 
     while i < n {
@@ -754,7 +754,7 @@ pub fn grow<T: Copy>(v: &mut ~[T], n: uint, initval: &T) {
  *             value
  */
 pub fn grow_fn<T>(v: &mut ~[T], n: uint, op: iter::InitOp<T>) {
-    reserve_at_least(v, v.len() + n);
+    reserve_at_least(&mut *v, v.len() + n);
     let mut i: uint = 0u;
     while i < n {
         v.push(op(i));
@@ -772,7 +772,7 @@ pub fn grow_fn<T>(v: &mut ~[T], n: uint, op: iter::InitOp<T>) {
  */
 pub fn grow_set<T: Copy>(v: &mut ~[T], index: uint, initval: &T, val: T) {
     let l = v.len();
-    if index >= l { grow(v, index - l + 1u, initval); }
+    if index >= l { grow(&mut *v, index - l + 1u, initval); }
     v[index] = val;
 }