diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/allocator.rs | 81 | ||||
| -rw-r--r-- | src/lib.rs | 13 |
2 files changed, 94 insertions, 0 deletions
diff --git a/src/allocator.rs b/src/allocator.rs new file mode 100644 index 00000000000..72ddf5312bd --- /dev/null +++ b/src/allocator.rs @@ -0,0 +1,81 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use crate::prelude::*; + +use crate::rustc::middle::allocator::AllocatorKind; +use crate::rustc_allocator::{ALLOCATOR_METHODS, AllocatorTy}; + +pub fn codegen(tcx: TyCtxt, module: &mut Module<impl Backend + 'static>, kind: AllocatorKind) { + let usize_ty = module.target_config().pointer_type(); + + for method in ALLOCATOR_METHODS { + let mut arg_tys = Vec::with_capacity(method.inputs.len()); + for ty in method.inputs.iter() { + match *ty { + AllocatorTy::Layout => { + arg_tys.push(usize_ty); // size + arg_tys.push(usize_ty); // align + } + AllocatorTy::Ptr => arg_tys.push(usize_ty), + AllocatorTy::Usize => arg_tys.push(usize_ty), + + AllocatorTy::ResultPtr | + AllocatorTy::Unit => panic!("invalid allocator arg"), + } + } + let output = match method.output { + AllocatorTy::ResultPtr => Some(usize_ty), + AllocatorTy::Unit => None, + + AllocatorTy::Layout | + AllocatorTy::Usize | + AllocatorTy::Ptr => panic!("invalid allocator output"), + }; + + let sig = Signature { + call_conv: CallConv::Fast, + params: arg_tys.iter().cloned().map(AbiParam::new).collect(), + returns: output.into_iter().map(AbiParam::new).collect(), + }; + + let func_id = module + .declare_function(&format!("__rust_{}", method.name), Linkage::Export, &sig) + .unwrap(); + + let callee_func_id = module + .declare_function(&kind.fn_name(method.name), Linkage::Import, &sig) + .unwrap(); + + let mut ctx = Context::new(); + ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig.clone()); + { + let mut func_ctx = FunctionBuilderContext::new(); + let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); + + let ebb = bcx.create_ebb(); + bcx.switch_to_block(ebb); + let args = arg_tys + .into_iter() + .map(|ty| bcx.append_ebb_param(ebb, ty)) + .collect::<Vec<Value>>(); + + let callee_func_ref = module.declare_func_in_func(callee_func_id, &mut bcx.func); + + let call_inst = bcx.ins().call(callee_func_ref, &args); + + let results = bcx.inst_results(call_inst).to_vec(); // Clone to prevent borrow error + bcx.ins().return_(&results); + bcx.seal_all_blocks(); + bcx.finalize(); + } + module.define_function(func_id, &mut ctx).unwrap(); + } +} diff --git a/src/lib.rs b/src/lib.rs index c9ca758e55a..013dbc510d8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ extern crate byteorder; extern crate syntax; #[macro_use] extern crate rustc; +extern crate rustc_allocator; extern crate rustc_codegen_utils; extern crate rustc_incremental; extern crate rustc_mir; @@ -47,6 +48,7 @@ macro_rules! unimpl { } mod abi; +mod allocator; mod analyze; mod base; mod common; @@ -374,6 +376,17 @@ fn codegen_mono_items<'a, 'tcx: 'a>( crate::main_shim::maybe_create_entry_wrapper(tcx, module); + let any_dynamic_crate = tcx.sess.dependency_formats.borrow() + .iter() + .any(|(_, list)| { + use crate::rustc::middle::dependency_format::Linkage; + list.iter().any(|&linkage| linkage == Linkage::Dynamic) + }); + if any_dynamic_crate { + } else if let Some(kind) = *tcx.sess.allocator_kind.get() { + allocator::codegen(tcx, module, kind); + } + ccx.finalize(tcx, module); let after = ::std::time::Instant::now(); |
