From ef870d37a58df136b18f1440f45d4f0102c55c1a Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 30 Jul 2013 00:33:52 -0400 Subject: [PATCH] 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) --- src/libextra/arena.rs | 8 +-- src/libextra/c_vec.rs | 4 +- src/libextra/ebml.rs | 2 +- src/libextra/par.rs | 2 +- src/librustc/metadata/loader.rs | 2 +- src/librustc/middle/trans/foreign.rs | 5 ++ src/librustc/middle/trans/type_use.rs | 2 +- src/librustc/middle/typeck/check/mod.rs | 14 ++++++ src/libstd/at_vec.rs | 2 +- src/libstd/gc.rs | 12 ++--- src/libstd/io.rs | 2 +- src/libstd/os.rs | 6 +-- src/libstd/ptr.rs | 67 +++++++++++++++++-------- src/libstd/repr.rs | 2 +- src/libstd/rt/args.rs | 2 +- src/libstd/rt/stack.rs | 2 +- src/libstd/str.rs | 38 +++++++------- src/libstd/unstable/intrinsics.rs | 7 +++ src/libstd/vec.rs | 32 ++++++------ 19 files changed, 131 insertions(+), 80 deletions(-) diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index 3c10c3545bf..efe1d47563e 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -116,7 +116,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) { let fill = chunk.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 (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", // start, size, align, 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 @@ -176,7 +176,7 @@ impl Arena { //debug!("idx = %u, size = %u, align = %u, fill = %u", // 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); 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)); } } diff --git a/src/libextra/c_vec.rs b/src/libextra/c_vec.rs index f72d3ee694f..e656360aa5a 100644 --- a/src/libextra/c_vec.rs +++ b/src/libextra/c_vec.rs @@ -122,7 +122,7 @@ pub unsafe fn c_vec_with_dtor(base: *mut T, len: uint, dtor: @fn()) pub fn get(t: CVec, ofs: uint) -> T { assert!(ofs < len(t)); 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: CVec, ofs: uint) -> T { */ pub fn set(t: CVec, ofs: uint, v: T) { assert!(ofs < len(t)); - unsafe { *ptr::mut_offset(t.base, ofs) = v }; + unsafe { *ptr::mut_offset(t.base, ofs as int) = v }; } /* diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index c9b0cbb2753..f66677c21f7 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -150,7 +150,7 @@ pub mod reader { unsafe { let (ptr, _): (*u8, uint) = transmute(data); - let ptr = offset(ptr, start); + let ptr = offset(ptr, start as int); let ptr: *i32 = transmute(ptr); let val = bswap32(*ptr); let val: u32 = transmute(val); diff --git a/src/libextra/par.rs b/src/libextra/par.rs index f462a0cfae7..4069c68e71c 100644 --- a/src/libextra/par.rs +++ b/src/libextra/par.rs @@ -58,7 +58,7 @@ fn map_slices( let f = do future_spawn() || { unsafe { let len = end - base; - let slice = (ptr::offset(p, base), + let slice = (ptr::offset(p, base as int), len * sys::size_of::()); info!("pre-slice: %?", (base, slice)); let slice : &[A] = diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 481d27f6944..1037e3a7628 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -215,7 +215,7 @@ fn get_metadata_section(os: os, } 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", csz - vlen); do vec::raw::buf_as_slice(cvbuf1, csz-vlen) |bytes| { diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 080d1f2adb5..f1850beb9a1 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -884,6 +884,11 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to()); 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), "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), diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index aa19af01893..61bb989764a 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -149,7 +149,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint) "visit_tydesc" | "forget" | "frame_address" | "morestack_addr" => 0, - "memcpy32" | "memcpy64" | "memmove32" | "memmove64" | + "offset" | "memcpy32" | "memcpy64" | "memmove32" | "memmove64" | "memset32" | "memset64" => use_repr, "sqrtf32" | "sqrtf64" | "powif32" | "powif64" | diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index cffceee88d3..4c408147383 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3606,6 +3606,20 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { "morestack_addr" => { (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" => { (1, ~[ diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index 0b2519e6fb4..8e5b6b93111 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -233,7 +233,7 @@ pub mod raw { let repr: *mut Box> = cast::transmute_copy(v); let amt = v.len(); (*repr).data.fill += sys::size_of::(); - 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); } diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs index 4feec26a2d9..ee270b553e6 100644 --- a/src/libstd/gc.rs +++ b/src/libstd/gc.rs @@ -74,7 +74,7 @@ pub mod rustrt { } unsafe fn bump(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(ptr: *T) -> *T { @@ -140,11 +140,11 @@ unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool { // Stack roots let mut sri = 0; while sri < num_stack_roots { - if *ptr::offset(addrspaces, sri) >= 1 { + if *ptr::offset(addrspaces, sri as int) >= 1 { 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; - let tydescpp = ptr::offset(tydescs, sri); + let tydescpp = ptr::offset(tydescs, sri as int); let tydesc = if ptr::is_not_null(tydescpp) && ptr::is_not_null(*tydescpp) { **tydescpp @@ -159,7 +159,7 @@ unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool { // Register roots let mut rri = 0; 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. } 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 // return address for morestack. 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) { loop; diff --git a/src/libstd/io.rs b/src/libstd/io.rs index 1865dc5dece..1a92e5e07c7 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -1213,7 +1213,7 @@ impl Writer for fd_t { let mut count = 0u; do v.as_imm_buf |vbuf, 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); if nout < 0 as ssize_t { error!("error writing buffer"); diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 142021be471..ac03735894a 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1114,7 +1114,7 @@ pub fn set_exit_status(code: int) { unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] { let mut args = ~[]; 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 } @@ -1165,9 +1165,9 @@ pub fn real_args() -> ~[~str] { for uint::range(0, nArgs as uint) |i| { unsafe { // Determine the length of this argument. - let ptr = *szArgList.offset(i); + let ptr = *szArgList.offset(i as int); 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. args.push(vec::raw::buf_as_slice(ptr, len, diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index 29564bd9728..3af4769fcdb 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -13,6 +13,7 @@ use cast; use clone::Clone; use option::{Option, Some, None}; +#[cfg(stage0)] use sys; use unstable::intrinsics; use util::swap; @@ -25,20 +26,44 @@ use uint; /// Calculate the offset from a pointer #[inline] -pub fn offset(ptr: *T, count: uint) -> *T { - (ptr as uint + count * sys::size_of::()) as *T +#[cfg(stage0)] +pub fn offset(ptr: *T, count: int) -> *T { + (ptr as uint + (count as uint) * sys::size_of::()) as *T } /// Calculate the offset from a const pointer #[inline] -pub fn const_offset(ptr: *const T, count: uint) -> *const T { - (ptr as uint + count * sys::size_of::()) as *T +#[cfg(stage0)] +pub fn const_offset(ptr: *const T, count: int) -> *const T { + (ptr as uint + (count as uint) * sys::size_of::()) as *T } /// Calculate the offset from a mut pointer #[inline] -pub fn mut_offset(ptr: *mut T, count: uint) -> *mut T { - (ptr as uint + count * sys::size_of::()) as *mut T +#[cfg(stage0)] +pub fn mut_offset(ptr: *mut T, count: int) -> *mut T { + (ptr as uint + (count as uint) * sys::size_of::()) as *mut T +} + +/// Calculate the offset from a pointer +#[inline] +#[cfg(not(stage0))] +pub fn offset(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(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(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`. @@ -58,7 +83,7 @@ impl Clone for *T { pub unsafe fn position(buf: *T, f: &fn(&T) -> bool) -> uint { let mut i = 0; loop { - if f(&(*offset(buf, i))) { return i; } + if f(&(*offset(buf, i as int))) { return i; } else { i += 1; } } } @@ -242,7 +267,7 @@ pub unsafe fn array_each_with_len(arr: **T, len: uint, cb: &fn(*T)) { } //let start_ptr = *arr; uint::iterate(0, len, |e| { - let n = offset(arr, e); + let n = offset(arr, e as int); cb(*n); true }); @@ -273,7 +298,7 @@ pub trait RawPtr { fn is_null(&self) -> bool; fn is_not_null(&self) -> bool; unsafe fn to_option(&self) -> Option<&T>; - fn offset(&self, count: uint) -> Self; + fn offset(&self, count: int) -> Self; } /// Extension methods for immutable pointers @@ -305,7 +330,7 @@ impl RawPtr for *T { /// Calculates the offset from a pointer. #[inline] - fn offset(&self, count: uint) -> *T { offset(*self, count) } + fn offset(&self, count: int) -> *T { offset(*self, count) } } /// Extension methods for mutable pointers @@ -337,7 +362,7 @@ impl RawPtr for *mut T { /// Calculates the offset from a mutable pointer. #[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 @@ -378,7 +403,7 @@ impl Add for *T { /// Is calculated according to the size of the type pointed to. #[inline] 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 Sub for *T { /// Is calculated according to the size of the type pointed to. #[inline] 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 Add for *mut T { /// Is calculated according to the size of the type pointed to. #[inline] 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 Sub for *mut T { /// Is calculated according to the size of the type pointed to. #[inline] 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 mut v1 = ~[0u16, 0u16, 0u16]; - copy_memory(mut_offset(vec::raw::to_mut_ptr(v1), 1u), - offset(vec::raw::to_ptr(v0), 1u), 1u); + copy_memory(mut_offset(vec::raw::to_mut_ptr(v1), 1), + offset(vec::raw::to_ptr(v0), 1), 1); assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16)); 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 && 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); assert!((v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16)); @@ -495,7 +520,7 @@ pub mod ptr_tests { assert!(p.is_null()); assert!(!p.is_not_null()); - let q = offset(p, 1u); + let q = offset(p, 1); assert!(!q.is_null()); assert!(q.is_not_null()); @@ -503,7 +528,7 @@ pub mod ptr_tests { assert!(mp.is_null()); assert!(!mp.is_not_null()); - let mq = mp.offset(1u); + let mq = mp.offset(1); assert!(!mq.is_null()); assert!(mq.is_not_null()); } diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index eb4e1918add..60bd30bbee8 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -212,7 +212,7 @@ impl ReprVisitor { self.writer.write_str(", "); } 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; } self.writer.write_char(']'); diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs index 85cdb9fc941..cd950471286 100644 --- a/src/libstd/rt/args.rs +++ b/src/libstd/rt/args.rs @@ -114,7 +114,7 @@ mod imp { unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] { let mut args = ~[]; 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; } diff --git a/src/libstd/rt/stack.rs b/src/libstd/rt/stack.rs index fbb516b2df4..a1269968921 100644 --- a/src/libstd/rt/stack.rs +++ b/src/libstd/rt/stack.rs @@ -44,7 +44,7 @@ impl StackSegment { /// Point one word beyond the high end of the allocated stack 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 } } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index fff859321fb..6031632031b 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -191,7 +191,7 @@ impl<'self, S: Str> StrVector for &'self [S] { do ss.as_slice().as_imm_buf |ssbuf, sslen| { let sslen = sslen - 1; 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; } else { ptr::copy_memory(buf, sepbuf, seplen); - buf = buf.offset(seplen); + buf = buf.offset(seplen as int); } 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; while *curr != 0u8 { i += 1u; - curr = ptr::offset(buf, i); + curr = ptr::offset(buf, i as int); } return from_buf_len(buf, i); } @@ -844,7 +844,7 @@ pub mod raw { let mut len = 0u; while *curr != 0u8 { len += 1u; - curr = ptr::offset(s, len); + curr = ptr::offset(s, len as int); } let v = Slice { data: s, len: len + 1 }; assert!(is_utf8(cast::transmute(v))); @@ -868,7 +868,7 @@ pub mod raw { assert!((end <= n)); cast::transmute(Slice { - data: ptr::offset(sbuf, begin), + data: ptr::offset(sbuf, begin as int), len: end - begin + 1, }) } @@ -879,7 +879,7 @@ pub mod raw { let new_len = s.len() + 1; s.reserve_at_least(new_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); } @@ -915,7 +915,7 @@ pub mod raw { let v: **mut String = cast::transmute(v); let repr = *v; (*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; } @@ -1833,7 +1833,7 @@ impl<'self> StrSlice<'self> for &'self str { for nn.times { ptr::copy_memory(rbuf, buf, len); - rbuf = rbuf.offset(len); + rbuf = rbuf.offset(len as int); } } 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| { // NB: len includes the trailing null. 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)) } else { f(buf as *libc::c_char) @@ -2051,7 +2051,7 @@ impl OwnedStr for ~str { self.reserve(llen + rlen); do self.as_imm_buf |lbuf, _llen| { 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); ptr::copy_memory(dst, rbuf, rlen); } @@ -2069,7 +2069,7 @@ impl OwnedStr for ~str { self.reserve_at_least(llen + rlen); do self.as_imm_buf |lbuf, _llen| { 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); ptr::copy_memory(dst, rbuf, rlen); } @@ -2090,7 +2090,7 @@ impl OwnedStr for ~str { let len = self.len(); let new_len = len + nb; self.reserve_at_least(new_len); - let off = len; + let off = len as int; do self.as_mut_buf |buf, _len| { match nb { 1u => { @@ -2098,18 +2098,18 @@ impl OwnedStr for ~str { } 2u => { *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 => { *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 + 2u) = (code & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 1) = (code >> 6u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 2) = (code & 63u | TAG_CONT) as u8; } 4u => { *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 + 2u) = (code >> 6u & 63u | TAG_CONT) as u8; - *ptr::mut_offset(buf, off + 3u) = (code & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 1) = (code >> 12u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 2) = (code >> 6u & 63u | TAG_CONT) as u8; + *ptr::mut_offset(buf, off + 3) = (code & 63u | TAG_CONT) as u8; } _ => {} } diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 655ede6b4eb..5d6cd594f48 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -321,6 +321,13 @@ extern "rust-intrinsic" { /// Get the address of the `__morestack` stack growth function. 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(dst: *T, offset: int) -> *T; + /// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` pub fn memcpy32(dst: *mut T, src: *T, count: u32); diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index cfd28fcfc5e..72e8ad71b34 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -52,7 +52,7 @@ pub fn from_fn(n_elts: uint, op: &fn(uint) -> T) -> ~[T] { let p = raw::to_mut_ptr(v); let mut i: uint = 0u; 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; } raw::set_len(&mut v, n_elts); @@ -76,7 +76,7 @@ pub fn from_elem(n_elts: uint, t: T) -> ~[T] { let p = raw::to_mut_ptr(v); let mut i = 0u; 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; } 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| { unsafe { cast::transmute(Slice { - data: ptr::offset(p, start), + data: ptr::offset(p, start as int), len: (end - start) * sys::nonzero_size_of::(), }) } @@ -947,7 +947,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { /// bounds checking. #[inline] 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 OwnedVector for ~[T] { let fill = (**repr).data.fill; (**repr).data.fill += sys::nonzero_size_of::(); 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); } else { let repr: **mut Vec = cast::transmute(self); let fill = (**repr).fill; (**repr).fill += sys::nonzero_size_of::(); 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); } } @@ -1270,7 +1270,7 @@ impl OwnedVector for ~[T] { unsafe { // Note: infallible. let self_p = vec::raw::to_mut_ptr(*self); 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(&mut rhs, 0); } @@ -1351,7 +1351,7 @@ impl OwnedVector for ~[T] { // Swap out the element we want from the end 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)) } @@ -1415,7 +1415,7 @@ impl OwnedVector for ~[T] { unsafe { // This loop is optimized out for non-drop types. 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 OwnedEqVector for ~[T] { let mut w = 1; while r < ln { - let p_r = ptr::mut_offset(p, r); - let p_wm1 = ptr::mut_offset(p, w - 1); + let p_r = ptr::mut_offset(p, r as int); + let p_wm1 = ptr::mut_offset(p, (w - 1) as int); if *p_r != *p_wm1 { if r != w { 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| { unsafe { 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::() }) } @@ -1793,7 +1793,7 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { #[inline] 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] @@ -1923,7 +1923,7 @@ pub mod raw { */ #[inline] pub unsafe fn get(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(v: &mut [T], i: uint, val: T) { let mut box = Some(val); 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()); } } @@ -2145,7 +2145,7 @@ impl<'self, T> RandomAccessIterator<&'self T> for VecIterator<'self, T> { fn idx(&self, index: uint) -> Option<&'self T> { unsafe { if index < self.indexable() { - cast::transmute(self.ptr.offset(index)) + cast::transmute(self.ptr.offset(index as int)) } else { None }