@@ -23,22 +23,30 @@ import lib.llvm.llvm.BasicBlockRef;
23
23
import lib. llvm . False ;
24
24
import lib. llvm . True ;
25
25
26
+ state obj namegen ( mutable int i) {
27
+ fn next ( str prefix ) -> str {
28
+ i += 1 ;
29
+ ret prefix + istr ( i) ;
30
+ }
31
+ }
32
+
26
33
type glue_fns = rec ( ValueRef activate_glue ,
27
34
ValueRef yield_glue ,
28
35
ValueRef exit_task_glue ,
29
36
vec[ ValueRef ] upcall_glues ) ;
30
37
31
- type trans_ctxt = rec ( session . session sess,
32
- ModuleRef llmod,
33
- hashmap[ str, ValueRef ] upcalls ,
34
- hashmap[ str, ValueRef ] fns ,
35
- @glue_fns glues ,
36
- str path ) ;
38
+ state type trans_ctxt = rec ( session. session sess,
39
+ ModuleRef llmod,
40
+ hashmap[ str, ValueRef ] upcalls,
41
+ hashmap[ str, ValueRef ] fns,
42
+ @glue_fns glues,
43
+ namegen names,
44
+ str path) ;
37
45
38
- type fn_ctxt = rec ( ValueRef llfn,
39
- ValueRef lloutptr,
40
- ValueRef lltaskptr ,
41
- @trans_ctxt tcx ) ;
46
+ state type fn_ctxt = rec ( ValueRef llfn,
47
+ ValueRef lloutptr,
48
+ ValueRef lltaskptr ,
49
+ @trans_ctxt tcx ) ;
42
50
43
51
type terminator = fn ( @fn_ctxt cx , builder build) ;
44
52
@@ -54,10 +62,27 @@ fn T_nil() -> TypeRef {
54
62
ret llvm. LLVMVoidType ( ) ;
55
63
}
56
64
57
- fn T_int ( ) -> TypeRef {
65
+ fn T_i8 ( ) -> TypeRef {
66
+ ret llvm. LLVMInt8Type ( ) ;
67
+ }
68
+
69
+ fn T_i16 ( ) -> TypeRef {
70
+ ret llvm. LLVMInt16Type ( ) ;
71
+ }
72
+
73
+ fn T_i32 ( ) -> TypeRef {
58
74
ret llvm. LLVMInt32Type ( ) ;
59
75
}
60
76
77
+ fn T_i64 ( ) -> TypeRef {
78
+ ret llvm. LLVMInt64Type ( ) ;
79
+ }
80
+
81
+ fn T_int ( ) -> TypeRef {
82
+ // FIXME: switch on target type.
83
+ ret T_i32 ( ) ;
84
+ }
85
+
61
86
fn T_fn ( vec[ TypeRef ] inputs , TypeRef output) -> TypeRef {
62
87
ret llvm. LLVMFunctionType ( output,
63
88
_vec. buf [ TypeRef ] ( inputs) ,
@@ -124,19 +149,26 @@ fn C_null(TypeRef t) -> ValueRef {
124
149
ret llvm. LLVMConstNull ( t) ;
125
150
}
126
151
127
- fn C_int ( int i) -> ValueRef {
152
+ fn C_integral ( int i, TypeRef t ) -> ValueRef {
128
153
// FIXME. We can't use LLVM.ULongLong with our existing minimal native
129
154
// API, which only knows word-sized args. Lucky for us LLVM has a "take a
130
155
// string encoding" version. Hilarious. Please fix to handle:
131
156
//
132
157
// ret llvm.LLVMConstInt(T_int(), t as LLVM.ULongLong, False);
133
158
//
134
- ret llvm. LLVMConstIntOfString ( T_int ( ) ,
135
- _str. buf ( istr ( i) ) , 10 ) ;
159
+ ret llvm. LLVMConstIntOfString ( t, _str. buf ( istr ( i) ) , 10 ) ;
160
+ }
161
+
162
+ fn C_int ( int i) -> ValueRef {
163
+ ret C_integral ( i, T_int ( ) ) ;
136
164
}
137
165
138
- fn C_str ( str s) -> ValueRef {
139
- ret llvm. LLVMConstString ( _str. buf ( s) , _str. byte_len ( s) , False ) ;
166
+ fn C_str ( @trans_ctxt cx , str s) -> ValueRef {
167
+ auto sc = llvm. LLVMConstString ( _str. buf ( s) , _str. byte_len ( s) , False ) ;
168
+ auto g = llvm. LLVMAddGlobal ( cx. llmod , llvm. LLVMTypeOf ( sc) ,
169
+ _str. buf ( cx. names . next ( "str" ) ) ) ;
170
+ llvm. LLVMSetInitializer ( g, sc) ;
171
+ ret g;
140
172
}
141
173
142
174
fn C_struct ( vec[ ValueRef ] elts ) -> ValueRef {
@@ -192,7 +224,10 @@ fn trans_upcall(@block_ctxt cx, str name, vec[ValueRef] args) -> ValueRef {
192
224
llupcall = llvm. LLVMConstPointerCast ( llupcall, T_int ( ) ) ;
193
225
194
226
let ValueRef llglue = cx. fcx . tcx . glues . upcall_glues . ( n) ;
195
- let vec[ ValueRef ] call_args = vec ( cx. fcx . lltaskptr , llupcall) + args;
227
+ let vec[ ValueRef ] call_args = vec ( cx. fcx . lltaskptr , llupcall) ;
228
+ for ( ValueRef a in args) {
229
+ call_args += cx. build . ZExtOrBitCast ( a, T_int ( ) ) ;
230
+ }
196
231
log "emitting indirect-upcall via " + abi. upcall_glue_name ( n) ;
197
232
for ( ValueRef v in call_args) {
198
233
log "arg: " + lib. llvm. type_to_str( llvm. LLVMTypeOf ( v) ) ;
@@ -202,15 +237,50 @@ fn trans_upcall(@block_ctxt cx, str name, vec[ValueRef] args) -> ValueRef {
202
237
ret cx. build. Call ( llglue, call_args) ;
203
238
}
204
239
205
- fn trans_log ( @block_ctxt cx, & ast. expr e) {
240
+ fn trans_expr ( @block_ctxt cx, & ast. expr e) -> ValueRef {
206
241
alt ( e) {
207
242
case ( ast. expr_lit( ?lit) ) {
208
243
alt ( * lit) {
209
244
case ( ast. lit_int( ?i) ) {
210
- trans_upcall( cx, "upcall_log_int" , vec( C_int ( i) ) ) ;
245
+ ret C_int ( i) ;
246
+ }
247
+ case ( ast. lit_uint( ?u) ) {
248
+ ret C_int ( u as int) ;
249
+ }
250
+ case ( ast. lit_char( ?c) ) {
251
+ ret C_integral ( c as int, T_i32 ( ) ) ;
252
+ }
253
+ case ( ast. lit_bool( ?b) ) {
254
+ if ( b) {
255
+ ret C_integral ( 1 , T_i8 ( ) ) ;
256
+ } else {
257
+ ret C_integral ( 0 , T_i8 ( ) ) ;
258
+ }
259
+ }
260
+ case ( ast. lit_str( ?s) ) {
261
+ auto len = ( _str. byte_len( s) as int) + 1 ;
262
+ ret trans_upcall( cx, "upcall_new_str" ,
263
+ vec( p2i( C_str ( cx. fcx. tcx, s) ) ,
264
+ C_int ( len) ) ) ;
265
+ }
266
+ }
267
+ }
268
+ }
269
+ cx. fcx. tcx. sess. unimpl( "expr variant in trans_expr" ) ;
270
+ fail;
271
+ }
272
+
273
+ fn trans_log( @block_ctxt cx, & ast. expr e) {
274
+ alt ( e) {
275
+ case ( ast. expr_lit( ?lit) ) {
276
+ alt ( * lit) {
277
+ case ( ast. lit_str( _) ) {
278
+ auto v = trans_expr( cx, e) ;
279
+ trans_upcall( cx, "upcall_log_str" , vec( v) ) ;
211
280
}
212
281
case ( _) {
213
- cx. fcx. tcx. sess. unimpl( "literal variant in trans_log" ) ;
282
+ auto v = trans_expr( cx, e) ;
283
+ trans_upcall( cx, "upcall_log_int" , vec( v) ) ;
214
284
}
215
285
}
216
286
}
@@ -432,6 +502,7 @@ fn trans_crate(session.session sess, ast.crate crate) {
432
502
upcalls = new_str_hash[ ValueRef ] ( ) ,
433
503
fns = new_str_hash[ ValueRef ] ( ) ,
434
504
glues = glues,
505
+ names = namegen( 0 ) ,
435
506
path = "_rust" ) ;
436
507
437
508
trans_mod( cx, crate . module) ;
0 commit comments