@@ -33,6 +33,21 @@ type trans_ctxt = rec(session.session sess,
33
33
@glue_fns glues ,
34
34
str path ) ;
35
35
36
+ type fn_ctxt = rec ( ValueRef llfn,
37
+ ValueRef lloutptr,
38
+ ValueRef lltaskptr ,
39
+ @trans_ctxt tcx ) ;
40
+
41
+ type terminator = fn ( @fn_ctxt cx , builder build) ;
42
+
43
+ type block_ctxt = rec ( BasicBlockRef llbb,
44
+ builder build,
45
+ terminator term,
46
+ @fn_ctxt fcx ) ;
47
+
48
+
49
+ // LLVM type constructors.
50
+
36
51
fn T_nil ( ) -> TypeRef {
37
52
ret llvm. LLVMVoidType ( ) ;
38
53
}
@@ -67,9 +82,38 @@ fn T_task() -> TypeRef {
67
82
T_opaque ( ) ) ) ; // Rest is opaque for now
68
83
}
69
84
85
+
86
+ // LLVM constant constructors.
87
+
88
+ fn C_null ( TypeRef t) -> ValueRef {
89
+ ret llvm. LLVMConstNull ( t) ;
90
+ }
91
+
92
+ fn C_int ( int i) -> ValueRef {
93
+ // FIXME. We can't use LLVM.ULongLong with our existing minimal native
94
+ // API, which only knows word-sized args. Lucky for us LLVM has a "take a
95
+ // string encoding" version. Hilarious. Please fix to handle:
96
+ //
97
+ // ret llvm.LLVMConstInt(T_int(), t as LLVM.ULongLong, False);
98
+ //
99
+ ret llvm. LLVMConstIntOfString ( T_int ( ) ,
100
+ _str. buf ( istr ( i) ) , 10 ) ;
101
+ }
102
+
103
+ fn C_str ( str s) -> ValueRef {
104
+ ret llvm. LLVMConstString ( _str. buf ( s) , _str. byte_len ( s) , False ) ;
105
+ }
106
+
107
+ fn C_struct ( vec[ ValueRef ] elts ) -> ValueRef {
108
+ ret llvm. LLVMConstStruct ( _vec. buf [ ValueRef ] ( elts) ,
109
+ _vec. len [ ValueRef ] ( elts) ,
110
+ False ) ;
111
+ }
112
+
70
113
fn decl_cdecl_fn ( ModuleRef llmod, str name ,
71
114
vec[ TypeRef ] inputs , TypeRef output) -> ValueRef {
72
115
let TypeRef llty = T_fn ( inputs, output) ;
116
+ log "declaring " + name + " with type " + lib. llvm . type_to_str ( llty) ;
73
117
let ValueRef llfn =
74
118
llvm. LLVMAddFunction ( llmod, _str. buf ( name) , llty) ;
75
119
llvm. LLVMSetFunctionCallConv ( llfn, lib. llvm . LLVMCCallConv ) ;
@@ -82,7 +126,7 @@ fn decl_glue(ModuleRef llmod, str s) -> ValueRef {
82
126
83
127
fn decl_upcall ( ModuleRef llmod, uint _n) -> ValueRef {
84
128
let int n = _n as int ;
85
- let str s = "rust_upcall_" + istr ( n) ;
129
+ let str s = abi . upcall_glue_name ( n) ;
86
130
let vec[ TypeRef ] args =
87
131
vec ( T_ptr ( T_task ( ) ) , // taskptr
88
132
T_int ( ) ) // callee
@@ -91,9 +135,7 @@ fn decl_upcall(ModuleRef llmod, uint _n) -> ValueRef {
91
135
ret decl_cdecl_fn ( llmod, s, args, T_int ( ) ) ;
92
136
}
93
137
94
- type terminator = fn ( & trans_ctxt cx, builder b) ;
95
-
96
- fn get_upcall ( & trans_ctxt cx, str name , int n_args ) -> ValueRef {
138
+ fn get_upcall ( @trans_ctxt cx , str name , int n_args ) -> ValueRef {
97
139
if ( cx. upcalls . contains_key ( name) ) {
98
140
ret cx. upcalls . get ( name) ;
99
141
}
@@ -105,61 +147,87 @@ fn get_upcall(&trans_ctxt cx, str name, int n_args) -> ValueRef {
105
147
ret f;
106
148
}
107
149
108
- fn trans_log ( & trans_ctxt cx, builder b, & ast. atom a ) {
150
+ fn trans_upcall( @block_ctxt cx , str name , vec[ ValueRef ] args ) -> ValueRef {
151
+ let int n = _vec. len [ ValueRef ] ( args) as int ;
152
+ let ValueRef llupcall = get_upcall ( cx. fcx . tcx , name, n) ;
153
+ llupcall = llvm. LLVMConstPointerCast ( llupcall, T_int ( ) ) ;
154
+
155
+ let ValueRef llglue = cx. fcx . tcx . glues . upcall_glues . ( n) ;
156
+ let vec[ ValueRef ] call_args = vec ( cx. fcx . lltaskptr , llupcall) + args;
157
+ log "emitting indirect-upcall via " + abi. upcall_glue_name ( n) ;
158
+ for ( ValueRef v in call_args) {
159
+ log "arg: " + lib. llvm. type_to_str( llvm. LLVMTypeOf ( v) ) ;
160
+ }
161
+ log "emitting call to callee of type: " +
162
+ lib. llvm. type_to_str( llvm. LLVMTypeOf ( llglue) ) ;
163
+ ret cx. build. Call ( llglue, call_args) ;
164
+ }
165
+
166
+ fn trans_log( @block_ctxt cx, & ast. atom a) {
109
167
alt ( a) {
110
168
case ( ast. atom_lit( ?lit) ) {
111
169
alt ( * lit) {
112
170
case ( ast. lit_int( ?i) ) {
113
- cx . sess . unimpl ( "log int" ) ;
171
+ trans_upcall ( cx , "upcall_log_int" , vec ( C_int ( i ) ) ) ;
114
172
}
115
173
case ( _) {
116
- cx. sess . unimpl ( "literal variant in trans_log" ) ;
174
+ cx. fcx . tcx . sess. unimpl( "literal variant in trans_log" ) ;
117
175
}
118
176
}
119
177
}
120
178
case ( _) {
121
- cx. sess . unimpl ( "atom variant in trans_log" ) ;
179
+ cx. fcx . tcx . sess. unimpl( "atom variant in trans_log" ) ;
122
180
}
123
181
}
124
182
}
125
183
126
- fn trans_stmt ( & trans_ctxt cx, builder b , & ast . stmt s, terminator t ) {
184
+ fn trans_stmt( @block_ctxt cx, & ast. stmt s) {
127
185
alt ( s) {
128
186
case ( ast. stmt_log( ?a) ) {
129
- trans_log ( cx, b , * a) ;
187
+ trans_log( cx, * a) ;
130
188
}
131
189
case ( _) {
132
- cx. sess . unimpl ( "stmt variant" ) ;
190
+ cx. fcx . tcx . sess. unimpl( "stmt variant" ) ;
133
191
}
134
192
}
135
193
}
136
194
137
- fn default_terminate ( & trans_ctxt cx, builder b ) {
138
- b . RetVoid ( ) ;
195
+ fn default_terminate( @fn_ctxt cx, builder build ) {
196
+ build . RetVoid ( ) ;
139
197
}
140
198
141
- fn trans_block ( & trans_ctxt cx, ValueRef llfn , & ast . block b, terminator t ) {
199
+ fn trans_block( @fn_ctxt cx, & ast. block b, terminator term ) {
142
200
let BasicBlockRef llbb =
143
- llvm. LLVMAppendBasicBlock ( llfn, _str. buf ( "" ) ) ;
201
+ llvm. LLVMAppendBasicBlock ( cx . llfn, _str. buf( "" ) ) ;
144
202
let BuilderRef llbuild = llvm. LLVMCreateBuilder ( ) ;
145
203
llvm. LLVMPositionBuilderAtEnd ( llbuild, llbb) ;
146
- auto bld = builder ( llbuild) ;
204
+ auto bcx = @rec( llbb=llbb,
205
+ build=builder( llbuild) ,
206
+ term=term,
207
+ fcx=cx) ;
147
208
for ( @ast. stmt s in b) {
148
- trans_stmt ( cx , bld , * s , t ) ;
209
+ trans_stmt( bcx , * s ) ;
149
210
}
150
- t ( cx, bld ) ;
211
+ bcx . term ( cx, bcx . build ) ;
151
212
}
152
213
153
- fn trans_fn ( & trans_ctxt cx, & ast . _fn f) {
154
- let vec[ TypeRef ] args = vec ( ) ;
214
+ fn trans_fn( @trans_ctxt cx, & ast. _fn f) {
215
+ let vec[ TypeRef ] args = vec( T_ptr ( T_int ( ) ) , // outptr.
216
+ T_ptr ( T_task ( ) ) // taskptr
217
+ ) ;
155
218
let ValueRef llfn = decl_cdecl_fn( cx. llmod, cx. path, args, T_nil ( ) ) ;
219
+ let ValueRef lloutptr = llvm. LLVMGetParam ( llfn, 0 u) ;
220
+ let ValueRef lltaskptr = llvm. LLVMGetParam ( llfn, 1 u) ;
221
+ auto fcx = @rec( llfn=llfn,
222
+ lloutptr=lloutptr,
223
+ lltaskptr=lltaskptr,
224
+ tcx=cx) ;
156
225
auto term = default_terminate;
157
-
158
- trans_block ( cx, llfn, f. body , term) ;
226
+ trans_block( fcx, f. body, term) ;
159
227
}
160
228
161
- fn trans_item ( & trans_ctxt cx, & str name , & ast . item item) {
162
- auto sub_cx = rec ( path=cx. path + "." + name with cx) ;
229
+ fn trans_item( @ trans_ctxt cx, & str name, & ast. item item) {
230
+ auto sub_cx = @ rec( path=cx. path + "." + name with * cx) ;
163
231
alt ( item) {
164
232
case ( ast. item_fn( ?f) ) {
165
233
trans_fn( sub_cx, * f) ;
@@ -170,7 +238,7 @@ fn trans_item(&trans_ctxt cx, &str name, &ast.item item) {
170
238
}
171
239
}
172
240
173
- fn trans_mod ( & trans_ctxt cx, & ast. _mod m ) {
241
+ fn trans_mod( @ trans_ctxt cx, & ast. _mod m) {
174
242
for each ( tup( str, ast. item) pair in m. items( ) ) {
175
243
trans_item( cx, pair. _0, pair. _1) ;
176
244
}
@@ -183,17 +251,18 @@ fn trans_crate(session.session sess, ast.crate crate) {
183
251
184
252
llvm. LLVMSetModuleInlineAsm ( llmod, _str. buf( x86. get_module_asm( ) ) ) ;
185
253
186
- auto glues = @rec ( activate_glue = decl_glue ( llmod, "rust_activate_glue" ) ,
187
- yield_glue = decl_glue ( llmod, "rust_yield_glue" ) ,
254
+ auto glues = @rec( activate_glue = decl_glue( llmod,
255
+ abi. activate_glue_name( ) ) ,
256
+ yield_glue = decl_glue( llmod, abi. yield_glue_name( ) ) ,
188
257
upcall_glues =
189
258
_vec. init_fn[ ValueRef ] ( bind decl_upcall( llmod, _) ,
190
259
abi. n_upcall_glues as uint) ) ;
191
260
192
- auto cx = rec ( sess = sess,
193
- llmod = llmod,
194
- upcalls = new_str_hash[ ValueRef ] ( ) ,
195
- glues = glues,
196
- path = "" ) ;
261
+ auto cx = @ rec( sess = sess,
262
+ llmod = llmod,
263
+ upcalls = new_str_hash[ ValueRef ] ( ) ,
264
+ glues = glues,
265
+ path = "" ) ;
197
266
198
267
trans_mod( cx, crate . module) ;
199
268
0 commit comments