11#[ cfg( feature="master" ) ]
22use gccjit:: FnAttribute ;
3- use gccjit:: { FunctionType , GlobalKind , ToRValue } ;
3+ use gccjit:: { Context , FunctionType , GlobalKind , ToRValue , Type } ;
44use 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