Skip to content

Commit 7ba60ec

Browse files
committed
Extract a create_wrapper_function for use in allocator shim writing
This deduplicates some logic and makes it easier to follow what wrappers are produced. In the future it may allow moving the code to determine which wrappers to create to cg_ssa.
1 parent 3a74f93 commit 7ba60ec

File tree

1 file changed

+50
-59
lines changed

1 file changed

+50
-59
lines changed

src/allocator.rs

Lines changed: 50 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#[cfg(feature="master")]
22
use gccjit::FnAttribute;
3-
use gccjit::{FunctionType, GlobalKind, ToRValue};
3+
use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type};
44
use rustc_ast::expand::allocator::{
55
alloc_error_handler_name, default_fn_name, global_fn_name, AllocatorKind, AllocatorTy,
66
ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE,
@@ -22,7 +22,6 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam
2222
};
2323
let i8 = context.new_type::<i8>();
2424
let i8p = i8.make_pointer();
25-
let void = context.new_type::<()>();
2625

2726
if kind == AllocatorKind::Default {
2827
for method in ALLOCATOR_METHODS {
@@ -47,67 +46,62 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam
4746
panic!("invalid allocator output")
4847
}
4948
};
50-
let name = global_fn_name(method.name);
49+
let from_name = global_fn_name(method.name);
50+
let to_name = default_fn_name(method.name);
5151

52-
let args: Vec<_> = types.iter().enumerate()
53-
.map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index)))
54-
.collect();
55-
let func = context.new_function(None, FunctionType::Exported, output.unwrap_or(void), &args, name, false);
52+
create_wrapper_function(tcx, context, &from_name, &to_name, &types, output);
53+
}
54+
}
5655

57-
if tcx.sess.target.options.default_hidden_visibility {
58-
#[cfg(feature="master")]
59-
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
60-
}
61-
if tcx.sess.must_emit_unwind_tables() {
62-
// TODO(antoyo): emit unwind tables.
63-
}
56+
// FIXME(bjorn3): Add noreturn attribute
57+
create_wrapper_function(
58+
tcx,
59+
context,
60+
"__rust_alloc_error_handler",
61+
&alloc_error_handler_name(alloc_error_handler_kind),
62+
&[usize, usize],
63+
None,
64+
);
6465

65-
let callee = default_fn_name(method.name);
66-
let args: Vec<_> = types.iter().enumerate()
67-
.map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index)))
68-
.collect();
69-
let callee = context.new_function(None, FunctionType::Extern, output.unwrap_or(void), &args, callee, false);
70-
#[cfg(feature="master")]
71-
callee.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
72-
73-
let block = func.new_block("entry");
74-
75-
let args = args
76-
.iter()
77-
.enumerate()
78-
.map(|(i, _)| func.get_param(i as i32).to_rvalue())
79-
.collect::<Vec<_>>();
80-
let ret = context.new_call(None, callee, &args);
81-
//llvm::LLVMSetTailCall(ret, True);
82-
if output.is_some() {
83-
block.end_with_return(None, ret);
84-
}
85-
else {
86-
block.end_with_void_return(None);
87-
}
66+
let name = OomStrategy::SYMBOL.to_string();
67+
let global = context.new_global(None, GlobalKind::Exported, i8, name);
68+
let value = tcx.sess.opts.unstable_opts.oom.should_panic();
69+
let value = context.new_rvalue_from_int(i8, value as i32);
70+
global.global_set_initializer_rvalue(value);
8871

89-
// TODO(@Commeownist): Check if we need to emit some extra debugging info in certain circumstances
90-
// as described in https://github.com/rust-lang/rust/commit/77a96ed5646f7c3ee8897693decc4626fe380643
91-
}
92-
}
72+
let name = NO_ALLOC_SHIM_IS_UNSTABLE.to_string();
73+
let global = context.new_global(None, GlobalKind::Exported, i8, name);
74+
let value = context.new_rvalue_from_int(i8, 0);
75+
global.global_set_initializer_rvalue(value);
76+
}
77+
78+
fn create_wrapper_function(
79+
tcx: TyCtxt<'_>,
80+
context: &Context<'_>,
81+
from_name: &str,
82+
to_name: &str,
83+
types: &[Type<'_>],
84+
output: Option<Type<'_>>,
85+
) {
86+
let void = context.new_type::<()>();
9387

94-
let types = [usize, usize];
95-
let name = "__rust_alloc_error_handler".to_string();
9688
let args: Vec<_> = types.iter().enumerate()
9789
.map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index)))
9890
.collect();
99-
let func = context.new_function(None, FunctionType::Exported, void, &args, name, false);
91+
let func = context.new_function(None, FunctionType::Exported, output.unwrap_or(void), &args, from_name, false);
10092

101-
if tcx.sess.target.default_hidden_visibility {
93+
if tcx.sess.target.options.default_hidden_visibility {
10294
#[cfg(feature="master")]
10395
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
10496
}
97+
if tcx.sess.must_emit_unwind_tables() {
98+
// TODO(antoyo): emit unwind tables.
99+
}
105100

106-
let callee = alloc_error_handler_name(alloc_error_handler_kind);
107101
let args: Vec<_> = types.iter().enumerate()
108102
.map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index)))
109103
.collect();
110-
let callee = context.new_function(None, FunctionType::Extern, void, &args, callee, false);
104+
let callee = context.new_function(None, FunctionType::Extern, output.unwrap_or(void), &args, to_name, false);
111105
#[cfg(feature="master")]
112106
callee.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
113107

@@ -118,18 +112,15 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam
118112
.enumerate()
119113
.map(|(i, _)| func.get_param(i as i32).to_rvalue())
120114
.collect::<Vec<_>>();
121-
let _ret = context.new_call(None, callee, &args);
115+
let ret = context.new_call(None, callee, &args);
122116
//llvm::LLVMSetTailCall(ret, True);
123-
block.end_with_void_return(None);
124-
125-
let name = OomStrategy::SYMBOL.to_string();
126-
let global = context.new_global(None, GlobalKind::Exported, i8, name);
127-
let value = tcx.sess.opts.unstable_opts.oom.should_panic();
128-
let value = context.new_rvalue_from_int(i8, value as i32);
129-
global.global_set_initializer_rvalue(value);
117+
if output.is_some() {
118+
block.end_with_return(None, ret);
119+
}
120+
else {
121+
block.end_with_void_return(None);
122+
}
130123

131-
let name = NO_ALLOC_SHIM_IS_UNSTABLE.to_string();
132-
let global = context.new_global(None, GlobalKind::Exported, i8, name);
133-
let value = context.new_rvalue_from_int(i8, 0);
134-
global.global_set_initializer_rvalue(value);
124+
// TODO(@Commeownist): Check if we need to emit some extra debugging info in certain circumstances
125+
// as described in https://github.com/rust-lang/rust/commit/77a96ed5646f7c3ee8897693decc4626fe380643
135126
}

0 commit comments

Comments
 (0)