]>
Commit | Line | Data |
---|---|---|
29967ef6 XL |
1 | //! Allocator shim |
2 | // Adapted from rustc | |
3 | ||
4 | use crate::prelude::*; | |
5 | ||
49aad941 FG |
6 | use rustc_ast::expand::allocator::{ |
7 | alloc_error_handler_name, default_fn_name, global_fn_name, AllocatorKind, AllocatorTy, | |
8 | ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, | |
9 | }; | |
353b0b11 | 10 | use rustc_codegen_ssa::base::allocator_kind_for_codegen; |
5e7ed085 | 11 | use rustc_session::config::OomStrategy; |
29967ef6 XL |
12 | |
13 | /// Returns whether an allocator shim was created | |
14 | pub(crate) fn codegen( | |
15 | tcx: TyCtxt<'_>, | |
16 | module: &mut impl Module, | |
17df50a5 | 17 | unwind_context: &mut UnwindContext, |
29967ef6 | 18 | ) -> bool { |
353b0b11 FG |
19 | let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; |
20 | codegen_inner( | |
21 | module, | |
22 | unwind_context, | |
23 | kind, | |
24 | tcx.alloc_error_handler_kind(()).unwrap(), | |
25 | tcx.sess.opts.unstable_opts.oom, | |
26 | ); | |
27 | true | |
29967ef6 XL |
28 | } |
29 | ||
30 | fn codegen_inner( | |
31 | module: &mut impl Module, | |
17df50a5 | 32 | unwind_context: &mut UnwindContext, |
29967ef6 | 33 | kind: AllocatorKind, |
487cf647 | 34 | alloc_error_handler_kind: AllocatorKind, |
5e7ed085 | 35 | oom_strategy: OomStrategy, |
29967ef6 XL |
36 | ) { |
37 | let usize_ty = module.target_config().pointer_type(); | |
38 | ||
49aad941 FG |
39 | if kind == AllocatorKind::Default { |
40 | for method in ALLOCATOR_METHODS { | |
41 | let mut arg_tys = Vec::with_capacity(method.inputs.len()); | |
42 | for ty in method.inputs.iter() { | |
43 | match *ty { | |
44 | AllocatorTy::Layout => { | |
45 | arg_tys.push(usize_ty); // size | |
46 | arg_tys.push(usize_ty); // align | |
47 | } | |
48 | AllocatorTy::Ptr => arg_tys.push(usize_ty), | |
49 | AllocatorTy::Usize => arg_tys.push(usize_ty), | |
29967ef6 | 50 | |
49aad941 FG |
51 | AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), |
52 | } | |
29967ef6 | 53 | } |
49aad941 FG |
54 | let output = match method.output { |
55 | AllocatorTy::ResultPtr => Some(usize_ty), | |
56 | AllocatorTy::Unit => None, | |
29967ef6 | 57 | |
49aad941 FG |
58 | AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { |
59 | panic!("invalid allocator output") | |
60 | } | |
61 | }; | |
29967ef6 | 62 | |
49aad941 FG |
63 | let sig = Signature { |
64 | call_conv: module.target_config().default_call_conv, | |
65 | params: arg_tys.iter().cloned().map(AbiParam::new).collect(), | |
66 | returns: output.into_iter().map(AbiParam::new).collect(), | |
67 | }; | |
68 | crate::common::create_wrapper_function( | |
69 | module, | |
70 | unwind_context, | |
71 | sig, | |
72 | &global_fn_name(method.name), | |
73 | &default_fn_name(method.name), | |
74 | ); | |
75 | } | |
29967ef6 XL |
76 | } |
77 | ||
78 | let sig = Signature { | |
9c376795 | 79 | call_conv: module.target_config().default_call_conv, |
29967ef6 XL |
80 | params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)], |
81 | returns: vec![], | |
82 | }; | |
9ffffee4 FG |
83 | crate::common::create_wrapper_function( |
84 | module, | |
85 | unwind_context, | |
86 | sig, | |
87 | "__rust_alloc_error_handler", | |
49aad941 | 88 | &alloc_error_handler_name(alloc_error_handler_kind), |
9ffffee4 | 89 | ); |
5e7ed085 FG |
90 | |
91 | let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap(); | |
92 | let mut data_ctx = DataContext::new(); | |
93 | data_ctx.set_align(1); | |
94 | let val = oom_strategy.should_panic(); | |
95 | data_ctx.define(Box::new([val])); | |
96 | module.define_data(data_id, &data_ctx).unwrap(); | |
49aad941 FG |
97 | |
98 | let data_id = | |
99 | module.declare_data(NO_ALLOC_SHIM_IS_UNSTABLE, Linkage::Export, false, false).unwrap(); | |
100 | let mut data_ctx = DataContext::new(); | |
101 | data_ctx.set_align(1); | |
102 | data_ctx.define(Box::new([0])); | |
103 | module.define_data(data_id, &data_ctx).unwrap(); | |
29967ef6 | 104 | } |