1
Fork 0

implement pointer arithmetic with GEP

Closes #8118, #7136

~~~rust
extern mod extra;

use std::vec;
use std::ptr;

fn bench_from_elem(b: &mut extra::test::BenchHarness) {
    do b.iter {
        let v: ~[u8] = vec::from_elem(1024, 0u8);
    }
}

fn bench_set_memory(b: &mut extra::test::BenchHarness) {
    do b.iter {
        let mut v: ~[u8] = vec::with_capacity(1024);
        unsafe {
            let vp = vec::raw::to_mut_ptr(v);
            ptr::set_memory(vp, 0, 1024);
            vec::raw::set_len(&mut v, 1024);
        }
    }
}

fn bench_vec_repeat(b: &mut extra::test::BenchHarness) {
    do b.iter {
        let v: ~[u8] = ~[0u8, ..1024];
    }
}
~~~

Before:

    test bench_from_elem ... bench: 415 ns/iter (+/- 17)
    test bench_set_memory ... bench: 85 ns/iter (+/- 4)
    test bench_vec_repeat ... bench: 83 ns/iter (+/- 3)

After:

    test bench_from_elem ... bench: 84 ns/iter (+/- 2)
    test bench_set_memory ... bench: 84 ns/iter (+/- 5)
    test bench_vec_repeat ... bench: 84 ns/iter (+/- 3)
This commit is contained in:
Daniel Micay 2013-07-30 00:33:52 -04:00
parent e94e4d51ca
commit ef870d37a5
19 changed files with 131 additions and 80 deletions

View file

@ -116,7 +116,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
let fill = chunk.fill; let fill = chunk.fill;
while idx < fill { while idx < fill {
let tydesc_data: *uint = transmute(ptr::offset(buf, idx)); let tydesc_data: *uint = transmute(ptr::offset(buf, idx as int));
let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data); let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
let (size, align) = ((*tydesc).size, (*tydesc).align); let (size, align) = ((*tydesc).size, (*tydesc).align);
@ -127,7 +127,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
//debug!("freeing object: idx = %u, size = %u, align = %u, done = %b", //debug!("freeing object: idx = %u, size = %u, align = %u, done = %b",
// start, size, align, is_done); // start, size, align, is_done);
if is_done { if is_done {
((*tydesc).drop_glue)(ptr::offset(buf, start) as *i8); ((*tydesc).drop_glue)(ptr::offset(buf, start as int) as *i8);
} }
// Find where the next tydesc lives // Find where the next tydesc lives
@ -176,7 +176,7 @@ impl Arena {
//debug!("idx = %u, size = %u, align = %u, fill = %u", //debug!("idx = %u, size = %u, align = %u, fill = %u",
// start, n_bytes, align, head.fill); // start, n_bytes, align, head.fill);
ptr::offset(vec::raw::to_ptr(this.pod_head.data), start) ptr::offset(vec::raw::to_ptr(this.pod_head.data), start as int)
} }
} }
@ -233,7 +233,7 @@ impl Arena {
// start, n_bytes, align, head.fill); // start, n_bytes, align, head.fill);
let buf = vec::raw::to_ptr(self.head.data); let buf = vec::raw::to_ptr(self.head.data);
return (ptr::offset(buf, tydesc_start), ptr::offset(buf, start)); return (ptr::offset(buf, tydesc_start as int), ptr::offset(buf, start as int));
} }
} }

View file

