@@ -26,8 +26,9 @@ extern crate libc;
26
26
extern crate log;
27
27
extern crate llvm = "rustc_llvm" ;
28
28
29
- use getopts:: { optopt, optflag, getopts, reqopt, OptGroup , Matches } ;
29
+ use getopts:: { optopt, optflag, getopts, reqopt, optmulti , OptGroup , Matches } ;
30
30
use std:: c_str:: CString ;
31
+ use std:: collections:: { HashSet , HashMap } ;
31
32
use std:: fmt:: Show ;
32
33
use std:: io:: fs:: File ;
33
34
use std:: io:: process:: { Command , InheritFd , ExitStatus } ;
@@ -62,7 +63,9 @@ fn optgroups() -> Vec<OptGroup> {
62
63
optopt( "" , "opt-level" , "Optimize with possible levels 0-3" , "LEVEL" ) ,
63
64
optflag( "" , "save-temps" , "Save temp files" ) ,
64
65
optopt( "" , "target" , "The target triple to codegen for" , "" ) ,
65
- reqopt( "" , "cross-path" , "The path to the Pepper SDK" , "" ) )
66
+ reqopt( "" , "cross-path" , "The path to the Pepper SDK" , "" ) ,
67
+ optmulti( "" , "raw" , "The specified bitcodes have had none of the usual PNaCl IR \
68
+ legalization passes run on them", "" ) )
66
69
67
70
}
68
71
fn fatal < T : Str + Show > ( msg : T ) -> ! {
@@ -137,17 +140,36 @@ pub fn main() {
137
140
let cross_path = matches. opt_str ( "cross-path" ) . unwrap ( ) ;
138
141
let cross_path = os:: make_absolute ( & Path :: new ( cross_path) ) ;
139
142
140
- let input = if ! matches. free . is_empty ( ) {
141
- matches . free . clone ( )
142
- } else {
143
- fatal ( "missing input file(s)" ) ;
144
- } ;
143
+ let mut input: Vec < ( String , bool ) > = matches. free
144
+ . iter ( )
145
+ . map ( |i| ( i . clone ( ) , false ) )
146
+ . collect ( ) ;
147
+
145
148
let output = matches. opt_str ( "o" ) . unwrap ( ) ;
146
149
let ctxt = unsafe { llvm:: LLVMContextCreate ( ) } ;
147
150
148
- let mut bc_input = Vec :: new ( ) ;
151
+ unsafe {
152
+ llvm:: LLVMInitializePasses ( ) ;
153
+ }
154
+
155
+ {
156
+ let raw_bitcodes_vec = matches. opt_strs ( "raw" ) ;
157
+ let mut raw_bitcodes = HashSet :: new ( ) ;
158
+ for i in raw_bitcodes_vec. move_iter ( ) {
159
+ if !raw_bitcodes. insert ( i. clone ( ) ) {
160
+ warn ( format ! ( "file specified two or more times in --raw: `{}`" , i) ) ;
161
+ }
162
+ input. push ( ( i, true ) ) ;
163
+ }
164
+ }
165
+
166
+ if input. is_empty ( ) {
167
+ fatal ( "missing input file(s)" ) ;
168
+ }
169
+
170
+ let mut bc_input = HashMap :: new ( ) ;
149
171
let mut obj_input: Vec < String > = Vec :: new ( ) ;
150
- for i in input. move_iter ( ) {
172
+ for ( i , is_raw ) in input. move_iter ( ) {
151
173
let bc = match File :: open ( & Path :: new ( i. clone ( ) ) ) . read_to_end ( ) {
152
174
Ok ( buf) => buf,
153
175
Err ( e) => {
@@ -165,9 +187,23 @@ pub fn main() {
165
187
}
166
188
} ) ;
167
189
if llmod == ptr:: mut_null ( ) {
190
+ if is_raw {
191
+ warn ( format ! ( "raw bitcode isn't bitcode: `{}`" , i) ) ;
192
+ }
168
193
obj_input. push ( i) ;
169
194
} else {
170
- bc_input. push ( ( llmod, i) ) ;
195
+ if is_raw {
196
+ unsafe {
197
+ let pm = llvm:: LLVMCreatePassManager ( ) ;
198
+ "pnacl-sjlj-eh" . with_c_str ( |s| assert ! ( llvm:: LLVMRustAddPass ( pm, s) ) ) ;
199
+ "expand-varargs" . with_c_str ( |s| assert ! ( llvm:: LLVMRustAddPass ( pm, s) ) ) ;
200
+ llvm:: LLVMRunPassManager ( pm, llmod) ;
201
+ llvm:: LLVMDisposePassManager ( pm) ;
202
+ }
203
+ }
204
+ if !bc_input. insert ( i. clone ( ) , llmod) {
205
+ warn ( format ! ( "file specified two or more times: `{}`" , i) ) ;
206
+ }
171
207
}
172
208
}
173
209
@@ -191,8 +227,6 @@ pub fn main() {
191
227
}
192
228
}
193
229
194
- llvm:: LLVMInitializePasses ( ) ;
195
-
196
230
// Only initialize the platforms supported by Rust here, because
197
231
// using --llvm-root will have multiple platforms that rustllvm
198
232
// doesn't actually link to and it's pointless to put target info
@@ -239,7 +273,7 @@ pub fn main() {
239
273
240
274
let obj_input: Vec < String > = bc_input
241
275
. move_iter ( )
242
- . filter_map ( |( llmod , i ) | {
276
+ . filter_map ( |( i , llmod ) | {
243
277
debug ! ( "translating `{}`" , i) ;
244
278
unsafe {
245
279
let pm = llvm:: LLVMCreatePassManager ( ) ;
0 commit comments