@@ -30,6 +30,7 @@ type glue_fns = rec(ValueRef activate_glue,
30
30
type trans_ctxt = rec ( session . session sess,
31
31
ModuleRef llmod,
32
32
hashmap[ str, ValueRef ] upcalls ,
33
+ hashmap[ str, ValueRef ] fns ,
33
34
@glue_fns glues ,
34
35
str path ) ;
35
36
@@ -233,13 +234,17 @@ fn default_terminate(@fn_ctxt cx, builder build) {
233
234
build. RetVoid ( ) ;
234
235
}
235
236
237
+ fn new_builder( BasicBlockRef llbb) -> builder {
238
+ let BuilderRef llbuild = llvm. LLVMCreateBuilder ( ) ;
239
+ llvm. LLVMPositionBuilderAtEnd ( llbuild, llbb) ;
240
+ ret builder( llbuild) ;
241
+ }
242
+
236
243
fn trans_block( @fn_ctxt cx, & ast. block b, terminator term) {
237
244
let BasicBlockRef llbb =
238
245
llvm. LLVMAppendBasicBlock ( cx. llfn, _str. buf( "" ) ) ;
239
- let BuilderRef llbuild = llvm. LLVMCreateBuilder ( ) ;
240
- llvm. LLVMPositionBuilderAtEnd ( llbuild, llbb) ;
241
246
auto bcx = @rec( llbb=llbb,
242
- build=builder ( llbuild ) ,
247
+ build=new_builder ( llbb ) ,
243
248
term=term,
244
249
fcx=cx) ;
245
250
for ( @ast. stmt s in b) {
@@ -253,6 +258,7 @@ fn trans_fn(@trans_ctxt cx, &ast._fn f) {
253
258
T_taskptr ( ) // taskptr
254
259
) ;
255
260
let ValueRef llfn = decl_cdecl_fn( cx. llmod, cx. path, args, T_nil ( ) ) ;
261
+ cx. fns. insert( cx. path, llfn) ;
256
262
let ValueRef lloutptr = llvm. LLVMGetParam ( llfn, 0 u) ;
257
263
let ValueRef lltaskptr = llvm. LLVMGetParam ( llfn, 1 u) ;
258
264
auto fcx = @rec( llfn=llfn,
@@ -281,16 +287,17 @@ fn trans_mod(@trans_ctxt cx, &ast._mod m) {
281
287
}
282
288
}
283
289
290
+
291
+ fn p2i( ValueRef v) -> ValueRef {
292
+ ret llvm. LLVMConstPtrToInt ( v, T_int( ) ) ;
293
+ }
294
+
284
295
fn crate_constant( @trans_ctxt cx) -> ValueRef {
285
296
286
297
let ValueRef crate_ptr =
287
- llvm. LLVMAddGlobal ( cx. llmod, T_ptr ( T_crate ( ) ) ,
298
+ llvm. LLVMAddGlobal ( cx. llmod, T_crate( ) ,
288
299
_str. buf( "rust_crate") ) ;
289
300
290
- fn p2i( ValueRef v) -> ValueRef {
291
- ret llvm. LLVMConstPtrToInt ( v, T_int( ) ) ;
292
- }
293
-
294
301
let ValueRef crate_addr = p2i( crate_ptr) ;
295
302
296
303
let ValueRef activate_glue_off =
@@ -305,7 +312,7 @@ fn crate_constant(@trans_ctxt cx) -> ValueRef {
305
312
306
313
let ValueRef crate_val =
307
314
C_struct ( vec( C_null ( T_int( ) ) , // ptrdiff_t image_base_off
308
- crate_ptr, // uintptr_t self_addr
315
+ p2i ( crate_ptr) , // uintptr_t self_addr
309
316
C_null( T_int ( ) ) , // ptrdiff_t debug_abbrev_off
310
317
C_null( T_int ( ) ) , // size_t debug_abbrev_sz
311
318
C_null( T_int ( ) ) , // ptrdiff_t debug_info_off
@@ -324,6 +331,38 @@ fn crate_constant(@trans_ctxt cx) -> ValueRef {
324
331
ret crate_ptr;
325
332
}
326
333
334
+ fn trans_main_fn( @trans_ctxt cx, ValueRef llcrate) {
335
+ auto T_main_args = vec( T_int ( ) , T_int ( ) ) ;
336
+ auto T_rust_start_args = vec( T_int ( ) , T_int ( ) , T_int ( ) , T_int ( ) ) ;
337
+
338
+ auto llmain =
339
+ decl_cdecl_fn( cx. llmod, "main" , T_main_args , T_int ( ) ) ;
340
+
341
+ auto llrust_start =
342
+ decl_cdecl_fn( cx. llmod, "rust_start" , T_rust_start_args , T_int ( ) ) ;
343
+
344
+ auto llargc = llvm. LLVMGetParam ( llmain, 0 u) ;
345
+ auto llargv = llvm. LLVMGetParam ( llmain, 1 u) ;
346
+ auto llrust_main = cx. fns. get( "_rust.main" ) ;
347
+
348
+ //
349
+ // Emit the moral equivalent of:
350
+ //
351
+ // main(int argc, char **argv) {
352
+ // rust_start(&_rust.main, &crate, argc, argv);
353
+ // }
354
+ //
355
+
356
+ let BasicBlockRef llbb =
357
+ llvm. LLVMAppendBasicBlock ( llmain, _str. buf( "" ) ) ;
358
+ auto b = new_builder( llbb) ;
359
+
360
+ auto start_args = vec( p2i( llrust_main) , p2i( llcrate) , llargc, llargv) ;
361
+
362
+ b. Ret ( b. Call ( llrust_start, start_args) ) ;
363
+
364
+ }
365
+
327
366
fn trans_crate( session. session sess, ast. crate crate) {
328
367
auto llmod =
329
368
llvm. LLVMModuleCreateWithNameInContext ( _str. buf( "rust_out" ) ,
@@ -341,11 +380,14 @@ fn trans_crate(session.session sess, ast.crate crate) {
341
380
auto cx = @rec( sess = sess,
342
381
llmod = llmod,
343
382
upcalls = new_str_hash[ ValueRef ] ( ) ,
383
+ fns = new_str_hash[ ValueRef ] ( ) ,
344
384
glues = glues,
345
385
path = "_rust" ) ;
346
386
347
387
trans_mod( cx, crate . module) ;
348
388
389
+ trans_main_fn( cx, crate_constant( cx) ) ;
390
+
349
391
llvm. LLVMWriteBitcodeToFile ( llmod, _str. buf( "rust_out.bc" ) ) ;
350
392
llvm. LLVMDisposeModule ( llmod) ;
351
393
}
0 commit comments