@ -122,7 +122,7 @@ pub unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: @fn())
pub fn get<T:Clone>(t: CVec<T>, ofs: uint) -> T { pub fn get<T:Clone>(t: CVec<T>, ofs: uint) -> T {
assert!(ofs < len(t)); assert!(ofs < len(t));
return unsafe { return unsafe {
(*ptr::mut_offset(t.base, ofs)).clone() (*ptr::mut_offset(t.base, ofs as int)).clone()
}; };
} }
@ -133,7 +133,7 @@ pub fn get<T:Clone>(t: CVec<T>, ofs: uint) -> T {
*/ */
pub fn set<T>(t: CVec<T>, ofs: uint, v: T) { pub fn set<T>(t: CVec<T>, ofs: uint, v: T) {
assert!(ofs < len(t)); assert!(ofs < len(t));
unsafe { *ptr::mut_offset(t.base, ofs) = v }; unsafe { *ptr::mut_offset(t.base, ofs as int) = v };
} }
/* /*

View file

@ -150,7 +150,7 @@ pub mod reader {
unsafe { unsafe {
let (ptr, _): (*u8, uint) = transmute(data); let (ptr, _): (*u8, uint) = transmute(data);
let ptr = offset(ptr, start); let ptr = offset(ptr, start as int);
let ptr: *i32 = transmute(ptr); let ptr: *i32 = transmute(ptr);
let val = bswap32(*ptr); let val = bswap32(*ptr);
let val: u32 = transmute(val); let val: u32 = transmute(val);

View file

@ -58,7 +58,7 @@ fn map_slices<A:Clone + Send,B:Clone + Send>(
let f = do future_spawn() || { let f = do future_spawn() || {
unsafe { unsafe {
let len = end - base; let len = end - base;
let slice = (ptr::offset(p, base), let slice = (ptr::offset(p, base as int),
len * sys::size_of::<A>()); len * sys::size_of::<A>());
info!("pre-slice: %?", (base, slice)); info!("pre-slice: %?", (base, slice));
let slice : &[A] = let slice : &[A] =

View file

@ -215,7 +215,7 @@ fn get_metadata_section(os: os,
} }
if !version_ok { return None; } if !version_ok { return None; }
let cvbuf1 = ptr::offset(cvbuf, vlen); let cvbuf1 = ptr::offset(cvbuf, vlen as int);
debug!("inflating %u bytes of compressed metadata", debug!("inflating %u bytes of compressed metadata",
csz - vlen); csz - vlen);
do vec::raw::buf_as_slice(cvbuf1, csz-vlen) |bytes| { do vec::raw::buf_as_slice(cvbuf1, csz-vlen) |bytes| {

View file

@ -884,6 +884,11 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to()); let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to());
Ret(bcx, morestack_addr); Ret(bcx, morestack_addr);
} }
"offset" => {
let ptr = get_param(decl, first_real_arg);
let offset = get_param(decl, first_real_arg + 1);
Ret(bcx, GEP(bcx, ptr, [offset]));
}
"memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32), "memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32),
"memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64), "memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64),
"memmove32" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i32", substs.tys[0], 32), "memmove32" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i32", substs.tys[0], 32),

View file

@ -149,7 +149,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
"visit_tydesc" | "forget" | "frame_address" | "visit_tydesc" | "forget" | "frame_address" |
"morestack_addr" => 0, "morestack_addr" => 0,
"memcpy32" | "memcpy64" | "memmove32" | "memmove64" | "offset" | "memcpy32" | "memcpy64" | "memmove32" | "memmove64" |
"memset32" | "memset64" => use_repr, "memset32" | "memset64" => use_repr,
"sqrtf32" | "sqrtf64" | "powif32" | "powif64" | "sqrtf32" | "sqrtf64" | "powif32" | "powif64" |

View file

@ -3606,6 +3606,20 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
"morestack_addr" => { "morestack_addr" => {
(0u, ~[], ty::mk_nil_ptr(ccx.tcx)) (0u, ~[], ty::mk_nil_ptr(ccx.tcx))
} }
"offset" => {
(1,
~[
ty::mk_ptr(tcx, ty::mt {
ty: param(ccx, 0),
mutbl: ast::m_imm
}),
ty::mk_int()
],
ty::mk_ptr(tcx, ty::mt {
ty: param(ccx, 0),
mutbl: ast::m_imm
}))
}
"memcpy32" => { "memcpy32" => {
(1, (1,
~[ ~[

View file

@ -233,7 +233,7 @@ pub mod raw {
let repr: *mut Box<Vec<T>> = cast::transmute_copy(v); let repr: *mut Box<Vec<T>> = cast::transmute_copy(v);
let amt = v.len(); let amt = v.len();
(*repr).data.fill += sys::size_of::<T>(); (*repr).data.fill += sys::size_of::<T>();
let p = ptr::offset(&(*repr).data.data as *T, amt) as *mut T; let p = ptr::offset(&(*repr).data.data as *T, amt as int) as *mut T;
move_val_init(&mut(*p), initval); move_val_init(&mut(*p), initval);
} }

View file

@ -74,7 +74,7 @@ pub mod rustrt {
} }
unsafe fn bump<T, U>(ptr: *T, count: uint) -> *U { unsafe fn bump<T, U>(ptr: *T, count: uint) -> *U {
return ptr::offset(ptr, count) as *U; return ptr::offset(ptr, count as int) as *U;
} }
unsafe fn align_to_pointer<T>(ptr: *T) -> *T { unsafe fn align_to_pointer<T>(ptr: *T) -> *T {
@ -140,11 +140,11 @@ unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
// Stack roots // Stack roots
let mut sri = 0; let mut sri = 0;
while sri < num_stack_roots { while sri < num_stack_roots {
if *ptr::offset(addrspaces, sri) >= 1 { if *ptr::offset(addrspaces, sri as int) >= 1 {
let root = let root =
ptr::offset(fp_bytes, *ptr::offset(stack_roots, sri) as Word) ptr::offset(fp_bytes, *ptr::offset(stack_roots, sri as int) as int)
as **Word; as **Word;
let tydescpp = ptr::offset(tydescs, sri); let tydescpp = ptr::offset(tydescs, sri as int);
let tydesc = if ptr::is_not_null(tydescpp) && let tydesc = if ptr::is_not_null(tydescpp) &&
ptr::is_not_null(*tydescpp) { ptr::is_not_null(*tydescpp) {
**tydescpp **tydescpp
@ -159,7 +159,7 @@ unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
// Register roots // Register roots
let mut rri = 0; let mut rri = 0;
while rri < num_reg_roots { while rri < num_reg_roots {
if *ptr::offset(addrspaces, num_stack_roots + rri) == 1 { if *ptr::offset(addrspaces, (num_stack_roots + rri) as int) == 1 {
// FIXME(#2997): Need to find callee saved registers on the stack. // FIXME(#2997): Need to find callee saved registers on the stack.
} }
rri += 1; rri += 1;
@ -246,7 +246,7 @@ unsafe fn _walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> boo
// for this second return address is 3 greater than the // for this second return address is 3 greater than the
// return address for morestack. // return address for morestack.
let ret_offset = if boundary { 4 } else { 1 }; let ret_offset = if boundary { 4 } else { 1 };
last_ret = *ptr::offset(frame.fp, ret_offset) as *Word; last_ret = *ptr::offset(frame.fp, ret_offset as int) as *Word;
if ptr::is_null(pc) { if ptr::is_null(pc) {
loop; loop;

View file

@ -1213,7 +1213,7 @@ impl Writer for fd_t {
let mut count = 0u; let mut count = 0u;
do v.as_imm_buf |vbuf, len| { do v.as_imm_buf |vbuf, len| {
while count < len { while count < len {
let vb = ptr::offset(vbuf, count) as *c_void; let vb = ptr::offset(vbuf, count as int) as *c_void;
let nout = libc::write(*self, vb, len as size_t); let nout = libc::write(*self, vb, len as size_t);
if nout < 0 as ssize_t { if nout < 0 as ssize_t {
error!("error writing buffer"); error!("error writing buffer");

View file

@ -1114,7 +1114,7 @@ pub fn set_exit_status(code: int) {
unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] { unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] {
let mut args = ~[]; let mut args = ~[];
for uint::range(0, argc as uint) |i| { for uint::range(0, argc as uint) |i| {
args.push(str::raw::from_c_str(*argv.offset(i))); args.push(str::raw::from_c_str(*argv.offset(i as int)));
} }
args args
} }
@ -1165,9 +1165,9 @@ pub fn real_args() -> ~[~str] {
for uint::range(0, nArgs as uint) |i| { for uint::range(0, nArgs as uint) |i| {
unsafe { unsafe {
// Determine the length of this argument. // Determine the length of this argument.
let ptr = *szArgList.offset(i); let ptr = *szArgList.offset(i as int);
let mut len = 0; let mut len = 0;
while *ptr.offset(len) != 0 { len += 1; } while *ptr.offset(len as int) != 0 { len += 1; }
// Push it onto the list. // Push it onto the list.
args.push(vec::raw::buf_as_slice(ptr, len, args.push(vec::raw::buf_as_slice(ptr, len,

View file

@ -13,6 +13,7 @@
use cast; use cast;
use clone::Clone; use clone::Clone;
use option::{Option, Some, None}; use option::{Option, Some, None};
#[cfg(stage0)]
use sys; use sys;
use unstable::intrinsics; use unstable::intrinsics;
use util::swap; use util::swap;
@ -25,20 +26,44 @@ use uint;
/// Calculate the offset from a pointer /// Calculate the offset from a pointer
#[inline] #[inline]
pub fn offset<T>(ptr: *T, count: uint) -> *T { #[cfg(stage0)]
(ptr as uint + count * sys::size_of::<T>()) as *T pub fn offset<T>(ptr: *T, count: int) -> *T {
(ptr as uint + (count as uint) * sys::size_of::<T>()) as *T
} }
/// Calculate the offset from a const pointer /// Calculate the offset from a const pointer
#[inline] #[inline]
pub fn const_offset<T>(ptr: *const T, count: uint) -> *const T { #[cfg(stage0)]
(ptr as uint + count * sys::size_of::<T>()) as *T pub fn const_offset<T>(ptr: *const T, count: int) -> *const T {
(ptr as uint + (count as uint) * sys::size_of::<T>()) as *T
} }
/// Calculate the offset from a mut pointer /// Calculate the offset from a mut pointer
#[inline] #[inline]
pub fn mut_offset<T>(ptr: *mut T, count: uint) -> *mut T { #[cfg(stage0)]
(ptr as uint + count * sys::size_of::<T>()) as *mut T pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
(ptr as uint + (count as uint) * sys::size_of::<T>()) as *mut T
}
/// Calculate the offset from a pointer
#[inline]
#[cfg(not(stage0))]
pub fn offset<T>(ptr: *T, count: int) -> *T {
unsafe { intrinsics::offset(ptr, count) }
}
/// Calculate the offset from a const pointer
#[inline]
#[cfg(not(stage0))]
pub fn const_offset<T>(ptr: *const T, count: int) -> *const T {
unsafe { intrinsics::offset(ptr as *T, count) }
}
/// Calculate the offset from a mut pointer
#[inline]
#[cfg(not(stage0))]
pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
unsafe { intrinsics::offset(ptr as *T, count) as *mut T }
} }
/// Return the offset of the first null pointer in `buf`. /// Return the offset of the first null pointer in `buf`.
@ -58,7 +83,7 @@ impl<T> Clone for *T {
pub unsafe fn position<T>(buf: *T, f: &fn(&T) -> bool) -> uint { pub unsafe fn position<T>(buf: *T, f: &fn(&T) -> bool) -> uint {
let mut i = 0; let mut i = 0;
loop { loop {
if f(&(*offset(buf, i))) { return i; } if f(&(*offset(buf, i as int))) { return i; }
else { i += 1; } else { i += 1; }
} }
} }
@ -242,7 +267,7 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: &fn(*T)) {
} }
//let start_ptr = *arr; //let start_ptr = *arr;
uint::iterate(0, len, |e| { uint::iterate(0, len, |e| {
let n = offset(arr, e); let n = offset(arr, e as int);
cb(*n); cb(*n);
true true
}); });
@ -273,7 +298,7 @@ pub trait RawPtr<T> {
fn is_null(&self) -> bool; fn is_null(&self) -> bool;
fn is_not_null(&self) -> bool; fn is_not_null(&self) -> bool;
unsafe fn to_option(&self) -> Option<&T>; unsafe fn to_option(&self) -> Option<&T>;
fn offset(&self, count: uint) -> Self; fn offset(&self, count: int) -> Self;
} }
/// Extension methods for immutable pointers /// Extension methods for immutable pointers
@ -305,7 +330,7 @@ impl<T> RawPtr<T> for *T {
/// Calculates the offset from a pointer. /// Calculates the offset from a pointer.
#[inline] #[inline]
fn offset(&self, count: uint) -> *T { offset(*self, count) } fn offset(&self, count: int) -> *T { offset(*self, count) }
} }
/// Extension methods for mutable pointers /// Extension methods for mutable pointers
@ -337,7 +362,7 @@ impl<T> RawPtr<T> for *mut T {
/// Calculates the offset from a mutable pointer. /// Calculates the offset from a mutable pointer.
#[inline] #[inline]
fn offset(&self, count: uint) -> *mut T { mut_offset(*self, count) } fn offset(&self, count: int) -> *mut T { mut_offset(*self, count) }
} }
// Equality for pointers // Equality for pointers
@ -378,7 +403,7 @@ impl<T, I: Int> Add<I, *T> for *T {
/// Is calculated according to the size of the type pointed to. /// Is calculated according to the size of the type pointed to.
#[inline] #[inline]
pub fn add(&self, rhs: &I) -> *T { pub fn add(&self, rhs: &I) -> *T {
self.offset(rhs.to_int() as uint) self.offset(rhs.to_int() as int)
} }
} }
@ -388,7 +413,7 @@ impl<T, I: Int> Sub<I, *T> for *T {
/// Is calculated according to the size of the type pointed to. /// Is calculated according to the size of the type pointed to.
#[inline] #[inline]
pub fn sub(&self, rhs: &I) -> *T { pub fn sub(&self, rhs: &I) -> *T {
self.offset(-rhs.to_int() as uint) self.offset(-rhs.to_int() as int)
} }
} }
@ -398,7 +423,7 @@ impl<T, I: Int> Add<I, *mut T> for *mut T {
/// Is calculated according to the size of the type pointed to. /// Is calculated according to the size of the type pointed to.
#[inline] #[inline]
pub fn add(&self, rhs: &I) -> *mut T { pub fn add(&self, rhs: &I) -> *mut T {
self.offset(rhs.to_int() as uint) self.offset(rhs.to_int() as int)
} }
} }
@ -408,7 +433,7 @@ impl<T, I: Int> Sub<I, *mut T> for *mut T {
/// Is calculated according to the size of the type pointed to. /// Is calculated according to the size of the type pointed to.
#[inline] #[inline]
pub fn sub(&self, rhs: &I) -> *mut T { pub fn sub(&self, rhs: &I) -> *mut T {
self.offset(-rhs.to_int() as uint) self.offset(-rhs.to_int() as int)
} }
} }
@ -445,14 +470,14 @@ pub mod ptr_tests {
let v0 = ~[32000u16, 32001u16, 32002u16]; let v0 = ~[32000u16, 32001u16, 32002u16];
let mut v1 = ~[0u16, 0u16, 0u16]; let mut v1 = ~[0u16, 0u16, 0u16];
copy_memory(mut_offset(vec::raw::to_mut_ptr(v1), 1u), copy_memory(mut_offset(vec::raw::to_mut_ptr(v1), 1),
offset(vec::raw::to_ptr(v0), 1u), 1u); offset(vec::raw::to_ptr(v0), 1), 1);
assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16)); assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16));
copy_memory(vec::raw::to_mut_ptr(v1), copy_memory(vec::raw::to_mut_ptr(v1),
offset(vec::raw::to_ptr(v0), 2u), 1u); offset(vec::raw::to_ptr(v0), 2), 1);
assert!((v1[0] == 32002u16 && v1[1] == 32001u16 && assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
v1[2] == 0u16)); v1[2] == 0u16));
copy_memory(mut_offset(vec::raw::to_mut_ptr(v1), 2u), copy_memory(mut_offset(vec::raw::to_mut_ptr(v1), 2),
vec::raw::to_ptr(v0), 1u); vec::raw::to_ptr(v0), 1u);
assert!((v1[0] == 32002u16 && v1[1] == 32001u16 && assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
v1[2] == 32000u16)); v1[2] == 32000u16));
@ -495,7 +520,7 @@ pub mod ptr_tests {
assert!(p.is_null()); assert!(p.is_null());
assert!(!p.is_not_null()); assert!(!p.is_not_null());
let q = offset(p, 1u); let q = offset(p, 1);
assert!(!q.is_null()); assert!(!q.is_null());
assert!(q.is_not_null()); assert!(q.is_not_null());
@ -503,7 +528,7 @@ pub mod ptr_tests {
assert!(mp.is_null()); assert!(mp.is_null());
assert!(!mp.is_not_null()); assert!(!mp.is_not_null());
let mq = mp.offset(1u); let mq = mp.offset(1);
assert!(!mq.is_null()); assert!(!mq.is_null());
assert!(mq.is_not_null()); assert!(mq.is_not_null());
} }

View file

@ -212,7 +212,7 @@ impl ReprVisitor {
self.writer.write_str(", "); self.writer.write_str(", ");
} }
self.visit_ptr_inner(p as *c_void, inner); self.visit_ptr_inner(p as *c_void, inner);
p = align(ptr::offset(p, sz) as uint, al) as *u8; p = align(ptr::offset(p, sz as int) as uint, al) as *u8;
left -= dec; left -= dec;
} }
self.writer.write_char(']'); self.writer.write_char(']');

View file

@ -114,7 +114,7 @@ mod imp {
unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] { unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] {
let mut args = ~[]; let mut args = ~[];
for uint::range(0, argc as uint) |i| { for uint::range(0, argc as uint) |i| {
args.push(str::raw::from_c_str(*(argv as **libc::c_char).offset(i))); args.push(str::raw::from_c_str(*(argv as **libc::c_char).offset(i as int)));
} }
return args; return args;
} }

View file

@ -44,7 +44,7 @@ impl StackSegment {
/// Point one word beyond the high end of the allocated stack /// Point one word beyond the high end of the allocated stack
pub fn end(&self) -> *uint { pub fn end(&self) -> *uint {
vec::raw::to_ptr(self.buf).offset(self.buf.len()) as *uint vec::raw::to_ptr(self.buf).offset(self.buf.len() as int) as *uint
} }
} }

View file

@ -191,7 +191,7 @@ impl<'self, S: Str> StrVector for &'self [S] {
do ss.as_slice().as_imm_buf |ssbuf, sslen| { do ss.as_slice().as_imm_buf |ssbuf, sslen| {
let sslen = sslen - 1; let sslen = sslen - 1;
ptr::copy_memory(buf, ssbuf, sslen); ptr::copy_memory(buf, ssbuf, sslen);
buf = buf.offset(sslen); buf = buf.offset(sslen as int);
} }
} }
} }
@ -227,10 +227,10 @@ impl<'self, S: Str> StrVector for &'self [S] {
first = false; first = false;
} else { } else {
ptr::copy_memory(buf, sepbuf, seplen); ptr::copy_memory(buf, sepbuf, seplen);
buf = buf.offset(seplen); buf = buf.offset(seplen as int);
} }
ptr::copy_memory(buf, ssbuf, sslen); ptr::copy_memory(buf, ssbuf, sslen);
buf = buf.offset(sslen); buf = buf.offset(sslen as int);
} }
} }
} }
@ -783,7 +783,7 @@ pub mod raw {
let mut i = 0u; let mut i = 0u;
while *curr != 0u8 { while *curr != 0u8 {
i += 1u; i += 1u;
curr = ptr::offset(buf, i); curr = ptr::offset(buf, i as int);
} }
return from_buf_len(buf, i); return from_buf_len(buf, i);
} }
@ -844,7 +844,7 @@ pub mod raw {
let mut len = 0u; let mut len = 0u;
while *curr != 0u8 { while *curr != 0u8 {
len += 1u; len += 1u;
curr = ptr::offset(s, len); curr = ptr::offset(s, len as int);
} }
let v = Slice { data: s, len: len + 1 }; let v = Slice { data: s, len: len + 1 };
assert!(is_utf8(cast::transmute(v))); assert!(is_utf8(cast::transmute(v)));
@ -868,7 +868,7 @@ pub mod raw {
assert!((end <= n)); assert!((end <= n));
cast::transmute(Slice { cast::transmute(Slice {
data: ptr::offset(sbuf, begin), data: ptr::offset(sbuf, begin as int),
len: end - begin + 1, len: end - begin + 1,
}) })
} }
@ -879,7 +879,7 @@ pub mod raw {
let new_len = s.len() + 1; let new_len = s.len() + 1;
s.reserve_at_least(new_len); s.reserve_at_least(new_len);
do s.as_mut_buf |buf, len| { do s.as_mut_buf |buf, len| {
*ptr::mut_offset(buf, len) = b; *ptr::mut_offset(buf, len as int) = b;
} }
set_len(&mut *s, new_len); set_len(&mut *s, new_len);
} }
@ -915,7 +915,7 @@ pub mod raw {
let v: **mut String = cast::transmute(v); let v: **mut String = cast::transmute(v);
let repr = *v; let repr = *v;
(*repr).fill = new_len + 1u; (*repr).fill = new_len + 1u;
let null = ptr::mut_offset(&mut ((*repr).data), new_len); let null = ptr::mut_offset(&mut ((*repr).data), new_len as int);
*null = 0u8; *null = 0u8;
} }
@ -1833,7 +1833,7 @@ impl<'self> StrSlice<'self> for &'self str {
for nn.times { for nn.times {
ptr::copy_memory(rbuf, buf, len); ptr::copy_memory(rbuf, buf, len);
rbuf = rbuf.offset(len); rbuf = rbuf.offset(len as int);
} }
} }
raw::set_len(&mut ret, nn * len); raw::set_len(&mut ret, nn * len);
@ -1973,7 +1973,7 @@ impl<'self> StrSlice<'self> for &'self str {
do self.as_imm_buf |buf, len| { do self.as_imm_buf |buf, len| {
// NB: len includes the trailing null. // NB: len includes the trailing null.
assert!(len > 0); assert!(len > 0);
if unsafe { *(ptr::offset(buf, len - 1)) != 0 } { if unsafe { *(ptr::offset(buf, (len - 1) as int)) != 0 } {
self.to_owned().as_c_str(|s| f(s)) self.to_owned().as_c_str(|s| f(s))
} else { } else {
f(buf as *libc::c_char) f(buf as *libc::c_char)
@ -2051,7 +2051,7 @@ impl OwnedStr for ~str {
self.reserve(llen + rlen); self.reserve(llen + rlen);
do self.as_imm_buf |lbuf, _llen| { do self.as_imm_buf |lbuf, _llen| {
do rhs.as_imm_buf |rbuf, _rlen| { do rhs.as_imm_buf |rbuf, _rlen| {
let dst = ptr::offset(lbuf, llen); let dst = ptr::offset(lbuf, llen as int);
let dst = cast::transmute_mut_unsafe(dst); let dst = cast::transmute_mut_unsafe(dst);
ptr::copy_memory(dst, rbuf, rlen); ptr::copy_memory(dst, rbuf, rlen);
} }
@ -2069,7 +2069,7 @@ impl OwnedStr for ~str {
self.reserve_at_least(llen + rlen); self.reserve_at_least(llen + rlen);
do self.as_imm_buf |lbuf, _llen| { do self.as_imm_buf |lbuf, _llen| {
do rhs.as_imm_buf |rbuf, _rlen| { do rhs.as_imm_buf |rbuf, _rlen| {
let dst = ptr::offset(lbuf, llen); let dst = ptr::offset(lbuf, llen as int);
let dst = cast::transmute_mut_unsafe(dst); let dst = cast::transmute_mut_unsafe(dst);
ptr::copy_memory(dst, rbuf, rlen); ptr::copy_memory(dst, rbuf, rlen);
} }
@ -2090,7 +2090,7 @@ impl OwnedStr for ~str {
let len = self.len(); let len = self.len();
let new_len = len + nb; let new_len = len + nb;
self.reserve_at_least(new_len); self.reserve_at_least(new_len);
let off = len; let off = len as int;
do self.as_mut_buf |buf, _len| { do self.as_mut_buf |buf, _len| {
match nb { match nb {
1u => { 1u => {
@ -2098,18 +2098,18 @@ impl OwnedStr for ~str {
} }
2u => { 2u => {
*ptr::mut_offset(buf, off) = (code >> 6u & 31u | TAG_TWO_B) as u8; *ptr::mut_offset(buf, off) = (code >> 6u & 31u | TAG_TWO_B) as u8;
*ptr::mut_offset(buf, off + 1u) = (code & 63u | TAG_CONT) as u8; *ptr::mut_offset(buf, off + 1) = (code & 63u | TAG_CONT) as u8;
} }
3u => { 3u => {
*ptr::mut_offset(buf, off) = (code >> 12u & 15u | TAG_THREE_B) as u8; *ptr::mut_offset(buf, off) = (code >> 12u & 15u | TAG_THREE_B) as u8;
*ptr::mut_offset(buf, off + 1u) = (code >> 6u & 63u | TAG_CONT) as u8; *ptr::mut_offset(buf, off + 1) = (code >> 6u & 63u | TAG_CONT) as u8;
*ptr::mut_offset(buf, off + 2u) = (code & 63u | TAG_CONT) as u8; *ptr::mut_offset(buf, off + 2) = (code & 63u | TAG_CONT) as u8;
} }
4u => { 4u => {
*ptr::mut_offset(buf, off) = (code >> 18u & 7u | TAG_FOUR_B) as u8; *ptr::mut_offset(buf, off) = (code >> 18u & 7u | TAG_FOUR_B) as u8;
*ptr::mut_offset(buf, off + 1u) = (code >> 12u & 63u | TAG_CONT) as u8; *ptr::mut_offset(buf, off + 1) = (code >> 12u & 63u | TAG_CONT) as u8;
*ptr::mut_offset(buf, off + 2u) = (code >> 6u & 63u | TAG_CONT) as u8; *ptr::mut_offset(buf, off + 2) = (code >> 6u & 63u | TAG_CONT) as u8;
*ptr::mut_offset(buf, off + 3u) = (code & 63u | TAG_CONT) as u8; *ptr::mut_offset(buf, off + 3) = (code & 63u | TAG_CONT) as u8;
} }
_ => {} _ => {}
} }

View file

@ -321,6 +321,13 @@ extern "rust-intrinsic" {
/// Get the address of the `__morestack` stack growth function. /// Get the address of the `__morestack` stack growth function.
pub fn morestack_addr() -> *(); pub fn morestack_addr() -> *();
/// Adjust a pointer by an offset.
///
/// This is implemented as an intrinsic to avoid converting to and from an
/// integer, since the conversion would throw away aliasing information.
#[cfg(not(stage0))]
pub fn offset<T>(dst: *T, offset: int) -> *T;
/// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of /// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of
/// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()` /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
pub fn memcpy32<T>(dst: *mut T, src: *T, count: u32); pub fn memcpy32<T>(dst: *mut T, src: *T, count: u32);

View file

@ -52,7 +52,7 @@ pub fn from_fn<T>(n_elts: uint, op: &fn(uint) -> T) -> ~[T] {
let p = raw::to_mut_ptr(v); let p = raw::to_mut_ptr(v);
let mut i: uint = 0u; let mut i: uint = 0u;
while i < n_elts { while i < n_elts {
intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i)); intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i as int)), op(i));
i += 1u; i += 1u;
} }
raw::set_len(&mut v, n_elts); raw::set_len(&mut v, n_elts);
@ -76,7 +76,7 @@ pub fn from_elem<T:Clone>(n_elts: uint, t: T) -> ~[T] {
let p = raw::to_mut_ptr(v); let p = raw::to_mut_ptr(v);
let mut i = 0u; let mut i = 0u;
while i < n_elts { while i < n_elts {
intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), t.clone()); intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i as int)), t.clone());
i += 1u; i += 1u;
} }
raw::set_len(&mut v, n_elts); raw::set_len(&mut v, n_elts);
@ -735,7 +735,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
do self.as_imm_buf |p, _len| { do self.as_imm_buf |p, _len| {
unsafe { unsafe {
cast::transmute(Slice { cast::transmute(Slice {
data: ptr::offset(p, start), data: ptr::offset(p, start as int),
len: (end - start) * sys::nonzero_size_of::<T>(), len: (end - start) * sys::nonzero_size_of::<T>(),
}) })
} }
@ -947,7 +947,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
/// bounds checking. /// bounds checking.
#[inline] #[inline]
unsafe fn unsafe_ref(&self, index: uint) -> *T { unsafe fn unsafe_ref(&self, index: uint) -> *T {
self.repr().data.offset(index) self.repr().data.offset(index as int)
} }
/** /**
@ -1237,14 +1237,14 @@ impl<T> OwnedVector<T> for ~[T] {
let fill = (**repr).data.fill; let fill = (**repr).data.fill;
(**repr).data.fill += sys::nonzero_size_of::<T>(); (**repr).data.fill += sys::nonzero_size_of::<T>();
let p = to_unsafe_ptr(&((**repr).data.data)); let p = to_unsafe_ptr(&((**repr).data.data));
let p = ptr::offset(p, fill) as *mut T; let p = ptr::offset(p, fill as int) as *mut T;
intrinsics::move_val_init(&mut(*p), t); intrinsics::move_val_init(&mut(*p), t);
} else { } else {
let repr: **mut Vec<u8> = cast::transmute(self); let repr: **mut Vec<u8> = cast::transmute(self);
let fill = (**repr).fill; let fill = (**repr).fill;
(**repr).fill += sys::nonzero_size_of::<T>(); (**repr).fill += sys::nonzero_size_of::<T>();
let p = to_unsafe_ptr(&((**repr).data)); let p = to_unsafe_ptr(&((**repr).data));
let p = ptr::offset(p, fill) as *mut T; let p = ptr::offset(p, fill as int) as *mut T;
intrinsics::move_val_init(&mut(*p), t); intrinsics::move_val_init(&mut(*p), t);
} }
} }
@ -1270,7 +1270,7 @@ impl<T> OwnedVector<T> for ~[T] {
unsafe { // Note: infallible. unsafe { // Note: infallible.
let self_p = vec::raw::to_mut_ptr(*self); let self_p = vec::raw::to_mut_ptr(*self);
let rhs_p = vec::raw::to_ptr(rhs); let rhs_p = vec::raw::to_ptr(rhs);
ptr::copy_memory(ptr::mut_offset(self_p, self_len), rhs_p, rhs_len); ptr::copy_memory(ptr::mut_offset(self_p, self_len as int), rhs_p, rhs_len);
raw::set_len(self, new_len); raw::set_len(self, new_len);
raw::set_len(&mut rhs, 0); raw::set_len(&mut rhs, 0);
} }
@ -1351,7 +1351,7 @@ impl<T> OwnedVector<T> for ~[T] {
// Swap out the element we want from the end // Swap out the element we want from the end
let vp = raw::to_mut_ptr(*self); let vp = raw::to_mut_ptr(*self);
let vp = ptr::mut_offset(vp, next_ln - 1); let vp = ptr::mut_offset(vp, (next_ln - 1) as int);
Some(ptr::replace_ptr(vp, work_elt)) Some(ptr::replace_ptr(vp, work_elt))
} }
@ -1415,7 +1415,7 @@ impl<T> OwnedVector<T> for ~[T] {
unsafe { unsafe {
// This loop is optimized out for non-drop types. // This loop is optimized out for non-drop types.
for uint::range(newlen, oldlen) |i| { for uint::range(newlen, oldlen) |i| {
ptr::read_and_zero_ptr(ptr::mut_offset(p, i)); ptr::read_and_zero_ptr(ptr::mut_offset(p, i as int));
} }
} }
} }
@ -1634,8 +1634,8 @@ impl<T:Eq> OwnedEqVector<T> for ~[T] {
let mut w = 1; let mut w = 1;
while r < ln { while r < ln {
let p_r = ptr::mut_offset(p, r); let p_r = ptr::mut_offset(p, r as int);
let p_wm1 = ptr::mut_offset(p, w - 1); let p_wm1 = ptr::mut_offset(p, (w - 1) as int);
if *p_r != *p_wm1 { if *p_r != *p_wm1 {
if r != w { if r != w {
let p_w = ptr::mut_offset(p_wm1, 1); let p_w = ptr::mut_offset(p_wm1, 1);
@ -1702,7 +1702,7 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
do self.as_mut_buf |p, _len| { do self.as_mut_buf |p, _len| {
unsafe { unsafe {
cast::transmute(Slice { cast::transmute(Slice {
data: ptr::mut_offset(p, start) as *T, data: ptr::mut_offset(p, start as int) as *T,
len: (end - start) * sys::nonzero_size_of::<T>() len: (end - start) * sys::nonzero_size_of::<T>()
}) })
} }
@ -1793,7 +1793,7 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
#[inline] #[inline]
unsafe fn unsafe_mut_ref(self, index: uint) -> *mut T { unsafe fn unsafe_mut_ref(self, index: uint) -> *mut T {
ptr::mut_offset(self.repr().data as *mut T, index) ptr::mut_offset(self.repr().data as *mut T, index as int)
} }
#[inline] #[inline]
@ -1923,7 +1923,7 @@ pub mod raw {
*/ */
#[inline] #[inline]
pub unsafe fn get<T:Clone>(v: &[T], i: uint) -> T { pub unsafe fn get<T:Clone>(v: &[T], i: uint) -> T {
v.as_imm_buf(|p, _len| (*ptr::offset(p, i)).clone()) v.as_imm_buf(|p, _len| (*ptr::offset(p, i as int)).clone())
} }
/** /**
@ -1935,7 +1935,7 @@ pub mod raw {
pub unsafe fn init_elem<T>(v: &mut [T], i: uint, val: T) { pub unsafe fn init_elem<T>(v: &mut [T], i: uint, val: T) {
let mut box = Some(val); let mut box = Some(val);
do v.as_mut_buf |p, _len| { do v.as_mut_buf |p, _len| {
intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i as int)),
box.take_unwrap()); box.take_unwrap());
} }
} }
@ -2145,7 +2145,7 @@ impl<'self, T> RandomAccessIterator<&'self T> for VecIterator<'self, T> {
fn idx(&self, index: uint) -> Option<&'self T> { fn idx(&self, index: uint) -> Option<&'self T> {
unsafe { unsafe {
if index < self.indexable() { if index < self.indexable() {
cast::transmute(self.ptr.offset(index)) cast::transmute(self.ptr.offset(index as int))
} else { } else {
None None
} }