diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2013-01-11 21:01:42 -0800 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2013-01-17 11:50:20 -0800 |
| commit | f405e41d7a43ebd7fdd0fcd90f6e0542a5a6ccf6 (patch) | |
| tree | 62e7e079cb5998e833ec950e9525330a1dc1e9e8 /src/libcore | |
| parent | 8bde2c1d6533bf693dbb6ae8105bb082ad0ff0fe (diff) | |
| download | rust-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.rs | 4 | ||||
| -rw-r--r-- | src/libcore/core.rc | 2 | ||||
| -rw-r--r-- | src/libcore/managed.rs | 2 | ||||
| -rw-r--r-- | src/libcore/rt.rs | 39 | ||||
| -rw-r--r-- | src/libcore/str.rs | 16 | ||||
| -rw-r--r-- | src/libcore/task/spawn.rs | 8 | ||||
| -rw-r--r-- | src/libcore/vec.rs | 24 |
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; } |
