aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-09-27 13:43:53 -0700
committerGraydon Hoare <[email protected]>2010-09-27 13:43:53 -0700
commitd31eca41d5dd18a079d0b06de3a965cedf1ec4f9 (patch)
treeead293996f87cc4069e738ea962c1116a9e4f0eb /src/comp
parentConstruct the crate constant in rustc. (diff)
downloadrust-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.rs60
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);
}