Run rustfmt 0.9.0-nightly (69ad879 2018-07-27)
This commit is contained in:
@@ -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) {
|
fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u32) {
|
||||||
(
|
(
|
||||||
a as u8,
|
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,
|
||||||
a as u16,
|
b as u32,
|
||||||
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 {
|
fn size_of<T>() -> usize {
|
||||||
unsafe {
|
unsafe { intrinsics::size_of::<T>() }
|
||||||
intrinsics::size_of::<T>()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn use_size_of() -> usize {
|
fn use_size_of() -> usize {
|
||||||
@@ -111,15 +101,11 @@ fn use_const() -> u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn call_closure_3arg() {
|
fn call_closure_3arg() {
|
||||||
(|_, _, _| {
|
(|_, _, _| {})(0u8, 42u16, 0u8)
|
||||||
|
|
||||||
})(0u8, 42u16, 0u8)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_closure_2arg() {
|
fn call_closure_2arg() {
|
||||||
(|_, _| {
|
(|_, _| {})(0u8, 42u16)
|
||||||
|
|
||||||
})(0u8, 42u16)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IsNotEmpty;
|
struct IsNotEmpty;
|
||||||
|
|||||||
@@ -80,18 +80,30 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for u8 {
|
impl PartialEq for u8 {
|
||||||
fn eq(&self, other: &u8) -> bool { (*self) == (*other) }
|
fn eq(&self, other: &u8) -> bool {
|
||||||
fn ne(&self, other: &u8) -> bool { (*self) != (*other) }
|
(*self) == (*other)
|
||||||
|
}
|
||||||
|
fn ne(&self, other: &u8) -> bool {
|
||||||
|
(*self) != (*other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for char {
|
impl PartialEq for char {
|
||||||
fn eq(&self, other: &char) -> bool { (*self) == (*other) }
|
fn eq(&self, other: &char) -> bool {
|
||||||
fn ne(&self, other: &char) -> bool { (*self) != (*other) }
|
(*self) == (*other)
|
||||||
|
}
|
||||||
|
fn ne(&self, other: &char) -> bool {
|
||||||
|
(*self) != (*other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized> PartialEq for *const T {
|
impl<T: ?Sized> PartialEq for *const T {
|
||||||
fn eq(&self, other: &*const T) -> bool { *self == *other }
|
fn eq(&self, other: &*const T) -> bool {
|
||||||
fn ne(&self, other: &*const T) -> bool { *self != *other }
|
*self == *other
|
||||||
|
}
|
||||||
|
fn ne(&self, other: &*const T) -> bool {
|
||||||
|
*self != *other
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "fn_once"]
|
#[lang = "fn_once"]
|
||||||
|
|||||||
120
src/abi.rs
120
src/abi.rs
@@ -5,14 +5,22 @@ use rustc_target::spec::abi::Abi;
|
|||||||
|
|
||||||
use crate::prelude::*;
|
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);
|
let sig = ty_fn_sig(tcx, fn_ty);
|
||||||
assert!(!sig.variadic, "Variadic function are not yet supported");
|
assert!(!sig.variadic, "Variadic function are not yet supported");
|
||||||
let (call_conv, inputs, _output): (CallConv, Vec<Ty>, Ty) = match sig.abi {
|
let (call_conv, inputs, _output): (CallConv, Vec<Ty>, Ty) = match sig.abi {
|
||||||
Abi::Rust => (CallConv::Fast, sig.inputs().to_vec(), sig.output()),
|
Abi::Rust => (CallConv::Fast, sig.inputs().to_vec(), sig.output()),
|
||||||
Abi::C => (CallConv::SystemV, sig.inputs().to_vec(), sig.output()),
|
Abi::C => (CallConv::SystemV, sig.inputs().to_vec(), sig.output()),
|
||||||
Abi::RustCall => {
|
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);
|
assert_eq!(sig.inputs().len(), 2);
|
||||||
let extra_args = match sig.inputs().last().unwrap().sty {
|
let extra_args = match sig.inputs().last().unwrap().sty {
|
||||||
ty::TyTuple(ref tupled_arguments) => tupled_arguments,
|
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]];
|
let mut inputs: Vec<Ty> = vec![sig.inputs()[0]];
|
||||||
inputs.extend(extra_args.into_iter());
|
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::System => bug!("system abi should be selected elsewhere"),
|
||||||
Abi::RustIntrinsic => (CallConv::SystemV, sig.inputs().to_vec(), sig.output()),
|
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>(
|
fn ty_fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> ty::FnSig<'tcx> {
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
||||||
ty: Ty<'tcx>
|
|
||||||
) -> ty::FnSig<'tcx> {
|
|
||||||
let sig = match ty.sty {
|
let sig = match ty.sty {
|
||||||
ty::TyFnDef(..) |
|
ty::TyFnDef(..) |
|
||||||
// Shims currently have type TyFnPtr. Not sure this should remain.
|
// 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());
|
assert!(!inst.substs.needs_infer() && !inst.substs.has_param_types());
|
||||||
let fn_ty = inst.ty(self.tcx);
|
let fn_ty = inst.ty(self.tcx);
|
||||||
let sig = cton_sig_from_fn_ty(self.tcx, fn_ty);
|
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();
|
let mut name = String::new();
|
||||||
def_path_based_names.push_instance_as_string(inst, &mut name);
|
def_path_based_names.push_instance_as_string(inst, &mut name);
|
||||||
let func_id = self.module.declare_function(&name, Linkage::Import, &sig).unwrap();
|
let func_id = self
|
||||||
self.module.declare_func_in_func(func_id, &mut self.bcx.func)
|
.module
|
||||||
|
.declare_function(&name, Linkage::Import, &sig)
|
||||||
|
.unwrap();
|
||||||
|
self.module
|
||||||
|
.declare_func_in_func(func_id, &mut self.bcx.func)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lib_call(
|
fn lib_call(
|
||||||
@@ -124,8 +130,13 @@ impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
|
|||||||
call_conv: CallConv::SystemV,
|
call_conv: CallConv::SystemV,
|
||||||
argument_bytes: None,
|
argument_bytes: None,
|
||||||
};
|
};
|
||||||
let func_id = self.module.declare_function(&name, Linkage::Import, &sig).unwrap();
|
let func_id = self
|
||||||
let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func);
|
.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);
|
let call_inst = self.bcx.ins().call(func_ref, args);
|
||||||
if output_ty.is_none() {
|
if output_ty.is_none() {
|
||||||
return None;
|
return None;
|
||||||
@@ -135,8 +146,20 @@ impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
|
|||||||
Some(results[0])
|
Some(results[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn easy_call(&mut self, name: &str, args: &[CValue<'tcx>], return_ty: Ty<'tcx>) -> CValue<'tcx> {
|
pub fn easy_call(
|
||||||
let (input_tys, args): (Vec<_>, Vec<_>) = args.into_iter().map(|arg| (self.cton_type(arg.layout().ty).unwrap(), arg.load_value(self))).unzip();
|
&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_layout = self.layout_of(return_ty);
|
||||||
let return_ty = if let TypeVariants::TyTuple(tup) = return_ty.sty {
|
let return_ty = if let TypeVariants::TyTuple(tup) = return_ty.sty {
|
||||||
if !tup.is_empty() {
|
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)>>();
|
}).collect::<Vec<(Local, ArgKind, Ty)>>();
|
||||||
|
|
||||||
let ret_layout = fx.layout_of(fx.return_type());
|
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 {
|
for (local, arg_kind, ty) in func_params {
|
||||||
let layout = fx.layout_of(ty);
|
let layout = fx.layout_of(ty);
|
||||||
@@ -284,17 +308,18 @@ pub fn codegen_call<'a, 'tcx: 'a>(
|
|||||||
for (i, _) in tupled_arguments.iter().enumerate() {
|
for (i, _) in tupled_arguments.iter().enumerate() {
|
||||||
args.push(pack_arg.value_field(fx, mir::Field::new(i)));
|
args.push(pack_arg.value_field(fx, mir::Field::new(i)));
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => bug!("argument to function with \"rust-call\" ABI is not a tuple"),
|
_ => 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
|
args
|
||||||
} else {
|
} else {
|
||||||
args
|
args.into_iter()
|
||||||
.into_iter()
|
.map(|arg| trans_operand(fx, arg))
|
||||||
.map(|arg| {
|
|
||||||
trans_operand(fx, arg)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -326,7 +351,11 @@ pub fn codegen_call<'a, 'tcx: 'a>(
|
|||||||
let dst = args[1];
|
let dst = args[1];
|
||||||
let count = args[2].load_value(fx);
|
let count = args[2].load_value(fx);
|
||||||
let byte_amount = fx.bcx.ins().imul(count, elem_size);
|
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");
|
unimplemented!("copy");
|
||||||
}
|
}
|
||||||
"discriminant_value" => {
|
"discriminant_value" => {
|
||||||
@@ -362,12 +391,24 @@ pub fn codegen_call<'a, 'tcx: 'a>(
|
|||||||
_ => unimplemented!("intrinsic {}", intrinsic),
|
_ => unimplemented!("intrinsic {}", intrinsic),
|
||||||
};
|
};
|
||||||
let res = match ret.layout().ty.sty {
|
let res = match ret.layout().ty.sty {
|
||||||
TypeVariants::TyUint(_) => {
|
TypeVariants::TyUint(_) => crate::base::trans_int_binop(
|
||||||
crate::base::trans_int_binop(fx, bin_op, args[0], args[1], ret.layout().ty, false, false)
|
fx,
|
||||||
}
|
bin_op,
|
||||||
TypeVariants::TyInt(_) => {
|
args[0],
|
||||||
crate::base::trans_int_binop(fx, bin_op, args[0], args[1], ret.layout().ty, true, false)
|
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!(),
|
_ => panic!(),
|
||||||
};
|
};
|
||||||
ret.write_cvalue(fx, res);
|
ret.write_cvalue(fx, res);
|
||||||
@@ -402,7 +443,10 @@ pub fn codegen_call<'a, 'tcx: 'a>(
|
|||||||
let uninit_val = uninit_place.to_cvalue(fx);
|
let uninit_val = uninit_place.to_cvalue(fx);
|
||||||
ret.write_cvalue(fx, uninit_val);
|
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 {
|
if let Some((_, dest)) = *destination {
|
||||||
let ret_ebb = fx.get_ebb(dest);
|
let ret_ebb = fx.get_ebb(dest);
|
||||||
@@ -419,7 +463,9 @@ pub fn codegen_call<'a, 'tcx: 'a>(
|
|||||||
None => fx.bcx.ins().iconst(types::I64, 0),
|
None => fx.bcx.ins().iconst(types::I64, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
let call_args = Some(return_ptr).into_iter().chain(args.into_iter().map(|arg| {
|
let call_args = Some(return_ptr)
|
||||||
|
.into_iter()
|
||||||
|
.chain(args.into_iter().map(|arg| {
|
||||||
if fx.cton_type(arg.layout().ty).is_some() {
|
if fx.cton_type(arg.layout().ty).is_some() {
|
||||||
arg.load_value(fx)
|
arg.load_value(fx)
|
||||||
} else {
|
} else {
|
||||||
@@ -434,7 +480,9 @@ pub fn codegen_call<'a, 'tcx: 'a>(
|
|||||||
func => {
|
func => {
|
||||||
let func_ty = func.layout().ty;
|
let func_ty = func.layout().ty;
|
||||||
let func = func.load_value(fx);
|
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);
|
fx.bcx.ins().call_indirect(sig, func, &call_args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
312
src/base.rs
312
src/base.rs
@@ -1,6 +1,10 @@
|
|||||||
use crate::prelude::*;
|
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;
|
let tcx = cx.tcx;
|
||||||
|
|
||||||
match mono_item {
|
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());
|
let mut mir = ::std::io::Cursor::new(Vec::new());
|
||||||
::rustc_mir::util::write_mir_pretty(tcx, Some(def_id), &mut mir).unwrap();
|
::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 = inst.ty(tcx);
|
||||||
let fn_ty = tcx.subst_and_normalize_erasing_regions(
|
let fn_ty = tcx.subst_and_normalize_erasing_regions(
|
||||||
@@ -23,13 +31,21 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend
|
|||||||
|
|
||||||
let func_id = {
|
let func_id = {
|
||||||
// WARNING: keep in sync with FunctionCx::get_function_ref
|
// 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();
|
let mut name = String::new();
|
||||||
def_path_based_names.push_instance_as_string(inst, &mut name);
|
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,
|
Ok(comments) => comments,
|
||||||
@@ -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 writer = crate::pretty_clif::CommentWriter(comments);
|
||||||
let mut cton = String::new();
|
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);
|
tcx.sess.warn(&cton);
|
||||||
|
|
||||||
let flags = settings::Flags::new(settings::builder());
|
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(_) => {}
|
Ok(_) => {}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
tcx.sess.err(&format!("{:?}", err));
|
tcx.sess.err(&format!("{:?}", err));
|
||||||
let pretty_error = ::cranelift::codegen::print_errors::pretty_verifier_error(&f, None, Some(Box::new(writer)), &err);
|
let pretty_error =
|
||||||
tcx.sess.fatal(&format!("cretonne verify error:\n{}", 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();
|
context.clear();
|
||||||
}
|
}
|
||||||
inst => cx.tcx.sess.warn(&format!("Unimplemented instance {:?}", inst)),
|
inst => cx
|
||||||
}
|
.tcx
|
||||||
MonoItem::Static(def_id) => cx.tcx.sess.err(&format!("Unimplemented static mono item {:?}", def_id)),
|
.sess
|
||||||
MonoItem::GlobalAsm(node_id) => cx.tcx.sess.err(&format!("Unimplemented global asm mono item {:?}", node_id)),
|
.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 mir = cx.tcx.optimized_mir(instance.def_id());
|
||||||
let mut func_ctx = FunctionBuilderContext::new();
|
let mut func_ctx = FunctionBuilderContext::new();
|
||||||
let mut bcx: FunctionBuilder<Variable> = FunctionBuilder::new(f, &mut func_ctx);
|
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);
|
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() {
|
for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
|
||||||
let ebb = fx.get_ebb(bb);
|
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();
|
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();
|
let inst = fx.bcx.func.layout.last_inst(ebb).unwrap();
|
||||||
fx.add_comment(inst, terminator_head);
|
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 => {
|
TerminatorKind::Return => {
|
||||||
fx.bcx.ins().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 cond = trans_operand(fx, cond).load_value(fx);
|
||||||
let target = fx.get_ebb(*target);
|
let target = fx.get_ebb(*target);
|
||||||
if *expected {
|
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));
|
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 discr = trans_operand(fx, discr).load_value(fx);
|
||||||
let mut jt_data = JumpTableData::new();
|
let mut jt_data = JumpTableData::new();
|
||||||
for (i, value) in values.iter().enumerate() {
|
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]);
|
let otherwise_ebb = fx.get_ebb(targets[targets.len() - 1]);
|
||||||
fx.bcx.ins().jump(otherwise_ebb, &[]);
|
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);
|
crate::abi::codegen_call(fx, func, args, destination);
|
||||||
}
|
}
|
||||||
TerminatorKind::Resume | TerminatorKind::Abort | TerminatorKind::Unreachable => {
|
TerminatorKind::Resume | TerminatorKind::Abort | TerminatorKind::Unreachable => {
|
||||||
fx.bcx.ins().trap(TrapCode::User(!0));
|
fx.bcx.ins().trap(TrapCode::User(!0));
|
||||||
}
|
}
|
||||||
TerminatorKind::Yield { .. } |
|
TerminatorKind::Yield { .. }
|
||||||
TerminatorKind::FalseEdges { .. } |
|
| TerminatorKind::FalseEdges { .. }
|
||||||
TerminatorKind::FalseUnwind { .. } => {
|
| TerminatorKind::FalseUnwind { .. } => {
|
||||||
bug!("shouldn't exist at trans {:?}", bb_data.terminator());
|
bug!("shouldn't exist at trans {:?}", bb_data.terminator());
|
||||||
}
|
}
|
||||||
TerminatorKind::Drop { target, .. } | TerminatorKind::DropAndReplace { target, .. } => {
|
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())
|
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));
|
fx.tcx.sess.warn(&format!("stmt {:?}", stmt));
|
||||||
|
|
||||||
let inst = fx.bcx.func.layout.last_inst(cur_ebb).unwrap();
|
let inst = fx.bcx.func.layout.last_inst(cur_ebb).unwrap();
|
||||||
fx.add_comment(inst, format!("{:?}", stmt));
|
fx.add_comment(inst, format!("{:?}", stmt));
|
||||||
|
|
||||||
match &stmt.kind {
|
match &stmt.kind {
|
||||||
StatementKind::SetDiscriminant { place, variant_index } => {
|
StatementKind::SetDiscriminant {
|
||||||
|
place,
|
||||||
|
variant_index,
|
||||||
|
} => {
|
||||||
let place = trans_place(fx, place);
|
let place = trans_place(fx, place);
|
||||||
let layout = place.layout();
|
let layout = place.layout();
|
||||||
if layout.for_variant(&*fx, *variant_index).abi == layout::Abi::Uninhabited {
|
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 { .. } => {
|
layout::Variants::Tagged { .. } => {
|
||||||
let ptr = place.place_field(fx, mir::Field::new(0));
|
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)
|
.discriminant_for_variant(fx.tcx, *variant_index)
|
||||||
.val;
|
.val;
|
||||||
let discr = CValue::const_val(fx, ptr.layout().ty, to as u64 as i64);
|
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 {
|
UnOp::Neg => match ty.sty {
|
||||||
TypeVariants::TyFloat(_) => fx.bcx.ins().fneg(val),
|
TypeVariants::TyFloat(_) => fx.bcx.ins().fneg(val),
|
||||||
_ => unimplemented!("un op Neg for {:?}", ty),
|
_ => unimplemented!("un op Neg for {:?}", ty),
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
lval.write_cvalue(fx, CValue::ByVal(res, layout));
|
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 operand = trans_operand(fx, operand);
|
||||||
let from_ty = operand.layout().ty;
|
let from_ty = operand.layout().ty;
|
||||||
match (&from_ty.sty, &to_ty.sty) {
|
match (&from_ty.sty, &to_ty.sty) {
|
||||||
(TypeVariants::TyRef(..), TypeVariants::TyRef(..)) |
|
(TypeVariants::TyRef(..), TypeVariants::TyRef(..))
|
||||||
(TypeVariants::TyRef(..), TypeVariants::TyRawPtr(..)) |
|
| (TypeVariants::TyRef(..), TypeVariants::TyRawPtr(..))
|
||||||
(TypeVariants::TyRawPtr(..), TypeVariants::TyRef(..)) |
|
| (TypeVariants::TyRawPtr(..), TypeVariants::TyRef(..))
|
||||||
(TypeVariants::TyRawPtr(..), TypeVariants::TyRawPtr(..)) => {
|
| (TypeVariants::TyRawPtr(..), TypeVariants::TyRawPtr(..)) => {
|
||||||
lval.write_cvalue(fx, operand.unchecked_cast_to(dest_layout));
|
lval.write_cvalue(fx, operand.unchecked_cast_to(dest_layout));
|
||||||
}
|
}
|
||||||
(TypeVariants::TyChar, TypeVariants::TyUint(_)) |
|
(TypeVariants::TyChar, TypeVariants::TyUint(_))
|
||||||
(TypeVariants::TyUint(_), TypeVariants::TyInt(_)) |
|
| (TypeVariants::TyUint(_), TypeVariants::TyInt(_))
|
||||||
(TypeVariants::TyUint(_), TypeVariants::TyUint(_)) => {
|
| (TypeVariants::TyUint(_), TypeVariants::TyUint(_)) => {
|
||||||
let from = operand.load_value(fx);
|
let from = operand.load_value(fx);
|
||||||
let res = crate::common::cton_intcast(fx, from, from_ty, to_ty, false);
|
let res = crate::common::cton_intcast(fx, from, from_ty, to_ty, false);
|
||||||
lval.write_cvalue(fx, CValue::ByVal(res, dest_layout));
|
lval.write_cvalue(fx, CValue::ByVal(res, dest_layout));
|
||||||
}
|
}
|
||||||
(TypeVariants::TyInt(_), TypeVariants::TyInt(_)) |
|
(TypeVariants::TyInt(_), TypeVariants::TyInt(_))
|
||||||
(TypeVariants::TyInt(_), TypeVariants::TyUint(_)) => {
|
| (TypeVariants::TyInt(_), TypeVariants::TyUint(_)) => {
|
||||||
let from = operand.load_value(fx);
|
let from = operand.load_value(fx);
|
||||||
let res = crate::common::cton_intcast(fx, from, from_ty, to_ty, true);
|
let res = crate::common::cton_intcast(fx, from, from_ty, to_ty, true);
|
||||||
lval.write_cvalue(fx, CValue::ByVal(res, dest_layout));
|
lval.write_cvalue(fx, CValue::ByVal(res, dest_layout));
|
||||||
}
|
}
|
||||||
_ => return Err(format!("rval misc {:?} {:?}", operand, to_ty)),
|
_ => return Err(format!("rval misc {:?} {:?}", operand, to_ty)),
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Rvalue::Cast(CastKind::ClosureFnPointer, operand, ty) => unimplemented!("rval closure_fn_ptr {:?} {:?}", operand, ty),
|
Rvalue::Cast(CastKind::ClosureFnPointer, operand, ty) => {
|
||||||
Rvalue::Cast(CastKind::Unsize, operand, ty) => return Err(format!("rval unsize {:?} {:?}", 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) => {
|
Rvalue::Discriminant(place) => {
|
||||||
let place = trans_place(fx, place).to_cvalue(fx);
|
let place = trans_place(fx, place).to_cvalue(fx);
|
||||||
let discr = trans_get_discriminant(fx, place, dest_layout);
|
let discr = trans_get_discriminant(fx, place, dest_layout);
|
||||||
lval.write_cvalue(fx, discr);
|
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::Len(lval) => return Err(format!("rval len {:?}", lval)),
|
||||||
Rvalue::NullaryOp(NullOp::Box, ty) => unimplemented!("rval box {:?}", ty),
|
Rvalue::NullaryOp(NullOp::Box, ty) => unimplemented!("rval box {:?}", ty),
|
||||||
Rvalue::NullaryOp(NullOp::SizeOf, ty) => unimplemented!("rval size_of {:?}", ty),
|
Rvalue::NullaryOp(NullOp::SizeOf, ty) => unimplemented!("rval size_of {:?}", ty),
|
||||||
Rvalue::Aggregate(_, _) => bug!("shouldn't exist at trans {:?}", rval),
|
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"),
|
StatementKind::InlineAsm { .. } => fx.tcx.sess.fatal("Inline assembly is not supported"),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
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();
|
let layout = value.layout();
|
||||||
|
|
||||||
if layout.abi == layout::Abi::Uninhabited {
|
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 {
|
match layout.variants {
|
||||||
layout::Variants::Single { index } => {
|
layout::Variants::Single { index } => {
|
||||||
let discr_val = layout.ty.ty_adt_def().map_or(
|
let discr_val = layout.ty.ty_adt_def().map_or(index as u128, |def| {
|
||||||
index as u128,
|
def.discriminant_for_variant(fx.tcx, index).val
|
||||||
|def| def.discriminant_for_variant(fx.tcx, index).val);
|
});
|
||||||
return CValue::const_val(fx, dest_layout.ty, discr_val as u64 as i64);
|
return CValue::const_val(fx, dest_layout.ty, discr_val as u64 as i64);
|
||||||
}
|
}
|
||||||
layout::Variants::Tagged { .. } |
|
layout::Variants::Tagged { .. } | layout::Variants::NicheFilling { .. } => {}
|
||||||
layout::Variants::NicheFilling { .. } => {},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let discr = value.value_field(fx, mir::Field::new(0));
|
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, .. } => {
|
layout::Variants::Tagged { ref tag, .. } => {
|
||||||
let signed = match tag.value {
|
let signed = match tag.value {
|
||||||
layout::Int(_, signed) => signed,
|
layout::Int(_, signed) => signed,
|
||||||
_ => false
|
_ => false,
|
||||||
};
|
};
|
||||||
let val = cton_intcast(fx, lldiscr, discr_ty, dest_layout.ty, signed);
|
let val = cton_intcast(fx, lldiscr, discr_ty, dest_layout.ty, signed);
|
||||||
return CValue::ByVal(val, dest_layout);
|
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();
|
let niche_llty = fx.cton_type(discr_ty).unwrap();
|
||||||
if niche_variants.start() == niche_variants.end() {
|
if niche_variants.start() == niche_variants.end() {
|
||||||
let dest_cton_ty = fx.cton_type(dest_layout.ty).unwrap();
|
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 b = fx
|
||||||
let if_true = fx.bcx.ins().iconst(dest_cton_ty, *niche_variants.start() as u64 as i64);
|
.bcx
|
||||||
let if_false = fx.bcx.ins().iconst(dest_cton_ty, dataful_variant as u64 as i64);
|
.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);
|
let val = fx.bcx.ins().select(b, if_true, if_false);
|
||||||
return CValue::ByVal(val, dest_layout);
|
return CValue::ByVal(val, dest_layout);
|
||||||
} else {
|
} 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 = niche_start.wrapping_sub(*niche_variants.start() as u128);
|
||||||
let delta = fx.bcx.ins().iconst(niche_llty, delta as u64 as i64);
|
let delta = fx.bcx.ins().iconst(niche_llty, delta as u64 as i64);
|
||||||
let lldiscr = fx.bcx.ins().isub(lldiscr, delta);
|
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_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);
|
let val = fx.bcx.ins().select(b, if_true, if_false);
|
||||||
return CValue::ByVal(val, dest_layout);
|
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! {
|
let res = binop_match! {
|
||||||
fx, bin_op, false, lhs, rhs, ty, "bool";
|
fx, bin_op, false, lhs, rhs, ty, "bool";
|
||||||
Add (_) bug;
|
Add (_) bug;
|
||||||
@@ -474,7 +580,15 @@ fn trans_bool_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp,
|
|||||||
res
|
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! {
|
let res = binop_match! {
|
||||||
fx, bin_op, signed, lhs, rhs, ty, "int/uint";
|
fx, bin_op, signed, lhs, rhs, ty, "int/uint";
|
||||||
Add (_) iadd;
|
Add (_) iadd;
|
||||||
@@ -509,7 +623,13 @@ pub fn trans_int_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinO
|
|||||||
res
|
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! {
|
let res = binop_match! {
|
||||||
fx, bin_op, false, lhs, rhs, ty, "float";
|
fx, bin_op, false, lhs, rhs, ty, "float";
|
||||||
Add (_) fadd;
|
Add (_) fadd;
|
||||||
@@ -544,7 +664,13 @@ fn trans_float_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp,
|
|||||||
res
|
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! {
|
let res = binop_match! {
|
||||||
fx, bin_op, false, lhs, rhs, ty, "char";
|
fx, bin_op, false, lhs, rhs, ty, "char";
|
||||||
Add (_) bug;
|
Add (_) bug;
|
||||||
@@ -571,7 +697,14 @@ fn trans_char_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp,
|
|||||||
res
|
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! {
|
binop_match! {
|
||||||
fx, bin_op, false, lhs, rhs, ty, "ptr";
|
fx, bin_op, false, lhs, rhs, ty, "ptr";
|
||||||
Add (_) bug;
|
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 {
|
match place {
|
||||||
Place::Local(local) => fx.get_local_place(*local),
|
Place::Local(local) => fx.get_local_place(*local),
|
||||||
Place::Promoted(promoted) => crate::constant::trans_promoted(fx, promoted.0),
|
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) => {
|
Place::Projection(projection) => {
|
||||||
let base = trans_place(fx, &projection.base);
|
let base = trans_place(fx, &projection.base);
|
||||||
match projection.elem {
|
match projection.elem {
|
||||||
ProjectionElem::Deref => {
|
ProjectionElem::Deref => CPlace::Addr(
|
||||||
CPlace::Addr(base.to_cvalue(fx).load_value(fx), fx.layout_of(place.ty(&*fx.mir, fx.tcx).to_ty(fx.tcx)))
|
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::Field(field, _ty) => base.place_field(fx, field),
|
||||||
}
|
ProjectionElem::Index(local) => {
|
||||||
ProjectionElem::Index(local) => unimplemented!("projection index {:?} {:?}", projection.base, 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::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 {
|
match operand {
|
||||||
Operand::Move(place) |
|
Operand::Move(place) | Operand::Copy(place) => {
|
||||||
Operand::Copy(place) => {
|
|
||||||
let cplace = trans_place(fx, place);
|
let cplace = trans_place(fx, place);
|
||||||
cplace.to_cvalue(fx)
|
cplace.to_cvalue(fx)
|
||||||
},
|
}
|
||||||
Operand::Constant(const_) => {
|
Operand::Constant(const_) => crate::constant::trans_constant(fx, const_),
|
||||||
crate::constant::trans_constant(fx, const_)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
114
src/common.rs
114
src/common.rs
@@ -2,7 +2,7 @@ use std::fmt;
|
|||||||
|
|
||||||
use rustc_target::spec::{HasTargetSpec, Target};
|
use rustc_target::spec::{HasTargetSpec, Target};
|
||||||
|
|
||||||
use cranelift_module::{Module, DataId};
|
use cranelift_module::{DataId, Module};
|
||||||
|
|
||||||
use crate::prelude::*;
|
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 {
|
Some(match ty.sty {
|
||||||
TypeVariants::TyBool => types::I8,
|
TypeVariants::TyBool => types::I8,
|
||||||
TypeVariants::TyUint(size) => {
|
TypeVariants::TyUint(size) => match size {
|
||||||
match size {
|
|
||||||
UintTy::U8 => types::I8,
|
UintTy::U8 => types::I8,
|
||||||
UintTy::U16 => types::I16,
|
UintTy::U16 => types::I16,
|
||||||
UintTy::U32 => types::I32,
|
UintTy::U32 => types::I32,
|
||||||
UintTy::U64 => types::I64,
|
UintTy::U64 => types::I64,
|
||||||
UintTy::U128 => unimplemented!("u128"),
|
UintTy::U128 => unimplemented!("u128"),
|
||||||
UintTy::Usize => types::I64,
|
UintTy::Usize => types::I64,
|
||||||
}
|
},
|
||||||
}
|
TypeVariants::TyInt(size) => match size {
|
||||||
TypeVariants::TyInt(size) => {
|
|
||||||
match size {
|
|
||||||
IntTy::I8 => types::I8,
|
IntTy::I8 => types::I8,
|
||||||
IntTy::I16 => types::I16,
|
IntTy::I16 => types::I16,
|
||||||
IntTy::I32 => types::I32,
|
IntTy::I32 => types::I32,
|
||||||
IntTy::I64 => types::I64,
|
IntTy::I64 => types::I64,
|
||||||
IntTy::I128 => unimplemented!("i128"),
|
IntTy::I128 => unimplemented!("i128"),
|
||||||
IntTy::Isize => types::I64,
|
IntTy::Isize => types::I64,
|
||||||
}
|
},
|
||||||
}
|
|
||||||
TypeVariants::TyChar => types::I32,
|
TypeVariants::TyChar => types::I32,
|
||||||
TypeVariants::TyFloat(size) => {
|
TypeVariants::TyFloat(size) => match size {
|
||||||
match size {
|
|
||||||
FloatTy::F32 => types::I32,
|
FloatTy::F32 => types::I32,
|
||||||
FloatTy::F64 => types::I64,
|
FloatTy::F64 => types::I64,
|
||||||
}
|
},
|
||||||
}
|
|
||||||
TypeVariants::TyFnPtr(_) => types::I64,
|
TypeVariants::TyFnPtr(_) => types::I64,
|
||||||
TypeVariants::TyRawPtr(TypeAndMut { ty, mutbl: _ }) | TypeVariants::TyRef(_, ty, _) => {
|
TypeVariants::TyRawPtr(TypeAndMut { ty, mutbl: _ }) | TypeVariants::TyRef(_, ty, _) => {
|
||||||
if ty.is_sized(tcx.at(DUMMY_SP), ParamEnv::reveal_all()) {
|
if ty.is_sized(tcx.at(DUMMY_SP), ParamEnv::reveal_all()) {
|
||||||
@@ -68,7 +65,7 @@ fn codegen_field<'a, 'tcx: 'a>(
|
|||||||
fx: &mut FunctionCx<'a, 'tcx>,
|
fx: &mut FunctionCx<'a, 'tcx>,
|
||||||
base: Value,
|
base: Value,
|
||||||
layout: TyLayout<'tcx>,
|
layout: TyLayout<'tcx>,
|
||||||
field: mir::Field
|
field: mir::Field,
|
||||||
) -> (Value, TyLayout<'tcx>) {
|
) -> (Value, TyLayout<'tcx>) {
|
||||||
let field_offset = layout.fields.offset(field.index());
|
let field_offset = layout.fields.offset(field.index());
|
||||||
let field_ty = layout.field(&*fx, field.index());
|
let field_ty = layout.field(&*fx, field.index());
|
||||||
@@ -91,13 +88,14 @@ pub enum CValue<'tcx> {
|
|||||||
impl<'tcx> CValue<'tcx> {
|
impl<'tcx> CValue<'tcx> {
|
||||||
pub fn layout(&self) -> TyLayout<'tcx> {
|
pub fn layout(&self) -> TyLayout<'tcx> {
|
||||||
match *self {
|
match *self {
|
||||||
CValue::ByRef(_, layout) |
|
CValue::ByRef(_, layout) | CValue::ByVal(_, layout) | CValue::Func(_, layout) => 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 {
|
match self {
|
||||||
CValue::ByRef(value, _layout) => value,
|
CValue::ByRef(value, _layout) => value,
|
||||||
CValue::ByVal(value, layout) => {
|
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 {
|
match self {
|
||||||
CValue::ByRef(addr, layout) => {
|
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)
|
fx.bcx.ins().load(cton_ty, MemFlags::new(), addr, 0)
|
||||||
}
|
}
|
||||||
CValue::ByVal(value, _layout) => value,
|
CValue::ByVal(value, _layout) => value,
|
||||||
CValue::Func(func, _layout) => {
|
CValue::Func(func, _layout) => fx.bcx.ins().func_addr(types::I64, func),
|
||||||
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 {
|
let (base, layout) = match self {
|
||||||
CValue::ByRef(addr, layout) => (addr, layout),
|
CValue::ByRef(addr, layout) => (addr, layout),
|
||||||
_ => bug!("place_field for {:?}", self),
|
_ => bug!("place_field for {:?}", self),
|
||||||
@@ -147,7 +151,14 @@ impl<'tcx> CValue<'tcx> {
|
|||||||
CValue::ByRef(field_ptr, field_layout)
|
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 cton_ty = fx.cton_type(ty).unwrap();
|
||||||
let layout = fx.layout_of(ty);
|
let layout = fx.layout_of(ty);
|
||||||
CValue::ByVal(fx.bcx.ins().iconst(cton_ty, const_val), layout)
|
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> {
|
impl<'a, 'tcx: 'a> CPlace<'tcx> {
|
||||||
pub fn layout(&self) -> TyLayout<'tcx> {
|
pub fn layout(&self) -> TyLayout<'tcx> {
|
||||||
match *self {
|
match *self {
|
||||||
CPlace::Var(_, layout) |
|
CPlace::Var(_, layout) | CPlace::Addr(_, layout) => 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);
|
let layout = fx.layout_of(ty);
|
||||||
CPlace::Addr(fx.bcx.ins().stack_addr(types::I64, stack_slot, 0), layout)
|
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>) {
|
pub fn write_cvalue(self, fx: &mut FunctionCx<'a, 'tcx>, from: CValue<'tcx>) {
|
||||||
match (&self.layout().ty.sty, &from.layout().ty.sty) {
|
match (&self.layout().ty.sty, &from.layout().ty.sty) {
|
||||||
(TypeVariants::TyRef(_, t, dest_mut), TypeVariants::TyRef(_, u, src_mut)) if (
|
(TypeVariants::TyRef(_, t, dest_mut), TypeVariants::TyRef(_, u, src_mut))
|
||||||
if *dest_mut != ::rustc::hir::Mutability::MutImmutable && src_mut != dest_mut {
|
if (if *dest_mut != ::rustc::hir::Mutability::MutImmutable && src_mut != dest_mut {
|
||||||
false
|
false
|
||||||
} else if t != u {
|
} else if t != u {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
}
|
}) =>
|
||||||
) => {
|
{
|
||||||
// &mut T -> &T is allowed
|
// &mut T -> &T is allowed
|
||||||
// &'a T -> &'b T is allowed
|
// &'a T -> &'b T is allowed
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
assert_eq!(
|
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{:#?}",
|
"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,
|
fx,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -224,7 +240,7 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
|
|||||||
CPlace::Var(var, _) => {
|
CPlace::Var(var, _) => {
|
||||||
let data = from.load_value(fx);
|
let data = from.load_value(fx);
|
||||||
fx.bcx.def_var(var, data)
|
fx.bcx.def_var(var, data)
|
||||||
},
|
}
|
||||||
CPlace::Addr(addr, layout) => {
|
CPlace::Addr(addr, layout) => {
|
||||||
let size = layout.size.bytes() as i32;
|
let size = layout.size.bytes() as i32;
|
||||||
|
|
||||||
@@ -235,17 +251,26 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
|
|||||||
let from = from.expect_byref();
|
let from = from.expect_byref();
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
while size - offset >= 8 {
|
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);
|
fx.bcx.ins().store(MemFlags::new(), byte, addr, offset);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
}
|
}
|
||||||
while size - offset >= 4 {
|
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);
|
fx.bcx.ins().store(MemFlags::new(), byte, addr, offset);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
while offset < size {
|
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);
|
fx.bcx.ins().store(MemFlags::new(), byte, addr, offset);
|
||||||
offset += 1;
|
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 from = fx.cton_type(from).unwrap();
|
||||||
let to = fx.cton_type(to).unwrap();
|
let to = fx.cton_type(to).unwrap();
|
||||||
if from == to {
|
if from == to {
|
||||||
@@ -352,7 +383,8 @@ impl<'a, 'tcx> HasTargetSpec for &'a FunctionCx<'a, 'tcx> {
|
|||||||
|
|
||||||
impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
|
impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
|
||||||
pub fn monomorphize<T>(&self, value: &T) -> T
|
pub fn monomorphize<T>(&self, value: &T) -> T
|
||||||
where T: TypeFoldable<'tcx>
|
where
|
||||||
|
T: TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
self.tcx.subst_and_normalize_erasing_regions(
|
self.tcx.subst_and_normalize_erasing_regions(
|
||||||
self.param_substs,
|
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 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
|
let const_ = fx
|
||||||
.tcx
|
.tcx
|
||||||
.const_eval(ParamEnv::reveal_all().and(GlobalId {
|
.const_eval(ParamEnv::reveal_all().and(GlobalId {
|
||||||
instance: fx.instance,
|
instance: fx.instance,
|
||||||
promoted: Some(promoted),
|
promoted: Some(promoted),
|
||||||
}))
|
})).unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let const_ = force_eval_const(fx, const_);
|
let const_ = force_eval_const(fx, const_);
|
||||||
trans_const_place(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_ = fx.monomorphize(&constant.literal);
|
||||||
let const_ = force_eval_const(fx, const_);
|
let const_ = force_eval_const(fx, const_);
|
||||||
trans_const_value(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 {
|
match const_.val {
|
||||||
ConstValue::Unevaluated(def_id, ref substs) => {
|
ConstValue::Unevaluated(def_id, ref substs) => {
|
||||||
let param_env = ParamEnv::reveal_all();
|
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,
|
promoted: None,
|
||||||
};
|
};
|
||||||
fx.tcx.const_eval(param_env.and(cid)).unwrap()
|
fx.tcx.const_eval(param_env.and(cid)).unwrap()
|
||||||
},
|
}
|
||||||
_ => const_,
|
_ => 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 ty = fx.monomorphize(&const_.ty);
|
||||||
let layout = fx.layout_of(ty);
|
let layout = fx.layout_of(ty);
|
||||||
match ty.sty {
|
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));
|
let func_ref = fx.get_function_ref(Instance::new(def_id, substs));
|
||||||
CValue::Func(func_ref, layout)
|
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 ty = fx.monomorphize(&const_.ty);
|
||||||
let layout = fx.layout_of(ty);
|
let layout = fx.layout_of(ty);
|
||||||
if true {
|
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 mut memory = Memory::<CompileTimeEvaluator>::new(fx.tcx.at(DUMMY_SP), ());
|
||||||
let alloc = fx.tcx.const_value_to_allocation(const_);
|
let alloc = fx.tcx.const_value_to_allocation(const_);
|
||||||
//println!("const value: {:?} allocation: {:?}", value, alloc);
|
//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 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);
|
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?
|
// 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
|
// 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;
|
use std::collections::hash_map::Entry;
|
||||||
match fx.constants.entry(alloc_id) {
|
match fx.constants.entry(alloc_id) {
|
||||||
Entry::Occupied(mut occ) => {
|
Entry::Occupied(mut occ) => (*occ.get_mut(), false),
|
||||||
(*occ.get_mut(), false)
|
|
||||||
}
|
|
||||||
Entry::Vacant(vac) => {
|
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);
|
todo.insert(alloc_id, data_id);
|
||||||
vac.insert(data_id);
|
vac.insert(data_id);
|
||||||
(data_id, true)
|
(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) {
|
if let Some(data_id) = fx.constants.get(&alloc_id) {
|
||||||
return *data_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();
|
let mut done = HashSet::new();
|
||||||
define_global_for_alloc_id(fx, alloc_id, &mut todo);
|
define_global_for_alloc_id(fx, alloc_id, &mut todo);
|
||||||
|
|
||||||
while let Some((alloc_id, data_id)) = { let next = todo.drain().next(); next } {
|
while let Some((alloc_id, data_id)) = {
|
||||||
println!("cur: {:?}:{:?} todo: {:?} done: {:?}", alloc_id, data_id, todo, done);
|
let next = todo.drain().next();
|
||||||
|
next
|
||||||
|
} {
|
||||||
|
println!(
|
||||||
|
"cur: {:?}:{:?} todo: {:?} done: {:?}",
|
||||||
|
alloc_id, data_id, todo, done
|
||||||
|
);
|
||||||
|
|
||||||
let alloc = memory.get(alloc_id).unwrap();
|
let alloc = memory.get(alloc_id).unwrap();
|
||||||
let mut data_ctx = DataContext::new();
|
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() {
|
for &(offset, reloc) in alloc.relocations.iter() {
|
||||||
let data_id = define_global_for_alloc_id(fx, reloc, &mut todo).0;
|
let data_id = define_global_for_alloc_id(fx, reloc, &mut todo).0;
|
||||||
|
|||||||
157
src/lib.rs
157
src/lib.rs
@@ -4,82 +4,81 @@
|
|||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rustc;
|
extern crate rustc;
|
||||||
extern crate rustc_mir;
|
|
||||||
extern crate rustc_codegen_utils;
|
extern crate rustc_codegen_utils;
|
||||||
extern crate rustc_target;
|
|
||||||
extern crate rustc_incremental;
|
extern crate rustc_incremental;
|
||||||
|
extern crate rustc_mir;
|
||||||
|
extern crate rustc_target;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rustc_data_structures;
|
extern crate rustc_data_structures;
|
||||||
|
|
||||||
extern crate ar;
|
extern crate ar;
|
||||||
extern crate faerie;
|
extern crate faerie;
|
||||||
//extern crate goblin;
|
//extern crate goblin;
|
||||||
extern crate target_lexicon;
|
|
||||||
extern crate cranelift;
|
extern crate cranelift;
|
||||||
|
extern crate cranelift_faerie;
|
||||||
extern crate cranelift_module;
|
extern crate cranelift_module;
|
||||||
extern crate cranelift_simplejit;
|
extern crate cranelift_simplejit;
|
||||||
extern crate cranelift_faerie;
|
extern crate target_lexicon;
|
||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::sync::{mpsc, Arc};
|
|
||||||
use std::path::Path;
|
|
||||||
use std::fs::File;
|
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::dep_graph::DepGraph;
|
||||||
|
use rustc::middle::cstore::MetadataLoader;
|
||||||
|
use rustc::session::{
|
||||||
|
config::{CrateType, OutputFilenames},
|
||||||
|
CompileIncomplete,
|
||||||
|
};
|
||||||
use rustc::ty::query::Providers;
|
use rustc::ty::query::Providers;
|
||||||
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
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 rustc_data_structures::owning_ref::{self, OwningRef};
|
||||||
|
use syntax::symbol::Symbol;
|
||||||
|
|
||||||
use cranelift::codegen::settings;
|
use cranelift::codegen::settings;
|
||||||
use cranelift_faerie::*;
|
use cranelift_faerie::*;
|
||||||
|
|
||||||
mod abi;
|
mod abi;
|
||||||
mod base;
|
mod base;
|
||||||
mod constant;
|
|
||||||
mod common;
|
mod common;
|
||||||
|
mod constant;
|
||||||
mod pretty_clif;
|
mod pretty_clif;
|
||||||
|
|
||||||
mod prelude {
|
mod prelude {
|
||||||
pub use std::any::Any;
|
pub use std::any::Any;
|
||||||
pub use std::collections::{HashMap, HashSet};
|
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::hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
pub use rustc::mir;
|
pub use rustc::mir;
|
||||||
pub use rustc::mir::*;
|
|
||||||
pub use rustc::mir::interpret::AllocId;
|
pub use rustc::mir::interpret::AllocId;
|
||||||
|
pub use rustc::mir::*;
|
||||||
pub use rustc::session::Session;
|
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::{
|
pub use rustc::ty::{
|
||||||
self, subst::Substs, FnSig, Instance, InstanceDef, ParamEnv, PolyFnSig, Ty, TyCtxt,
|
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_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::{
|
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::codegen::Context;
|
||||||
pub use cranelift::prelude::*;
|
pub use cranelift::prelude::*;
|
||||||
pub use cranelift_module::{Module, Backend, DataContext, FuncId, DataId, Linkage, Writability};
|
pub use cranelift_module::{
|
||||||
pub use cranelift_simplejit::{SimpleJITBuilder, SimpleJITBackend};
|
Backend, DataContext, DataId, FuncId, Linkage, Module, Writability,
|
||||||
|
};
|
||||||
|
pub use cranelift_simplejit::{SimpleJITBackend, SimpleJITBuilder};
|
||||||
|
|
||||||
pub use crate::abi::*;
|
pub use crate::abi::*;
|
||||||
|
pub use crate::base::{trans_operand, trans_place};
|
||||||
pub use crate::common::Variable;
|
pub use crate::common::Variable;
|
||||||
pub use crate::common::*;
|
pub use crate::common::*;
|
||||||
pub use crate::base::{trans_operand, trans_place};
|
|
||||||
|
|
||||||
pub use crate::CodegenCx;
|
pub use crate::CodegenCx;
|
||||||
}
|
}
|
||||||
@@ -95,7 +94,11 @@ pub struct CodegenCx<'a, 'tcx: 'a, B: Backend + 'a> {
|
|||||||
struct CraneliftMetadataLoader;
|
struct CraneliftMetadataLoader;
|
||||||
|
|
||||||
impl MetadataLoader for CraneliftMetadataLoader {
|
impl MetadataLoader for CraneliftMetadataLoader {
|
||||||
fn get_rlib_metadata(&self, _target: &rustc_target::spec::Target, path: &Path) -> Result<owning_ref::ErasedBoxRef<[u8]>, String> {
|
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))?);
|
let mut archive = ar::Archive::new(File::open(path).map_err(|e| format!("{:?}", e))?);
|
||||||
// Iterate over all entries in the archive:
|
// Iterate over all entries in the archive:
|
||||||
while let Some(entry_result) = archive.next_entry() {
|
while let Some(entry_result) = archive.next_entry() {
|
||||||
@@ -112,7 +115,11 @@ impl MetadataLoader for CraneliftMetadataLoader {
|
|||||||
//self.get_dylib_metadata(target, path)
|
//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;
|
//use goblin::Object;
|
||||||
|
|
||||||
//let buffer = ::std::fs::read(path).map_err(|e|format!("{:?}", e))?;
|
//let buffer = ::std::fs::read(path).map_err(|e|format!("{:?}", e))?;
|
||||||
@@ -149,13 +156,15 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||||||
fn init(&self, sess: &Session) {
|
fn init(&self, sess: &Session) {
|
||||||
for cty in sess.opts.crate_types.iter() {
|
for cty in sess.opts.crate_types.iter() {
|
||||||
match *cty {
|
match *cty {
|
||||||
CrateType::CrateTypeRlib | CrateType::CrateTypeDylib |
|
CrateType::CrateTypeRlib
|
||||||
CrateType::CrateTypeExecutable => {},
|
| CrateType::CrateTypeDylib
|
||||||
|
| CrateType::CrateTypeExecutable => {}
|
||||||
_ => {
|
_ => {
|
||||||
sess.parse_sess.span_diagnostic.warn(
|
sess.parse_sess.span_diagnostic.warn(&format!(
|
||||||
&format!("LLVM unsupported, so output type {} is not supported", cty)
|
"LLVM unsupported, so output type {} is not supported",
|
||||||
);
|
cty
|
||||||
},
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,9 +176,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||||||
fn provide(&self, providers: &mut Providers) {
|
fn provide(&self, providers: &mut Providers) {
|
||||||
rustc_codegen_utils::symbol_names::provide(providers);
|
rustc_codegen_utils::symbol_names::provide(providers);
|
||||||
|
|
||||||
providers.target_features_whitelist = |_tcx, _cnum| {
|
providers.target_features_whitelist = |_tcx, _cnum| Lrc::new(Default::default());
|
||||||
Lrc::new(Default::default())
|
|
||||||
};
|
|
||||||
providers.is_reachable_non_generic = |_tcx, _defid| true;
|
providers.is_reachable_non_generic = |_tcx, _defid| true;
|
||||||
providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new());
|
providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new());
|
||||||
}
|
}
|
||||||
@@ -180,7 +187,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||||||
fn codegen_crate<'a, 'tcx>(
|
fn codegen_crate<'a, 'tcx>(
|
||||||
&self,
|
&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_rx: mpsc::Receiver<Box<Any + Send>>
|
_rx: mpsc::Receiver<Box<Any + Send>>,
|
||||||
) -> Box<Any> {
|
) -> Box<Any> {
|
||||||
use rustc_mir::monomorphize::item::MonoItem;
|
use rustc_mir::monomorphize::item::MonoItem;
|
||||||
|
|
||||||
@@ -188,20 +195,18 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||||||
rustc_codegen_utils::symbol_names_test::report_symbol_names(tcx);
|
rustc_codegen_utils::symbol_names_test::report_symbol_names(tcx);
|
||||||
rustc_incremental::assert_dep_graph(tcx);
|
rustc_incremental::assert_dep_graph(tcx);
|
||||||
rustc_incremental::assert_module_sources::assert_module_sources(tcx);
|
rustc_incremental::assert_module_sources::assert_module_sources(tcx);
|
||||||
rustc_mir::monomorphize::assert_symbols_are_distinct(tcx,
|
rustc_mir::monomorphize::assert_symbols_are_distinct(
|
||||||
collector::collect_crate_mono_items(
|
|
||||||
tcx,
|
tcx,
|
||||||
collector::MonoItemCollectionMode::Eager
|
collector::collect_crate_mono_items(tcx, collector::MonoItemCollectionMode::Eager)
|
||||||
).0.iter()
|
.0
|
||||||
|
.iter(),
|
||||||
);
|
);
|
||||||
//::rustc::middle::dependency_format::calculate(tcx);
|
//::rustc::middle::dependency_format::calculate(tcx);
|
||||||
let _ = tcx.link_args(LOCAL_CRATE);
|
let _ = tcx.link_args(LOCAL_CRATE);
|
||||||
let _ = tcx.native_libraries(LOCAL_CRATE);
|
let _ = tcx.native_libraries(LOCAL_CRATE);
|
||||||
for mono_item in
|
for mono_item in
|
||||||
collector::collect_crate_mono_items(
|
collector::collect_crate_mono_items(tcx, collector::MonoItemCollectionMode::Eager).0
|
||||||
tcx,
|
{
|
||||||
collector::MonoItemCollectionMode::Eager
|
|
||||||
).0 {
|
|
||||||
match mono_item {
|
match mono_item {
|
||||||
MonoItem::Fn(inst) => {
|
MonoItem::Fn(inst) => {
|
||||||
let def_id = inst.def_id();
|
let def_id = inst.def_id();
|
||||||
@@ -221,7 +226,9 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||||||
let mut flags_builder = settings::builder();
|
let mut flags_builder = settings::builder();
|
||||||
flags_builder.enable("is_pic").unwrap();
|
flags_builder.enable("is_pic").unwrap();
|
||||||
let flags = settings::Flags::new(flags_builder);
|
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 module: Module<SimpleJITBackend> = Module::new(SimpleJITBuilder::new());
|
||||||
let mut context = Context::new();
|
let mut context = Context::new();
|
||||||
|
|
||||||
@@ -233,10 +240,8 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for mono_item in
|
for mono_item in
|
||||||
collector::collect_crate_mono_items(
|
collector::collect_crate_mono_items(tcx, collector::MonoItemCollectionMode::Eager).0
|
||||||
tcx,
|
{
|
||||||
collector::MonoItemCollectionMode::Eager
|
|
||||||
).0 {
|
|
||||||
base::trans_mono_item(&mut cx, &mut context, mono_item)
|
base::trans_mono_item(&mut cx, &mut context, mono_item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,11 +254,8 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||||||
tcx.sess.warn("Finalized everything");
|
tcx.sess.warn("Finalized everything");
|
||||||
|
|
||||||
for mono_item in
|
for mono_item in
|
||||||
collector::collect_crate_mono_items(
|
collector::collect_crate_mono_items(tcx, collector::MonoItemCollectionMode::Eager).0
|
||||||
tcx,
|
{
|
||||||
collector::MonoItemCollectionMode::Eager
|
|
||||||
).0 {
|
|
||||||
|
|
||||||
let inst = match mono_item {
|
let inst = match mono_item {
|
||||||
MonoItem::Fn(inst) => inst,
|
MonoItem::Fn(inst) => inst,
|
||||||
_ => continue,
|
_ => continue,
|
||||||
@@ -266,17 +268,21 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||||||
|
|
||||||
let fn_ty = inst.ty(tcx);
|
let fn_ty = inst.ty(tcx);
|
||||||
let sig = cton_sig_from_fn_ty(tcx, fn_ty);
|
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();
|
let mut name = String::new();
|
||||||
def_path_based_names.push_instance_as_string(inst, &mut name);
|
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 finalized_function: *const u8 = module.finalize_function(func_id);
|
||||||
/*let f: extern "C" fn(&mut u32) = unsafe { ::std::mem::transmute(finalized_function) };
|
/*let f: extern "C" fn(&mut u32) = unsafe { ::std::mem::transmute(finalized_function) };
|
||||||
let mut res = 0u32;
|
let mut res = 0u32;
|
||||||
f(&mut res);
|
f(&mut res);
|
||||||
tcx.sess.warn(&format!("ret_42 returned {}", 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;
|
let mut res = false;
|
||||||
f(&mut res, &3, false);
|
f(&mut res, &3, false);
|
||||||
tcx.sess.warn(&format!("option_unwrap_or returned {}", res));
|
tcx.sess.warn(&format!("option_unwrap_or returned {}", res));
|
||||||
@@ -290,9 +296,8 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||||||
isa,
|
isa,
|
||||||
"some_file.o".to_string(),
|
"some_file.o".to_string(),
|
||||||
FaerieTrapCollection::Disabled,
|
FaerieTrapCollection::Disabled,
|
||||||
FaerieBuilder::default_libcall_names()
|
FaerieBuilder::default_libcall_names(),
|
||||||
)
|
).unwrap(),
|
||||||
.unwrap()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Box::new(OngoingCodegen {
|
Box::new(OngoingCodegen {
|
||||||
@@ -309,30 +314,42 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||||||
_dep_graph: &DepGraph,
|
_dep_graph: &DepGraph,
|
||||||
outputs: &OutputFilenames,
|
outputs: &OutputFilenames,
|
||||||
) -> Result<(), CompileIncomplete> {
|
) -> Result<(), CompileIncomplete> {
|
||||||
let ongoing_codegen = *ongoing_codegen.downcast::<OngoingCodegen>()
|
let ongoing_codegen = *ongoing_codegen
|
||||||
|
.downcast::<OngoingCodegen>()
|
||||||
.expect("Expected CraneliftCodegenBackend's OngoingCodegen, found Box<Any>");
|
.expect("Expected CraneliftCodegenBackend's OngoingCodegen, found Box<Any>");
|
||||||
|
|
||||||
let mut artifact = ongoing_codegen.product.artifact;
|
let mut artifact = ongoing_codegen.product.artifact;
|
||||||
let metadata = ongoing_codegen.metadata;
|
let metadata = ongoing_codegen.metadata;
|
||||||
|
|
||||||
artifact.declare_with(
|
artifact
|
||||||
|
.declare_with(
|
||||||
".rustc.clif_metadata",
|
".rustc.clif_metadata",
|
||||||
faerie::artifact::Decl::Data {
|
faerie::artifact::Decl::Data {
|
||||||
global: true,
|
global: true,
|
||||||
writeable: false
|
writeable: false,
|
||||||
},
|
},
|
||||||
metadata.clone(),
|
metadata.clone(),
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
for &crate_type in sess.opts.crate_types.iter() {
|
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));
|
sess.fatal(&format!("Unsupported crate type: {:?}", crate_type));
|
||||||
}
|
}
|
||||||
let output_name =
|
let output_name = out_filename(
|
||||||
out_filename(sess, crate_type, &outputs, &ongoing_codegen.crate_name.as_str());
|
sess,
|
||||||
|
crate_type,
|
||||||
|
&outputs,
|
||||||
|
&ongoing_codegen.crate_name.as_str(),
|
||||||
|
);
|
||||||
let file = File::create(&output_name).unwrap();
|
let file = File::create(&output_name).unwrap();
|
||||||
let mut builder = ar::Builder::new(file);
|
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();
|
//artifact.write(file).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user