Implement Box rvalue
This commit is contained in:
parent
e407f39ba8
commit
8adc744645
5 changed files with 47 additions and 15 deletions
|
@ -40,7 +40,6 @@ $ ./build.sh
|
|||
* Unsized types
|
||||
* Slice indexing
|
||||
* Sub slice
|
||||
* Some rvalue's
|
||||
|
||||
* Inline assembly
|
||||
* Custom sections
|
||||
|
|
|
@ -45,6 +45,7 @@ unsafe impl Sync for i32 {}
|
|||
unsafe impl Sync for isize {}
|
||||
unsafe impl Sync for char {}
|
||||
unsafe impl<'a, T: ?Sized> Sync for &'a T {}
|
||||
unsafe impl Sync for [u8; 16] {}
|
||||
|
||||
#[lang = "freeze"]
|
||||
trait Freeze {}
|
||||
|
@ -186,6 +187,16 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
|||
drop_in_place(to_drop);
|
||||
}
|
||||
|
||||
#[lang = "owned_box"]
|
||||
pub struct Box<T>(*mut T);
|
||||
|
||||
static mut MY_TINY_HEAP: [u8; 16] = [0; 16];
|
||||
|
||||
#[lang = "exchange_malloc"]
|
||||
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
|
||||
&mut MY_TINY_HEAP as *mut [u8; 16] as *mut u8
|
||||
}
|
||||
|
||||
pub mod intrinsics {
|
||||
extern "rust-intrinsic" {
|
||||
pub fn abort() -> !;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
|
||||
|
||||
#![feature(no_core, unboxed_closures, start, lang_items)]
|
||||
#![feature(no_core, unboxed_closures, start, lang_items, box_syntax)]
|
||||
#![no_core]
|
||||
#![allow(dead_code)]
|
||||
|
||||
|
@ -43,9 +43,11 @@ static NUM_REF: &'static u8 = unsafe { &NUM };
|
|||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let slice: &[u8] = b"Hello!\0" as &[u8; 7];
|
||||
let slice: &[u8] = b"Hello\0" as &[u8; 6];
|
||||
let ptr: *const u8 = slice as *const [u8] as *const u8;
|
||||
let world = box "World!\0";
|
||||
puts(ptr);
|
||||
puts(*world as *const str as *const u8);
|
||||
}
|
||||
|
||||
//panic(&("panic msg", "abc.rs", 0, 43));
|
||||
|
|
23
src/base.rs
23
src/base.rs
|
@ -488,7 +488,28 @@ fn trans_stmt<'a, 'tcx: 'a>(
|
|||
let usize_layout = fx.layout_of(fx.tcx.types.usize);
|
||||
lval.write_cvalue(fx, CValue::ByVal(size, usize_layout));
|
||||
}
|
||||
Rvalue::NullaryOp(NullOp::Box, ty) => unimplemented!("rval box {:?}", ty),
|
||||
Rvalue::NullaryOp(NullOp::Box, content_ty) => {
|
||||
use rustc::middle::lang_items::ExchangeMallocFnLangItem;
|
||||
|
||||
let usize_type = fx.cton_type(fx.tcx.types.usize).unwrap();
|
||||
let (size, align) = fx.layout_of(content_ty).size_and_align();
|
||||
let llsize = fx.bcx.ins().iconst(usize_type, size.bytes() as i64);
|
||||
let llalign = fx.bcx.ins().iconst(usize_type, align.abi() as i64);
|
||||
let box_layout = fx.layout_of(fx.tcx.mk_box(content_ty));
|
||||
|
||||
// Allocate space:
|
||||
let def_id = match fx.tcx.lang_items().require(ExchangeMallocFnLangItem) {
|
||||
Ok(id) => id,
|
||||
Err(s) => {
|
||||
fx.tcx.sess.fatal(&format!("allocation of `{}` {}", box_layout.ty, s));
|
||||
}
|
||||
};
|
||||
let instance = ty::Instance::mono(fx.tcx, def_id);
|
||||
let func_ref = fx.get_function_ref(instance);
|
||||
let call = fx.bcx.ins().call(func_ref, &[llsize, llalign]);
|
||||
let ptr = fx.bcx.inst_results(call)[0];
|
||||
lval.write_cvalue(fx, CValue::ByVal(ptr, box_layout));
|
||||
},
|
||||
Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
|
||||
assert!(
|
||||
lval.layout()
|
||||
|
|
|
@ -29,14 +29,6 @@ fn scalar_to_cton_type(tcx: TyCtxt, scalar: &Scalar) -> Type {
|
|||
}
|
||||
}
|
||||
|
||||
fn ptr_referee<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match ty.sty {
|
||||
ty::Ref(_, ty, _) => ty,
|
||||
ty::RawPtr(TypeAndMut { ty, mutbl: _ }) => ty,
|
||||
_ => bug!("{:?}", ty),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cton_type_from_ty<'a, 'tcx: 'a>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
|
@ -153,7 +145,14 @@ impl<'tcx> CValue<'tcx> {
|
|||
CValue::ByRef(addr, layout) => {
|
||||
let cton_ty = fx
|
||||
.cton_type(layout.ty)
|
||||
.expect(&format!("load_value of type {:?}", layout.ty));
|
||||
.unwrap_or_else(|| {
|
||||
if layout.ty.is_box() && !fx.layout_of(layout.ty.builtin_deref(true).unwrap().ty).is_unsized() {
|
||||
// Consider sized box to be a ptr
|
||||
pointer_ty(fx.tcx)
|
||||
} else {
|
||||
panic!("load_value of type {:?}", layout.ty);
|
||||
}
|
||||
});
|
||||
fx.bcx.ins().load(cton_ty, MemFlags::new(), addr, 0)
|
||||
}
|
||||
CValue::ByVal(value, _layout) => value,
|
||||
|
@ -223,7 +222,7 @@ impl<'tcx> CValue<'tcx> {
|
|||
}
|
||||
match &self.layout().ty.sty {
|
||||
ty::Ref(_, ty, _) | ty::RawPtr(TypeAndMut { ty, mutbl: _ }) => {
|
||||
let (ptr, extra) = match ptr_referee(dest.layout().ty).sty {
|
||||
let (ptr, extra) = match dest.layout().ty.builtin_deref(true).unwrap().ty.sty {
|
||||
ty::Slice(slice_elem_ty) => match ty.sty {
|
||||
ty::Array(array_elem_ty, size) => {
|
||||
assert_eq!(slice_elem_ty, array_elem_ty);
|
||||
|
@ -453,7 +452,7 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
|
|||
}
|
||||
|
||||
pub fn place_deref(self, fx: &mut FunctionCx<'a, 'tcx, impl Backend>) -> CPlace<'tcx> {
|
||||
let inner_layout = fx.layout_of(ptr_referee(self.layout().ty));
|
||||
let inner_layout = fx.layout_of(self.layout().ty.builtin_deref(true).unwrap().ty);
|
||||
if !inner_layout.is_unsized() {
|
||||
CPlace::Addr(self.to_cvalue(fx).load_value(fx), None, inner_layout)
|
||||
} else {
|
||||
|
|
Loading…
Add table
Reference in a new issue