提交 e1a26ad2 编写于 作者: D Daniel Micay

use element count in slices, not size in bytes

This allows the indexing bounds check or other comparisons against an
element length to avoid a multiplication by the size.
上级 aa93381e
...@@ -1059,7 +1059,7 @@ fn extract_vec_elems(bcx: @mut Block, ...@@ -1059,7 +1059,7 @@ fn extract_vec_elems(bcx: @mut Block,
Store(bcx, slice_begin, Store(bcx, slice_begin,
GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]) GEPi(bcx, scratch.val, [0u, abi::slice_elt_base])
); );
Store(bcx, slice_len, Store(bcx, UDiv(bcx, slice_len, vt.llunit_size),
GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]) GEPi(bcx, scratch.val, [0u, abi::slice_elt_len])
); );
elems[n] = scratch.val; elems[n] = scratch.val;
......
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
use middle::trans::inline; use middle::trans::inline;
use middle::trans::llrepr::LlvmRepr; use middle::trans::llrepr::LlvmRepr;
use middle::trans::machine; use middle::trans::machine;
use middle::trans::machine::{llalign_of_min, llsize_of, llsize_of_alloc}; use middle::trans::machine::{llalign_of_min, llsize_of};
use middle::trans::meth; use middle::trans::meth;
use middle::trans::monomorphize; use middle::trans::monomorphize;
use middle::trans::tvec; use middle::trans::tvec;
...@@ -2910,7 +2910,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) { ...@@ -2910,7 +2910,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
} }
} }
pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint, uint) { pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint) {
let str_slice_type = Type::struct_([Type::i8p(), ccx.int_type], false); let str_slice_type = Type::struct_([Type::i8p(), ccx.int_type], false);
let elttype = Type::struct_([str_slice_type, ccx.int_type], false); let elttype = Type::struct_([str_slice_type, ccx.int_type], false);
let maptype = Type::array(&elttype, ccx.module_data.len() as u64); let maptype = Type::array(&elttype, ccx.module_data.len() as u64);
...@@ -2942,7 +2942,7 @@ pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint, uint) { ...@@ -2942,7 +2942,7 @@ pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint, uint) {
unsafe { unsafe {
llvm::LLVMSetInitializer(map, C_array(elttype, elts)); llvm::LLVMSetInitializer(map, C_array(elttype, elts));
} }
return (map, keys.len(), llsize_of_alloc(ccx, elttype)); return (map, keys.len())
} }
...@@ -3004,19 +3004,17 @@ pub fn fill_crate_map(ccx: &mut CrateContext, map: ValueRef) { ...@@ -3004,19 +3004,17 @@ pub fn fill_crate_map(ccx: &mut CrateContext, map: ValueRef) {
lib::llvm::SetLinkage(vec_elements, lib::llvm::InternalLinkage); lib::llvm::SetLinkage(vec_elements, lib::llvm::InternalLinkage);
llvm::LLVMSetInitializer(vec_elements, C_array(ccx.int_type, subcrates)); llvm::LLVMSetInitializer(vec_elements, C_array(ccx.int_type, subcrates));
let (mod_map, mod_count, mod_struct_size) = create_module_map(ccx); let (mod_map, mod_count) = create_module_map(ccx);
llvm::LLVMSetInitializer(map, C_struct( llvm::LLVMSetInitializer(map, C_struct(
[C_i32(2), [C_i32(2),
C_struct([ C_struct([
p2i(ccx, mod_map), p2i(ccx, mod_map),
// byte size of the module map array, an entry consists of two integers C_uint(ccx, mod_count)
C_int(ccx, ((mod_count * mod_struct_size) as int))
], false), ], false),
C_struct([ C_struct([
p2i(ccx, vec_elements), p2i(ccx, vec_elements),
// byte size of the subcrates array, an entry consists of an integer C_uint(ccx, subcrates.len())
C_int(ccx, (subcrates.len() * llsize_of_alloc(ccx, ccx.int_type)) as int)
], false) ], false)
], false)); ], false));
} }
......
...@@ -83,14 +83,10 @@ pub fn const_ptrcast(cx: &mut CrateContext, a: ValueRef, t: Type) -> ValueRef { ...@@ -83,14 +83,10 @@ pub fn const_ptrcast(cx: &mut CrateContext, a: ValueRef, t: Type) -> ValueRef {
} }
} }
pub fn const_vec(cx: @mut CrateContext, e: &ast::Expr, es: &[@ast::Expr]) fn const_vec(cx: @mut CrateContext, e: &ast::Expr, es: &[@ast::Expr]) -> (ValueRef, Type, bool) {
-> (ValueRef, ValueRef, Type, bool) {
unsafe {
let vec_ty = ty::expr_ty(cx.tcx, e); let vec_ty = ty::expr_ty(cx.tcx, e);
let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty); let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
let llunitty = type_of::type_of(cx, unit_ty); let llunitty = type_of::type_of(cx, unit_ty);
let unit_sz = machine::llsize_of(cx, llunitty);
let sz = llvm::LLVMConstMul(C_uint(cx, es.len()), unit_sz);
let (vs, inlineable) = vec::unzip(es.iter().map(|e| const_expr(cx, *e))); let (vs, inlineable) = vec::unzip(es.iter().map(|e| const_expr(cx, *e)));
// If the vector contains enums, an LLVM array won't work. // If the vector contains enums, an LLVM array won't work.
let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) { let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
...@@ -98,8 +94,7 @@ pub fn const_vec(cx: @mut CrateContext, e: &ast::Expr, es: &[@ast::Expr]) ...@@ -98,8 +94,7 @@ pub fn const_vec(cx: @mut CrateContext, e: &ast::Expr, es: &[@ast::Expr])
} else { } else {
C_array(llunitty, vs) C_array(llunitty, vs)
}; };
return (v, sz, llunitty, inlineable.iter().fold(true, |a, &b| a && b)); (v, llunitty, inlineable.iter().fold(true, |a, &b| a && b))
}
} }
fn const_addr_of(cx: &mut CrateContext, cv: ValueRef) -> ValueRef { fn const_addr_of(cx: &mut CrateContext, cv: ValueRef) -> ValueRef {
...@@ -225,9 +220,8 @@ pub fn const_expr(cx: @mut CrateContext, e: &ast::Expr) -> (ValueRef, bool) { ...@@ -225,9 +220,8 @@ pub fn const_expr(cx: @mut CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
assert_eq!(abi::slice_elt_len, 1); assert_eq!(abi::slice_elt_len, 1);
match ty::get(ty).sty { match ty::get(ty).sty {
ty::ty_evec(_, ty::vstore_fixed(*)) => { ty::ty_evec(_, ty::vstore_fixed(len)) => {
let size = machine::llsize_of(cx, val_ty(llconst)); llconst = C_struct([llptr, C_uint(cx, len)], false);
llconst = C_struct([llptr, size], false);
} }
_ => {} _ => {}
} }
...@@ -412,14 +406,8 @@ fn map_list(cx: @mut CrateContext, ...@@ -412,14 +406,8 @@ fn map_list(cx: @mut CrateContext,
(bv, C_uint(cx, u)), (bv, C_uint(cx, u)),
ty::vstore_slice(_) => { ty::vstore_slice(_) => {
let unit_ty = ty::sequence_element_type(cx.tcx, bt);
let llunitty = type_of::type_of(cx, unit_ty);
let unit_sz = machine::llsize_of(cx, llunitty);
let e1 = const_get_elt(cx, bv, [0]); let e1 = const_get_elt(cx, bv, [0]);
(const_deref_ptr(cx, e1), (const_deref_ptr(cx, e1), const_get_elt(cx, bv, [1]))
llvm::LLVMConstUDiv(const_get_elt(cx, bv, [1]),
unit_sz))
}, },
_ => cx.sess.span_bug(base.span, _ => cx.sess.span_bug(base.span,
"index-expr base must be fixed-size or slice") "index-expr base must be fixed-size or slice")
...@@ -538,7 +526,7 @@ fn map_list(cx: @mut CrateContext, ...@@ -538,7 +526,7 @@ fn map_list(cx: @mut CrateContext,
} }
} }
ast::ExprVec(ref es, ast::MutImmutable) => { ast::ExprVec(ref es, ast::MutImmutable) => {
let (v, _, _, inlineable) = const_vec(cx, e, *es); let (v, _, inlineable) = const_vec(cx, e, *es);
(v, inlineable) (v, inlineable)
} }
ast::ExprVstore(sub, ast::ExprVstoreSlice) => { ast::ExprVstore(sub, ast::ExprVstoreSlice) => {
...@@ -550,7 +538,7 @@ fn map_list(cx: @mut CrateContext, ...@@ -550,7 +538,7 @@ fn map_list(cx: @mut CrateContext,
} }
} }
ast::ExprVec(ref es, ast::MutImmutable) => { ast::ExprVec(ref es, ast::MutImmutable) => {
let (cv, sz, llunitty, _) = const_vec(cx, e, *es); let (cv, llunitty, _) = const_vec(cx, e, *es);
let llty = val_ty(cv); let llty = val_ty(cv);
let gv = do "const".with_c_str |name| { let gv = do "const".with_c_str |name| {
llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name) llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name)
...@@ -559,7 +547,7 @@ fn map_list(cx: @mut CrateContext, ...@@ -559,7 +547,7 @@ fn map_list(cx: @mut CrateContext,
llvm::LLVMSetGlobalConstant(gv, True); llvm::LLVMSetGlobalConstant(gv, True);
SetLinkage(gv, PrivateLinkage); SetLinkage(gv, PrivateLinkage);
let p = const_ptrcast(cx, gv, llunitty); let p = const_ptrcast(cx, gv, llunitty);
(C_struct([p, sz], false), false) (C_struct([p, C_uint(cx, es.len())], false), false)
} }
_ => cx.sess.span_bug(e.span, "bad const-slice expr") _ => cx.sess.span_bug(e.span, "bad const-slice expr")
} }
......
...@@ -1865,7 +1865,7 @@ fn vec_slice_metadata(cx: &mut CrateContext, ...@@ -1865,7 +1865,7 @@ fn vec_slice_metadata(cx: &mut CrateContext,
offset: ComputedMemberOffset, offset: ComputedMemberOffset,
}, },
MemberDescription { MemberDescription {
name: @"size_in_bytes", name: @"length",
llvm_type: member_llvm_types[1], llvm_type: member_llvm_types[1],
type_metadata: type_metadata(cx, ty::mk_uint(), span), type_metadata: type_metadata(cx, ty::mk_uint(), span),
offset: ComputedMemberOffset, offset: ComputedMemberOffset,
......
...@@ -274,8 +274,12 @@ fn auto_slice(bcx: @mut Block, ...@@ -274,8 +274,12 @@ fn auto_slice(bcx: @mut Block,
ty::vstore_slice(ty::re_static)); ty::vstore_slice(ty::re_static));
let scratch = scratch_datum(bcx, slice_ty, "__adjust", false); let scratch = scratch_datum(bcx, slice_ty, "__adjust", false);
let vt = tvec::vec_types(bcx, datum.ty);
let unscaled_len = UDiv(bcx, len, vt.llunit_size);
Store(bcx, base, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base])); Store(bcx, base, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
Store(bcx, len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len])); Store(bcx, unscaled_len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]));
DatumBlock {bcx: bcx, datum: scratch} DatumBlock {bcx: bcx, datum: scratch}
} }
......
...@@ -237,8 +237,7 @@ pub fn trans_slice_vstore(bcx: @mut Block, ...@@ -237,8 +237,7 @@ pub fn trans_slice_vstore(bcx: @mut Block,
Ignore => {} Ignore => {}
SaveIn(lldest) => { SaveIn(lldest) => {
Store(bcx, llfixed, GEPi(bcx, lldest, [0u, abi::slice_elt_base])); Store(bcx, llfixed, GEPi(bcx, lldest, [0u, abi::slice_elt_base]));
let lllen = Mul(bcx, llcount, vt.llunit_size); Store(bcx, llcount, GEPi(bcx, lldest, [0u, abi::slice_elt_len]));
Store(bcx, lllen, GEPi(bcx, lldest, [0u, abi::slice_elt_len]));
} }
} }
...@@ -529,7 +528,8 @@ pub fn get_base_and_len(bcx: @mut Block, ...@@ -529,7 +528,8 @@ pub fn get_base_and_len(bcx: @mut Block,
} }
ty::vstore_slice(_) => { ty::vstore_slice(_) => {
let base = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_base])); let base = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_base]));
let len = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_len])); let count = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_len]));
let len = Mul(bcx, count, vt.llunit_size);
(base, len) (base, len)
} }
ty::vstore_uniq | ty::vstore_box => { ty::vstore_uniq | ty::vstore_box => {
......
...@@ -52,6 +52,8 @@ fn main () { ...@@ -52,6 +52,8 @@ fn main () {
``` ```
*/ */
use sys::size_of;
use unstable::raw::Slice;
use cast; use cast;
use container::Container; use container::Container;
use iter::{Iterator, range}; use iter::{Iterator, range};
...@@ -133,10 +135,10 @@ fn next_u64(&mut self) -> u64 { ...@@ -133,10 +135,10 @@ fn next_u64(&mut self) -> u64 {
/// println!("{:?}", v); /// println!("{:?}", v);
/// } /// }
/// ``` /// ```
fn fill_bytes(&mut self, mut dest: &mut [u8]) { fn fill_bytes(&mut self, dest: &mut [u8]) {
// this relies on the lengths being transferred correctly when let mut slice: Slice<u64> = unsafe { cast::transmute_copy(&dest) };
// transmuting between vectors like this. slice.len /= size_of::<u64>();
let as_u64: &mut &mut [u64] = unsafe { cast::transmute(&mut dest) }; let as_u64: &mut [u64] = unsafe { cast::transmute(slice) };
for dest in as_u64.mut_iter() { for dest in as_u64.mut_iter() {
*dest = self.next_u64(); *dest = self.next_u64();
} }
...@@ -147,7 +149,9 @@ fn fill_bytes(&mut self, mut dest: &mut [u8]) { ...@@ -147,7 +149,9 @@ fn fill_bytes(&mut self, mut dest: &mut [u8]) {
// space for a u32 // space for a u32
if remaining >= 4 { if remaining >= 4 {
let as_u32: &mut &mut [u32] = unsafe { cast::transmute(&mut dest) }; let mut slice: Slice<u32> = unsafe { cast::transmute_copy(&dest) };
slice.len /= size_of::<u32>();
let as_u32: &mut [u32] = unsafe { cast::transmute(slice) };
as_u32[as_u32.len() - 1] = self.next_u32(); as_u32[as_u32.len() - 1] = self.next_u32();
remaining -= 4; remaining -= 4;
} }
......
...@@ -186,12 +186,7 @@ pub fn write_mut_qualifier(&mut self, mtbl: uint) { ...@@ -186,12 +186,7 @@ pub fn write_mut_qualifier(&mut self, mtbl: uint) {
} }
} }
pub fn write_vec_range(&mut self, pub fn write_vec_range(&mut self, ptr: *(), len: uint, inner: *TyDesc) -> bool {
_mtbl: uint,
ptr: *(),
len: uint,
inner: *TyDesc)
-> bool {
let mut p = ptr as *u8; let mut p = ptr as *u8;
let (sz, al) = unsafe { ((*inner).size, (*inner).align) }; let (sz, al) = unsafe { ((*inner).size, (*inner).align) };
self.writer.write(['[' as u8]); self.writer.write(['[' as u8]);
...@@ -213,13 +208,8 @@ pub fn write_vec_range(&mut self, ...@@ -213,13 +208,8 @@ pub fn write_vec_range(&mut self,
true true
} }
pub fn write_unboxed_vec_repr(&mut self, pub fn write_unboxed_vec_repr(&mut self, _: uint, v: &raw::Vec<()>, inner: *TyDesc) -> bool {
mtbl: uint, self.write_vec_range(ptr::to_unsafe_ptr(&v.data), v.fill, inner)
v: &raw::Vec<()>,
inner: *TyDesc)
-> bool {
self.write_vec_range(mtbl, ptr::to_unsafe_ptr(&v.data),
v.fill, inner)
} }
fn write_escaped_char(&mut self, ch: char, is_str: bool) { fn write_escaped_char(&mut self, ch: char, is_str: bool) {
...@@ -377,19 +367,32 @@ fn visit_evec_uniq_managed(&mut self, mtbl: uint, inner: *TyDesc) -> bool { ...@@ -377,19 +367,32 @@ fn visit_evec_uniq_managed(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
} }
} }
#[cfg(stage0)]
fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool { fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
do self.get::<raw::Slice<()>> |this, s| { do self.get::<raw::Slice<()>> |this, s| {
this.writer.write(['&' as u8]); this.writer.write(['&' as u8]);
this.write_mut_qualifier(mtbl); this.write_mut_qualifier(mtbl);
this.write_vec_range(mtbl, s.data, s.len, inner); this.write_vec_range(s.data, s.len, inner);
}
}
#[cfg(not(stage0))]
fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
do self.get::<raw::Slice<()>> |this, s| {
this.writer.write(['&' as u8]);
this.write_mut_qualifier(mtbl);
let size = unsafe {
if (*inner).size == 0 { 1 } else { (*inner).size }
};
this.write_vec_range(s.data, s.len * size, inner);
} }
} }
fn visit_evec_fixed(&mut self, n: uint, sz: uint, _align: uint, fn visit_evec_fixed(&mut self, n: uint, sz: uint, _align: uint,
mtbl: uint, inner: *TyDesc) -> bool { _: uint, inner: *TyDesc) -> bool {
let assumed_size = if sz == 0 { n } else { sz }; let assumed_size = if sz == 0 { n } else { sz };
do self.get::<()> |this, b| { do self.get::<()> |this, b| {
this.write_vec_range(mtbl, ptr::to_unsafe_ptr(b), assumed_size, inner); this.write_vec_range(ptr::to_unsafe_ptr(b), assumed_size, inner);
} }
} }
......
...@@ -974,6 +974,7 @@ pub trait ImmutableVector<'self, T> { ...@@ -974,6 +974,7 @@ pub trait ImmutableVector<'self, T> {
impl<'self,T> ImmutableVector<'self, T> for &'self [T] { impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
#[inline] #[inline]
#[cfg(stage0)]
fn slice(&self, start: uint, end: uint) -> &'self [T] { fn slice(&self, start: uint, end: uint) -> &'self [T] {
assert!(start <= end); assert!(start <= end);
assert!(end <= self.len()); assert!(end <= self.len());
...@@ -986,10 +987,27 @@ fn slice(&self, start: uint, end: uint) -> &'self [T] { ...@@ -986,10 +987,27 @@ fn slice(&self, start: uint, end: uint) -> &'self [T] {
} }
} }
} }
#[inline]
#[cfg(not(stage0))]
fn slice(&self, start: uint, end: uint) -> &'self [T] {
assert!(start <= end);
assert!(end <= self.len());
do self.as_imm_buf |p, _len| {
unsafe {
cast::transmute(Slice {
data: ptr::offset(p, start as int),
len: (end - start)
})
}
}
}
#[inline] #[inline]
fn slice_from(&self, start: uint) -> &'self [T] { fn slice_from(&self, start: uint) -> &'self [T] {
self.slice(start, self.len()) self.slice(start, self.len())
} }
#[inline] #[inline]
fn slice_to(&self, end: uint) -> &'self [T] { fn slice_to(&self, end: uint) -> &'self [T] {
self.slice(0, end) self.slice(0, end)
...@@ -1130,10 +1148,18 @@ fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U] { ...@@ -1130,10 +1148,18 @@ fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U] {
} }
#[inline] #[inline]
#[cfg(stage0)]
fn as_imm_buf<U>(&self, f: &fn(*T, uint) -> U) -> U { fn as_imm_buf<U>(&self, f: &fn(*T, uint) -> U) -> U {
let s = self.repr(); let s = self.repr();
f(s.data, s.len / sys::nonzero_size_of::<T>()) f(s.data, s.len / sys::nonzero_size_of::<T>())
} }
#[inline]
#[cfg(not(stage0))]
fn as_imm_buf<U>(&self, f: &fn(*T, uint) -> U) -> U {
let s = self.repr();
f(s.data, s.len)
}
} }
/// Extension methods for vectors contain `Eq` elements. /// Extension methods for vectors contain `Eq` elements.
...@@ -1899,6 +1925,7 @@ fn mut_split(self, mid: uint) -> (&'self mut [T], ...@@ -1899,6 +1925,7 @@ fn mut_split(self, mid: uint) -> (&'self mut [T],
impl<'self,T> MutableVector<'self, T> for &'self mut [T] { impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
#[inline] #[inline]
#[cfg(stage0)]
fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] { fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] {
assert!(start <= end); assert!(start <= end);
assert!(end <= self.len()); assert!(end <= self.len());
...@@ -1912,6 +1939,21 @@ fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] { ...@@ -1912,6 +1939,21 @@ fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] {
} }
} }
#[inline]
#[cfg(not(stage0))]
fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] {
assert!(start <= end);
assert!(end <= self.len());
do self.as_mut_buf |p, _len| {
unsafe {
cast::transmute(Slice {
data: ptr::mut_offset(p, start as int) as *T,
len: (end - start)
})
}
}
}
#[inline] #[inline]
fn mut_slice_from(self, start: uint) -> &'self mut [T] { fn mut_slice_from(self, start: uint) -> &'self mut [T] {
let len = self.len(); let len = self.len();
...@@ -1991,11 +2033,18 @@ unsafe fn unsafe_set(self, index: uint, val: T) { ...@@ -1991,11 +2033,18 @@ unsafe fn unsafe_set(self, index: uint, val: T) {
} }
#[inline] #[inline]
#[cfg(stage0)]
fn as_mut_buf<U>(self, f: &fn(*mut T, uint) -> U) -> U { fn as_mut_buf<U>(self, f: &fn(*mut T, uint) -> U) -> U {
let Slice{ data, len } = self.repr(); let Slice{ data, len } = self.repr();
f(data as *mut T, len / sys::nonzero_size_of::<T>()) f(data as *mut T, len / sys::nonzero_size_of::<T>())
} }
#[inline]
#[cfg(not(stage0))]
fn as_mut_buf<U>(self, f: &fn(*mut T, uint) -> U) -> U {
let Slice{ data, len } = self.repr();
f(data as *mut T, len)
}
} }
/// Trait for &[T] where T is Cloneable /// Trait for &[T] where T is Cloneable
...@@ -2083,6 +2132,7 @@ pub fn to_mut_ptr<T>(v: &mut [T]) -> *mut T { ...@@ -2083,6 +2132,7 @@ pub fn to_mut_ptr<T>(v: &mut [T]) -> *mut T {
* not bytes). * not bytes).
*/ */
#[inline] #[inline]
#[cfg(stage0)]
pub unsafe fn buf_as_slice<T,U>(p: *T, pub unsafe fn buf_as_slice<T,U>(p: *T,
len: uint, len: uint,
f: &fn(v: &[T]) -> U) -> U { f: &fn(v: &[T]) -> U) -> U {
...@@ -2097,6 +2147,22 @@ pub unsafe fn buf_as_slice<T,U>(p: *T, ...@@ -2097,6 +2147,22 @@ pub unsafe fn buf_as_slice<T,U>(p: *T,
* not bytes). * not bytes).
*/ */
#[inline] #[inline]
#[cfg(not(stage0))]
pub unsafe fn buf_as_slice<T,U>(p: *T,
len: uint,
f: &fn(v: &[T]) -> U) -> U {
f(cast::transmute(Slice {
data: p,
len: len
}))
}
/**
* Form a slice from a pointer and length (as a number of units,
* not bytes).
*/
#[inline]
#[cfg(stage0)]
pub unsafe fn mut_buf_as_slice<T,U>(p: *mut T, pub unsafe fn mut_buf_as_slice<T,U>(p: *mut T,
len: uint, len: uint,
f: &fn(v: &mut [T]) -> U) -> U { f: &fn(v: &mut [T]) -> U) -> U {
...@@ -2106,6 +2172,21 @@ pub unsafe fn mut_buf_as_slice<T,U>(p: *mut T, ...@@ -2106,6 +2172,21 @@ pub unsafe fn mut_buf_as_slice<T,U>(p: *mut T,
})) }))
} }
/**
* Form a slice from a pointer and length (as a number of units,
* not bytes).
*/
#[inline]
#[cfg(not(stage0))]
pub unsafe fn mut_buf_as_slice<T,U>(p: *mut T,
len: uint,
f: &fn(v: &mut [T]) -> U) -> U {
f(cast::transmute(Slice {
data: p as *T,
len: len
}))
}
/** /**
* Unchecked vector indexing. * Unchecked vector indexing.
*/ */
......
...@@ -13,33 +13,33 @@ ...@@ -13,33 +13,33 @@
// debugger:rbreak zzz // debugger:rbreak zzz
// debugger:run // debugger:run
// debugger:finish // debugger:finish
// debugger:print empty.size_in_bytes // debugger:print empty.length
// check:$1 = 0 // check:$1 = 0
// debugger:print singleton.size_in_bytes // debugger:print singleton.length
// check:$2 = 8 // check:$2 = 1
// debugger:print *((int64_t[1]*)(singleton.data_ptr)) // debugger:print *((int64_t[1]*)(singleton.data_ptr))
// check:$3 = {1} // check:$3 = {1}
// debugger:print multiple.size_in_bytes // debugger:print multiple.length
// check:$4 = 32 // check:$4 = 4
// debugger:print *((int64_t[4]*)(multiple.data_ptr)) // debugger:print *((int64_t[4]*)(multiple.data_ptr))
// check:$5 = {2, 3, 4, 5} // check:$5 = {2, 3, 4, 5}
// debugger:print slice_of_slice.size_in_bytes // debugger:print slice_of_slice.length
// check:$6 = 16 // check:$6 = 2
// debugger:print *((int64_t[2]*)(slice_of_slice.data_ptr)) // debugger:print *((int64_t[2]*)(slice_of_slice.data_ptr))
// check:$7 = {3, 4} // check:$7 = {3, 4}
// debugger:print padded_tuple.size_in_bytes // debugger:print padded_tuple.length
// check:$8 = 16 // check:$8 = 2
// debugger:print padded_tuple.data_ptr[0] // debugger:print padded_tuple.data_ptr[0]
// check:$9 = {6, 7} // check:$9 = {6, 7}
// debugger:print padded_tuple.data_ptr[1] // debugger:print padded_tuple.data_ptr[1]
// check:$10 = {8, 9} // check:$10 = {8, 9}
// debugger:print padded_struct.size_in_bytes // debugger:print padded_struct.length
// check:$11 = 24 // check:$11 = 2
// debugger:print padded_struct.data_ptr[0] // debugger:print padded_struct.data_ptr[0]
// check:$12 = {x = 10, y = 11, z = 12} // check:$12 = {x = 10, y = 11, z = 12}
// debugger:print padded_struct.data_ptr[1] // debugger:print padded_struct.data_ptr[1]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册