about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorZack Corr <zack@z0w0.me>2012-08-29 15:49:35 +1000
committerBrian Anderson <banderson@mozilla.com>2012-08-31 16:20:36 -0700
commitefb576a60dbd12cdd9c732cb5d8b202283b9864a (patch)
tree0edac79bfc3b3c8931c5d2d14a71174590513aed /src/rustc
parente27b8f7f02a6d9f963aae5823bbe07a962c04e33 (diff)
jit: Clean rustllvm code, let rustc expose __morestack instead of linking in libmorestack and return _rust_main and call it from rustc
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/back/link.rs60
-rw-r--r--src/rustc/lib/llvm.rs5
2 files changed, 56 insertions, 9 deletions
diff --git a/src/rustc/back/link.rs b/src/rustc/back/link.rs
index 82b1a52c37c..9632da761cb 100644
--- a/src/rustc/back/link.rs
+++ b/src/rustc/back/link.rs
@@ -12,7 +12,7 @@ import std::sha1::sha1;
 import syntax::ast;
 import syntax::print::pprust;
 import lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data, True, False,
-        FileType};
+        PassManagerRef, FileType};
 import metadata::filesearch;
 import syntax::ast_map::{path, path_mod, path_name};
 import io::{Writer, WriterUtil};
@@ -54,6 +54,57 @@ fn WriteOutputFile(sess:session,
     }
 }
 
+#[cfg(stage0)]
+mod jit {
+    fn exec(_sess: session,
+            _pm: PassManagerRef,
+            _m: ModuleRef,
+            _opt: c_int,
+            _stacks: bool) {
+        fail
+    }
+}
+
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+mod jit {
+    #[nolink]
+    #[abi = "rust-intrinsic"]
+    extern mod rusti {
+        fn morestack_addr() -> *();
+    }
+
+    struct Closure {
+        code: *();
+        env: *();
+    }
+
+    fn exec(sess: session,
+            pm: PassManagerRef,
+            m: ModuleRef,
+            opt: c_int,
+            stacks: bool) unsafe {
+        let ptr = llvm::LLVMRustJIT(rusti::morestack_addr(), pm, m, opt, stacks);
+
+        if ptr::is_null(ptr) {
+            llvm_err(sess, ~"Could not JIT");
+        } else {
+            let bin = match os::self_exe_path() {
+                Some(path) => path.to_str(),
+                _ => ~"rustc"
+            };
+            let closure = Closure {
+                code: ptr,
+                env: ptr::null()
+            };
+            let func: fn(~[~str]) = unsafe::transmute(closure);
+
+            func(~[bin]);
+        }
+    }
+}
+
 mod write {
     fn is_object_or_assembly_or_exe(ot: output_type) -> bool {
         if ot == output_type_assembly || ot == output_type_object ||
@@ -174,12 +225,7 @@ mod write {
                         });
                 }*/
 
-                if !llvm::LLVMRustJIT(pm.llpm,
-                                      llmod,
-                                      CodeGenOptLevel,
-                                      true) {
-                    llvm_err(sess, ~"Could not JIT");
-                }
+                jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true);
 
                 if sess.time_llvm_passes() {
                     llvm::LLVMRustPrintPassTimings();
diff --git a/src/rustc/lib/llvm.rs b/src/rustc/lib/llvm.rs
index f325b3a3d03..ddce3c9640e 100644
--- a/src/rustc/lib/llvm.rs
+++ b/src/rustc/lib/llvm.rs
@@ -990,10 +990,11 @@ extern mod llvm {
     fn LLVMRustLoadLibrary(Filename: *c_char) -> bool;
 
     /** Create and execute the JIT engine. */
-    fn LLVMRustJIT(PM: PassManagerRef,
+    fn LLVMRustJIT(__morestack: *(),
+                   PM: PassManagerRef,
                    M: ModuleRef,
                    OptLevel: c_int,
-                   EnableSegmentedStacks: bool) -> bool;
+                   EnableSegmentedStacks: bool) -> *();
 
     /** Parses the bitcode in the given memory buffer. */
     fn LLVMRustParseBitcode(MemBuf: MemoryBufferRef) -> ModuleRef;