1
1
import std. _str ;
2
2
import std. _vec ;
3
+ import std. ebml ;
4
+ import std. io ;
3
5
import std. option ;
4
6
5
7
import front. ast ;
8
+ import middle. fold ;
6
9
import middle. trans ;
7
10
import middle. ty ;
8
11
import back. x86 ;
@@ -12,6 +15,22 @@ import lib.llvm.llvm;
12
15
import lib. llvm . llvm . ValueRef ;
13
16
import lib. llvm . False ;
14
17
18
+ const uint tag_paths = 0x01 u;
19
+ const uint tag_items = 0x02 u;
20
+
21
+ const uint tag_paths_name = 0x03 u;
22
+ const uint tag_paths_item = 0x04 u;
23
+ const uint tag_paths_mod = 0x05 u;
24
+
25
+ const uint tag_items_item = 0x06 u;
26
+ const uint tag_items_def_id = 0x07 u;
27
+ const uint tag_items_kind = 0x08 u;
28
+ const uint tag_items_ty_param = 0x09 u;
29
+ const uint tag_items_type = 0x0a u;
30
+ const uint tag_items_symbol = 0x0b u;
31
+ const uint tag_items_variant = 0x0c u;
32
+ const uint tag_items_tag_id = 0x0d u;
33
+
15
34
// Type encoding
16
35
17
36
// Compact string representation for ty.t values. API ty_str & parse_from_str.
@@ -102,7 +121,8 @@ fn sty_str(ty.sty st, def_str ds) -> str {
102
121
}
103
122
case ( ty. ty_var ( ?id) ) { ret "X" + common. istr ( id) ; }
104
123
case ( ty. ty_native ) { ret "E" ; }
105
- // TODO (maybe?) ty_param(ast.def_id), ty_type;
124
+ case ( ty. ty_param ( ?def) ) { ret "p" + ds ( def) ; }
125
+ // TODO (maybe?) ty_type;
106
126
}
107
127
}
108
128
@@ -128,13 +148,270 @@ fn C_postr(str s) -> ValueRef {
128
148
ret llvm. LLVMConstString ( _str. buf ( s) , _str. byte_len ( s) , False ) ;
129
149
}
130
150
131
- fn collect_meta_directives ( @trans. crate_ctxt cx , @ast. crate crate)
132
- -> ValueRef {
133
- ret C_postr ( "Hello world!" ) ; // TODO
151
+
152
+ // Path table encoding
153
+
154
+ fn encode_name ( & ebml. writer ebml_w , str name ) {
155
+ ebml. start_tag ( ebml_w, tag_paths_name) ;
156
+ ebml_w. writer . write ( _str. bytes ( name) ) ;
157
+ ebml. end_tag ( ebml_w) ;
158
+ }
159
+
160
+ fn encode_def_id ( & ebml. writer ebml_w , & ast. def_id id ) {
161
+ ebml. start_tag ( ebml_w, tag_items_def_id) ;
162
+ ebml_w. writer . write ( _str. bytes ( def_to_str ( id) ) ) ;
163
+ ebml. end_tag ( ebml_w) ;
164
+ }
165
+
166
+ fn encode_tag_variant_paths ( & ebml. writer ebml_w , vec[ ast. variant] variants ) {
167
+ for ( ast. variant variant in variants) {
168
+ ebml. start_tag ( ebml_w, tag_paths_item) ;
169
+ encode_name ( ebml_w, variant. name ) ;
170
+ encode_def_id ( ebml_w, variant. id ) ;
171
+ ebml. end_tag ( ebml_w) ;
172
+ }
173
+ }
174
+
175
+ fn encode_native_module_item_paths ( & ebml. writer ebml_w ,
176
+ & ast. native_mod nmod ) {
177
+ for ( @ast. native_item nitem in nmod. items) {
178
+ alt ( nitem. node ) {
179
+ case ( ast. native_item_ty ( ?id, ?did) ) {
180
+ ebml. start_tag ( ebml_w, tag_paths_item) ;
181
+ encode_name ( ebml_w, id) ;
182
+ encode_def_id ( ebml_w, did) ;
183
+ ebml. end_tag ( ebml_w) ;
184
+ }
185
+ case ( ast. native_item_fn ( ?id, _, _, _, ?did, _) ) {
186
+ ebml. start_tag ( ebml_w, tag_paths_item) ;
187
+ encode_name ( ebml_w, id) ;
188
+ encode_def_id ( ebml_w, did) ;
189
+ ebml. end_tag ( ebml_w) ;
190
+ }
191
+ }
192
+ }
193
+ }
194
+
195
+ fn encode_module_item_paths ( & ebml. writer ebml_w , & ast. _mod module ) {
196
+ // TODO: only encode exported items
197
+ for ( @ast. item it in module. items ) {
198
+ alt ( it. node ) {
199
+ case ( ast. item_const ( ?id, _, ?tps, ?did, ?ann) ) {
200
+ ebml. start_tag ( ebml_w, tag_paths_item) ;
201
+ encode_name ( ebml_w, id) ;
202
+ encode_def_id ( ebml_w, did) ;
203
+ ebml. end_tag ( ebml_w) ;
204
+ }
205
+ case ( ast. item_fn ( ?id, _, ?tps, ?did, ?ann) ) {
206
+ ebml. start_tag ( ebml_w, tag_paths_item) ;
207
+ encode_name ( ebml_w, id) ;
208
+ encode_def_id ( ebml_w, did) ;
209
+ ebml. end_tag ( ebml_w) ;
210
+ }
211
+ case ( ast. item_mod ( ?id, ?_mod, _) ) {
212
+ ebml. start_tag ( ebml_w, tag_paths_mod) ;
213
+ encode_name ( ebml_w, id) ;
214
+ encode_module_item_paths ( ebml_w, _mod) ;
215
+ ebml. end_tag ( ebml_w) ;
216
+ }
217
+ case ( ast. item_native_mod ( ?id, ?nmod, _) ) {
218
+ ebml. start_tag ( ebml_w, tag_paths_mod) ;
219
+ encode_name ( ebml_w, id) ;
220
+ encode_native_module_item_paths ( ebml_w, nmod) ;
221
+ ebml. end_tag ( ebml_w) ;
222
+ }
223
+ case ( ast. item_ty ( ?id, _, ?tps, ?did, ?ann) ) {
224
+ ebml. start_tag ( ebml_w, tag_paths_item) ;
225
+ encode_name ( ebml_w, id) ;
226
+ encode_def_id ( ebml_w, did) ;
227
+ ebml. end_tag ( ebml_w) ;
228
+ }
229
+ case ( ast. item_tag ( ?id, ?variants, ?tps, ?did) ) {
230
+ ebml. start_tag ( ebml_w, tag_paths_item) ;
231
+ encode_name ( ebml_w, id) ;
232
+ encode_tag_variant_paths ( ebml_w, variants) ;
233
+ encode_def_id ( ebml_w, did) ;
234
+ ebml. end_tag ( ebml_w) ;
235
+ }
236
+ case ( ast. item_obj ( ?id, _, ?tps, ?did, ?ann) ) {
237
+ ebml. start_tag ( ebml_w, tag_paths_item) ;
238
+ encode_name ( ebml_w, id) ;
239
+ encode_def_id ( ebml_w, did) ;
240
+ ebml. end_tag ( ebml_w) ;
241
+ }
242
+ }
243
+ }
244
+ }
245
+
246
+ fn encode_item_paths ( & ebml. writer ebml_w , @ast. crate crate) {
247
+ ebml. start_tag ( ebml_w, tag_paths) ;
248
+ encode_module_item_paths ( ebml_w, crate . node. module ) ;
249
+ ebml. end_tag ( ebml_w) ;
250
+ }
251
+
252
+
253
+ // Item info table encoding
254
+
255
+ fn encode_kind ( & ebml. writer ebml_w , u8 c) {
256
+ ebml. start_tag ( ebml_w, tag_items_kind) ;
257
+ ebml_w. writer . write ( vec ( c) ) ;
258
+ ebml. end_tag ( ebml_w) ;
259
+ }
260
+
261
+ fn def_to_str ( ast. def_id did ) -> str {
262
+ ret #fmt( "%d:%d" , did. _0 , did. _1 ) ;
263
+ }
264
+
265
+ // TODO: We need to encode the "crate numbers" somewhere for diamond imports.
266
+ fn encode_type_params ( & ebml. writer ebml_w , vec[ ast. ty_param] tps ) {
267
+ for ( ast. ty_param tp in tps) {
268
+ ebml. start_tag ( ebml_w, tag_items_ty_param) ;
269
+ ebml_w. writer . write ( _str. bytes ( def_to_str ( tp. id ) ) ) ;
270
+ ebml. end_tag ( ebml_w) ;
271
+ }
272
+ }
273
+
274
+ fn encode_type ( & ebml. writer ebml_w , @ty. t typ ) {
275
+ ebml. start_tag ( ebml_w, tag_items_type) ;
276
+ auto f = def_to_str;
277
+ ebml_w. writer . write ( _str. bytes ( ty_str ( typ, f) ) ) ;
278
+ ebml. end_tag ( ebml_w) ;
279
+ }
280
+
281
+ fn encode_symbol ( @trans. crate_ctxt cx , & ebml. writer ebml_w , ast. def_id did ) {
282
+ ebml. start_tag ( ebml_w, tag_items_symbol) ;
283
+ ebml_w. writer . write ( _str. bytes ( cx. item_symbols . get ( did) ) ) ;
284
+ ebml. end_tag ( ebml_w) ;
285
+ }
286
+
287
+ fn encode_discriminant ( @trans. crate_ctxt cx , & ebml. writer ebml_w ,
288
+ ast. def_id did ) {
289
+ ebml. start_tag ( ebml_w, tag_items_symbol) ;
290
+ ebml_w. writer . write ( _str. bytes ( cx. discrim_symbols . get ( did) ) ) ;
291
+ ebml. end_tag ( ebml_w) ;
292
+ }
293
+
294
+ fn encode_tag_id ( & ebml. writer ebml_w , & ast. def_id id ) {
295
+ ebml. start_tag ( ebml_w, tag_items_tag_id) ;
296
+ ebml_w. writer . write ( _str. bytes ( def_to_str ( id) ) ) ;
297
+ ebml. end_tag ( ebml_w) ;
298
+ }
299
+
300
+
301
+ fn encode_tag_variant_info ( @trans. crate_ctxt cx , & ebml. writer ebml_w ,
302
+ ast. def_id did , vec[ ast. variant] variants ) {
303
+ for ( ast. variant variant in variants) {
304
+ ebml. start_tag ( ebml_w, tag_items_variant) ;
305
+ encode_def_id ( ebml_w, variant. id ) ;
306
+ encode_tag_id ( ebml_w, did) ;
307
+ encode_type ( ebml_w, trans. node_ann_type ( cx, variant. ann ) ) ;
308
+ if ( _vec. len [ ast. variant_arg ] ( variant. args ) > 0 u) {
309
+ encode_symbol ( cx, ebml_w, variant. id ) ;
310
+ }
311
+ encode_discriminant ( cx, ebml_w, variant. id ) ;
312
+ ebml. end_tag ( ebml_w) ;
313
+ }
314
+ }
315
+
316
+ fn encode_info_for_item ( @trans. crate_ctxt cx , & ebml. writer ebml_w ,
317
+ @ast . item item) {
318
+ alt ( item. node ) {
319
+ case ( ast. item_const ( _, _, _, ?did, ?ann) ) {
320
+ ebml. start_tag ( ebml_w, tag_items_item) ;
321
+ encode_def_id ( ebml_w, did) ;
322
+ encode_kind ( ebml_w, 'c' as u8 ) ;
323
+ encode_type ( ebml_w, trans. node_ann_type ( cx, ann) ) ;
324
+ encode_symbol ( cx, ebml_w, did) ;
325
+ ebml. end_tag ( ebml_w) ;
326
+ }
327
+ case ( ast. item_fn ( _, _, ?tps, ?did, ?ann) ) {
328
+ ebml. start_tag ( ebml_w, tag_items_item) ;
329
+ encode_def_id ( ebml_w, did) ;
330
+ encode_kind ( ebml_w, 'f' as u8 ) ;
331
+ encode_type_params ( ebml_w, tps) ;
332
+ encode_type ( ebml_w, trans. node_ann_type ( cx, ann) ) ;
333
+ encode_symbol ( cx, ebml_w, did) ;
334
+ ebml. end_tag ( ebml_w) ;
335
+ }
336
+ case ( ast. item_mod ( _, _, _) ) {
337
+ // nothing to do
338
+ }
339
+ case ( ast. item_native_mod ( _, _, _) ) {
340
+ // nothing to do
341
+ }
342
+ case ( ast. item_ty ( ?id, _, ?tps, ?did, ?ann) ) {
343
+ ebml. start_tag ( ebml_w, tag_items_item) ;
344
+ encode_def_id ( ebml_w, did) ;
345
+ encode_kind ( ebml_w, 'y' as u8 ) ;
346
+ encode_type_params ( ebml_w, tps) ;
347
+ encode_type ( ebml_w, trans. node_ann_type ( cx, ann) ) ;
348
+ ebml. end_tag ( ebml_w) ;
349
+ }
350
+ case ( ast. item_tag ( ?id, ?variants, ?tps, ?did) ) {
351
+ ebml. start_tag ( ebml_w, tag_items_item) ;
352
+ encode_def_id ( ebml_w, did) ;
353
+ encode_kind ( ebml_w, 't' as u8 ) ;
354
+ encode_type_params ( ebml_w, tps) ;
355
+ ebml. end_tag ( ebml_w) ;
356
+
357
+ encode_tag_variant_info ( cx, ebml_w, did, variants) ;
358
+ }
359
+ case ( ast. item_obj ( ?id, _, ?tps, ?did, ?ann) ) {
360
+ ebml. start_tag ( ebml_w, tag_items_item) ;
361
+ encode_def_id ( ebml_w, did) ;
362
+ encode_kind ( ebml_w, 'o' as u8 ) ;
363
+ encode_type_params ( ebml_w, tps) ;
364
+ encode_type ( ebml_w, trans. node_ann_type ( cx, ann) ) ;
365
+ encode_symbol ( cx, ebml_w, did) ;
366
+ ebml. end_tag ( ebml_w) ;
367
+ }
368
+ }
369
+ }
370
+
371
+ fn encode_info_for_native_item ( @trans. crate_ctxt cx , & ebml. writer ebml_w ,
372
+ @ast. native_item nitem ) {
373
+ ebml. start_tag ( ebml_w, tag_items_item) ;
374
+ alt ( nitem. node ) {
375
+ case ( ast. native_item_ty ( _, ?did) ) {
376
+ encode_def_id ( ebml_w, did) ;
377
+ encode_kind ( ebml_w, 'T' as u8 ) ;
378
+ }
379
+ case ( ast. native_item_fn ( _, _, _, ?tps, ?did, ?ann) ) {
380
+ encode_def_id ( ebml_w, did) ;
381
+ encode_kind ( ebml_w, 'F' as u8 ) ;
382
+ encode_type_params ( ebml_w, tps) ;
383
+ encode_type ( ebml_w, trans. node_ann_type ( cx, ann) ) ;
384
+ }
385
+ }
386
+ ebml. end_tag ( ebml_w) ;
387
+ }
388
+
389
+ fn encode_info_for_items ( @trans. crate_ctxt cx , & ebml. writer ebml_w ) {
390
+ ebml. start_tag ( ebml_w, tag_items) ;
391
+ for each ( @tup( ast. def_id, @ast. item) kvp in cx. items . items ( ) ) {
392
+ encode_info_for_item ( cx, ebml_w, kvp. _1 ) ;
393
+ }
394
+ for each ( @tup( ast. def_id, @ast. native_item) kvp in
395
+ cx. native_items . items ( ) ) {
396
+ encode_info_for_native_item ( cx, ebml_w, kvp. _1 ) ;
397
+ }
398
+ ebml. end_tag ( ebml_w) ;
399
+ }
400
+
401
+
402
+ fn encode_metadata ( @trans. crate_ctxt cx , @ast. crate crate) -> ValueRef {
403
+ auto string_w = io. string_writer ( ) ;
404
+ auto buf_w = string_w. get_writer ( ) . get_buf_writer ( ) ;
405
+ auto ebml_w = ebml. create_writer ( buf_w) ;
406
+
407
+ encode_item_paths ( ebml_w, crate ) ;
408
+ encode_info_for_items ( cx, ebml_w) ;
409
+
410
+ ret C_postr ( string_w. get_str ( ) ) ;
134
411
}
135
412
136
413
fn write_metadata ( @trans. crate_ctxt cx , @ast. crate crate) {
137
- auto llmeta = collect_meta_directives ( cx, crate ) ;
414
+ auto llmeta = encode_metadata ( cx, crate ) ;
138
415
139
416
auto llconst = trans. C_struct ( vec ( llmeta) ) ;
140
417
auto llglobal = llvm. LLVMAddGlobal ( cx. llmod , trans. val_ty ( llconst) ,
0 commit comments