Skip to content

Commit d31eca4

Browse files
committed
First linkable and executable translation from rustc. Upcalls to log, passes wrong arg, crashes. Baby steps.
1 parent d53209c commit d31eca4

File tree

1 file changed

+51
-9
lines changed

1 file changed

+51
-9
lines changed

src/comp/middle/trans.rs

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type glue_fns = rec(ValueRef activate_glue,
3030
type trans_ctxt = rec(session.session sess,
3131
ModuleRef llmod,
3232
hashmap[str,ValueRef] upcalls,
33+
hashmap[str,ValueRef] fns,
3334
@glue_fns glues,
3435
str path);
3536

@@ -233,13 +234,17 @@ fn default_terminate(@fn_ctxt cx, builder build) {
233234
build.RetVoid();
234235
}
235236

237+
fn new_builder(BasicBlockRef llbb) -> builder {
238+
let BuilderRef llbuild = llvm.LLVMCreateBuilder();
239+
llvm.LLVMPositionBuilderAtEnd(llbuild, llbb);
240+
ret builder(llbuild);
241+
}
242+
236243
fn trans_block(@fn_ctxt cx, &ast.block b, terminator term) {
237244
let BasicBlockRef llbb =
238245
llvm.LLVMAppendBasicBlock(cx.llfn, _str.buf(""));
239-
let BuilderRef llbuild = llvm.LLVMCreateBuilder();
240-
llvm.LLVMPositionBuilderAtEnd(llbuild, llbb);
241246
auto bcx = @rec(llbb=llbb,
242-
build=builder(llbuild),
247+
build=new_builder(llbb),
243248
term=term,
244249
fcx=cx);
245250
for (@ast.stmt s in b) {
@@ -253,6 +258,7 @@ fn trans_fn(@trans_ctxt cx, &ast._fn f) {
253258
T_taskptr() // taskptr
254259
);
255260
let ValueRef llfn = decl_cdecl_fn(cx.llmod, cx.path, args, T_nil());
261+
cx.fns.insert(cx.path, llfn);
256262
let ValueRef lloutptr = llvm.LLVMGetParam(llfn, 0u);
257263
let ValueRef lltaskptr = llvm.LLVMGetParam(llfn, 1u);
258264
auto fcx = @rec(llfn=llfn,
@@ -281,16 +287,17 @@ fn trans_mod(@trans_ctxt cx, &ast._mod m) {
281287
}
282288
}
283289

290+
291+
fn p2i(ValueRef v) -> ValueRef {
292+
ret llvm.LLVMConstPtrToInt(v, T_int());
293+
}
294+
284295
fn crate_constant(@trans_ctxt cx) -> ValueRef {
285296

286297
let ValueRef crate_ptr =
287-
llvm.LLVMAddGlobal(cx.llmod, T_ptr(T_crate()),
298+
llvm.LLVMAddGlobal(cx.llmod, T_crate(),
288299
_str.buf("rust_crate"));
289300

290-
fn p2i(ValueRef v) -> ValueRef {
291-
ret llvm.LLVMConstPtrToInt(v, T_int());
292-
}
293-
294301
let ValueRef crate_addr = p2i(crate_ptr);
295302

296303
let ValueRef activate_glue_off =
@@ -305,7 +312,7 @@ fn crate_constant(@trans_ctxt cx) -> ValueRef {
305312

306313
let ValueRef crate_val =
307314
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
309316
C_null(T_int()), // ptrdiff_t debug_abbrev_off
310317
C_null(T_int()), // size_t debug_abbrev_sz
311318
C_null(T_int()), // ptrdiff_t debug_info_off
@@ -324,6 +331,38 @@ fn crate_constant(@trans_ctxt cx) -> ValueRef {
324331
ret crate_ptr;
325332
}
326333

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, 0u);
345+
auto llargv = llvm.LLVMGetParam(llmain, 1u);
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+
327366
fn trans_crate(session.session sess, ast.crate crate) {
328367
auto llmod =
329368
llvm.LLVMModuleCreateWithNameInContext(_str.buf("rust_out"),
@@ -341,11 +380,14 @@ fn trans_crate(session.session sess, ast.crate crate) {
341380
auto cx = @rec(sess = sess,
342381
llmod = llmod,
343382
upcalls = new_str_hash[ValueRef](),
383+
fns = new_str_hash[ValueRef](),
344384
glues = glues,
345385
path = "_rust");
346386

347387
trans_mod(cx, crate.module);
348388

389+
trans_main_fn(cx, crate_constant(cx));
390+
349391
llvm.LLVMWriteBitcodeToFile(llmod, _str.buf("rust_out.bc"));
350392
llvm.LLVMDisposeModule(llmod);
351393
}

0 commit comments

Comments
 (0)