diff options
| author | Graydon Hoare <[email protected]> | 2010-09-27 13:43:53 -0700 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2010-09-27 13:43:53 -0700 |
| commit | d31eca41d5dd18a079d0b06de3a965cedf1ec4f9 (patch) | |
| tree | ead293996f87cc4069e738ea962c1116a9e4f0eb /src/comp | |
| parent | Construct the crate constant in rustc. (diff) | |
| download | rust-d31eca41d5dd18a079d0b06de3a965cedf1ec4f9.tar.xz rust-d31eca41d5dd18a079d0b06de3a965cedf1ec4f9.zip | |
First linkable and executable translation from rustc. Upcalls to log, passes wrong arg, crashes. Baby steps.
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/middle/trans.rs | 60 |
1 files changed, 51 insertions, 9 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 80d87c24..c56fcef3 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -30,6 +30,7 @@ type glue_fns = rec(ValueRef activate_glue, type trans_ctxt = rec(session.session sess, ModuleRef llmod, hashmap[str,ValueRef] upcalls, + hashmap[str,ValueRef] fns, @glue_fns glues, str path); @@ -233,13 +234,17 @@ fn default_terminate(@fn_ctxt cx, builder build) { build.RetVoid(); } +fn new_builder(BasicBlockRef llbb) -> builder { + let BuilderRef llbuild = llvm.LLVMCreateBuilder(); + llvm.LLVMPositionBuilderAtEnd(llbuild, llbb); + ret builder(llbuild); +} + fn trans_block(@fn_ctxt cx, &ast.block b, terminator term) { let BasicBlockRef llbb = llvm.LLVMAppendBasicBlock(cx.llfn, _str.buf("")); - let BuilderRef llbuild = llvm.LLVMCreateBuilder(); - llvm.LLVMPositionBuilderAtEnd(llbuild, llbb); auto bcx = @rec(llbb=llbb, - build=builder(llbuild), + build=new_builder(llbb), term=term, fcx=cx); for (@ast.stmt s in b) { @@ -253,6 +258,7 @@ fn trans_fn(@trans_ctxt cx, &ast._fn f) { T_taskptr() // taskptr ); let ValueRef llfn = decl_cdecl_fn(cx.llmod, cx.path, args, T_nil()); + cx.fns.insert(cx.path, llfn); let ValueRef lloutptr = llvm.LLVMGetParam(llfn, 0u); let ValueRef lltaskptr = llvm.LLVMGetParam(llfn, 1u); auto fcx = @rec(llfn=llfn, @@ -281,16 +287,17 @@ fn trans_mod(@trans_ctxt cx, &ast._mod m) { } } + +fn p2i(ValueRef v) -> ValueRef { + ret llvm.LLVMConstPtrToInt(v, T_int()); +} + fn crate_constant(@trans_ctxt cx) -> ValueRef { let ValueRef crate_ptr = - llvm.LLVMAddGlobal(cx.llmod, T_ptr(T_crate()), + llvm.LLVMAddGlobal(cx.llmod, T_crate(), _str.buf("rust_crate")); - fn p2i(ValueRef v) -> ValueRef { - ret llvm.LLVMConstPtrToInt(v, T_int()); - } - let ValueRef crate_addr = p2i(crate_ptr); let ValueRef activate_glue_off = @@ -305,7 +312,7 @@ fn crate_constant(@trans_ctxt cx) -> ValueRef { let ValueRef crate_val = C_struct(vec(C_null(T_int()), // ptrdiff_t image_base_off - crate_ptr, // uintptr_t self_addr + p2i(crate_ptr), // uintptr_t self_addr C_null(T_int()), // ptrdiff_t debug_abbrev_off C_null(T_int()), // size_t debug_abbrev_sz C_null(T_int()), // ptrdiff_t debug_info_off @@ -324,6 +331,38 @@ fn crate_constant(@trans_ctxt cx) -> ValueRef { ret crate_ptr; } +fn trans_main_fn(@trans_ctxt cx, ValueRef llcrate) { + auto T_main_args = vec(T_int(), T_int()); + auto T_rust_start_args = vec(T_int(), T_int(), T_int(), T_int()); + + auto llmain = + decl_cdecl_fn(cx.llmod, "main", T_main_args, T_int()); + + auto llrust_start = + decl_cdecl_fn(cx.llmod, "rust_start", T_rust_start_args, T_int()); + + auto llargc = llvm.LLVMGetParam(llmain, 0u); + auto llargv = llvm.LLVMGetParam(llmain, 1u); + auto llrust_main = cx.fns.get("_rust.main"); + + // + // Emit the moral equivalent of: + // + // main(int argc, char **argv) { + // rust_start(&_rust.main, &crate, argc, argv); + // } + // + + let BasicBlockRef llbb = + llvm.LLVMAppendBasicBlock(llmain, _str.buf("")); + auto b = new_builder(llbb); + + auto start_args = vec(p2i(llrust_main), p2i(llcrate), llargc, llargv); + + b.Ret(b.Call(llrust_start, start_args)); + +} + fn trans_crate(session.session sess, ast.crate crate) { auto llmod = llvm.LLVMModuleCreateWithNameInContext(_str.buf("rust_out"), @@ -341,11 +380,14 @@ fn trans_crate(session.session sess, ast.crate crate) { auto cx = @rec(sess = sess, llmod = llmod, upcalls = new_str_hash[ValueRef](), + fns = new_str_hash[ValueRef](), glues = glues, path = "_rust"); trans_mod(cx, crate.module); + trans_main_fn(cx, crate_constant(cx)); + llvm.LLVMWriteBitcodeToFile(llmod, _str.buf("rust_out.bc")); llvm.LLVMDisposeModule(llmod); } |