Run rustfmt 0.9.0-nightly (69ad879
2018-07-27)
This commit is contained in:
parent
82dbd07806
commit
f001808249
7 changed files with 603 additions and 318 deletions
|
@ -62,16 +62,8 @@ fn cmp_raw_ptr(a: *const u8, b: *const u8) -> bool {
|
|||
|
||||
fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u32) {
|
||||
(
|
||||
a as u8,
|
||||
a as u16,
|
||||
a as u32,
|
||||
a as usize,
|
||||
a as i8,
|
||||
a as i16,
|
||||
a as i32,
|
||||
a as isize,
|
||||
b as u8,
|
||||
b as u32
|
||||
a as u8, a as u16, a as u32, a as usize, a as i8, a as i16, a as i32, a as isize, b as u8,
|
||||
b as u32,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -86,9 +78,7 @@ fn debug_tuple() -> DebugTuple {
|
|||
}
|
||||
|
||||
fn size_of<T>() -> usize {
|
||||
unsafe {
|
||||
intrinsics::size_of::<T>()
|
||||
}
|
||||
unsafe { intrinsics::size_of::<T>() }
|
||||
}
|
||||
|
||||
fn use_size_of() -> usize {
|
||||
|
@ -111,31 +101,27 @@ fn use_const() -> u8 {
|
|||
}
|
||||
|
||||
fn call_closure_3arg() {
|
||||
(|_, _, _| {
|
||||
|
||||
})(0u8, 42u16, 0u8)
|
||||
(|_, _, _| {})(0u8, 42u16, 0u8)
|
||||
}
|
||||
|
||||
fn call_closure_2arg() {
|
||||
(|_, _| {
|
||||
|
||||
})(0u8, 42u16)
|
||||
(|_, _| {})(0u8, 42u16)
|
||||
}
|
||||
|
||||
struct IsNotEmpty;
|
||||
|
||||
impl<'a, 'b> FnOnce<(&'a &'b [u16], )> for IsNotEmpty {
|
||||
impl<'a, 'b> FnOnce<(&'a &'b [u16],)> for IsNotEmpty {
|
||||
type Output = bool;
|
||||
|
||||
#[inline]
|
||||
extern "rust-call" fn call_once(mut self, arg: (&'a &'b [u16], )) -> bool {
|
||||
extern "rust-call" fn call_once(mut self, arg: (&'a &'b [u16],)) -> bool {
|
||||
self.call_mut(arg)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> FnMut<(&'a &'b [u16], )> for IsNotEmpty {
|
||||
impl<'a, 'b> FnMut<(&'a &'b [u16],)> for IsNotEmpty {
|
||||
#[inline]
|
||||
extern "rust-call" fn call_mut(&mut self, arg: (&'a &'b [u16], )) -> bool {
|
||||
extern "rust-call" fn call_mut(&mut self, arg: (&'a &'b [u16],)) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#![no_core]
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[lang="sized"]
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "unsize"]
|
||||
|
@ -11,9 +11,9 @@ pub trait Unsize<T: ?Sized> {}
|
|||
#[lang = "coerce_unsized"]
|
||||
pub trait CoerceUnsized<T> {}
|
||||
|
||||
impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
|
||||
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
|
||||
|
||||
#[lang="copy"]
|
||||
#[lang = "copy"]
|
||||
pub unsafe trait Copy {}
|
||||
|
||||
unsafe impl Copy for bool {}
|
||||
|
@ -30,10 +30,10 @@ unsafe impl Copy for char {}
|
|||
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
|
||||
unsafe impl<T: ?Sized> Copy for *const T {}
|
||||
|
||||
#[lang="freeze"]
|
||||
#[lang = "freeze"]
|
||||
trait Freeze {}
|
||||
|
||||
#[lang="mul"]
|
||||
#[lang = "mul"]
|
||||
pub trait Mul<RHS = Self> {
|
||||
type Output;
|
||||
|
||||
|
@ -49,7 +49,7 @@ impl Mul for u8 {
|
|||
}
|
||||
}
|
||||
|
||||
#[lang="bitor"]
|
||||
#[lang = "bitor"]
|
||||
pub trait BitOr<RHS = Self> {
|
||||
type Output;
|
||||
|
||||
|
@ -80,18 +80,30 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
|
|||
}
|
||||
|
||||
impl PartialEq for u8 {
|
||||
fn eq(&self, other: &u8) -> bool { (*self) == (*other) }
|
||||
fn ne(&self, other: &u8) -> bool { (*self) != (*other) }
|
||||
fn eq(&self, other: &u8) -> bool {
|
||||
(*self) == (*other)
|
||||
}
|
||||
fn ne(&self, other: &u8) -> bool {
|
||||
(*self) != (*other)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for char {
|
||||
fn eq(&self, other: &char) -> bool { (*self) == (*other) }
|
||||
fn ne(&self, other: &char) -> bool { (*self) != (*other) }
|
||||
fn eq(&self, other: &char) -> bool {
|
||||
(*self) == (*other)
|
||||
}
|
||||
fn ne(&self, other: &char) -> bool {
|
||||
(*self) != (*other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> PartialEq for *const T {
|
||||
fn eq(&self, other: &*const T) -> bool { *self == *other }
|
||||
fn ne(&self, other: &*const T) -> bool { *self != *other }
|
||||
fn eq(&self, other: &*const T) -> bool {
|
||||
*self == *other
|
||||
}
|
||||
fn ne(&self, other: &*const T) -> bool {
|
||||
*self != *other
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "fn_once"]
|
||||
|
@ -104,11 +116,11 @@ pub trait FnOnce<Args> {
|
|||
|
||||
#[lang = "fn_mut"]
|
||||
#[rustc_paren_sugar]
|
||||
pub trait FnMut<Args> : FnOnce<Args> {
|
||||
pub trait FnMut<Args>: FnOnce<Args> {
|
||||
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
|
||||
}
|
||||
|
||||
#[lang="panic"]
|
||||
#[lang = "panic"]
|
||||
pub fn panic(_expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
|
132
src/abi.rs
132
src/abi.rs
|
@ -5,14 +5,22 @@ use rustc_target::spec::abi::Abi;
|
|||
|
||||
use crate::prelude::*;
|
||||
|
||||
pub fn cton_sig_from_fn_ty<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn_ty: Ty<'tcx>) -> Signature {
|
||||
pub fn cton_sig_from_fn_ty<'a, 'tcx: 'a>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn_ty: Ty<'tcx>,
|
||||
) -> Signature {
|
||||
let sig = ty_fn_sig(tcx, fn_ty);
|
||||
assert!(!sig.variadic, "Variadic function are not yet supported");
|
||||
let (call_conv, inputs, _output): (CallConv, Vec<Ty>, Ty) = match sig.abi {
|
||||
Abi::Rust => (CallConv::Fast, sig.inputs().to_vec(), sig.output()),
|
||||
Abi::C => (CallConv::SystemV, sig.inputs().to_vec(), sig.output()),
|
||||
Abi::RustCall => {
|
||||
println!("rust-call sig: {:?} inputs: {:?} output: {:?}", sig, sig.inputs(), sig.output());
|
||||
println!(
|
||||
"rust-call sig: {:?} inputs: {:?} output: {:?}",
|
||||
sig,
|
||||
sig.inputs(),
|
||||
sig.output()
|
||||
);
|
||||
assert_eq!(sig.inputs().len(), 2);
|
||||
let extra_args = match sig.inputs().last().unwrap().sty {
|
||||
ty::TyTuple(ref tupled_arguments) => tupled_arguments,
|
||||
|
@ -20,11 +28,7 @@ pub fn cton_sig_from_fn_ty<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn_ty: Ty<
|
|||
};
|
||||
let mut inputs: Vec<Ty> = vec![sig.inputs()[0]];
|
||||
inputs.extend(extra_args.into_iter());
|
||||
(
|
||||
CallConv::Fast,
|
||||
inputs,
|
||||
sig.output(),
|
||||
)
|
||||
(CallConv::Fast, inputs, sig.output())
|
||||
}
|
||||
Abi::System => bug!("system abi should be selected elsewhere"),
|
||||
Abi::RustIntrinsic => (CallConv::SystemV, sig.inputs().to_vec(), sig.output()),
|
||||
|
@ -50,10 +54,7 @@ pub fn cton_sig_from_fn_ty<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn_ty: Ty<
|
|||
}
|
||||
}
|
||||
|
||||
fn ty_fn_sig<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
ty: Ty<'tcx>
|
||||
) -> ty::FnSig<'tcx> {
|
||||
fn ty_fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> ty::FnSig<'tcx> {
|
||||
let sig = match ty.sty {
|
||||
ty::TyFnDef(..) |
|
||||
// Shims currently have type TyFnPtr. Not sure this should remain.
|
||||
|
@ -104,11 +105,16 @@ impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
|
|||
assert!(!inst.substs.needs_infer() && !inst.substs.has_param_types());
|
||||
let fn_ty = inst.ty(self.tcx);
|
||||
let sig = cton_sig_from_fn_ty(self.tcx, fn_ty);
|
||||
let def_path_based_names = ::rustc_mir::monomorphize::item::DefPathBasedNames::new(self.tcx, false, false);
|
||||
let def_path_based_names =
|
||||
::rustc_mir::monomorphize::item::DefPathBasedNames::new(self.tcx, false, false);
|
||||
let mut name = String::new();
|
||||
def_path_based_names.push_instance_as_string(inst, &mut name);
|
||||
let func_id = self.module.declare_function(&name, Linkage::Import, &sig).unwrap();
|
||||
self.module.declare_func_in_func(func_id, &mut self.bcx.func)
|
||||
let func_id = self
|
||||
.module
|
||||
.declare_function(&name, Linkage::Import, &sig)
|
||||
.unwrap();
|
||||
self.module
|
||||
.declare_func_in_func(func_id, &mut self.bcx.func)
|
||||
}
|
||||
|
||||
fn lib_call(
|
||||
|
@ -124,8 +130,13 @@ impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
|
|||
call_conv: CallConv::SystemV,
|
||||
argument_bytes: None,
|
||||
};
|
||||
let func_id = self.module.declare_function(&name, Linkage::Import, &sig).unwrap();
|
||||
let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func);
|
||||
let func_id = self
|
||||
.module
|
||||
.declare_function(&name, Linkage::Import, &sig)
|
||||
.unwrap();
|
||||
let func_ref = self
|
||||
.module
|
||||
.declare_func_in_func(func_id, &mut self.bcx.func);
|
||||
let call_inst = self.bcx.ins().call(func_ref, args);
|
||||
if output_ty.is_none() {
|
||||
return None;
|
||||
|
@ -135,8 +146,20 @@ impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
|
|||
Some(results[0])
|
||||
}
|
||||
|
||||
pub fn easy_call(&mut self, name: &str, args: &[CValue<'tcx>], return_ty: Ty<'tcx>) -> CValue<'tcx> {
|
||||
let (input_tys, args): (Vec<_>, Vec<_>) = args.into_iter().map(|arg| (self.cton_type(arg.layout().ty).unwrap(), arg.load_value(self))).unzip();
|
||||
pub fn easy_call(
|
||||
&mut self,
|
||||
name: &str,
|
||||
args: &[CValue<'tcx>],
|
||||
return_ty: Ty<'tcx>,
|
||||
) -> CValue<'tcx> {
|
||||
let (input_tys, args): (Vec<_>, Vec<_>) = args
|
||||
.into_iter()
|
||||
.map(|arg| {
|
||||
(
|
||||
self.cton_type(arg.layout().ty).unwrap(),
|
||||
arg.load_value(self),
|
||||
)
|
||||
}).unzip();
|
||||
let return_layout = self.layout_of(return_ty);
|
||||
let return_ty = if let TypeVariants::TyTuple(tup) = return_ty.sty {
|
||||
if !tup.is_empty() {
|
||||
|
@ -209,7 +232,8 @@ pub fn codegen_fn_prelude<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, start_ebb
|
|||
}).collect::<Vec<(Local, ArgKind, Ty)>>();
|
||||
|
||||
let ret_layout = fx.layout_of(fx.return_type());
|
||||
fx.local_map.insert(RETURN_PLACE, CPlace::Addr(ret_param, ret_layout));
|
||||
fx.local_map
|
||||
.insert(RETURN_PLACE, CPlace::Addr(ret_param, ret_layout));
|
||||
|
||||
for (local, arg_kind, ty) in func_params {
|
||||
let layout = fx.layout_of(ty);
|
||||
|
@ -284,17 +308,18 @@ pub fn codegen_call<'a, 'tcx: 'a>(
|
|||
for (i, _) in tupled_arguments.iter().enumerate() {
|
||||
args.push(pack_arg.value_field(fx, mir::Field::new(i)));
|
||||
}
|
||||
},
|
||||
}
|
||||
_ => bug!("argument to function with \"rust-call\" ABI is not a tuple"),
|
||||
}
|
||||
println!("{:?} {:?}", pack_arg.layout().ty, args.iter().map(|a|a.layout().ty).collect::<Vec<_>>());
|
||||
println!(
|
||||
"{:?} {:?}",
|
||||
pack_arg.layout().ty,
|
||||
args.iter().map(|a| a.layout().ty).collect::<Vec<_>>()
|
||||
);
|
||||
args
|
||||
} else {
|
||||
args
|
||||
.into_iter()
|
||||
.map(|arg| {
|
||||
trans_operand(fx, arg)
|
||||
})
|
||||
args.into_iter()
|
||||
.map(|arg| trans_operand(fx, arg))
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
|
@ -326,7 +351,11 @@ pub fn codegen_call<'a, 'tcx: 'a>(
|
|||
let dst = args[1];
|
||||
let count = args[2].load_value(fx);
|
||||
let byte_amount = fx.bcx.ins().imul(count, elem_size);
|
||||
fx.easy_call("memmove", &[dst, src, CValue::ByVal(byte_amount, usize_layout)], nil_ty);
|
||||
fx.easy_call(
|
||||
"memmove",
|
||||
&[dst, src, CValue::ByVal(byte_amount, usize_layout)],
|
||||
nil_ty,
|
||||
);
|
||||
unimplemented!("copy");
|
||||
}
|
||||
"discriminant_value" => {
|
||||
|
@ -362,12 +391,24 @@ pub fn codegen_call<'a, 'tcx: 'a>(
|
|||
_ => unimplemented!("intrinsic {}", intrinsic),
|
||||
};
|
||||
let res = match ret.layout().ty.sty {
|
||||
TypeVariants::TyUint(_) => {
|
||||
crate::base::trans_int_binop(fx, bin_op, args[0], args[1], ret.layout().ty, false, false)
|
||||
}
|
||||
TypeVariants::TyInt(_) => {
|
||||
crate::base::trans_int_binop(fx, bin_op, args[0], args[1], ret.layout().ty, true, false)
|
||||
}
|
||||
TypeVariants::TyUint(_) => crate::base::trans_int_binop(
|
||||
fx,
|
||||
bin_op,
|
||||
args[0],
|
||||
args[1],
|
||||
ret.layout().ty,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
TypeVariants::TyInt(_) => crate::base::trans_int_binop(
|
||||
fx,
|
||||
bin_op,
|
||||
args[0],
|
||||
args[1],
|
||||
ret.layout().ty,
|
||||
true,
|
||||
false,
|
||||
),
|
||||
_ => panic!(),
|
||||
};
|
||||
ret.write_cvalue(fx, res);
|
||||
|
@ -402,7 +443,10 @@ pub fn codegen_call<'a, 'tcx: 'a>(
|
|||
let uninit_val = uninit_place.to_cvalue(fx);
|
||||
ret.write_cvalue(fx, uninit_val);
|
||||
}
|
||||
_ => fx.tcx.sess.fatal(&format!("unsupported intrinsic {}", intrinsic)),
|
||||
_ => fx
|
||||
.tcx
|
||||
.sess
|
||||
.fatal(&format!("unsupported intrinsic {}", intrinsic)),
|
||||
}
|
||||
if let Some((_, dest)) = *destination {
|
||||
let ret_ebb = fx.get_ebb(dest);
|
||||
|
@ -419,13 +463,15 @@ pub fn codegen_call<'a, 'tcx: 'a>(
|
|||
None => fx.bcx.ins().iconst(types::I64, 0),
|
||||
};
|
||||
|
||||
let call_args = Some(return_ptr).into_iter().chain(args.into_iter().map(|arg| {
|
||||
if fx.cton_type(arg.layout().ty).is_some() {
|
||||
arg.load_value(fx)
|
||||
} else {
|
||||
arg.force_stack(fx)
|
||||
}
|
||||
})).collect::<Vec<_>>();
|
||||
let call_args = Some(return_ptr)
|
||||
.into_iter()
|
||||
.chain(args.into_iter().map(|arg| {
|
||||
if fx.cton_type(arg.layout().ty).is_some() {
|
||||
arg.load_value(fx)
|
||||
} else {
|
||||
arg.force_stack(fx)
|
||||
}
|
||||
})).collect::<Vec<_>>();
|
||||
|
||||
match func {
|
||||
CValue::Func(func, _) => {
|
||||
|
@ -434,7 +480,9 @@ pub fn codegen_call<'a, 'tcx: 'a>(
|
|||
func => {
|
||||
let func_ty = func.layout().ty;
|
||||
let func = func.load_value(fx);
|
||||
let sig = fx.bcx.import_signature(cton_sig_from_fn_ty(fx.tcx, func_ty));
|
||||
let sig = fx
|
||||
.bcx
|
||||
.import_signature(cton_sig_from_fn_ty(fx.tcx, func_ty));
|
||||
fx.bcx.ins().call_indirect(sig, func, &call_args);
|
||||
}
|
||||
}
|
||||
|
|
312
src/base.rs
312
src/base.rs
|
@ -1,6 +1,10 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub fn trans_mono_item<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, context: &mut Context, mono_item: MonoItem<'tcx>) {
|
||||
pub fn trans_mono_item<'a, 'tcx: 'a>(
|
||||
cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>,
|
||||
context: &mut Context,
|
||||
mono_item: MonoItem<'tcx>,
|
||||
) {
|
||||
let tcx = cx.tcx;
|
||||
|
||||
match mono_item {
|
||||
|
@ -11,7 +15,11 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend
|
|||
} => {
|
||||
let mut mir = ::std::io::Cursor::new(Vec::new());
|
||||
::rustc_mir::util::write_mir_pretty(tcx, Some(def_id), &mut mir).unwrap();
|
||||
tcx.sess.warn(&format!("{:?}:\n\n{}", inst, String::from_utf8_lossy(&mir.into_inner())));
|
||||
tcx.sess.warn(&format!(
|
||||
"{:?}:\n\n{}",
|
||||
inst,
|
||||
String::from_utf8_lossy(&mir.into_inner())
|
||||
));
|
||||
|
||||
let fn_ty = inst.ty(tcx);
|
||||
let fn_ty = tcx.subst_and_normalize_erasing_regions(
|
||||
|
@ -23,15 +31,23 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend
|
|||
|
||||
let func_id = {
|
||||
// WARNING: keep in sync with FunctionCx::get_function_ref
|
||||
let def_path_based_names = ::rustc_mir::monomorphize::item::DefPathBasedNames::new(cx.tcx, false, false);
|
||||
let def_path_based_names =
|
||||
::rustc_mir::monomorphize::item::DefPathBasedNames::new(
|
||||
cx.tcx, false, false,
|
||||
);
|
||||
let mut name = String::new();
|
||||
def_path_based_names.push_instance_as_string(inst, &mut name);
|
||||
cx.module.declare_function(&name, Linkage::Export, &sig).unwrap()
|
||||
cx.module
|
||||
.declare_function(&name, Linkage::Export, &sig)
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let mut f = Function::with_name_signature(ExternalName::user(0, func_id.index() as u32), sig);
|
||||
let mut f = Function::with_name_signature(
|
||||
ExternalName::user(0, func_id.index() as u32),
|
||||
sig,
|
||||
);
|
||||
|
||||
let comments = match trans_fn(cx, &mut f, inst){
|
||||
let comments = match trans_fn(cx, &mut f, inst) {
|
||||
Ok(comments) => comments,
|
||||
Err(err) => {
|
||||
tcx.sess.err(&err);
|
||||
|
@ -41,7 +57,8 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend
|
|||
|
||||
let mut writer = crate::pretty_clif::CommentWriter(comments);
|
||||
let mut cton = String::new();
|
||||
::cranelift::codegen::write::decorate_function(&mut writer, &mut cton, &f, None).unwrap();
|
||||
::cranelift::codegen::write::decorate_function(&mut writer, &mut cton, &f, None)
|
||||
.unwrap();
|
||||
tcx.sess.warn(&cton);
|
||||
|
||||
let flags = settings::Flags::new(settings::builder());
|
||||
|
@ -49,8 +66,15 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend
|
|||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
tcx.sess.err(&format!("{:?}", err));
|
||||
let pretty_error = ::cranelift::codegen::print_errors::pretty_verifier_error(&f, None, Some(Box::new(writer)), &err);
|
||||
tcx.sess.fatal(&format!("cretonne verify error:\n{}", pretty_error));
|
||||
let pretty_error =
|
||||
::cranelift::codegen::print_errors::pretty_verifier_error(
|
||||
&f,
|
||||
None,
|
||||
Some(Box::new(writer)),
|
||||
&err,
|
||||
);
|
||||
tcx.sess
|
||||
.fatal(&format!("cretonne verify error:\n{}", pretty_error));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,14 +84,27 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend
|
|||
|
||||
context.clear();
|
||||
}
|
||||
inst => cx.tcx.sess.warn(&format!("Unimplemented instance {:?}", inst)),
|
||||
}
|
||||
MonoItem::Static(def_id) => cx.tcx.sess.err(&format!("Unimplemented static mono item {:?}", def_id)),
|
||||
MonoItem::GlobalAsm(node_id) => cx.tcx.sess.err(&format!("Unimplemented global asm mono item {:?}", node_id)),
|
||||
inst => cx
|
||||
.tcx
|
||||
.sess
|
||||
.warn(&format!("Unimplemented instance {:?}", inst)),
|
||||
},
|
||||
MonoItem::Static(def_id) => cx
|
||||
.tcx
|
||||
.sess
|
||||
.err(&format!("Unimplemented static mono item {:?}", def_id)),
|
||||
MonoItem::GlobalAsm(node_id) => cx
|
||||
.tcx
|
||||
.sess
|
||||
.err(&format!("Unimplemented global asm mono item {:?}", node_id)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &mut Function, instance: Instance<'tcx>) -> Result<HashMap<Inst, String>, String> {
|
||||
pub fn trans_fn<'a, 'tcx: 'a>(
|
||||
cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>,
|
||||
f: &mut Function,
|
||||
instance: Instance<'tcx>,
|
||||
) -> Result<HashMap<Inst, String>, String> {
|
||||
let mir = cx.tcx.optimized_mir(instance.def_id());
|
||||
let mut func_ctx = FunctionBuilderContext::new();
|
||||
let mut bcx: FunctionBuilder<Variable> = FunctionBuilder::new(f, &mut func_ctx);
|
||||
|
@ -98,7 +135,9 @@ pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &
|
|||
|
||||
crate::abi::codegen_fn_prelude(fx, start_ebb);
|
||||
|
||||
fx.bcx.ins().jump(*fx.ebb_map.get(&START_BLOCK).unwrap(), &[]);
|
||||
fx.bcx
|
||||
.ins()
|
||||
.jump(*fx.ebb_map.get(&START_BLOCK).unwrap(), &[]);
|
||||
|
||||
for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
|
||||
let ebb = fx.get_ebb(bb);
|
||||
|
@ -110,7 +149,11 @@ pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &
|
|||
}
|
||||
|
||||
let mut terminator_head = "\n".to_string();
|
||||
bb_data.terminator().kind.fmt_head(&mut terminator_head).unwrap();
|
||||
bb_data
|
||||
.terminator()
|
||||
.kind
|
||||
.fmt_head(&mut terminator_head)
|
||||
.unwrap();
|
||||
let inst = fx.bcx.func.layout.last_inst(ebb).unwrap();
|
||||
fx.add_comment(inst, terminator_head);
|
||||
|
||||
|
@ -122,7 +165,13 @@ pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &
|
|||
TerminatorKind::Return => {
|
||||
fx.bcx.ins().return_(&[]);
|
||||
}
|
||||
TerminatorKind::Assert { cond, expected, msg: _, target, cleanup: _ } => {
|
||||
TerminatorKind::Assert {
|
||||
cond,
|
||||
expected,
|
||||
msg: _,
|
||||
target,
|
||||
cleanup: _,
|
||||
} => {
|
||||
let cond = trans_operand(fx, cond).load_value(fx);
|
||||
let target = fx.get_ebb(*target);
|
||||
if *expected {
|
||||
|
@ -133,7 +182,12 @@ pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &
|
|||
fx.bcx.ins().trap(TrapCode::User(!0));
|
||||
}
|
||||
|
||||
TerminatorKind::SwitchInt { discr, switch_ty: _, values, targets } => {
|
||||
TerminatorKind::SwitchInt {
|
||||
discr,
|
||||
switch_ty: _,
|
||||
values,
|
||||
targets,
|
||||
} => {
|
||||
let discr = trans_operand(fx, discr).load_value(fx);
|
||||
let mut jt_data = JumpTableData::new();
|
||||
for (i, value) in values.iter().enumerate() {
|
||||
|
@ -145,15 +199,20 @@ pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &
|
|||
let otherwise_ebb = fx.get_ebb(targets[targets.len() - 1]);
|
||||
fx.bcx.ins().jump(otherwise_ebb, &[]);
|
||||
}
|
||||
TerminatorKind::Call { func, args, destination, cleanup: _ } => {
|
||||
TerminatorKind::Call {
|
||||
func,
|
||||
args,
|
||||
destination,
|
||||
cleanup: _,
|
||||
} => {
|
||||
crate::abi::codegen_call(fx, func, args, destination);
|
||||
}
|
||||
TerminatorKind::Resume | TerminatorKind::Abort | TerminatorKind::Unreachable => {
|
||||
fx.bcx.ins().trap(TrapCode::User(!0));
|
||||
}
|
||||
TerminatorKind::Yield { .. } |
|
||||
TerminatorKind::FalseEdges { .. } |
|
||||
TerminatorKind::FalseUnwind { .. } => {
|
||||
TerminatorKind::Yield { .. }
|
||||
| TerminatorKind::FalseEdges { .. }
|
||||
| TerminatorKind::FalseUnwind { .. } => {
|
||||
bug!("shouldn't exist at trans {:?}", bb_data.terminator());
|
||||
}
|
||||
TerminatorKind::Drop { target, .. } | TerminatorKind::DropAndReplace { target, .. } => {
|
||||
|
@ -174,14 +233,21 @@ pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &
|
|||
Ok(fx.comments.clone())
|
||||
}
|
||||
|
||||
fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, cur_ebb: Ebb, stmt: &Statement<'tcx>) -> Result<(), String> {
|
||||
fn trans_stmt<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
cur_ebb: Ebb,
|
||||
stmt: &Statement<'tcx>,
|
||||
) -> Result<(), String> {
|
||||
fx.tcx.sess.warn(&format!("stmt {:?}", stmt));
|
||||
|
||||
let inst = fx.bcx.func.layout.last_inst(cur_ebb).unwrap();
|
||||
fx.add_comment(inst, format!("{:?}", stmt));
|
||||
|
||||
match &stmt.kind {
|
||||
StatementKind::SetDiscriminant { place, variant_index } => {
|
||||
StatementKind::SetDiscriminant {
|
||||
place,
|
||||
variant_index,
|
||||
} => {
|
||||
let place = trans_place(fx, place);
|
||||
let layout = place.layout();
|
||||
if layout.for_variant(&*fx, *variant_index).abi == layout::Abi::Uninhabited {
|
||||
|
@ -193,7 +259,10 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, cur_ebb: Ebb, stmt: &
|
|||
}
|
||||
layout::Variants::Tagged { .. } => {
|
||||
let ptr = place.place_field(fx, mir::Field::new(0));
|
||||
let to = layout.ty.ty_adt_def().unwrap()
|
||||
let to = layout
|
||||
.ty
|
||||
.ty_adt_def()
|
||||
.unwrap()
|
||||
.discriminant_for_variant(fx.tcx, *variant_index)
|
||||
.val;
|
||||
let discr = CValue::const_val(fx, ptr.layout().ty, to as u64 as i64);
|
||||
|
@ -288,7 +357,7 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, cur_ebb: Ebb, stmt: &
|
|||
UnOp::Neg => match ty.sty {
|
||||
TypeVariants::TyFloat(_) => fx.bcx.ins().fneg(val),
|
||||
_ => unimplemented!("un op Neg for {:?}", ty),
|
||||
}
|
||||
},
|
||||
};
|
||||
lval.write_cvalue(fx, CValue::ByVal(res, layout));
|
||||
}
|
||||
|
@ -306,50 +375,66 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, cur_ebb: Ebb, stmt: &
|
|||
let operand = trans_operand(fx, operand);
|
||||
let from_ty = operand.layout().ty;
|
||||
match (&from_ty.sty, &to_ty.sty) {
|
||||
(TypeVariants::TyRef(..), TypeVariants::TyRef(..)) |
|
||||
(TypeVariants::TyRef(..), TypeVariants::TyRawPtr(..)) |
|
||||
(TypeVariants::TyRawPtr(..), TypeVariants::TyRef(..)) |
|
||||
(TypeVariants::TyRawPtr(..), TypeVariants::TyRawPtr(..)) => {
|
||||
(TypeVariants::TyRef(..), TypeVariants::TyRef(..))
|
||||
| (TypeVariants::TyRef(..), TypeVariants::TyRawPtr(..))
|
||||
| (TypeVariants::TyRawPtr(..), TypeVariants::TyRef(..))
|
||||
| (TypeVariants::TyRawPtr(..), TypeVariants::TyRawPtr(..)) => {
|
||||
lval.write_cvalue(fx, operand.unchecked_cast_to(dest_layout));
|
||||
}
|
||||
(TypeVariants::TyChar, TypeVariants::TyUint(_)) |
|
||||
(TypeVariants::TyUint(_), TypeVariants::TyInt(_)) |
|
||||
(TypeVariants::TyUint(_), TypeVariants::TyUint(_)) => {
|
||||
(TypeVariants::TyChar, TypeVariants::TyUint(_))
|
||||
| (TypeVariants::TyUint(_), TypeVariants::TyInt(_))
|
||||
| (TypeVariants::TyUint(_), TypeVariants::TyUint(_)) => {
|
||||
let from = operand.load_value(fx);
|
||||
let res = crate::common::cton_intcast(fx, from, from_ty, to_ty, false);
|
||||
lval.write_cvalue(fx, CValue::ByVal(res, dest_layout));
|
||||
}
|
||||
(TypeVariants::TyInt(_), TypeVariants::TyInt(_)) |
|
||||
(TypeVariants::TyInt(_), TypeVariants::TyUint(_)) => {
|
||||
(TypeVariants::TyInt(_), TypeVariants::TyInt(_))
|
||||
| (TypeVariants::TyInt(_), TypeVariants::TyUint(_)) => {
|
||||
let from = operand.load_value(fx);
|
||||
let res = crate::common::cton_intcast(fx, from, from_ty, to_ty, true);
|
||||
lval.write_cvalue(fx, CValue::ByVal(res, dest_layout));
|
||||
}
|
||||
_ => return Err(format!("rval misc {:?} {:?}", operand, to_ty)),
|
||||
}
|
||||
},
|
||||
Rvalue::Cast(CastKind::ClosureFnPointer, operand, ty) => unimplemented!("rval closure_fn_ptr {:?} {:?}", operand, ty),
|
||||
Rvalue::Cast(CastKind::Unsize, operand, ty) => return Err(format!("rval unsize {:?} {:?}", operand, ty)),
|
||||
}
|
||||
Rvalue::Cast(CastKind::ClosureFnPointer, operand, ty) => {
|
||||
unimplemented!("rval closure_fn_ptr {:?} {:?}", operand, ty)
|
||||
}
|
||||
Rvalue::Cast(CastKind::Unsize, operand, ty) => {
|
||||
return Err(format!("rval unsize {:?} {:?}", operand, ty))
|
||||
}
|
||||
Rvalue::Discriminant(place) => {
|
||||
let place = trans_place(fx, place).to_cvalue(fx);
|
||||
let discr = trans_get_discriminant(fx, place, dest_layout);
|
||||
lval.write_cvalue(fx, discr);
|
||||
}
|
||||
Rvalue::Repeat(operand, times) => unimplemented!("rval repeat {:?} {:?}", operand, times),
|
||||
Rvalue::Repeat(operand, times) => {
|
||||
unimplemented!("rval repeat {:?} {:?}", operand, times)
|
||||
}
|
||||
Rvalue::Len(lval) => return Err(format!("rval len {:?}", lval)),
|
||||
Rvalue::NullaryOp(NullOp::Box, ty) => unimplemented!("rval box {:?}", ty),
|
||||
Rvalue::NullaryOp(NullOp::SizeOf, ty) => unimplemented!("rval size_of {:?}", ty),
|
||||
Rvalue::Aggregate(_, _) => bug!("shouldn't exist at trans {:?}", rval),
|
||||
}
|
||||
}
|
||||
StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Nop | StatementKind::ReadForMatch(_) | StatementKind::Validate(_, _) | StatementKind::EndRegion(_) | StatementKind::UserAssertTy(_, _) => {}
|
||||
StatementKind::StorageLive(_)
|
||||
| StatementKind::StorageDead(_)
|
||||
| StatementKind::Nop
|
||||
| StatementKind::ReadForMatch(_)
|
||||
| StatementKind::Validate(_, _)
|
||||
| StatementKind::EndRegion(_)
|
||||
| StatementKind::UserAssertTy(_, _) => {}
|
||||
StatementKind::InlineAsm { .. } => fx.tcx.sess.fatal("Inline assembly is not supported"),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn trans_get_discriminant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, value: CValue<'tcx>, dest_layout: TyLayout<'tcx>) -> CValue<'tcx> {
|
||||
pub fn trans_get_discriminant<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
value: CValue<'tcx>,
|
||||
dest_layout: TyLayout<'tcx>,
|
||||
) -> CValue<'tcx> {
|
||||
let layout = value.layout();
|
||||
|
||||
if layout.abi == layout::Abi::Uninhabited {
|
||||
|
@ -357,13 +442,12 @@ pub fn trans_get_discriminant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, value
|
|||
}
|
||||
match layout.variants {
|
||||
layout::Variants::Single { index } => {
|
||||
let discr_val = layout.ty.ty_adt_def().map_or(
|
||||
index as u128,
|
||||
|def| def.discriminant_for_variant(fx.tcx, index).val);
|
||||
let discr_val = layout.ty.ty_adt_def().map_or(index as u128, |def| {
|
||||
def.discriminant_for_variant(fx.tcx, index).val
|
||||
});
|
||||
return CValue::const_val(fx, dest_layout.ty, discr_val as u64 as i64);
|
||||
}
|
||||
layout::Variants::Tagged { .. } |
|
||||
layout::Variants::NicheFilling { .. } => {},
|
||||
layout::Variants::Tagged { .. } | layout::Variants::NicheFilling { .. } => {}
|
||||
}
|
||||
|
||||
let discr = value.value_field(fx, mir::Field::new(0));
|
||||
|
@ -374,7 +458,7 @@ pub fn trans_get_discriminant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, value
|
|||
layout::Variants::Tagged { ref tag, .. } => {
|
||||
let signed = match tag.value {
|
||||
layout::Int(_, signed) => signed,
|
||||
_ => false
|
||||
_ => false,
|
||||
};
|
||||
let val = cton_intcast(fx, lldiscr, discr_ty, dest_layout.ty, signed);
|
||||
return CValue::ByVal(val, dest_layout);
|
||||
|
@ -388,9 +472,18 @@ pub fn trans_get_discriminant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, value
|
|||
let niche_llty = fx.cton_type(discr_ty).unwrap();
|
||||
if niche_variants.start() == niche_variants.end() {
|
||||
let dest_cton_ty = fx.cton_type(dest_layout.ty).unwrap();
|
||||
let b = fx.bcx.ins().icmp_imm(IntCC::Equal, lldiscr, niche_start as u64 as i64);
|
||||
let if_true = fx.bcx.ins().iconst(dest_cton_ty, *niche_variants.start() as u64 as i64);
|
||||
let if_false = fx.bcx.ins().iconst(dest_cton_ty, dataful_variant as u64 as i64);
|
||||
let b = fx
|
||||
.bcx
|
||||
.ins()
|
||||
.icmp_imm(IntCC::Equal, lldiscr, niche_start as u64 as i64);
|
||||
let if_true = fx
|
||||
.bcx
|
||||
.ins()
|
||||
.iconst(dest_cton_ty, *niche_variants.start() as u64 as i64);
|
||||
let if_false = fx
|
||||
.bcx
|
||||
.ins()
|
||||
.iconst(dest_cton_ty, dataful_variant as u64 as i64);
|
||||
let val = fx.bcx.ins().select(b, if_true, if_false);
|
||||
return CValue::ByVal(val, dest_layout);
|
||||
} else {
|
||||
|
@ -398,9 +491,16 @@ pub fn trans_get_discriminant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, value
|
|||
let delta = niche_start.wrapping_sub(*niche_variants.start() as u128);
|
||||
let delta = fx.bcx.ins().iconst(niche_llty, delta as u64 as i64);
|
||||
let lldiscr = fx.bcx.ins().isub(lldiscr, delta);
|
||||
let b = fx.bcx.ins().icmp_imm(IntCC::UnsignedLessThanOrEqual, lldiscr, *niche_variants.end() as u64 as i64);
|
||||
let b = fx.bcx.ins().icmp_imm(
|
||||
IntCC::UnsignedLessThanOrEqual,
|
||||
lldiscr,
|
||||
*niche_variants.end() as u64 as i64,
|
||||
);
|
||||
let if_true = cton_intcast(fx, lldiscr, discr_ty, dest_layout.ty, false);
|
||||
let if_false = fx.bcx.ins().iconst(niche_llty, dataful_variant as u64 as i64);
|
||||
let if_false = fx
|
||||
.bcx
|
||||
.ins()
|
||||
.iconst(niche_llty, dataful_variant as u64 as i64);
|
||||
let val = fx.bcx.ins().select(b, if_true, if_false);
|
||||
return CValue::ByVal(val, dest_layout);
|
||||
}
|
||||
|
@ -447,7 +547,13 @@ macro_rules! binop_match {
|
|||
}}
|
||||
}
|
||||
|
||||
fn trans_bool_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ty: Ty<'tcx>) -> CValue<'tcx> {
|
||||
fn trans_bool_binop<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
bin_op: BinOp,
|
||||
lhs: CValue<'tcx>,
|
||||
rhs: CValue<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> CValue<'tcx> {
|
||||
let res = binop_match! {
|
||||
fx, bin_op, false, lhs, rhs, ty, "bool";
|
||||
Add (_) bug;
|
||||
|
@ -474,7 +580,15 @@ fn trans_bool_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp,
|
|||
res
|
||||
}
|
||||
|
||||
pub fn trans_int_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ty: Ty<'tcx>, signed: bool, _checked: bool) -> CValue<'tcx> {
|
||||
pub fn trans_int_binop<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
bin_op: BinOp,
|
||||
lhs: CValue<'tcx>,
|
||||
rhs: CValue<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
signed: bool,
|
||||
_checked: bool,
|
||||
) -> CValue<'tcx> {
|
||||
let res = binop_match! {
|
||||
fx, bin_op, signed, lhs, rhs, ty, "int/uint";
|
||||
Add (_) iadd;
|
||||
|
@ -509,7 +623,13 @@ pub fn trans_int_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinO
|
|||
res
|
||||
}
|
||||
|
||||
fn trans_float_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ty: Ty<'tcx>) -> CValue<'tcx> {
|
||||
fn trans_float_binop<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
bin_op: BinOp,
|
||||
lhs: CValue<'tcx>,
|
||||
rhs: CValue<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> CValue<'tcx> {
|
||||
let res = binop_match! {
|
||||
fx, bin_op, false, lhs, rhs, ty, "float";
|
||||
Add (_) fadd;
|
||||
|
@ -544,7 +664,13 @@ fn trans_float_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp,
|
|||
res
|
||||
}
|
||||
|
||||
fn trans_char_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ty: Ty<'tcx>) -> CValue<'tcx> {
|
||||
fn trans_char_binop<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
bin_op: BinOp,
|
||||
lhs: CValue<'tcx>,
|
||||
rhs: CValue<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> CValue<'tcx> {
|
||||
let res = binop_match! {
|
||||
fx, bin_op, false, lhs, rhs, ty, "char";
|
||||
Add (_) bug;
|
||||
|
@ -571,7 +697,14 @@ fn trans_char_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp,
|
|||
res
|
||||
}
|
||||
|
||||
fn trans_ptr_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ty: Ty<'tcx>, _checked: bool) -> CValue<'tcx> {
|
||||
fn trans_ptr_binop<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
bin_op: BinOp,
|
||||
lhs: CValue<'tcx>,
|
||||
rhs: CValue<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
_checked: bool,
|
||||
) -> CValue<'tcx> {
|
||||
binop_match! {
|
||||
fx, bin_op, false, lhs, rhs, ty, "ptr";
|
||||
Add (_) bug;
|
||||
|
@ -596,41 +729,66 @@ fn trans_ptr_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, l
|
|||
}
|
||||
}
|
||||
|
||||
pub fn trans_place<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, place: &Place<'tcx>) -> CPlace<'tcx> {
|
||||
pub fn trans_place<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
place: &Place<'tcx>,
|
||||
) -> CPlace<'tcx> {
|
||||
match place {
|
||||
Place::Local(local) => fx.get_local_place(*local),
|
||||
Place::Promoted(promoted) => crate::constant::trans_promoted(fx, promoted.0),
|
||||
Place::Static(static_) => unimplemented!("static place {:?} ty {:?}", static_.def_id, static_.ty),
|
||||
Place::Static(static_) => {
|
||||
unimplemented!("static place {:?} ty {:?}", static_.def_id, static_.ty)
|
||||
}
|
||||
Place::Projection(projection) => {
|
||||
let base = trans_place(fx, &projection.base);
|
||||
match projection.elem {
|
||||
ProjectionElem::Deref => {
|
||||
CPlace::Addr(base.to_cvalue(fx).load_value(fx), fx.layout_of(place.ty(&*fx.mir, fx.tcx).to_ty(fx.tcx)))
|
||||
}
|
||||
ProjectionElem::Field(field, _ty) => {
|
||||
base.place_field(fx, field)
|
||||
}
|
||||
ProjectionElem::Index(local) => unimplemented!("projection index {:?} {:?}", projection.base, local),
|
||||
ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false } => unimplemented!("projection const index {:?} offset {:?} not from end", projection.base, offset),
|
||||
ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true } => unimplemented!("projection const index {:?} offset {:?} from end", projection.base, offset),
|
||||
ProjectionElem::Subslice { from, to } => unimplemented!("projection subslice {:?} from {} to {}", projection.base, from, to),
|
||||
ProjectionElem::Downcast(_adt_def, variant) => {
|
||||
base.downcast_variant(fx, variant)
|
||||
ProjectionElem::Deref => CPlace::Addr(
|
||||
base.to_cvalue(fx).load_value(fx),
|
||||
fx.layout_of(place.ty(&*fx.mir, fx.tcx).to_ty(fx.tcx)),
|
||||
),
|
||||
ProjectionElem::Field(field, _ty) => base.place_field(fx, field),
|
||||
ProjectionElem::Index(local) => {
|
||||
unimplemented!("projection index {:?} {:?}", projection.base, local)
|
||||
}
|
||||
ProjectionElem::ConstantIndex {
|
||||
offset,
|
||||
min_length: _,
|
||||
from_end: false,
|
||||
} => unimplemented!(
|
||||
"projection const index {:?} offset {:?} not from end",
|
||||
projection.base,
|
||||
offset
|
||||
),
|
||||
ProjectionElem::ConstantIndex {
|
||||
offset,
|
||||
min_length: _,
|
||||
from_end: true,
|
||||
} => unimplemented!(
|
||||
"projection const index {:?} offset {:?} from end",
|
||||
projection.base,
|
||||
offset
|
||||
),
|
||||
ProjectionElem::Subslice { from, to } => unimplemented!(
|
||||
"projection subslice {:?} from {} to {}",
|
||||
projection.base,
|
||||
from,
|
||||
to
|
||||
),
|
||||
ProjectionElem::Downcast(_adt_def, variant) => base.downcast_variant(fx, variant),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trans_operand<'a, 'tcx>(fx: &mut FunctionCx<'a, 'tcx>, operand: &Operand<'tcx>) -> CValue<'tcx> {
|
||||
pub fn trans_operand<'a, 'tcx>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
operand: &Operand<'tcx>,
|
||||
) -> CValue<'tcx> {
|
||||
match operand {
|
||||
Operand::Move(place) |
|
||||
Operand::Copy(place) => {
|
||||
Operand::Move(place) | Operand::Copy(place) => {
|
||||
let cplace = trans_place(fx, place);
|
||||
cplace.to_cvalue(fx)
|
||||
},
|
||||
Operand::Constant(const_) => {
|
||||
crate::constant::trans_constant(fx, const_)
|
||||
}
|
||||
Operand::Constant(const_) => crate::constant::trans_constant(fx, const_),
|
||||
}
|
||||
}
|
||||
|
|
144
src/common.rs
144
src/common.rs
|
@ -2,7 +2,7 @@ use std::fmt;
|
|||
|
||||
use rustc_target::spec::{HasTargetSpec, Target};
|
||||
|
||||
use cranelift_module::{Module, DataId};
|
||||
use cranelift_module::{DataId, Module};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
|
@ -21,36 +21,33 @@ impl EntityRef for Variable {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn cton_type_from_ty<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> Option<types::Type> {
|
||||
pub fn cton_type_from_ty<'a, 'tcx: 'a>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Option<types::Type> {
|
||||
Some(match ty.sty {
|
||||
TypeVariants::TyBool => types::I8,
|
||||
TypeVariants::TyUint(size) => {
|
||||
match size {
|
||||
UintTy::U8 => types::I8,
|
||||
UintTy::U16 => types::I16,
|
||||
UintTy::U32 => types::I32,
|
||||
UintTy::U64 => types::I64,
|
||||
UintTy::U128 => unimplemented!("u128"),
|
||||
UintTy::Usize => types::I64,
|
||||
}
|
||||
}
|
||||
TypeVariants::TyInt(size) => {
|
||||
match size {
|
||||
IntTy::I8 => types::I8,
|
||||
IntTy::I16 => types::I16,
|
||||
IntTy::I32 => types::I32,
|
||||
IntTy::I64 => types::I64,
|
||||
IntTy::I128 => unimplemented!("i128"),
|
||||
IntTy::Isize => types::I64,
|
||||
}
|
||||
}
|
||||
TypeVariants::TyUint(size) => match size {
|
||||
UintTy::U8 => types::I8,
|
||||
UintTy::U16 => types::I16,
|
||||
UintTy::U32 => types::I32,
|
||||
UintTy::U64 => types::I64,
|
||||
UintTy::U128 => unimplemented!("u128"),
|
||||
UintTy::Usize => types::I64,
|
||||
},
|
||||
TypeVariants::TyInt(size) => match size {
|
||||
IntTy::I8 => types::I8,
|
||||
IntTy::I16 => types::I16,
|
||||
IntTy::I32 => types::I32,
|
||||
IntTy::I64 => types::I64,
|
||||
IntTy::I128 => unimplemented!("i128"),
|
||||
IntTy::Isize => types::I64,
|
||||
},
|
||||
TypeVariants::TyChar => types::I32,
|
||||
TypeVariants::TyFloat(size) => {
|
||||
match size {
|
||||
FloatTy::F32 => types::I32,
|
||||
FloatTy::F64 => types::I64,
|
||||
}
|
||||
}
|
||||
TypeVariants::TyFloat(size) => match size {
|
||||
FloatTy::F32 => types::I32,
|
||||
FloatTy::F64 => types::I64,
|
||||
},
|
||||
TypeVariants::TyFnPtr(_) => types::I64,
|
||||
TypeVariants::TyRawPtr(TypeAndMut { ty, mutbl: _ }) | TypeVariants::TyRef(_, ty, _) => {
|
||||
if ty.is_sized(tcx.at(DUMMY_SP), ParamEnv::reveal_all()) {
|
||||
|
@ -59,7 +56,7 @@ pub fn cton_type_from_ty<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>
|
|||
return None;
|
||||
}
|
||||
}
|
||||
TypeVariants::TyParam(_) => bug!("{:?}: {:?}", ty, ty.sty),
|
||||
TypeVariants::TyParam(_) => bug!("{:?}: {:?}", ty, ty.sty),
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
@ -68,7 +65,7 @@ fn codegen_field<'a, 'tcx: 'a>(
|
|||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
base: Value,
|
||||
layout: TyLayout<'tcx>,
|
||||
field: mir::Field
|
||||
field: mir::Field,
|
||||
) -> (Value, TyLayout<'tcx>) {
|
||||
let field_offset = layout.fields.offset(field.index());
|
||||
let field_ty = layout.field(&*fx, field.index());
|
||||
|
@ -91,13 +88,14 @@ pub enum CValue<'tcx> {
|
|||
impl<'tcx> CValue<'tcx> {
|
||||
pub fn layout(&self) -> TyLayout<'tcx> {
|
||||
match *self {
|
||||
CValue::ByRef(_, layout) |
|
||||
CValue::ByVal(_, layout) |
|
||||
CValue::Func(_, layout) => layout
|
||||
CValue::ByRef(_, layout) | CValue::ByVal(_, layout) | CValue::Func(_, layout) => layout,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn force_stack<'a>(self, fx: &mut FunctionCx<'a, 'tcx>) -> Value where 'tcx: 'a {
|
||||
pub fn force_stack<'a>(self, fx: &mut FunctionCx<'a, 'tcx>) -> Value
|
||||
where
|
||||
'tcx: 'a,
|
||||
{
|
||||
match self {
|
||||
CValue::ByRef(value, _layout) => value,
|
||||
CValue::ByVal(value, layout) => {
|
||||
|
@ -116,16 +114,19 @@ impl<'tcx> CValue<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn load_value<'a>(self, fx: &mut FunctionCx<'a, 'tcx>) -> Value where 'tcx: 'a{
|
||||
pub fn load_value<'a>(self, fx: &mut FunctionCx<'a, 'tcx>) -> Value
|
||||
where
|
||||
'tcx: 'a,
|
||||
{
|
||||
match self {
|
||||
CValue::ByRef(addr, layout) => {
|
||||
let cton_ty = fx.cton_type(layout.ty).expect(&format!("load_value of type {:?}", layout.ty));
|
||||
let cton_ty = fx
|
||||
.cton_type(layout.ty)
|
||||
.expect(&format!("load_value of type {:?}", layout.ty));
|
||||
fx.bcx.ins().load(cton_ty, MemFlags::new(), addr, 0)
|
||||
}
|
||||
CValue::ByVal(value, _layout) => value,
|
||||
CValue::Func(func, _layout) => {
|
||||
fx.bcx.ins().func_addr(types::I64, func)
|
||||
}
|
||||
CValue::Func(func, _layout) => fx.bcx.ins().func_addr(types::I64, func),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,7 +138,10 @@ impl<'tcx> CValue<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn value_field<'a>(self, fx: &mut FunctionCx<'a, 'tcx>, field: mir::Field) -> CValue<'tcx> where 'tcx: 'a {
|
||||
pub fn value_field<'a>(self, fx: &mut FunctionCx<'a, 'tcx>, field: mir::Field) -> CValue<'tcx>
|
||||
where
|
||||
'tcx: 'a,
|
||||
{
|
||||
let (base, layout) = match self {
|
||||
CValue::ByRef(addr, layout) => (addr, layout),
|
||||
_ => bug!("place_field for {:?}", self),
|
||||
|
@ -147,7 +151,14 @@ impl<'tcx> CValue<'tcx> {
|
|||
CValue::ByRef(field_ptr, field_layout)
|
||||
}
|
||||
|
||||
pub fn const_val<'a>(fx: &mut FunctionCx<'a, 'tcx>, ty: Ty<'tcx>, const_val: i64) -> CValue<'tcx> where 'tcx: 'a {
|
||||
pub fn const_val<'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
const_val: i64,
|
||||
) -> CValue<'tcx>
|
||||
where
|
||||
'tcx: 'a,
|
||||
{
|
||||
let cton_ty = fx.cton_type(ty).unwrap();
|
||||
let layout = fx.layout_of(ty);
|
||||
CValue::ByVal(fx.bcx.ins().iconst(cton_ty, const_val), layout)
|
||||
|
@ -172,12 +183,15 @@ pub enum CPlace<'tcx> {
|
|||
impl<'a, 'tcx: 'a> CPlace<'tcx> {
|
||||
pub fn layout(&self) -> TyLayout<'tcx> {
|
||||
match *self {
|
||||
CPlace::Var(_, layout) |
|
||||
CPlace::Addr(_, layout) => layout,
|
||||
CPlace::Var(_, layout) | CPlace::Addr(_, layout) => layout,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_stack_slot(fx: &mut FunctionCx<'a, 'tcx>, stack_slot: StackSlot, ty: Ty<'tcx>) -> CPlace<'tcx> {
|
||||
pub fn from_stack_slot(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
stack_slot: StackSlot,
|
||||
ty: Ty<'tcx>,
|
||||
) -> CPlace<'tcx> {
|
||||
let layout = fx.layout_of(ty);
|
||||
CPlace::Addr(fx.bcx.ins().stack_addr(types::I64, stack_slot, 0), layout)
|
||||
}
|
||||
|
@ -198,23 +212,25 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
|
|||
|
||||
pub fn write_cvalue(self, fx: &mut FunctionCx<'a, 'tcx>, from: CValue<'tcx>) {
|
||||
match (&self.layout().ty.sty, &from.layout().ty.sty) {
|
||||
(TypeVariants::TyRef(_, t, dest_mut), TypeVariants::TyRef(_, u, src_mut)) if (
|
||||
if *dest_mut != ::rustc::hir::Mutability::MutImmutable && src_mut != dest_mut {
|
||||
(TypeVariants::TyRef(_, t, dest_mut), TypeVariants::TyRef(_, u, src_mut))
|
||||
if (if *dest_mut != ::rustc::hir::Mutability::MutImmutable && src_mut != dest_mut {
|
||||
false
|
||||
} else if t != u {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
) => {
|
||||
}) =>
|
||||
{
|
||||
// &mut T -> &T is allowed
|
||||
// &'a T -> &'b T is allowed
|
||||
}
|
||||
_ => {
|
||||
assert_eq!(
|
||||
self.layout().ty, from.layout().ty,
|
||||
self.layout().ty,
|
||||
from.layout().ty,
|
||||
"Can't write value of incompatible type to place {:?} {:?}\n\n{:#?}",
|
||||
self.layout().ty.sty, from.layout().ty.sty,
|
||||
self.layout().ty.sty,
|
||||
from.layout().ty.sty,
|
||||
fx,
|
||||
);
|
||||
}
|
||||
|
@ -224,7 +240,7 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
|
|||
CPlace::Var(var, _) => {
|
||||
let data = from.load_value(fx);
|
||||
fx.bcx.def_var(var, data)
|
||||
},
|
||||
}
|
||||
CPlace::Addr(addr, layout) => {
|
||||
let size = layout.size.bytes() as i32;
|
||||
|
||||
|
@ -235,17 +251,26 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
|
|||
let from = from.expect_byref();
|
||||
let mut offset = 0;
|
||||
while size - offset >= 8 {
|
||||
let byte = fx.bcx.ins().load(types::I64, MemFlags::new(), from.0, offset);
|
||||
let byte = fx
|
||||
.bcx
|
||||
.ins()
|
||||
.load(types::I64, MemFlags::new(), from.0, offset);
|
||||
fx.bcx.ins().store(MemFlags::new(), byte, addr, offset);
|
||||
offset += 8;
|
||||
}
|
||||
while size - offset >= 4 {
|
||||
let byte = fx.bcx.ins().load(types::I32, MemFlags::new(), from.0, offset);
|
||||
let byte = fx
|
||||
.bcx
|
||||
.ins()
|
||||
.load(types::I32, MemFlags::new(), from.0, offset);
|
||||
fx.bcx.ins().store(MemFlags::new(), byte, addr, offset);
|
||||
offset += 4;
|
||||
}
|
||||
while offset < size {
|
||||
let byte = fx.bcx.ins().load(types::I8, MemFlags::new(), from.0, offset);
|
||||
let byte = fx
|
||||
.bcx
|
||||
.ins()
|
||||
.load(types::I8, MemFlags::new(), from.0, offset);
|
||||
fx.bcx.ins().store(MemFlags::new(), byte, addr, offset);
|
||||
offset += 1;
|
||||
}
|
||||
|
@ -275,7 +300,13 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn cton_intcast<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, val: Value, from: Ty<'tcx>, to: Ty<'tcx>, signed: bool) -> Value {
|
||||
pub fn cton_intcast<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
val: Value,
|
||||
from: Ty<'tcx>,
|
||||
to: Ty<'tcx>,
|
||||
signed: bool,
|
||||
) -> Value {
|
||||
let from = fx.cton_type(from).unwrap();
|
||||
let to = fx.cton_type(to).unwrap();
|
||||
if from == to {
|
||||
|
@ -352,7 +383,8 @@ impl<'a, 'tcx> HasTargetSpec for &'a FunctionCx<'a, 'tcx> {
|
|||
|
||||
impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
|
||||
pub fn monomorphize<T>(&self, value: &T) -> T
|
||||
where T: TypeFoldable<'tcx>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
self.tcx.subst_and_normalize_erasing_regions(
|
||||
self.param_substs,
|
||||
|
|
|
@ -1,29 +1,37 @@
|
|||
use crate::prelude::*;
|
||||
use rustc::ty::Const;
|
||||
use rustc::mir::interpret::{ConstValue, GlobalId, AllocId, read_target_uint};
|
||||
use rustc_mir::interpret::{CompileTimeEvaluator, Memory, MemoryKind};
|
||||
use cranelift_module::*;
|
||||
use crate::prelude::*;
|
||||
use rustc::mir::interpret::{read_target_uint, AllocId, ConstValue, GlobalId};
|
||||
use rustc::ty::Const;
|
||||
use rustc_mir::interpret::{CompileTimeEvaluator, Memory, MemoryKind};
|
||||
|
||||
pub fn trans_promoted<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, promoted: Promoted) -> CPlace<'tcx> {
|
||||
pub fn trans_promoted<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
promoted: Promoted,
|
||||
) -> CPlace<'tcx> {
|
||||
let const_ = fx
|
||||
.tcx
|
||||
.const_eval(ParamEnv::reveal_all().and(GlobalId {
|
||||
instance: fx.instance,
|
||||
promoted: Some(promoted),
|
||||
}))
|
||||
.unwrap();
|
||||
})).unwrap();
|
||||
|
||||
let const_ = force_eval_const(fx, const_);
|
||||
trans_const_place(fx, const_)
|
||||
}
|
||||
|
||||
pub fn trans_constant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, constant: &Constant<'tcx>) -> CValue<'tcx> {
|
||||
pub fn trans_constant<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
constant: &Constant<'tcx>,
|
||||
) -> CValue<'tcx> {
|
||||
let const_ = fx.monomorphize(&constant.literal);
|
||||
let const_ = force_eval_const(fx, const_);
|
||||
trans_const_value(fx, const_)
|
||||
}
|
||||
|
||||
fn force_eval_const<'a, 'tcx: 'a>(fx: &FunctionCx<'a, 'tcx>, const_: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> {
|
||||
fn force_eval_const<'a, 'tcx: 'a>(
|
||||
fx: &FunctionCx<'a, 'tcx>,
|
||||
const_: &'tcx Const<'tcx>,
|
||||
) -> &'tcx Const<'tcx> {
|
||||
match const_.val {
|
||||
ConstValue::Unevaluated(def_id, ref substs) => {
|
||||
let param_env = ParamEnv::reveal_all();
|
||||
|
@ -33,12 +41,15 @@ fn force_eval_const<'a, 'tcx: 'a>(fx: &FunctionCx<'a, 'tcx>, const_: &'tcx Const
|
|||
promoted: None,
|
||||
};
|
||||
fx.tcx.const_eval(param_env.and(cid)).unwrap()
|
||||
},
|
||||
}
|
||||
_ => const_,
|
||||
}
|
||||
}
|
||||
|
||||
fn trans_const_value<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, const_: &'tcx Const<'tcx>) -> CValue<'tcx> {
|
||||
fn trans_const_value<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
const_: &'tcx Const<'tcx>,
|
||||
) -> CValue<'tcx> {
|
||||
let ty = fx.monomorphize(&const_.ty);
|
||||
let layout = fx.layout_of(ty);
|
||||
match ty.sty {
|
||||
|
@ -58,13 +69,14 @@ fn trans_const_value<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, const_: &'tcx
|
|||
let func_ref = fx.get_function_ref(Instance::new(def_id, substs));
|
||||
CValue::Func(func_ref, layout)
|
||||
}
|
||||
_ => {
|
||||
trans_const_place(fx, const_).to_cvalue(fx)
|
||||
}
|
||||
_ => trans_const_place(fx, const_).to_cvalue(fx),
|
||||
}
|
||||
}
|
||||
|
||||
fn trans_const_place<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, const_: &'tcx Const<'tcx>) -> CPlace<'tcx> {
|
||||
fn trans_const_place<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx>,
|
||||
const_: &'tcx Const<'tcx>,
|
||||
) -> CPlace<'tcx> {
|
||||
let ty = fx.monomorphize(&const_.ty);
|
||||
let layout = fx.layout_of(ty);
|
||||
if true {
|
||||
|
@ -75,7 +87,9 @@ fn trans_const_place<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, const_: &'tcx
|
|||
let mut memory = Memory::<CompileTimeEvaluator>::new(fx.tcx.at(DUMMY_SP), ());
|
||||
let alloc = fx.tcx.const_value_to_allocation(const_);
|
||||
//println!("const value: {:?} allocation: {:?}", value, alloc);
|
||||
let alloc_id = memory.allocate_value(alloc.clone(), MemoryKind::Stack).unwrap();
|
||||
let alloc_id = memory
|
||||
.allocate_value(alloc.clone(), MemoryKind::Stack)
|
||||
.unwrap();
|
||||
let data_id = get_global_for_alloc_id(fx, &memory, alloc_id);
|
||||
let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
|
||||
// TODO: does global_value return a ptr of a val?
|
||||
|
@ -84,14 +98,19 @@ fn trans_const_place<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, const_: &'tcx
|
|||
}
|
||||
|
||||
// If ret.1 is true, then the global didn't exist before
|
||||
fn define_global_for_alloc_id(fx: &mut FunctionCx, alloc_id: AllocId, todo: &mut HashMap<AllocId, DataId>) -> (DataId, bool) {
|
||||
fn define_global_for_alloc_id(
|
||||
fx: &mut FunctionCx,
|
||||
alloc_id: AllocId,
|
||||
todo: &mut HashMap<AllocId, DataId>,
|
||||
) -> (DataId, bool) {
|
||||
use std::collections::hash_map::Entry;
|
||||
match fx.constants.entry(alloc_id) {
|
||||
Entry::Occupied(mut occ) => {
|
||||
(*occ.get_mut(), false)
|
||||
}
|
||||
Entry::Occupied(mut occ) => (*occ.get_mut(), false),
|
||||
Entry::Vacant(vac) => {
|
||||
let data_id = fx.module.declare_data(&alloc_id.0.to_string(), Linkage::Local, false).unwrap();
|
||||
let data_id = fx
|
||||
.module
|
||||
.declare_data(&alloc_id.0.to_string(), Linkage::Local, false)
|
||||
.unwrap();
|
||||
todo.insert(alloc_id, data_id);
|
||||
vac.insert(data_id);
|
||||
(data_id, true)
|
||||
|
@ -99,7 +118,11 @@ fn define_global_for_alloc_id(fx: &mut FunctionCx, alloc_id: AllocId, todo: &mut
|
|||
}
|
||||
}
|
||||
|
||||
fn get_global_for_alloc_id(fx: &mut FunctionCx, memory: &Memory<CompileTimeEvaluator>, alloc_id: AllocId) -> DataId {
|
||||
fn get_global_for_alloc_id(
|
||||
fx: &mut FunctionCx,
|
||||
memory: &Memory<CompileTimeEvaluator>,
|
||||
alloc_id: AllocId,
|
||||
) -> DataId {
|
||||
if let Some(data_id) = fx.constants.get(&alloc_id) {
|
||||
return *data_id;
|
||||
}
|
||||
|
@ -108,13 +131,22 @@ fn get_global_for_alloc_id(fx: &mut FunctionCx, memory: &Memory<CompileTimeEvalu
|
|||
let mut done = HashSet::new();
|
||||
define_global_for_alloc_id(fx, alloc_id, &mut todo);
|
||||
|
||||
while let Some((alloc_id, data_id)) = { let next = todo.drain().next(); next } {
|
||||
println!("cur: {:?}:{:?} todo: {:?} done: {:?}", alloc_id, data_id, todo, done);
|
||||
while let Some((alloc_id, data_id)) = {
|
||||
let next = todo.drain().next();
|
||||
next
|
||||
} {
|
||||
println!(
|
||||
"cur: {:?}:{:?} todo: {:?} done: {:?}",
|
||||
alloc_id, data_id, todo, done
|
||||
);
|
||||
|
||||
let alloc = memory.get(alloc_id).unwrap();
|
||||
let mut data_ctx = DataContext::new();
|
||||
|
||||
data_ctx.define(alloc.bytes.to_vec().into_boxed_slice(), Writability::Readonly);
|
||||
data_ctx.define(
|
||||
alloc.bytes.to_vec().into_boxed_slice(),
|
||||
Writability::Readonly,
|
||||
);
|
||||
|
||||
for &(offset, reloc) in alloc.relocations.iter() {
|
||||
let data_id = define_global_for_alloc_id(fx, reloc, &mut todo).0;
|
||||
|
|
179
src/lib.rs
179
src/lib.rs
|
@ -4,82 +4,81 @@
|
|||
extern crate syntax;
|
||||
#[macro_use]
|
||||
extern crate rustc;
|
||||
extern crate rustc_mir;
|
||||
extern crate rustc_codegen_utils;
|
||||
extern crate rustc_target;
|
||||
extern crate rustc_incremental;
|
||||
extern crate rustc_mir;
|
||||
extern crate rustc_target;
|
||||
#[macro_use]
|
||||
extern crate rustc_data_structures;
|
||||
|
||||
extern crate ar;
|
||||
extern crate faerie;
|
||||
//extern crate goblin;
|
||||
extern crate target_lexicon;
|
||||
extern crate cranelift;
|
||||
extern crate cranelift_faerie;
|
||||
extern crate cranelift_module;
|
||||
extern crate cranelift_simplejit;
|
||||
extern crate cranelift_faerie;
|
||||
extern crate target_lexicon;
|
||||
|
||||
use std::any::Any;
|
||||
use std::sync::{mpsc, Arc};
|
||||
use std::path::Path;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use std::sync::{mpsc, Arc};
|
||||
|
||||
use syntax::symbol::Symbol;
|
||||
use rustc::session::{
|
||||
CompileIncomplete,
|
||||
config::{
|
||||
CrateType,
|
||||
OutputFilenames,
|
||||
},
|
||||
};
|
||||
use rustc::middle::cstore::MetadataLoader;
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::middle::cstore::MetadataLoader;
|
||||
use rustc::session::{
|
||||
config::{CrateType, OutputFilenames},
|
||||
CompileIncomplete,
|
||||
};
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||
use rustc_codegen_utils::link::{out_filename, build_link_meta};
|
||||
use rustc_codegen_utils::link::{build_link_meta, out_filename};
|
||||
use rustc_data_structures::owning_ref::{self, OwningRef};
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
use cranelift::codegen::settings;
|
||||
use cranelift_faerie::*;
|
||||
|
||||
mod abi;
|
||||
mod base;
|
||||
mod constant;
|
||||
mod common;
|
||||
mod constant;
|
||||
mod pretty_clif;
|
||||
|
||||
mod prelude {
|
||||
pub use std::any::Any;
|
||||
pub use std::collections::{HashMap, HashSet};
|
||||
|
||||
pub use syntax::codemap::DUMMY_SP;
|
||||
pub use syntax::ast::{IntTy, UintTy, FloatTy};
|
||||
pub use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
pub use rustc::mir;
|
||||
pub use rustc::mir::*;
|
||||
pub use rustc::mir::interpret::AllocId;
|
||||
pub use rustc::mir::*;
|
||||
pub use rustc::session::Session;
|
||||
pub use rustc::ty::layout::{self, LayoutOf, TyLayout, Size};
|
||||
pub use rustc::ty::layout::{self, LayoutOf, Size, TyLayout};
|
||||
pub use rustc::ty::{
|
||||
self, subst::Substs, FnSig, Instance, InstanceDef, ParamEnv, PolyFnSig, Ty, TyCtxt,
|
||||
TypeFoldable, TypeVariants, TypeAndMut,
|
||||
TypeAndMut, TypeFoldable, TypeVariants,
|
||||
};
|
||||
pub use rustc_data_structures::{indexed_vec::Idx, sync::Lrc};
|
||||
pub use rustc_mir::monomorphize::{MonoItem, collector};
|
||||
pub use rustc_mir::monomorphize::{collector, MonoItem};
|
||||
pub use syntax::ast::{FloatTy, IntTy, UintTy};
|
||||
pub use syntax::codemap::DUMMY_SP;
|
||||
|
||||
pub use cranelift::codegen::ir::{
|
||||
condcodes::IntCC, function::Function, ExternalName, FuncRef, StackSlot, Inst
|
||||
condcodes::IntCC, function::Function, ExternalName, FuncRef, Inst, StackSlot,
|
||||
};
|
||||
pub use cranelift::codegen::Context;
|
||||
pub use cranelift::prelude::*;
|
||||
pub use cranelift_module::{Module, Backend, DataContext, FuncId, DataId, Linkage, Writability};
|
||||
pub use cranelift_simplejit::{SimpleJITBuilder, SimpleJITBackend};
|
||||
pub use cranelift_module::{
|
||||
Backend, DataContext, DataId, FuncId, Linkage, Module, Writability,
|
||||
};
|
||||
pub use cranelift_simplejit::{SimpleJITBackend, SimpleJITBuilder};
|
||||
|
||||
pub use crate::abi::*;
|
||||
pub use crate::base::{trans_operand, trans_place};
|
||||
pub use crate::common::Variable;
|
||||
pub use crate::common::*;
|
||||
pub use crate::base::{trans_operand, trans_place};
|
||||
|
||||
pub use crate::CodegenCx;
|
||||
}
|
||||
|
@ -95,14 +94,18 @@ pub struct CodegenCx<'a, 'tcx: 'a, B: Backend + 'a> {
|
|||
struct CraneliftMetadataLoader;
|
||||
|
||||
impl MetadataLoader for CraneliftMetadataLoader {
|
||||
fn get_rlib_metadata(&self, _target: &rustc_target::spec::Target, path: &Path) -> Result<owning_ref::ErasedBoxRef<[u8]>, String> {
|
||||
let mut archive = ar::Archive::new(File::open(path).map_err(|e|format!("{:?}", e))?);
|
||||
fn get_rlib_metadata(
|
||||
&self,
|
||||
_target: &rustc_target::spec::Target,
|
||||
path: &Path,
|
||||
) -> Result<owning_ref::ErasedBoxRef<[u8]>, String> {
|
||||
let mut archive = ar::Archive::new(File::open(path).map_err(|e| format!("{:?}", e))?);
|
||||
// Iterate over all entries in the archive:
|
||||
while let Some(entry_result) = archive.next_entry() {
|
||||
let mut entry = entry_result.map_err(|e|format!("{:?}", e))?;
|
||||
let mut entry = entry_result.map_err(|e| format!("{:?}", e))?;
|
||||
if entry.header().identifier() == b".rustc.clif_metadata" {
|
||||
let mut buf = Vec::new();
|
||||
::std::io::copy(&mut entry, &mut buf).map_err(|e|format!("{:?}", e))?;
|
||||
::std::io::copy(&mut entry, &mut buf).map_err(|e| format!("{:?}", e))?;
|
||||
let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
|
||||
return Ok(rustc_erase_owner!(buf.map_owner_box()));
|
||||
}
|
||||
|
@ -112,7 +115,11 @@ impl MetadataLoader for CraneliftMetadataLoader {
|
|||
//self.get_dylib_metadata(target, path)
|
||||
}
|
||||
|
||||
fn get_dylib_metadata(&self, _target: &rustc_target::spec::Target, _path: &Path) -> Result<owning_ref::ErasedBoxRef<[u8]>, String> {
|
||||
fn get_dylib_metadata(
|
||||
&self,
|
||||
_target: &rustc_target::spec::Target,
|
||||
_path: &Path,
|
||||
) -> Result<owning_ref::ErasedBoxRef<[u8]>, String> {
|
||||
//use goblin::Object;
|
||||
|
||||
//let buffer = ::std::fs::read(path).map_err(|e|format!("{:?}", e))?;
|
||||
|
@ -149,13 +156,15 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
fn init(&self, sess: &Session) {
|
||||
for cty in sess.opts.crate_types.iter() {
|
||||
match *cty {
|
||||
CrateType::CrateTypeRlib | CrateType::CrateTypeDylib |
|
||||
CrateType::CrateTypeExecutable => {},
|
||||
CrateType::CrateTypeRlib
|
||||
| CrateType::CrateTypeDylib
|
||||
| CrateType::CrateTypeExecutable => {}
|
||||
_ => {
|
||||
sess.parse_sess.span_diagnostic.warn(
|
||||
&format!("LLVM unsupported, so output type {} is not supported", cty)
|
||||
);
|
||||
},
|
||||
sess.parse_sess.span_diagnostic.warn(&format!(
|
||||
"LLVM unsupported, so output type {} is not supported",
|
||||
cty
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,9 +176,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
fn provide(&self, providers: &mut Providers) {
|
||||
rustc_codegen_utils::symbol_names::provide(providers);
|
||||
|
||||
providers.target_features_whitelist = |_tcx, _cnum| {
|
||||
Lrc::new(Default::default())
|
||||
};
|
||||
providers.target_features_whitelist = |_tcx, _cnum| Lrc::new(Default::default());
|
||||
providers.is_reachable_non_generic = |_tcx, _defid| true;
|
||||
providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new());
|
||||
}
|
||||
|
@ -180,7 +187,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
fn codegen_crate<'a, 'tcx>(
|
||||
&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_rx: mpsc::Receiver<Box<Any + Send>>
|
||||
_rx: mpsc::Receiver<Box<Any + Send>>,
|
||||
) -> Box<Any> {
|
||||
use rustc_mir::monomorphize::item::MonoItem;
|
||||
|
||||
|
@ -188,24 +195,22 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
rustc_codegen_utils::symbol_names_test::report_symbol_names(tcx);
|
||||
rustc_incremental::assert_dep_graph(tcx);
|
||||
rustc_incremental::assert_module_sources::assert_module_sources(tcx);
|
||||
rustc_mir::monomorphize::assert_symbols_are_distinct(tcx,
|
||||
collector::collect_crate_mono_items(
|
||||
tcx,
|
||||
collector::MonoItemCollectionMode::Eager
|
||||
).0.iter()
|
||||
rustc_mir::monomorphize::assert_symbols_are_distinct(
|
||||
tcx,
|
||||
collector::collect_crate_mono_items(tcx, collector::MonoItemCollectionMode::Eager)
|
||||
.0
|
||||
.iter(),
|
||||
);
|
||||
//::rustc::middle::dependency_format::calculate(tcx);
|
||||
let _ = tcx.link_args(LOCAL_CRATE);
|
||||
let _ = tcx.native_libraries(LOCAL_CRATE);
|
||||
for mono_item in
|
||||
collector::collect_crate_mono_items(
|
||||
tcx,
|
||||
collector::MonoItemCollectionMode::Eager
|
||||
).0 {
|
||||
collector::collect_crate_mono_items(tcx, collector::MonoItemCollectionMode::Eager).0
|
||||
{
|
||||
match mono_item {
|
||||
MonoItem::Fn(inst) => {
|
||||
let def_id = inst.def_id();
|
||||
if def_id.is_local() {
|
||||
if def_id.is_local() {
|
||||
let _ = inst.def.is_inline(tcx);
|
||||
let _ = tcx.codegen_fn_attrs(def_id);
|
||||
}
|
||||
|
@ -221,7 +226,9 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
let mut flags_builder = settings::builder();
|
||||
flags_builder.enable("is_pic").unwrap();
|
||||
let flags = settings::Flags::new(flags_builder);
|
||||
let isa = cranelift::codegen::isa::lookup(target_lexicon::Triple::host()).unwrap().finish(flags);
|
||||
let isa = cranelift::codegen::isa::lookup(target_lexicon::Triple::host())
|
||||
.unwrap()
|
||||
.finish(flags);
|
||||
let mut module: Module<SimpleJITBackend> = Module::new(SimpleJITBuilder::new());
|
||||
let mut context = Context::new();
|
||||
|
||||
|
@ -233,10 +240,8 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
};
|
||||
|
||||
for mono_item in
|
||||
collector::collect_crate_mono_items(
|
||||
tcx,
|
||||
collector::MonoItemCollectionMode::Eager
|
||||
).0 {
|
||||
collector::collect_crate_mono_items(tcx, collector::MonoItemCollectionMode::Eager).0
|
||||
{
|
||||
base::trans_mono_item(&mut cx, &mut context, mono_item)
|
||||
}
|
||||
}
|
||||
|
@ -249,11 +254,8 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
tcx.sess.warn("Finalized everything");
|
||||
|
||||
for mono_item in
|
||||
collector::collect_crate_mono_items(
|
||||
tcx,
|
||||
collector::MonoItemCollectionMode::Eager
|
||||
).0 {
|
||||
|
||||
collector::collect_crate_mono_items(tcx, collector::MonoItemCollectionMode::Eager).0
|
||||
{
|
||||
let inst = match mono_item {
|
||||
MonoItem::Fn(inst) => inst,
|
||||
_ => continue,
|
||||
|
@ -266,17 +268,21 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
|
||||
let fn_ty = inst.ty(tcx);
|
||||
let sig = cton_sig_from_fn_ty(tcx, fn_ty);
|
||||
let def_path_based_names = ::rustc_mir::monomorphize::item::DefPathBasedNames::new(tcx, false, false);
|
||||
let def_path_based_names =
|
||||
::rustc_mir::monomorphize::item::DefPathBasedNames::new(tcx, false, false);
|
||||
let mut name = String::new();
|
||||
def_path_based_names.push_instance_as_string(inst, &mut name);
|
||||
let func_id = module.declare_function(&name, Linkage::Import, &sig).unwrap();
|
||||
let func_id = module
|
||||
.declare_function(&name, Linkage::Import, &sig)
|
||||
.unwrap();
|
||||
|
||||
let finalized_function: *const u8 = module.finalize_function(func_id);
|
||||
/*let f: extern "C" fn(&mut u32) = unsafe { ::std::mem::transmute(finalized_function) };
|
||||
let mut res = 0u32;
|
||||
f(&mut res);
|
||||
tcx.sess.warn(&format!("ret_42 returned {}", res));*/
|
||||
let f: extern "C" fn(&mut bool, &u8, bool) = unsafe { ::std::mem::transmute(finalized_function) };
|
||||
let f: extern "C" fn(&mut bool, &u8, bool) =
|
||||
unsafe { ::std::mem::transmute(finalized_function) };
|
||||
let mut res = false;
|
||||
f(&mut res, &3, false);
|
||||
tcx.sess.warn(&format!("option_unwrap_or returned {}", res));
|
||||
|
@ -290,9 +296,8 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
isa,
|
||||
"some_file.o".to_string(),
|
||||
FaerieTrapCollection::Disabled,
|
||||
FaerieBuilder::default_libcall_names()
|
||||
)
|
||||
.unwrap()
|
||||
FaerieBuilder::default_libcall_names(),
|
||||
).unwrap(),
|
||||
);
|
||||
|
||||
Box::new(OngoingCodegen {
|
||||
|
@ -309,30 +314,42 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
_dep_graph: &DepGraph,
|
||||
outputs: &OutputFilenames,
|
||||
) -> Result<(), CompileIncomplete> {
|
||||
let ongoing_codegen = *ongoing_codegen.downcast::<OngoingCodegen>()
|
||||
let ongoing_codegen = *ongoing_codegen
|
||||
.downcast::<OngoingCodegen>()
|
||||
.expect("Expected CraneliftCodegenBackend's OngoingCodegen, found Box<Any>");
|
||||
|
||||
let mut artifact = ongoing_codegen.product.artifact;
|
||||
let metadata = ongoing_codegen.metadata;
|
||||
|
||||
artifact.declare_with(
|
||||
".rustc.clif_metadata",
|
||||
faerie::artifact::Decl::Data {
|
||||
global: true,
|
||||
writeable: false
|
||||
},
|
||||
metadata.clone(),
|
||||
).unwrap();
|
||||
artifact
|
||||
.declare_with(
|
||||
".rustc.clif_metadata",
|
||||
faerie::artifact::Decl::Data {
|
||||
global: true,
|
||||
writeable: false,
|
||||
},
|
||||
metadata.clone(),
|
||||
).unwrap();
|
||||
|
||||
for &crate_type in sess.opts.crate_types.iter() {
|
||||
if crate_type != CrateType::CrateTypeRlib /*&& crate_type != CrateType::CrateTypeDylib*/ {
|
||||
if crate_type != CrateType::CrateTypeRlib
|
||||
/*&& crate_type != CrateType::CrateTypeDylib*/
|
||||
{
|
||||
sess.fatal(&format!("Unsupported crate type: {:?}", crate_type));
|
||||
}
|
||||
let output_name =
|
||||
out_filename(sess, crate_type, &outputs, &ongoing_codegen.crate_name.as_str());
|
||||
let output_name = out_filename(
|
||||
sess,
|
||||
crate_type,
|
||||
&outputs,
|
||||
&ongoing_codegen.crate_name.as_str(),
|
||||
);
|
||||
let file = File::create(&output_name).unwrap();
|
||||
let mut builder = ar::Builder::new(file);
|
||||
builder.append(&ar::Header::new(b".rustc.clif_metadata".to_vec(), metadata.len() as u64), ::std::io::Cursor::new(metadata.clone())).unwrap();
|
||||
builder
|
||||
.append(
|
||||
&ar::Header::new(b".rustc.clif_metadata".to_vec(), metadata.len() as u64),
|
||||
::std::io::Cursor::new(metadata.clone()),
|
||||
).unwrap();
|
||||
//artifact.write(file).unwrap();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue