@@ -14,8 +14,9 @@ use std::ptr;
14
14
use attributes;
15
15
use libc:: c_uint;
16
16
use rustc:: middle:: allocator:: AllocatorKind ;
17
+ use rustc:: session:: InjectedDefaultOomHook ;
17
18
use rustc:: ty:: TyCtxt ;
18
- use rustc_allocator:: { ALLOCATOR_METHODS , AllocatorTy } ;
19
+ use rustc_allocator:: { ALLOCATOR_METHODS , OOM_HANDLING_METHODS , AllocatorTy } ;
19
20
20
21
use ModuleLlvm ;
21
22
use llvm:: { self , False , True } ;
@@ -33,9 +34,10 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind
33
34
let i8p = llvm:: LLVMPointerType ( i8, 0 ) ;
34
35
let void = llvm:: LLVMVoidTypeInContext ( llcx) ;
35
36
36
- for method in ALLOCATOR_METHODS {
37
+ let build = |name : String , inputs : & [ AllocatorTy ] , output : & AllocatorTy ,
38
+ callee : Option < String > | {
37
39
let mut args = Vec :: new ( ) ;
38
- for ty in method . inputs . iter ( ) {
40
+ for ty in inputs. iter ( ) {
39
41
match * ty {
40
42
AllocatorTy :: Layout => {
41
43
args. push ( usize) ; // size
@@ -48,7 +50,7 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind
48
50
AllocatorTy :: Unit => panic ! ( "invalid allocator arg" ) ,
49
51
}
50
52
}
51
- let output = match method . output {
53
+ let output = match * output {
52
54
AllocatorTy :: ResultPtr => Some ( i8p) ,
53
55
AllocatorTy :: Unit => None ,
54
56
@@ -60,29 +62,40 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind
60
62
args. as_ptr ( ) ,
61
63
args. len ( ) as c_uint ,
62
64
False ) ;
63
- let name = CString :: new ( format ! ( "__rust_{}" , method . name) ) . unwrap ( ) ;
65
+ let name = CString :: new ( name) . unwrap ( ) ;
64
66
let llfn = llvm:: LLVMRustGetOrInsertFunction ( llmod,
65
67
name. as_ptr ( ) ,
66
68
ty) ;
67
69
68
70
if tcx. sess . target . target . options . default_hidden_visibility {
69
71
llvm:: LLVMRustSetVisibility ( llfn, llvm:: Visibility :: Hidden ) ;
70
72
}
71
- if tcx. sess . target . target . options . requires_uwtable {
72
- attributes:: emit_uwtable ( llfn, true ) ;
73
- }
74
-
75
- let callee = CString :: new ( kind. fn_name ( method. name ) ) . unwrap ( ) ;
76
- let callee = llvm:: LLVMRustGetOrInsertFunction ( llmod,
77
- callee. as_ptr ( ) ,
78
- ty) ;
73
+ if tcx. sess . target . target . options . requires_uwtable {
74
+ attributes:: emit_uwtable ( llfn, true ) ;
75
+ }
79
76
80
77
let llbb = llvm:: LLVMAppendBasicBlockInContext ( llcx,
81
78
llfn,
82
79
"entry\0 " . as_ptr ( ) as * const _ ) ;
83
80
84
81
let llbuilder = llvm:: LLVMCreateBuilderInContext ( llcx) ;
85
82
llvm:: LLVMPositionBuilderAtEnd ( llbuilder, llbb) ;
83
+
84
+ let callee = if let Some ( callee) = callee {
85
+ callee
86
+ } else {
87
+ // Generate a no-op function
88
+ llvm:: LLVMBuildRetVoid ( llbuilder) ;
89
+ llvm:: LLVMDisposeBuilder ( llbuilder) ;
90
+ return
91
+ } ;
92
+
93
+ // Forward the call to another function
94
+ let callee = CString :: new ( callee) . unwrap ( ) ;
95
+ let callee = llvm:: LLVMRustGetOrInsertFunction ( llmod,
96
+ callee. as_ptr ( ) ,
97
+ ty) ;
98
+
86
99
let args = args. iter ( ) . enumerate ( ) . map ( |( i, _) | {
87
100
llvm:: LLVMGetParam ( llfn, i as c_uint )
88
101
} ) . collect :: < Vec < _ > > ( ) ;
@@ -98,6 +111,28 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind
98
111
} else {
99
112
llvm:: LLVMBuildRetVoid ( llbuilder) ;
100
113
}
114
+
101
115
llvm:: LLVMDisposeBuilder ( llbuilder) ;
116
+ } ;
117
+
118
+ for method in ALLOCATOR_METHODS {
119
+ let name = format ! ( "__rust_{}" , method. name) ;
120
+ build ( name, method. inputs , & method. output , Some ( kind. fn_name ( method. name ) ) )
121
+ }
122
+
123
+ let has_plaftom_functions = match tcx. sess . injected_default_alloc_error_hook . get ( ) {
124
+ InjectedDefaultOomHook :: None => return ,
125
+ InjectedDefaultOomHook :: Noop => false ,
126
+ InjectedDefaultOomHook :: Platform => true ,
127
+ } ;
128
+
129
+ for method in OOM_HANDLING_METHODS {
130
+ let callee = if has_plaftom_functions {
131
+ Some ( format ! ( "__rust_{}" , method. name) )
132
+ } else {
133
+ None
134
+ } ;
135
+ let name = format ! ( "__rust_maybe_{}" , method. name) ;
136
+ build ( name, method. inputs , & method. output , callee)
102
137
}
103
138
}
0 commit comments