@@ -6,6 +6,9 @@ import std._vec.rustrt.vbuf;
6
6
import front. ast ;
7
7
import driver. session ;
8
8
import back. x86 ;
9
+ import back. abi ;
10
+
11
+ import util. common . istr ;
9
12
10
13
import lib. llvm . llvm ;
11
14
import lib. llvm . builder ;
@@ -18,8 +21,13 @@ import lib.llvm.llvm.BasicBlockRef;
18
21
import lib. llvm . False ;
19
22
import lib. llvm . True ;
20
23
24
+ type glue_fns = rec ( ValueRef activate_glue ,
25
+ ValueRef yield_glue ,
26
+ vec[ ValueRef ] upcall_glues ) ;
27
+
21
28
type trans_ctxt = rec ( session . session sess,
22
29
ModuleRef llmod,
30
+ @glue_fns glues ,
23
31
str path ) ;
24
32
25
33
fn T_nil ( ) -> TypeRef {
@@ -34,9 +42,53 @@ fn T_fn(vec[TypeRef] inputs, TypeRef output) -> TypeRef {
34
42
ret llvm. LLVMFunctionType ( output,
35
43
_vec. buf [ TypeRef ] ( inputs) ,
36
44
_vec. len [ TypeRef ] ( inputs) ,
37
- False ( ) ) ;
45
+ False ) ;
46
+ }
47
+
48
+ fn T_ptr ( TypeRef t) -> TypeRef {
49
+ ret llvm. LLVMPointerType ( t, 0 u) ;
50
+ }
51
+
52
+ fn T_struct ( vec[ TypeRef ] elts ) -> TypeRef {
53
+ ret llvm. LLVMStructType ( _vec. buf [ TypeRef ] ( elts) ,
54
+ _vec. len [ TypeRef ] ( elts) ,
55
+ False ) ;
56
+ }
57
+
58
+ fn T_opaque ( ) -> TypeRef {
59
+ ret llvm. LLVMOpaqueType ( ) ;
60
+ }
61
+
62
+ fn T_task ( ) -> TypeRef {
63
+ ret T_struct ( vec ( T_int ( ) , // Refcount
64
+ T_opaque ( ) ) ) ; // Rest is opaque for now
65
+ }
66
+
67
+ fn decl_cdecl_fn ( ModuleRef llmod, str name ,
68
+ vec[ TypeRef ] inputs , TypeRef output) -> ValueRef {
69
+ let TypeRef llty = T_fn ( inputs, output) ;
70
+ let ValueRef llfn =
71
+ llvm. LLVMAddFunction ( llmod, _str. buf ( name) , llty) ;
72
+ llvm. LLVMSetFunctionCallConv ( llfn, lib. llvm . LLVMCCallConv ) ;
73
+ ret llfn;
74
+ }
75
+
76
+ fn decl_glue ( ModuleRef llmod, str s) -> ValueRef {
77
+ ret decl_cdecl_fn ( llmod, s, vec ( T_ptr ( T_task ( ) ) ) , T_nil ( ) ) ;
38
78
}
39
79
80
+ fn decl_upcall ( ModuleRef llmod, uint _n) -> ValueRef {
81
+ let int n = _n as int ;
82
+ let str s = "rust_upcall_" + istr ( n) ;
83
+ let vec[ TypeRef ] args =
84
+ vec ( T_ptr ( T_task ( ) ) , // taskptr
85
+ T_int ( ) ) // callee
86
+ + _vec. init_elt [ TypeRef ] ( T_int ( ) , n as uint ) ;
87
+
88
+ ret decl_cdecl_fn ( llmod, s, args, T_int ( ) ) ;
89
+ }
90
+
91
+
40
92
type terminator = fn ( & trans_ctxt cx, builder b) ;
41
93
42
94
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) {
71
123
72
124
fn trans_fn ( & trans_ctxt cx, & ast . _fn f) {
73
125
let vec[ TypeRef ] args = vec ( ) ;
74
- let TypeRef llty = T_fn ( args, T_nil ( ) ) ;
75
- let ValueRef llfn =
76
- llvm. LLVMAddFunction ( cx. llmod , _str. buf ( cx. path ) , llty) ;
126
+ let ValueRef llfn = decl_cdecl_fn ( cx. llmod , cx. path , args, T_nil ( ) ) ;
77
127
auto term = default_terminate;
128
+
78
129
trans_block ( cx, llfn, f. body , term) ;
79
130
}
80
131
@@ -103,7 +154,13 @@ fn trans_crate(session.session sess, ast.crate crate) {
103
154
104
155
llvm. LLVMSetModuleInlineAsm ( llmod, _str. buf ( x86. get_module_asm ( ) ) ) ;
105
156
106
- auto cx = rec ( sess=sess, llmod=llmod, path="" ) ;
157
+ auto glues = @rec ( activate_glue = decl_glue ( llmod, "rust_activate_glue" ) ,
158
+ yield_glue = decl_glue ( llmod, "rust_yield_glue" ) ,
159
+ upcall_glues =
160
+ _vec. init_fn [ ValueRef ] ( bind decl_upcall ( llmod, _) ,
161
+ abi. n_upcall_glues as uint ) ) ;
162
+
163
+ auto cx = rec ( sess=sess, llmod=llmod, glues=glues, path="" ) ;
107
164
trans_mod ( cx, crate . module) ;
108
165
109
166
llvm. LLVMWriteBitcodeToFile ( llmod, _str. buf ( "rust_out.bc" ) ) ;
0 commit comments