blob: d91491efebe382a08380314e5023813431c6b6e5 [file] [log] [blame]
Brian Anderson45efb1f2011-06-27 23:03:011// Metadata encoding
2
Patrick Walton0e2fff52011-07-07 02:00:003import std::ivec;
Brian Anderson33294c72011-06-27 22:20:174import std::str;
Brian Anderson33294c72011-06-27 22:20:175import std::uint;
Patrick Waltonbe489ee2011-07-12 17:59:186import std::ioivec;
Brian Anderson33294c72011-06-27 22:20:177import std::option;
8import std::option::some;
9import std::option::none;
Patrick Waltonbe489ee2011-07-12 17:59:1810import std::ebmlivec;
Brian Andersond0a432f2011-07-08 06:55:4111import std::map;
Marijn Haverbeke6fd6fde2011-07-05 09:48:1912import syntax::ast::*;
Brian Andersone29ef1b2011-07-07 19:22:3913import common::*;
Michael Sullivan3b2d23b2011-07-22 00:27:3414import middle::trans_common::crate_ctxt;
Brian Anderson33294c72011-06-27 22:20:1715import middle::ty;
Brian Andersond2362592011-07-07 17:10:1016import middle::ty::node_id_to_monotype;
Brian Anderson5de916d2011-06-30 06:42:3517import front::attr;
Brian Anderson33294c72011-06-27 22:20:1718
Brian Anderson33294c72011-06-27 22:20:1719export encode_metadata;
Brian Anderson6ee1ffe2011-07-07 19:56:0120export encoded_ty;
Brian Anderson33294c72011-06-27 22:20:1721
Brian Andersond0a432f2011-07-08 06:55:4122type abbrev_map = map::hashmap[ty::t, tyencode::ty_abbrev];
23
Marijn Haverbekedf7f21d2011-07-27 12:19:3924type encode_ctxt = {ccx: @crate_ctxt, type_abbrevs: abbrev_map};
Brian Andersond0a432f2011-07-08 06:55:4125
Brian Anderson33294c72011-06-27 22:20:1726// Path table encoding
Marijn Haverbekedf7f21d2011-07-27 12:19:3927fn encode_name(ebml_w: &ebmlivec::writer, name: &str) {
Patrick Waltonbe489ee2011-07-12 17:59:1828 ebmlivec::start_tag(ebml_w, tag_paths_data_name);
Brian Anderson2e7e5882011-08-11 23:36:2029 ebml_w.writer.write(str::bytes(name));
Patrick Waltonbe489ee2011-07-12 17:59:1830 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:1731}
32
Marijn Haverbekedf7f21d2011-07-27 12:19:3933fn encode_def_id(ebml_w: &ebmlivec::writer, id: &def_id) {
Patrick Waltonbe489ee2011-07-12 17:59:1834 ebmlivec::start_tag(ebml_w, tag_def_id);
Brian Anderson2e7e5882011-08-11 23:36:2035 ebml_w.writer.write(str::bytes(def_to_str(id)));
Patrick Waltonbe489ee2011-07-12 17:59:1836 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:1737}
38
Marijn Haverbekedf7f21d2011-07-27 12:19:3939type entry[T] = {val: T, pos: uint};
Marijn Haverbekeaea53772011-07-26 12:06:0240
Erick Tryzelaar8b150452011-08-04 23:20:0941fn encode_tag_variant_paths(ebml_w: &ebmlivec::writer, variants: &[variant],
42 path: &[str], index: &mutable [entry[str]]) {
Marijn Haverbekedf7f21d2011-07-27 12:19:3943 for variant: variant in variants {
Brian Anderson33294c72011-06-27 22:20:1744 add_to_index(ebml_w, path, index, variant.node.name);
Patrick Waltonbe489ee2011-07-12 17:59:1845 ebmlivec::start_tag(ebml_w, tag_paths_data_item);
Brian Anderson33294c72011-06-27 22:20:1746 encode_name(ebml_w, variant.node.name);
47 encode_def_id(ebml_w, local_def(variant.node.id));
Patrick Waltonbe489ee2011-07-12 17:59:1848 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:1749 }
50}
51
Erick Tryzelaar8b150452011-08-04 23:20:0952fn add_to_index(ebml_w: &ebmlivec::writer, path: &[str],
53 index: &mutable [entry[str]], name: &str) {
Marijn Haverbekedf7f21d2011-07-27 12:19:3954 let full_path = path + ~[name];
55 index +=
56 ~[{val: str::connect_ivec(full_path, "::"),
57 pos: ebml_w.writer.tell()}];
Brian Anderson33294c72011-06-27 22:20:1758}
59
Marijn Haverbekedf7f21d2011-07-27 12:19:3960fn encode_native_module_item_paths(ebml_w: &ebmlivec::writer,
Erick Tryzelaar8b150452011-08-04 23:20:0961 nmod: &native_mod, path: &[str],
62 index: &mutable [entry[str]]) {
Marijn Haverbekedf7f21d2011-07-27 12:19:3963 for nitem: @native_item in nmod.items {
Brian Anderson33294c72011-06-27 22:20:1764 add_to_index(ebml_w, path, index, nitem.ident);
Patrick Waltonbe489ee2011-07-12 17:59:1865 ebmlivec::start_tag(ebml_w, tag_paths_data_item);
Brian Anderson33294c72011-06-27 22:20:1766 encode_name(ebml_w, nitem.ident);
67 encode_def_id(ebml_w, local_def(nitem.id));
Patrick Waltonbe489ee2011-07-12 17:59:1868 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:1769 }
70}
71
Marijn Haverbekedf7f21d2011-07-27 12:19:3972fn encode_module_item_paths(ebml_w: &ebmlivec::writer, module: &_mod,
Erick Tryzelaar8b150452011-08-04 23:20:0973 path: &[str], index: &mutable [entry[str]]) {
Marijn Haverbekedf7f21d2011-07-27 12:19:3974 for it: @item in module.items {
75 if !is_exported(it.ident, module) { cont; }
76 alt it.node {
77 item_const(_, _) {
78 add_to_index(ebml_w, path, index, it.ident);
79 ebmlivec::start_tag(ebml_w, tag_paths_data_item);
80 encode_name(ebml_w, it.ident);
81 encode_def_id(ebml_w, local_def(it.id));
82 ebmlivec::end_tag(ebml_w);
83 }
Patrick Walton59e9b622011-08-05 18:38:0684 item_fn(_, tps) {
Marijn Haverbekedf7f21d2011-07-27 12:19:3985 add_to_index(ebml_w, path, index, it.ident);
86 ebmlivec::start_tag(ebml_w, tag_paths_data_item);
87 encode_name(ebml_w, it.ident);
88 encode_def_id(ebml_w, local_def(it.id));
89 ebmlivec::end_tag(ebml_w);
90 }
91 item_mod(_mod) {
92 add_to_index(ebml_w, path, index, it.ident);
93 ebmlivec::start_tag(ebml_w, tag_paths_data_mod);
94 encode_name(ebml_w, it.ident);
95 encode_def_id(ebml_w, local_def(it.id));
96 encode_module_item_paths(ebml_w, _mod, path + ~[it.ident], index);
97 ebmlivec::end_tag(ebml_w);
98 }
99 item_native_mod(nmod) {
100 add_to_index(ebml_w, path, index, it.ident);
101 ebmlivec::start_tag(ebml_w, tag_paths_data_mod);
102 encode_name(ebml_w, it.ident);
103 encode_def_id(ebml_w, local_def(it.id));
104 encode_native_module_item_paths(ebml_w, nmod, path + ~[it.ident],
105 index);
106 ebmlivec::end_tag(ebml_w);
107 }
108 item_ty(_, tps) {
109 add_to_index(ebml_w, path, index, it.ident);
110 ebmlivec::start_tag(ebml_w, tag_paths_data_item);
111 encode_name(ebml_w, it.ident);
112 encode_def_id(ebml_w, local_def(it.id));
113 ebmlivec::end_tag(ebml_w);
114 }
115 item_res(_, _, tps, ctor_id) {
116 add_to_index(ebml_w, path, index, it.ident);
117 ebmlivec::start_tag(ebml_w, tag_paths_data_item);
118 encode_name(ebml_w, it.ident);
119 encode_def_id(ebml_w, local_def(ctor_id));
120 ebmlivec::end_tag(ebml_w);
121 add_to_index(ebml_w, path, index, it.ident);
122 ebmlivec::start_tag(ebml_w, tag_paths_data_item);
123 encode_name(ebml_w, it.ident);
124 encode_def_id(ebml_w, local_def(it.id));
125 ebmlivec::end_tag(ebml_w);
126 }
127 item_tag(variants, tps) {
128 add_to_index(ebml_w, path, index, it.ident);
129 ebmlivec::start_tag(ebml_w, tag_paths_data_item);
130 encode_name(ebml_w, it.ident);
131 encode_def_id(ebml_w, local_def(it.id));
132 ebmlivec::end_tag(ebml_w);
133 encode_tag_variant_paths(ebml_w, variants, path, index);
134 }
135 item_obj(_, tps, ctor_id) {
136 add_to_index(ebml_w, path, index, it.ident);
137 ebmlivec::start_tag(ebml_w, tag_paths_data_item);
138 encode_name(ebml_w, it.ident);
139 encode_def_id(ebml_w, local_def(ctor_id));
140 ebmlivec::end_tag(ebml_w);
141 add_to_index(ebml_w, path, index, it.ident);
142 ebmlivec::start_tag(ebml_w, tag_paths_data_item);
143 encode_name(ebml_w, it.ident);
144 encode_def_id(ebml_w, local_def(it.id));
145 ebmlivec::end_tag(ebml_w);
146 }
Brian Anderson33294c72011-06-27 22:20:17147 }
148 }
149}
150
Marijn Haverbekedf7f21d2011-07-27 12:19:39151fn encode_item_paths(ebml_w: &ebmlivec::writer, crate: &@crate) ->
Erick Tryzelaar8b150452011-08-04 23:20:09152 [entry[str]] {
153 let index: [entry[str]] = ~[];
154 let path: [str] = ~[];
Patrick Waltonbe489ee2011-07-12 17:59:18155 ebmlivec::start_tag(ebml_w, tag_paths);
Brian Anderson33294c72011-06-27 22:20:17156 encode_module_item_paths(ebml_w, crate.node.module, path, index);
Patrick Waltonbe489ee2011-07-12 17:59:18157 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17158 ret index;
159}
160
161
162// Item info table encoding
Graydon Hoare59c441a2011-07-29 23:40:23163fn encode_family(ebml_w: &ebmlivec::writer, c: u8) {
164 ebmlivec::start_tag(ebml_w, tag_items_data_item_family);
Patrick Waltonbe489ee2011-07-12 17:59:18165 ebml_w.writer.write(~[c]);
166 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17167}
168
Patrick Waltonb079e1a2011-08-05 20:58:33169fn encode_inlineness(ebml_w: &ebmlivec::writer, c: u8) {
170 ebmlivec::start_tag(ebml_w, tag_items_data_item_inlineness);
171 ebml_w.writer.write(~[c]);
172 ebmlivec::end_tag(ebml_w);
173}
174
Marijn Haverbekedf7f21d2011-07-27 12:19:39175fn def_to_str(did: &def_id) -> str { ret #fmt("%d:%d", did.crate, did.node); }
Brian Anderson33294c72011-06-27 22:20:17176
Erick Tryzelaar8b150452011-08-04 23:20:09177fn encode_type_param_kinds(ebml_w: &ebmlivec::writer, tps: &[ty_param]) {
Graydon Hoare59c441a2011-07-29 23:40:23178 ebmlivec::start_tag(ebml_w, tag_items_data_item_ty_param_kinds);
Patrick Waltonbe489ee2011-07-12 17:59:18179 ebmlivec::write_vint(ebml_w.writer, ivec::len[ty_param](tps));
Graydon Hoare59c441a2011-07-29 23:40:23180 for tp: ty_param in tps {
181 let c = alt tp.kind {
182 kind_unique. { 'u' }
183 kind_shared. { 's' }
184 kind_pinned. { 'p' }
185 };
186 ebml_w.writer.write(~[c as u8]);
187 }
Patrick Waltonbe489ee2011-07-12 17:59:18188 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17189}
190
Marijn Haverbekedf7f21d2011-07-27 12:19:39191fn encode_variant_id(ebml_w: &ebmlivec::writer, vid: &def_id) {
Patrick Waltonbe489ee2011-07-12 17:59:18192 ebmlivec::start_tag(ebml_w, tag_items_data_item_variant);
Brian Anderson2e7e5882011-08-11 23:36:20193 ebml_w.writer.write(str::bytes(def_to_str(vid)));
Patrick Waltonbe489ee2011-07-12 17:59:18194 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17195}
196
Marijn Haverbekedf7f21d2011-07-27 12:19:39197fn encode_type(ecx: &@encode_ctxt, ebml_w: &ebmlivec::writer, typ: &ty::t) {
Patrick Waltonbe489ee2011-07-12 17:59:18198 ebmlivec::start_tag(ebml_w, tag_items_data_item_type);
Marijn Haverbekedf7f21d2011-07-27 12:19:39199 let f = def_to_str;
200 let ty_str_ctxt =
201 @{ds: f,
202 tcx: ecx.ccx.tcx,
203 abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
Patrick Waltonbe489ee2011-07-12 17:59:18204 tyencode::enc_ty(ioivec::new_writer_(ebml_w.writer), ty_str_ctxt, typ);
205 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17206}
207
Marijn Haverbekedf7f21d2011-07-27 12:19:39208fn encode_symbol(ecx: &@encode_ctxt, ebml_w: &ebmlivec::writer, id: node_id) {
Patrick Waltonbe489ee2011-07-12 17:59:18209 ebmlivec::start_tag(ebml_w, tag_items_data_item_symbol);
Brian Anderson2e7e5882011-08-11 23:36:20210 ebml_w.writer.write(str::bytes(ecx.ccx.item_symbols.get(id)));
Patrick Waltonbe489ee2011-07-12 17:59:18211 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17212}
213
Marijn Haverbekedf7f21d2011-07-27 12:19:39214fn encode_discriminant(ecx: &@encode_ctxt, ebml_w: &ebmlivec::writer,
215 id: node_id) {
Patrick Waltonbe489ee2011-07-12 17:59:18216 ebmlivec::start_tag(ebml_w, tag_items_data_item_symbol);
Brian Anderson2e7e5882011-08-11 23:36:20217 ebml_w.writer.write(str::bytes(ecx.ccx.discrim_symbols.get(id)));
Patrick Waltonbe489ee2011-07-12 17:59:18218 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17219}
220
Marijn Haverbekedf7f21d2011-07-27 12:19:39221fn encode_tag_id(ebml_w: &ebmlivec::writer, id: &def_id) {
Patrick Waltonbe489ee2011-07-12 17:59:18222 ebmlivec::start_tag(ebml_w, tag_items_data_item_tag_id);
Brian Anderson2e7e5882011-08-11 23:36:20223 ebml_w.writer.write(str::bytes(def_to_str(id)));
Patrick Waltonbe489ee2011-07-12 17:59:18224 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17225}
226
Marijn Haverbekedf7f21d2011-07-27 12:19:39227fn encode_tag_variant_info(ecx: &@encode_ctxt, ebml_w: &ebmlivec::writer,
Erick Tryzelaar8b150452011-08-04 23:20:09228 id: node_id, variants: &[variant],
229 index: &mutable [entry[int]],
230 ty_params: &[ty_param]) {
Marijn Haverbekedf7f21d2011-07-27 12:19:39231 for variant: variant in variants {
232 index += ~[{val: variant.node.id, pos: ebml_w.writer.tell()}];
Patrick Waltonbe489ee2011-07-12 17:59:18233 ebmlivec::start_tag(ebml_w, tag_items_data_item);
Brian Anderson33294c72011-06-27 22:20:17234 encode_def_id(ebml_w, local_def(variant.node.id));
Graydon Hoare59c441a2011-07-29 23:40:23235 encode_family(ebml_w, 'v' as u8);
Brian Anderson33294c72011-06-27 22:20:17236 encode_tag_id(ebml_w, local_def(id));
Brian Andersond0a432f2011-07-08 06:55:41237 encode_type(ecx, ebml_w,
238 node_id_to_monotype(ecx.ccx.tcx, variant.node.id));
Marijn Haverbekedf7f21d2011-07-27 12:19:39239 if ivec::len[variant_arg](variant.node.args) > 0u {
Brian Andersond0a432f2011-07-08 06:55:41240 encode_symbol(ecx, ebml_w, variant.node.id);
Brian Anderson33294c72011-06-27 22:20:17241 }
Brian Andersond0a432f2011-07-08 06:55:41242 encode_discriminant(ecx, ebml_w, variant.node.id);
Graydon Hoare59c441a2011-07-29 23:40:23243 encode_type_param_kinds(ebml_w, ty_params);
Patrick Waltonbe489ee2011-07-12 17:59:18244 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17245 }
246}
247
Marijn Haverbekedf7f21d2011-07-27 12:19:39248fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: &ebmlivec::writer,
Erick Tryzelaar8b150452011-08-04 23:20:09249 item: @item, index: &mutable [entry[int]]) {
Marijn Haverbekedf7f21d2011-07-27 12:19:39250 alt item.node {
251 item_const(_, _) {
252 ebmlivec::start_tag(ebml_w, tag_items_data_item);
253 encode_def_id(ebml_w, local_def(item.id));
Graydon Hoare59c441a2011-07-29 23:40:23254 encode_family(ebml_w, 'c' as u8);
Marijn Haverbekedf7f21d2011-07-27 12:19:39255 encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
256 encode_symbol(ecx, ebml_w, item.id);
257 ebmlivec::end_tag(ebml_w);
258 }
Patrick Walton59e9b622011-08-05 18:38:06259 item_fn(fd, tps) {
Marijn Haverbekedf7f21d2011-07-27 12:19:39260 ebmlivec::start_tag(ebml_w, tag_items_data_item);
261 encode_def_id(ebml_w, local_def(item.id));
Graydon Hoare59c441a2011-07-29 23:40:23262 encode_family(ebml_w,
Marijn Haverbekedf7f21d2011-07-27 12:19:39263 alt fd.decl.purity { pure_fn. { 'p' } impure_fn. { 'f' } }
264 as u8);
Patrick Waltonb079e1a2011-08-05 20:58:33265 encode_inlineness(ebml_w,
266 alt fd.decl.il {
267 il_normal. { 'n' }
268 il_inline. { 'i' }
269 } as u8);
Graydon Hoare59c441a2011-07-29 23:40:23270 encode_type_param_kinds(ebml_w, tps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39271 encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
272 encode_symbol(ecx, ebml_w, item.id);
273 ebmlivec::end_tag(ebml_w);
274 }
275 item_mod(_) {
276 ebmlivec::start_tag(ebml_w, tag_items_data_item);
277 encode_def_id(ebml_w, local_def(item.id));
Graydon Hoare59c441a2011-07-29 23:40:23278 encode_family(ebml_w, 'm' as u8);
Marijn Haverbekedf7f21d2011-07-27 12:19:39279 ebmlivec::end_tag(ebml_w);
280 }
281 item_native_mod(_) {
282 ebmlivec::start_tag(ebml_w, tag_items_data_item);
283 encode_def_id(ebml_w, local_def(item.id));
Graydon Hoare59c441a2011-07-29 23:40:23284 encode_family(ebml_w, 'n' as u8);
Marijn Haverbekedf7f21d2011-07-27 12:19:39285 ebmlivec::end_tag(ebml_w);
286 }
287 item_ty(_, tps) {
288 ebmlivec::start_tag(ebml_w, tag_items_data_item);
289 encode_def_id(ebml_w, local_def(item.id));
Graydon Hoare59c441a2011-07-29 23:40:23290 encode_family(ebml_w, 'y' as u8);
291 encode_type_param_kinds(ebml_w, tps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39292 encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
293 ebmlivec::end_tag(ebml_w);
294 }
295 item_tag(variants, tps) {
296 ebmlivec::start_tag(ebml_w, tag_items_data_item);
297 encode_def_id(ebml_w, local_def(item.id));
Graydon Hoare59c441a2011-07-29 23:40:23298 encode_family(ebml_w, 't' as u8);
299 encode_type_param_kinds(ebml_w, tps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39300 encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
301 for v: variant in variants {
302 encode_variant_id(ebml_w, local_def(v.node.id));
Brian Anderson33294c72011-06-27 22:20:17303 }
Marijn Haverbekedf7f21d2011-07-27 12:19:39304 ebmlivec::end_tag(ebml_w);
305 encode_tag_variant_info(ecx, ebml_w, item.id, variants, index, tps);
306 }
307 item_res(_, _, tps, ctor_id) {
308 let fn_ty = node_id_to_monotype(ecx.ccx.tcx, ctor_id);
Brian Anderson33294c72011-06-27 22:20:17309
Marijn Haverbekedf7f21d2011-07-27 12:19:39310 ebmlivec::start_tag(ebml_w, tag_items_data_item);
311 encode_def_id(ebml_w, local_def(ctor_id));
Graydon Hoare59c441a2011-07-29 23:40:23312 encode_family(ebml_w, 'y' as u8);
313 encode_type_param_kinds(ebml_w, tps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39314 encode_type(ecx, ebml_w, ty::ty_fn_ret(ecx.ccx.tcx, fn_ty));
315 encode_symbol(ecx, ebml_w, item.id);
316 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17317
Marijn Haverbekedf7f21d2011-07-27 12:19:39318 index += ~[{val: ctor_id, pos: ebml_w.writer.tell()}];
319 ebmlivec::start_tag(ebml_w, tag_items_data_item);
320 encode_def_id(ebml_w, local_def(ctor_id));
Graydon Hoare59c441a2011-07-29 23:40:23321 encode_family(ebml_w, 'f' as u8);
322 encode_type_param_kinds(ebml_w, tps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39323 encode_type(ecx, ebml_w, fn_ty);
324 encode_symbol(ecx, ebml_w, ctor_id);
325 ebmlivec::end_tag(ebml_w);
326 }
327 item_obj(_, tps, ctor_id) {
328 let fn_ty = node_id_to_monotype(ecx.ccx.tcx, ctor_id);
Brian Anderson33294c72011-06-27 22:20:17329
Marijn Haverbekedf7f21d2011-07-27 12:19:39330 ebmlivec::start_tag(ebml_w, tag_items_data_item);
331 encode_def_id(ebml_w, local_def(item.id));
Graydon Hoare59c441a2011-07-29 23:40:23332 encode_family(ebml_w, 'y' as u8);
333 encode_type_param_kinds(ebml_w, tps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39334 encode_type(ecx, ebml_w, ty::ty_fn_ret(ecx.ccx.tcx, fn_ty));
335 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17336
Marijn Haverbekedf7f21d2011-07-27 12:19:39337 index += ~[{val: ctor_id, pos: ebml_w.writer.tell()}];
338 ebmlivec::start_tag(ebml_w, tag_items_data_item);
339 encode_def_id(ebml_w, local_def(ctor_id));
Graydon Hoare59c441a2011-07-29 23:40:23340 encode_family(ebml_w, 'f' as u8);
341 encode_type_param_kinds(ebml_w, tps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39342 encode_type(ecx, ebml_w, fn_ty);
343 encode_symbol(ecx, ebml_w, ctor_id);
344 ebmlivec::end_tag(ebml_w);
345 }
Brian Anderson33294c72011-06-27 22:20:17346 }
347}
348
Marijn Haverbekedf7f21d2011-07-27 12:19:39349fn encode_info_for_native_item(ecx: &@encode_ctxt, ebml_w: &ebmlivec::writer,
350 nitem: &@native_item) {
Patrick Waltonbe489ee2011-07-12 17:59:18351 ebmlivec::start_tag(ebml_w, tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39352 alt nitem.node {
353 native_item_ty. {
354 encode_def_id(ebml_w, local_def(nitem.id));
Graydon Hoare59c441a2011-07-29 23:40:23355 encode_family(ebml_w, 'T' as u8);
Marijn Haverbekedf7f21d2011-07-27 12:19:39356 encode_type(ecx, ebml_w,
357 ty::mk_native(ecx.ccx.tcx, local_def(nitem.id)));
358 }
359 native_item_fn(_, _, tps) {
360 encode_def_id(ebml_w, local_def(nitem.id));
Graydon Hoare59c441a2011-07-29 23:40:23361 encode_family(ebml_w, 'F' as u8);
362 encode_type_param_kinds(ebml_w, tps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39363 encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, nitem.id));
364 encode_symbol(ecx, ebml_w, nitem.id);
365 }
Brian Anderson33294c72011-06-27 22:20:17366 }
Patrick Waltonbe489ee2011-07-12 17:59:18367 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17368}
369
Marijn Haverbekedf7f21d2011-07-27 12:19:39370fn encode_info_for_items(ecx: &@encode_ctxt, ebml_w: &ebmlivec::writer) ->
Erick Tryzelaar8b150452011-08-04 23:20:09371 [entry[int]] {
372 let index: [entry[int]] = ~[];
Patrick Waltonbe489ee2011-07-12 17:59:18373 ebmlivec::start_tag(ebml_w, tag_items_data);
Marijn Haverbekedf7f21d2011-07-27 12:19:39374 for each kvp: @{key: node_id, val: middle::ast_map::ast_node} in
375 ecx.ccx.ast_map.items() {
376 alt kvp.val {
377 middle::ast_map::node_item(i) {
378 index += ~[{val: kvp.key, pos: ebml_w.writer.tell()}];
379 encode_info_for_item(ecx, ebml_w, i, index);
380 }
381 middle::ast_map::node_native_item(i) {
382 index += ~[{val: kvp.key, pos: ebml_w.writer.tell()}];
383 encode_info_for_native_item(ecx, ebml_w, i);
384 }
385 _ { }
Brian Anderson33294c72011-06-27 22:20:17386 }
387 }
Patrick Waltonbe489ee2011-07-12 17:59:18388 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17389 ret index;
390}
391
392
393// Path and definition ID indexing
394
Erick Tryzelaar8b150452011-08-04 23:20:09395fn create_index[T](index: &[entry[T]], hash_fn: fn(&T) -> uint ) ->
396 [@[entry[T]]] {
397 let buckets: [@mutable [entry[T]]] = ~[];
Marijn Haverbekedf7f21d2011-07-27 12:19:39398 for each i: uint in uint::range(0u, 256u) { buckets += ~[@mutable ~[]]; }
399 for elt: entry[T] in index {
400 let h = hash_fn(elt.val);
401 *buckets.(h % 256u) += ~[elt];
Brian Anderson33294c72011-06-27 22:20:17402 }
Patrick Walton1a6419b2011-07-14 21:25:43403
Marijn Haverbekedf7f21d2011-07-27 12:19:39404 let buckets_frozen = ~[];
Erick Tryzelaar8b150452011-08-04 23:20:09405 for bucket: @mutable [entry[T]] in buckets {
Patrick Walton1a6419b2011-07-14 21:25:43406 buckets_frozen += ~[@*bucket];
407 }
408 ret buckets_frozen;
Brian Anderson33294c72011-06-27 22:20:17409}
410
Erick Tryzelaar8b150452011-08-04 23:20:09411fn encode_index[T](ebml_w: &ebmlivec::writer, buckets: &[@[entry[T]]],
Marijn Haverbekedf7f21d2011-07-27 12:19:39412 write_fn: fn(&ioivec::writer, &T) ) {
413 let writer = ioivec::new_writer_(ebml_w.writer);
Patrick Waltonbe489ee2011-07-12 17:59:18414 ebmlivec::start_tag(ebml_w, tag_index);
Erick Tryzelaar8b150452011-08-04 23:20:09415 let bucket_locs: [uint] = ~[];
Patrick Waltonbe489ee2011-07-12 17:59:18416 ebmlivec::start_tag(ebml_w, tag_index_buckets);
Erick Tryzelaar8b150452011-08-04 23:20:09417 for bucket: @[entry[T]] in buckets {
Patrick Walton1a6419b2011-07-14 21:25:43418 bucket_locs += ~[ebml_w.writer.tell()];
Patrick Waltonbe489ee2011-07-12 17:59:18419 ebmlivec::start_tag(ebml_w, tag_index_buckets_bucket);
Marijn Haverbekedf7f21d2011-07-27 12:19:39420 for elt: entry[T] in *bucket {
Patrick Waltonbe489ee2011-07-12 17:59:18421 ebmlivec::start_tag(ebml_w, tag_index_buckets_bucket_elt);
Marijn Haverbekeaea53772011-07-26 12:06:02422 writer.write_be_uint(elt.pos, 4u);
423 write_fn(writer, elt.val);
Patrick Waltonbe489ee2011-07-12 17:59:18424 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17425 }
Patrick Waltonbe489ee2011-07-12 17:59:18426 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17427 }
Patrick Waltonbe489ee2011-07-12 17:59:18428 ebmlivec::end_tag(ebml_w);
429 ebmlivec::start_tag(ebml_w, tag_index_table);
Marijn Haverbekedf7f21d2011-07-27 12:19:39430 for pos: uint in bucket_locs { writer.write_be_uint(pos, 4u); }
Patrick Waltonbe489ee2011-07-12 17:59:18431 ebmlivec::end_tag(ebml_w);
432 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17433}
434
Marijn Haverbekedf7f21d2011-07-27 12:19:39435fn write_str(writer: &ioivec::writer, s: &str) { writer.write_str(s); }
Brian Anderson33294c72011-06-27 22:20:17436
Marijn Haverbekedf7f21d2011-07-27 12:19:39437fn write_int(writer: &ioivec::writer, n: &int) {
Brian Anderson33294c72011-06-27 22:20:17438 writer.write_be_uint(n as uint, 4u);
439}
440
Marijn Haverbekedf7f21d2011-07-27 12:19:39441fn encode_meta_item(ebml_w: &ebmlivec::writer, mi: &meta_item) {
442 alt mi.node {
443 meta_word(name) {
444 ebmlivec::start_tag(ebml_w, tag_meta_item_word);
445 ebmlivec::start_tag(ebml_w, tag_meta_item_name);
Brian Anderson2e7e5882011-08-11 23:36:20446 ebml_w.writer.write(str::bytes(name));
Marijn Haverbekedf7f21d2011-07-27 12:19:39447 ebmlivec::end_tag(ebml_w);
448 ebmlivec::end_tag(ebml_w);
449 }
450 meta_name_value(name, value) {
451 alt value.node {
452 lit_str(value, _) {
453 ebmlivec::start_tag(ebml_w, tag_meta_item_name_value);
Patrick Waltonbe489ee2011-07-12 17:59:18454 ebmlivec::start_tag(ebml_w, tag_meta_item_name);
Brian Anderson2e7e5882011-08-11 23:36:20455 ebml_w.writer.write(str::bytes(name));
Patrick Waltonbe489ee2011-07-12 17:59:18456 ebmlivec::end_tag(ebml_w);
Marijn Haverbekedf7f21d2011-07-27 12:19:39457 ebmlivec::start_tag(ebml_w, tag_meta_item_value);
Brian Anderson2e7e5882011-08-11 23:36:20458 ebml_w.writer.write(str::bytes(value));
Patrick Waltonbe489ee2011-07-12 17:59:18459 ebmlivec::end_tag(ebml_w);
Patrick Waltonbe489ee2011-07-12 17:59:18460 ebmlivec::end_tag(ebml_w);
Marijn Haverbekedf7f21d2011-07-27 12:19:39461 }
462 _ {/* FIXME (#611) */ }
Brian Andersonf53c4f72011-06-28 02:41:48463 }
Marijn Haverbekedf7f21d2011-07-27 12:19:39464 }
465 meta_list(name, items) {
466 ebmlivec::start_tag(ebml_w, tag_meta_item_list);
467 ebmlivec::start_tag(ebml_w, tag_meta_item_name);
Brian Anderson2e7e5882011-08-11 23:36:20468 ebml_w.writer.write(str::bytes(name));
Marijn Haverbekedf7f21d2011-07-27 12:19:39469 ebmlivec::end_tag(ebml_w);
470 for inner_item: @meta_item in items {
471 encode_meta_item(ebml_w, *inner_item);
472 }
473 ebmlivec::end_tag(ebml_w);
474 }
Brian Andersonf53c4f72011-06-28 02:41:48475 }
Brian Andersonf53c4f72011-06-28 02:41:48476}
477
Erick Tryzelaar8b150452011-08-04 23:20:09478fn encode_attributes(ebml_w: &ebmlivec::writer, attrs: &[attribute]) {
Patrick Waltonbe489ee2011-07-12 17:59:18479 ebmlivec::start_tag(ebml_w, tag_attributes);
Marijn Haverbekedf7f21d2011-07-27 12:19:39480 for attr: attribute in attrs {
Patrick Waltonbe489ee2011-07-12 17:59:18481 ebmlivec::start_tag(ebml_w, tag_attribute);
Brian Andersonf53c4f72011-06-28 02:41:48482 encode_meta_item(ebml_w, attr.node.value);
Patrick Waltonbe489ee2011-07-12 17:59:18483 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17484 }
Patrick Waltonbe489ee2011-07-12 17:59:18485 ebmlivec::end_tag(ebml_w);
Brian Andersonf53c4f72011-06-28 02:41:48486}
487
Graydon Hoarec796a8f2011-06-29 22:11:20488// So there's a special crate attribute called 'link' which defines the
489// metadata that Rust cares about for linking crates. This attribute requires
Brian Anderson70a28dc2011-07-01 00:03:08490// 'name' and 'vers' items, so if the user didn't provide them we will throw
Graydon Hoarec796a8f2011-06-29 22:11:20491// them in anyway with default values.
Erick Tryzelaar8b150452011-08-04 23:20:09492fn synthesize_crate_attrs(ecx: &@encode_ctxt, crate: &@crate) -> [attribute] {
Brian Anderson29afe1a2011-06-29 21:17:23493
Erick Tryzelaar8b150452011-08-04 23:20:09494 fn synthesize_link_attr(ecx: &@encode_ctxt, items: &[@meta_item]) ->
Marijn Haverbekedf7f21d2011-07-27 12:19:39495 attribute {
Brian Anderson29afe1a2011-06-29 21:17:23496
Marijn Haverbekedf7f21d2011-07-27 12:19:39497 assert (ecx.ccx.link_meta.name != "");
498 assert (ecx.ccx.link_meta.vers != "");
Brian Anderson29afe1a2011-06-29 21:17:23499
Marijn Haverbekedf7f21d2011-07-27 12:19:39500 let name_item =
501 attr::mk_name_value_item_str("name", ecx.ccx.link_meta.name);
502 let vers_item =
503 attr::mk_name_value_item_str("vers", ecx.ccx.link_meta.vers);
Brian Anderson29afe1a2011-06-29 21:17:23504
Marijn Haverbekedf7f21d2011-07-27 12:19:39505 let other_items =
506 {
507 let tmp = attr::remove_meta_items_by_name(items, "name");
508 attr::remove_meta_items_by_name(tmp, "vers")
509 };
Brian Anderson29afe1a2011-06-29 21:17:23510
Marijn Haverbekedf7f21d2011-07-27 12:19:39511 let meta_items = ~[name_item, vers_item] + other_items;
512 let link_item = attr::mk_list_item("link", meta_items);
Brian Anderson29afe1a2011-06-29 21:17:23513
Brian Anderson70a28dc2011-07-01 00:03:08514 ret attr::mk_attr(link_item);
Brian Anderson29afe1a2011-06-29 21:17:23515 }
516
Erick Tryzelaar8b150452011-08-04 23:20:09517 let attrs: [attribute] = ~[];
Marijn Haverbekedf7f21d2011-07-27 12:19:39518 let found_link_attr = false;
519 for attr: attribute in crate.node.attrs {
520 attrs +=
521 if attr::get_attr_name(attr) != "link" {
522 ~[attr]
523 } else {
524 alt attr.node.value.node {
525 meta_list(n, l) {
Brian Anderson29afe1a2011-06-29 21:17:23526 found_link_attr = true;
Patrick Walton1a6419b2011-07-14 21:25:43527 ~[synthesize_link_attr(ecx, l)]
Marijn Haverbekedf7f21d2011-07-27 12:19:39528 }
529 _ { ~[attr] }
Brian Anderson29afe1a2011-06-29 21:17:23530 }
Brian Anderson29afe1a2011-06-29 21:17:23531 }
Brian Anderson29afe1a2011-06-29 21:17:23532 }
533
Marijn Haverbekedf7f21d2011-07-27 12:19:39534 if !found_link_attr { attrs += ~[synthesize_link_attr(ecx, ~[])]; }
Brian Anderson29afe1a2011-06-29 21:17:23535
536 ret attrs;
537}
538
Marijn Haverbekedf7f21d2011-07-27 12:19:39539fn encode_crate_deps(ebml_w: &ebmlivec::writer, cstore: &cstore::cstore) {
Brian Anderson30704392011-07-08 18:29:56540
Erick Tryzelaar8b150452011-08-04 23:20:09541 fn get_ordered_names(cstore: &cstore::cstore) -> [str] {
Marijn Haverbekedf7f21d2011-07-27 12:19:39542 type hashkv = @{key: crate_num, val: cstore::crate_metadata};
543 type numname = {crate: crate_num, ident: str};
Brian Anderson30704392011-07-08 18:29:56544
545 // Pull the cnums and names out of cstore
Erick Tryzelaar8b150452011-08-04 23:20:09546 let pairs: [mutable numname] = ~[mutable];
Marijn Haverbekedf7f21d2011-07-27 12:19:39547 for each hashkv: hashkv in cstore::iter_crate_data(cstore) {
548 pairs += ~[mutable {crate: hashkv.key, ident: hashkv.val.name}];
Brian Anderson30704392011-07-08 18:29:56549 }
550
551 // Sort by cnum
Marijn Haverbekedf7f21d2011-07-27 12:19:39552 fn lteq(kv1: &numname, kv2: &numname) -> bool {
553 kv1.crate <= kv2.crate
554 }
Patrick Walton1a6419b2011-07-14 21:25:43555 std::sort::ivector::quick_sort(lteq, pairs);
Brian Anderson30704392011-07-08 18:29:56556
557 // Sanity-check the crate numbers
Marijn Haverbekedf7f21d2011-07-27 12:19:39558 let expected_cnum = 1;
559 for n: numname in pairs {
560 assert (n.crate == expected_cnum);
Brian Anderson30704392011-07-08 18:29:56561 expected_cnum += 1;
562 }
563
564 // Return just the names
Marijn Haverbekedf7f21d2011-07-27 12:19:39565 fn name(kv: &numname) -> str { kv.ident }
Patrick Walton1a6419b2011-07-14 21:25:43566 // mutable -> immutable hack for ivec::map
Marijn Haverbekedf7f21d2011-07-27 12:19:39567 let immpairs = ivec::slice(pairs, 0u, ivec::len(pairs));
Patrick Walton1a6419b2011-07-14 21:25:43568 ret ivec::map(name, immpairs);
Brian Anderson30704392011-07-08 18:29:56569 }
570
571 // We're just going to write a list of crate names, with the assumption
572 // that they are numbered 1 to n.
573 // FIXME: This is not nearly enough to support correct versioning
574 // but is enough to get transitive crate dependencies working.
Patrick Waltonbe489ee2011-07-12 17:59:18575 ebmlivec::start_tag(ebml_w, tag_crate_deps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39576 for cname: str in get_ordered_names(cstore) {
Patrick Waltonbe489ee2011-07-12 17:59:18577 ebmlivec::start_tag(ebml_w, tag_crate_dep);
Brian Anderson2e7e5882011-08-11 23:36:20578 ebml_w.writer.write(str::bytes(cname));
Patrick Waltonbe489ee2011-07-12 17:59:18579 ebmlivec::end_tag(ebml_w);
Brian Anderson30704392011-07-08 18:29:56580 }
Patrick Waltonbe489ee2011-07-12 17:59:18581 ebmlivec::end_tag(ebml_w);
Brian Anderson30704392011-07-08 18:29:56582}
583
Marijn Haverbekedf7f21d2011-07-27 12:19:39584fn encode_metadata(cx: &@crate_ctxt, crate: &@crate) -> str {
Brian Andersond0a432f2011-07-08 06:55:41585
Marijn Haverbekedf7f21d2011-07-27 12:19:39586 let abbrevs = map::mk_hashmap(ty::hash_ty, ty::eq_ty);
587 let ecx = @{ccx: cx, type_abbrevs: abbrevs};
Brian Andersond0a432f2011-07-08 06:55:41588
Marijn Haverbekedf7f21d2011-07-27 12:19:39589 let string_w = ioivec::string_writer();
590 let buf_w = string_w.get_writer().get_buf_writer();
591 let ebml_w = ebmlivec::create_writer(buf_w);
Brian Anderson33294c72011-06-27 22:20:17592
Marijn Haverbekedf7f21d2011-07-27 12:19:39593 let crate_attrs = synthesize_crate_attrs(ecx, crate);
Brian Anderson29afe1a2011-06-29 21:17:23594 encode_attributes(ebml_w, crate_attrs);
Brian Anderson30704392011-07-08 18:29:56595
596 encode_crate_deps(ebml_w, cx.sess.get_cstore());
597
Brian Anderson33294c72011-06-27 22:20:17598 // Encode and index the paths.
599
Patrick Waltonbe489ee2011-07-12 17:59:18600 ebmlivec::start_tag(ebml_w, tag_paths);
Marijn Haverbekedf7f21d2011-07-27 12:19:39601 let paths_index = encode_item_paths(ebml_w, crate);
602 let paths_buckets = create_index(paths_index, hash_path);
Marijn Haverbekee949aab2011-07-25 13:07:48603 encode_index(ebml_w, paths_buckets, write_str);
Patrick Waltonbe489ee2011-07-12 17:59:18604 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17605 // Encode and index the items.
606
Patrick Waltonbe489ee2011-07-12 17:59:18607 ebmlivec::start_tag(ebml_w, tag_items);
Marijn Haverbekedf7f21d2011-07-27 12:19:39608 let items_index = encode_info_for_items(ecx, ebml_w);
609 let items_buckets = create_index(items_index, hash_node_id);
Marijn Haverbekee949aab2011-07-25 13:07:48610 encode_index(ebml_w, items_buckets, write_int);
Patrick Waltonbe489ee2011-07-12 17:59:18611 ebmlivec::end_tag(ebml_w);
Brian Anderson33294c72011-06-27 22:20:17612 // Pad this, since something (LLVM, presumably) is cutting off the
Brian Anderson2e7e5882011-08-11 23:36:20613 // remaining % 4 bytes.
Brian Anderson33294c72011-06-27 22:20:17614
Patrick Waltonbe489ee2011-07-12 17:59:18615 buf_w.write(~[0u8, 0u8, 0u8, 0u8]);
Brian Anderson33294c72011-06-27 22:20:17616 ret string_w.get_str();
617}
Brian Anderson894e2222011-06-28 02:16:16618
Brian Anderson7d26d1d2011-07-07 19:47:39619// Get the encoded string for a type
Marijn Haverbekedf7f21d2011-07-27 12:19:39620fn encoded_ty(tcx: &ty::ctxt, t: &ty::t) -> str {
621 let cx = @{ds: def_to_str, tcx: tcx, abbrevs: tyencode::ac_no_abbrevs};
622 let sw = ioivec::string_writer();
Brian Anderson7d26d1d2011-07-07 19:47:39623 tyencode::enc_ty(sw.get_writer(), cx, t);
624 ret sw.get_str();
625}
626
Brian Anderson894e2222011-06-28 02:16:16627
628// Local Variables:
629// mode: rust
630// fill-column: 78;
631// indent-tabs-mode: nil
632// c-basic-offset: 4
633// buffer-file-coding-system: utf-8-unix
634// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
635// End: