aboutsummaryrefslogtreecommitdiff
path: root/src/comp/middle
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-09-23 17:16:34 -0700
committerGraydon Hoare <[email protected]>2010-09-23 17:16:34 -0700
commit2db1f864e23e38d26b6dfb1e0a00829122a6aefd (patch)
treea202f8803da270d30401db8d39b0f01b6632df86 /src/comp/middle
parentResolve constant types through to their definitions. (diff)
downloadrust-2db1f864e23e38d26b6dfb1e0a00829122a6aefd.tar.xz
rust-2db1f864e23e38d26b6dfb1e0a00829122a6aefd.zip
Declare the global and upcall glues as ValueRefs in rustc's trans.
Diffstat (limited to 'src/comp/middle')
-rw-r--r--src/comp/middle/trans.rs67
1 files changed, 62 insertions, 5 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 1b1c5b2d..b1e1306e 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -6,6 +6,9 @@ import std._vec.rustrt.vbuf;
import front.ast;
import driver.session;
import back.x86;
+import back.abi;
+
+import util.common.istr;
import lib.llvm.llvm;
import lib.llvm.builder;
@@ -18,8 +21,13 @@ import lib.llvm.llvm.BasicBlockRef;
import lib.llvm.False;
import lib.llvm.True;
+type glue_fns = rec(ValueRef activate_glue,
+ ValueRef yield_glue,
+ vec[ValueRef] upcall_glues);
+
type trans_ctxt = rec(session.session sess,
ModuleRef llmod,
+ @glue_fns glues,
str path);
fn T_nil() -> TypeRef {
@@ -34,9 +42,53 @@ fn T_fn(vec[TypeRef] inputs, TypeRef output) -> TypeRef {
ret llvm.LLVMFunctionType(output,
_vec.buf[TypeRef](inputs),
_vec.len[TypeRef](inputs),
- False());
+ False);
+}
+
+fn T_ptr(TypeRef t) -> TypeRef {
+ ret llvm.LLVMPointerType(t, 0u);
+}
+
+fn T_struct(vec[TypeRef] elts) -> TypeRef {
+ ret llvm.LLVMStructType(_vec.buf[TypeRef](elts),
+ _vec.len[TypeRef](elts),
+ False);
+}
+
+fn T_opaque() -> TypeRef {
+ ret llvm.LLVMOpaqueType();
+}
+
+fn T_task() -> TypeRef {
+ ret T_struct(vec(T_int(), // Refcount
+ T_opaque())); // Rest is opaque for now
+}
+
+fn decl_cdecl_fn(ModuleRef llmod, str name,
+ vec[TypeRef] inputs, TypeRef output) -> ValueRef {
+ let TypeRef llty = T_fn(inputs, output);
+ let ValueRef llfn =
+ llvm.LLVMAddFunction(llmod, _str.buf(name), llty);
+ llvm.LLVMSetFunctionCallConv(llfn, lib.llvm.LLVMCCallConv);
+ ret llfn;
+}
+
+fn decl_glue(ModuleRef llmod, str s) -> ValueRef {
+ ret decl_cdecl_fn(llmod, s, vec(T_ptr(T_task())), T_nil());
}
+fn decl_upcall(ModuleRef llmod, uint _n) -> ValueRef {
+ let int n = _n as int;
+ let str s = "rust_upcall_" + istr(n);
+ let vec[TypeRef] args =
+ vec(T_ptr(T_task()), // taskptr
+ T_int()) // callee
+ + _vec.init_elt[TypeRef](T_int(), n as uint);
+
+ ret decl_cdecl_fn(llmod, s, args, T_int());
+}
+
+
type terminator = fn(&trans_ctxt cx, builder b);
fn trans_log(&trans_ctxt cx, builder b, &ast.atom a) {
@@ -71,10 +123,9 @@ fn trans_block(&trans_ctxt cx, ValueRef llfn, &ast.block b, terminator t) {
fn trans_fn(&trans_ctxt cx, &ast._fn f) {
let vec[TypeRef] args = vec();
- let TypeRef llty = T_fn(args, T_nil());
- let ValueRef llfn =
- llvm.LLVMAddFunction(cx.llmod, _str.buf(cx.path), llty);
+ let ValueRef llfn = decl_cdecl_fn(cx.llmod, cx.path, args, T_nil());
auto term = default_terminate;
+
trans_block(cx, llfn, f.body, term);
}
@@ -103,7 +154,13 @@ fn trans_crate(session.session sess, ast.crate crate) {
llvm.LLVMSetModuleInlineAsm(llmod, _str.buf(x86.get_module_asm()));
- auto cx = rec(sess=sess, llmod=llmod, path="");
+ auto glues = @rec(activate_glue = decl_glue(llmod, "rust_activate_glue"),
+ yield_glue = decl_glue(llmod, "rust_yield_glue"),
+ upcall_glues =
+ _vec.init_fn[ValueRef](bind decl_upcall(llmod, _),
+ abi.n_upcall_glues as uint));
+
+ auto cx = rec(sess=sess, llmod=llmod, glues=glues, path="");
trans_mod(cx, crate.module);
llvm.LLVMWriteBitcodeToFile(llmod, _str.buf("rust_out.bc"));