|
14 | 14 | //! and methods are represented as just a fn ptr and not a full
|
15 | 15 | //! closure.
|
16 | 16 |
|
17 |
| -use llvm::{self, ValueRef, get_params}; |
| 17 | +use llvm::{self, ValueRef}; |
18 | 18 | use rustc::hir::def_id::DefId;
|
19 |
| -use rustc::ty::subst::{Substs, Subst}; |
20 |
| -use abi::{Abi, FnType}; |
| 19 | +use rustc::ty::subst::Substs; |
21 | 20 | use attributes;
|
22 |
| -use builder::Builder; |
23 | 21 | use common::{self, CrateContext};
|
24 |
| -use cleanup::CleanupScope; |
25 |
| -use mir::lvalue::LvalueRef; |
26 | 22 | use monomorphize;
|
27 | 23 | use consts;
|
28 | 24 | use declare;
|
29 |
| -use value::Value; |
30 | 25 | use monomorphize::Instance;
|
31 |
| -use back::symbol_names::symbol_name; |
32 | 26 | use trans_item::TransItem;
|
33 | 27 | use type_of;
|
34 |
| -use rustc::ty::{self, TypeFoldable}; |
35 |
| -use std::iter; |
36 |
| - |
37 |
| -use mir::lvalue::Alignment; |
38 |
| - |
39 |
| -fn trans_fn_once_adapter_shim<'a, 'tcx>( |
40 |
| - ccx: &'a CrateContext<'a, 'tcx>, |
41 |
| - def_id: DefId, |
42 |
| - substs: ty::ClosureSubsts<'tcx>, |
43 |
| - method_instance: Instance<'tcx>, |
44 |
| - llreffn: ValueRef) |
45 |
| - -> ValueRef |
46 |
| -{ |
47 |
| - if let Some(&llfn) = ccx.instances().borrow().get(&method_instance) { |
48 |
| - return llfn; |
49 |
| - } |
50 |
| - |
51 |
| - debug!("trans_fn_once_adapter_shim(def_id={:?}, substs={:?}, llreffn={:?})", |
52 |
| - def_id, substs, Value(llreffn)); |
53 |
| - |
54 |
| - let tcx = ccx.tcx(); |
55 |
| - |
56 |
| - // Find a version of the closure type. Substitute static for the |
57 |
| - // region since it doesn't really matter. |
58 |
| - let closure_ty = tcx.mk_closure_from_closure_substs(def_id, substs); |
59 |
| - let ref_closure_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReErased), closure_ty); |
60 |
| - |
61 |
| - // Make a version with the type of by-ref closure. |
62 |
| - let sig = tcx.closure_type(def_id).subst(tcx, substs.substs); |
63 |
| - let sig = tcx.erase_late_bound_regions_and_normalize(&sig); |
64 |
| - assert_eq!(sig.abi, Abi::RustCall); |
65 |
| - let llref_fn_sig = tcx.mk_fn_sig( |
66 |
| - iter::once(ref_closure_ty).chain(sig.inputs().iter().cloned()), |
67 |
| - sig.output(), |
68 |
| - sig.variadic, |
69 |
| - sig.unsafety, |
70 |
| - Abi::RustCall |
71 |
| - ); |
72 |
| - let llref_fn_ty = tcx.mk_fn_ptr(ty::Binder(llref_fn_sig)); |
73 |
| - debug!("trans_fn_once_adapter_shim: llref_fn_ty={:?}", |
74 |
| - llref_fn_ty); |
75 |
| - |
76 |
| - |
77 |
| - // Make a version of the closure type with the same arguments, but |
78 |
| - // with argument #0 being by value. |
79 |
| - let sig = tcx.mk_fn_sig( |
80 |
| - iter::once(closure_ty).chain(sig.inputs().iter().cloned()), |
81 |
| - sig.output(), |
82 |
| - sig.variadic, |
83 |
| - sig.unsafety, |
84 |
| - Abi::RustCall |
85 |
| - ); |
86 |
| - |
87 |
| - let fn_ty = FnType::new(ccx, sig, &[]); |
88 |
| - let llonce_fn_ty = tcx.mk_fn_ptr(ty::Binder(sig)); |
89 |
| - |
90 |
| - // Create the by-value helper. |
91 |
| - let function_name = symbol_name(method_instance, ccx.shared()); |
92 |
| - let lloncefn = declare::define_internal_fn(ccx, &function_name, llonce_fn_ty); |
93 |
| - attributes::set_frame_pointer_elimination(ccx, lloncefn); |
94 |
| - |
95 |
| - let orig_fn_ty = fn_ty; |
96 |
| - let mut bcx = Builder::new_block(ccx, lloncefn, "entry-block"); |
97 |
| - |
98 |
| - // the first argument (`self`) will be the (by value) closure env. |
99 |
| - |
100 |
| - let mut llargs = get_params(lloncefn); |
101 |
| - let fn_ty = FnType::new(ccx, llref_fn_sig, &[]); |
102 |
| - let self_idx = fn_ty.ret.is_indirect() as usize; |
103 |
| - let env_arg = &orig_fn_ty.args[0]; |
104 |
| - let env = if env_arg.is_indirect() { |
105 |
| - LvalueRef::new_sized_ty(llargs[self_idx], closure_ty, Alignment::AbiAligned) |
106 |
| - } else { |
107 |
| - let scratch = LvalueRef::alloca(&bcx, closure_ty, "self"); |
108 |
| - let mut llarg_idx = self_idx; |
109 |
| - env_arg.store_fn_arg(&bcx, &mut llarg_idx, scratch.llval); |
110 |
| - scratch |
111 |
| - }; |
112 |
| - |
113 |
| - debug!("trans_fn_once_adapter_shim: env={:?}", env); |
114 |
| - // Adjust llargs such that llargs[self_idx..] has the call arguments. |
115 |
| - // For zero-sized closures that means sneaking in a new argument. |
116 |
| - if env_arg.is_ignore() { |
117 |
| - llargs.insert(self_idx, env.llval); |
118 |
| - } else { |
119 |
| - llargs[self_idx] = env.llval; |
120 |
| - } |
121 |
| - |
122 |
| - // Call the by-ref closure body with `self` in a cleanup scope, |
123 |
| - // to drop `self` when the body returns, or in case it unwinds. |
124 |
| - let self_scope = CleanupScope::schedule_drop_mem(&bcx, env); |
125 |
| - |
126 |
| - let llret; |
127 |
| - if let Some(landing_pad) = self_scope.landing_pad { |
128 |
| - let normal_bcx = bcx.build_sibling_block("normal-return"); |
129 |
| - llret = bcx.invoke(llreffn, &llargs[..], normal_bcx.llbb(), landing_pad, None); |
130 |
| - bcx = normal_bcx; |
131 |
| - } else { |
132 |
| - llret = bcx.call(llreffn, &llargs[..], None); |
133 |
| - } |
134 |
| - fn_ty.apply_attrs_callsite(llret); |
135 |
| - |
136 |
| - if sig.output().is_never() { |
137 |
| - bcx.unreachable(); |
138 |
| - } else { |
139 |
| - self_scope.trans(&bcx); |
140 |
| - |
141 |
| - if fn_ty.ret.is_indirect() || fn_ty.ret.is_ignore() { |
142 |
| - bcx.ret_void(); |
143 |
| - } else { |
144 |
| - bcx.ret(llret); |
145 |
| - } |
146 |
| - } |
147 |
| - |
148 |
| - ccx.instances().borrow_mut().insert(method_instance, lloncefn); |
149 |
| - |
150 |
| - lloncefn |
151 |
| -} |
152 |
| - |
| 28 | +use rustc::ty::TypeFoldable; |
153 | 29 |
|
154 | 30 | /// Translates a reference to a fn/method item, monomorphizing and
|
155 | 31 | /// inlining as it goes.
|
156 | 32 | ///
|
157 | 33 | /// # Parameters
|
158 | 34 | ///
|
159 | 35 | /// - `ccx`: the crate context
|
160 |
| -/// - `def_id`: def id of the fn or method item being referenced |
161 |
| -/// - `substs`: values for each of the fn/method's parameters |
162 |
| -fn do_get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, |
163 |
| - instance: Instance<'tcx>) |
164 |
| - -> ValueRef |
| 36 | +/// - `instance`: the instance to be instantiated |
| 37 | +pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, |
| 38 | + instance: Instance<'tcx>) |
| 39 | + -> ValueRef |
165 | 40 | {
|
166 | 41 | let tcx = ccx.tcx();
|
167 | 42 |
|
@@ -248,40 +123,6 @@ fn do_get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
248 | 123 | llfn
|
249 | 124 | }
|
250 | 125 |
|
251 |
| -pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, |
252 |
| - instance: Instance<'tcx>) |
253 |
| - -> ValueRef |
254 |
| -{ |
255 |
| - match instance.def { |
256 |
| - ty::InstanceDef::Intrinsic(_) => { |
257 |
| - bug!("intrinsic {} getting reified", instance) |
258 |
| - } |
259 |
| - ty::InstanceDef::ClosureOnceShim { .. } => { |
260 |
| - let closure_ty = instance.substs.type_at(0); |
261 |
| - let (closure_def_id, closure_substs) = match closure_ty.sty { |
262 |
| - ty::TyClosure(def_id, substs) => (def_id, substs), |
263 |
| - _ => bug!("bad closure instance {:?}", instance) |
264 |
| - }; |
265 |
| - |
266 |
| - trans_fn_once_adapter_shim( |
267 |
| - ccx, |
268 |
| - closure_def_id, |
269 |
| - closure_substs, |
270 |
| - instance, |
271 |
| - do_get_fn( |
272 |
| - ccx, |
273 |
| - Instance::new(closure_def_id, closure_substs.substs) |
274 |
| - ) |
275 |
| - ) |
276 |
| - } |
277 |
| - ty::InstanceDef::FnPtrShim(..) | |
278 |
| - ty::InstanceDef::Item(..) | |
279 |
| - ty::InstanceDef::Virtual(..) => { |
280 |
| - do_get_fn(ccx, instance) |
281 |
| - } |
282 |
| - } |
283 |
| -} |
284 |
| - |
285 | 126 | pub fn resolve_and_get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
286 | 127 | def_id: DefId,
|
287 | 128 | substs: &'tcx Substs<'tcx>)
|
|
0 commit comments