blob: fee50a927e6028d2cdfbcccd177bfaf77fa88730 [file] [log] [blame]
Brian Anderson45efb1f2011-06-27 23:03:011// Metadata encoding
2
Graydon Hoare6f5853f2012-03-13 03:04:273import std::{ebml, map, list};
Patrick Waltonc9375fe2012-03-08 00:48:574import std::map::hashmap;
Marijn Haverbeke34d7f052012-01-11 14:15:545import io::writer_util;
Niko Matsakisf3ca50c2012-02-14 23:21:536import ebml::writer;
Marijn Haverbeke6fd6fde2011-07-05 09:48:197import syntax::ast::*;
Niko Matsakisf3ca50c2012-02-14 23:21:538import syntax::print::pprust;
Marijn Haverbekefe90c182012-03-08 22:37:459import syntax::{ast_util, visit};
Brian Anderson152cbaa2011-08-22 04:44:4110import syntax::ast_util::local_def;
Brian Andersone29ef1b2011-07-07 19:22:3911import common::*;
Marijn Haverbeke03e9dac2012-01-27 12:17:0612import middle::trans::common::crate_ctxt;
Brian Anderson33294c72011-06-27 22:20:1713import middle::ty;
Marijn Haverbeke86d473a2012-01-30 16:28:3014import middle::ty::node_id_to_type;
Niko Matsakisfdddf8f2012-02-10 14:01:3215import middle::ast_map;
Brian Anderson5de916d2011-06-30 06:42:3516import front::attr;
Tim Chevalierfba35e12012-01-31 05:00:5717import driver::session::session;
Niko Matsakisf3ca50c2012-02-14 23:21:5318import std::serialization::serializer;
Brian Anderson33294c72011-06-27 22:20:1719
Brian Anderson33294c72011-06-27 22:20:1720export encode_metadata;
Brian Anderson6ee1ffe2011-07-07 19:56:0121export encoded_ty;
Brian Anderson33294c72011-06-27 22:20:1722
Niko Matsakisf3ca50c2012-02-14 23:21:5323// used by astencode:
24export def_to_str;
25export encode_ctxt;
26export write_type;
27export encode_def_id;
28
Erick Tryzelaare4a0f992011-08-12 14:15:1829type abbrev_map = map::hashmap<ty::t, tyencode::ty_abbrev>;
Brian Andersond0a432f2011-07-08 06:55:4130
Patrick Walton273c5e52012-03-15 00:31:1631type encode_ctxt = {ccx: @crate_ctxt,
Marijn Haverbekefb61b8f2012-03-06 11:52:1332 type_abbrevs: abbrev_map,
33 reachable: reachable::map};
Brian Andersond0a432f2011-07-08 06:55:4134
Brian Anderson33294c72011-06-27 22:20:1735// Path table encoding
Marijn Haverbekefc6b7c82011-09-12 09:27:3036fn encode_name(ebml_w: ebml::writer, name: str) {
Niko Matsakisf3ca50c2012-02-14 23:21:5337 ebml_w.wr_tagged_str(tag_paths_data_name, name);
Brian Anderson33294c72011-06-27 22:20:1738}
39
Marijn Haverbekefc6b7c82011-09-12 09:27:3040fn encode_def_id(ebml_w: ebml::writer, id: def_id) {
Niko Matsakisf3ca50c2012-02-14 23:21:5341 ebml_w.wr_tagged_str(tag_def_id, def_to_str(id));
Niko Matsakis5d57fa32012-02-06 15:13:1442}
43
44fn encode_named_def_id(ebml_w: ebml::writer, name: str, id: def_id) {
45 ebml_w.wr_tag(tag_paths_data_item) {||
46 encode_name(ebml_w, name);
47 encode_def_id(ebml_w, id);
48 }
Brian Anderson33294c72011-06-27 22:20:1749}
50
Erick Tryzelaar4abc4712011-08-12 13:36:5151type entry<T> = {val: T, pos: uint};
Marijn Haverbekeaea53772011-07-26 12:06:0252
Marijn Haverbeke76aabbe2012-01-25 13:34:3153fn encode_enum_variant_paths(ebml_w: ebml::writer, variants: [variant],
Marijn Haverbekeca1df2b2011-09-12 10:39:3854 path: [str], &index: [entry<str>]) {
Lindsey Kuperf91351a2011-08-16 04:54:5255 for variant: variant in variants {
Brian Anderson03119fe2011-08-26 00:00:1256 add_to_index(ebml_w, path, index, variant.node.name);
Niko Matsakis5d57fa32012-02-06 15:13:1457 ebml_w.wr_tag(tag_paths_data_item) {||
58 encode_name(ebml_w, variant.node.name);
59 encode_def_id(ebml_w, local_def(variant.node.id));
60 }
Brian Anderson33294c72011-06-27 22:20:1761 }
62}
63
Marijn Haverbekeca1df2b2011-09-12 10:39:3864fn add_to_index(ebml_w: ebml::writer, path: [str], &index: [entry<str>],
65 name: str) {
Brian Anderson518dc522011-08-19 22:16:4866 let full_path = path + [name];
Marijn Haverbekedf7f21d2011-07-27 12:19:3967 index +=
Brian Anderson5c49e4f2011-09-02 22:34:5868 [{val: str::connect(full_path, "::"), pos: ebml_w.writer.tell()}];
Brian Anderson33294c72011-06-27 22:20:1769}
70
Marijn Haverbekefc6b7c82011-09-12 09:27:3071fn encode_native_module_item_paths(ebml_w: ebml::writer, nmod: native_mod,
Marijn Haverbekeca1df2b2011-09-12 10:39:3872 path: [str], &index: [entry<str>]) {
Lindsey Kuperf91351a2011-08-16 04:54:5273 for nitem: @native_item in nmod.items {
Brian Anderson03119fe2011-08-26 00:00:1274 add_to_index(ebml_w, path, index, nitem.ident);
Niko Matsakis5d57fa32012-02-06 15:13:1475 encode_named_def_id(ebml_w, nitem.ident, local_def(nitem.id));
Brian Anderson33294c72011-06-27 22:20:1776 }
77}
78
Marijn Haverbekefb61b8f2012-03-06 11:52:1379fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
80 module: _mod, path: [str], &index: [entry<str>]) {
Marijn Haverbeke057617c2011-12-20 15:33:5581 // FIXME factor out add_to_index/start/encode_name/encode_def_id/end ops
Lindsey Kuperf91351a2011-08-16 04:54:5282 for it: @item in module.items {
Marijn Haverbekec67679e2012-03-08 09:58:2383 if !ecx.reachable.contains_key(it.id) ||
84 !ast_util::is_exported(it.ident, module) { cont; }
Marijn Haverbekedf7f21d2011-07-27 12:19:3985 alt it.node {
86 item_const(_, _) {
Brian Anderson03119fe2011-08-26 00:00:1287 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakis5d57fa32012-02-06 15:13:1488 encode_named_def_id(ebml_w, it.ident, local_def(it.id));
Marijn Haverbekedf7f21d2011-07-27 12:19:3989 }
Marijn Haverbeke0490c362011-12-22 16:49:5490 item_fn(_, tps, _) {
Brian Anderson03119fe2011-08-26 00:00:1291 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakis5d57fa32012-02-06 15:13:1492 encode_named_def_id(ebml_w, it.ident, local_def(it.id));
Marijn Haverbekedf7f21d2011-07-27 12:19:3993 }
94 item_mod(_mod) {
Brian Anderson03119fe2011-08-26 00:00:1295 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:5396 ebml_w.start_tag(tag_paths_data_mod);
Brian Anderson03119fe2011-08-26 00:00:1297 encode_name(ebml_w, it.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:3998 encode_def_id(ebml_w, local_def(it.id));
Marijn Haverbekefb61b8f2012-03-06 11:52:1399 encode_module_item_paths(ebml_w, ecx, _mod, path + [it.ident],
100 index);
Niko Matsakisf3ca50c2012-02-14 23:21:53101 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39102 }
103 item_native_mod(nmod) {
Brian Anderson03119fe2011-08-26 00:00:12104 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:53105 ebml_w.start_tag(tag_paths_data_mod);
Brian Anderson03119fe2011-08-26 00:00:12106 encode_name(ebml_w, it.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39107 encode_def_id(ebml_w, local_def(it.id));
Brian Anderson5c49e4f2011-09-02 22:34:58108 encode_native_module_item_paths(ebml_w, nmod, path + [it.ident],
109 index);
Niko Matsakisf3ca50c2012-02-14 23:21:53110 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39111 }
112 item_ty(_, tps) {
Brian Anderson03119fe2011-08-26 00:00:12113 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:53114 ebml_w.start_tag(tag_paths_data_item);
Brian Anderson03119fe2011-08-26 00:00:12115 encode_name(ebml_w, it.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39116 encode_def_id(ebml_w, local_def(it.id));
Niko Matsakisf3ca50c2012-02-14 23:21:53117 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39118 }
Marijn Haverbeke0490c362011-12-22 16:49:54119 item_res(_, tps, _, _, ctor_id) {
Brian Anderson03119fe2011-08-26 00:00:12120 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:53121 ebml_w.start_tag(tag_paths_data_item);
Brian Anderson03119fe2011-08-26 00:00:12122 encode_name(ebml_w, it.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39123 encode_def_id(ebml_w, local_def(ctor_id));
Niko Matsakisf3ca50c2012-02-14 23:21:53124 ebml_w.end_tag();
Brian Anderson03119fe2011-08-26 00:00:12125 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:53126 ebml_w.start_tag(tag_paths_data_item);
Brian Anderson03119fe2011-08-26 00:00:12127 encode_name(ebml_w, it.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39128 encode_def_id(ebml_w, local_def(it.id));
Niko Matsakisf3ca50c2012-02-14 23:21:53129 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39130 }
Tim Chevaliere2fa6f02012-03-04 01:49:23131 item_class(_,_,_) {
Tim Chevalierf3343b32012-02-01 03:30:40132 fail "encode: implement item_class";
133 }
Marijn Haverbeke76aabbe2012-01-25 13:34:31134 item_enum(variants, tps) {
Brian Anderson03119fe2011-08-26 00:00:12135 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:53136 ebml_w.start_tag(tag_paths_data_item);
Brian Anderson03119fe2011-08-26 00:00:12137 encode_name(ebml_w, it.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39138 encode_def_id(ebml_w, local_def(it.id));
Niko Matsakisf3ca50c2012-02-14 23:21:53139 ebml_w.end_tag();
Marijn Haverbeke76aabbe2012-01-25 13:34:31140 encode_enum_variant_paths(ebml_w, variants, path, index);
Marijn Haverbekedf7f21d2011-07-27 12:19:39141 }
Marijn Haverbeke057617c2011-12-20 15:33:55142 item_iface(_, _) {
143 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:53144 ebml_w.start_tag(tag_paths_data_item);
Marijn Haverbeke057617c2011-12-20 15:33:55145 encode_name(ebml_w, it.ident);
146 encode_def_id(ebml_w, local_def(it.id));
Niko Matsakisf3ca50c2012-02-14 23:21:53147 ebml_w.end_tag();
Marijn Haverbeke057617c2011-12-20 15:33:55148 }
149 item_impl(_, _, _, _) {}
Brian Anderson33294c72011-06-27 22:20:17150 }
151 }
152}
153
Haitao Li9bb290c2011-12-15 10:42:27154fn encode_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt, crate: @crate)
155 -> [entry<str>] {
Brian Anderson5c49e4f2011-09-02 22:34:58156 let index: [entry<str>] = [];
157 let path: [str] = [];
Niko Matsakisf3ca50c2012-02-14 23:21:53158 ebml_w.start_tag(tag_paths);
Marijn Haverbekefb61b8f2012-03-06 11:52:13159 encode_module_item_paths(ebml_w, ecx, crate.node.module, path, index);
Haitao Li9bb290c2011-12-15 10:42:27160 encode_reexport_paths(ebml_w, ecx, index);
Niko Matsakisf3ca50c2012-02-14 23:21:53161 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17162 ret index;
163}
164
Haitao Li9bb290c2011-12-15 10:42:27165fn encode_reexport_paths(ebml_w: ebml::writer,
166 ecx: @encode_ctxt, &index: [entry<str>]) {
Marijn Haverbeke4e4bd582012-03-06 12:57:07167 let tcx = ecx.ccx.tcx;
168 ecx.ccx.exp_map.items {|exp_id, defs|
169 for def in defs {
170 if !def.reexp { cont; }
171 let path = alt check tcx.items.get(exp_id) {
172 ast_map::node_export(_, path) { ast_map::path_to_str(*path) }
173 };
Marijn Haverbekec590bde2012-01-26 16:33:12174 index += [{val: path, pos: ebml_w.writer.tell()}];
Niko Matsakisf3ca50c2012-02-14 23:21:53175 ebml_w.start_tag(tag_paths_data_item);
Marijn Haverbekec590bde2012-01-26 16:33:12176 encode_name(ebml_w, path);
Marijn Haverbeke4e4bd582012-03-06 12:57:07177 encode_def_id(ebml_w, def.id);
Niko Matsakisf3ca50c2012-02-14 23:21:53178 ebml_w.end_tag();
Marijn Haverbekec590bde2012-01-26 16:33:12179 }
Haitao Li9bb290c2011-12-15 10:42:27180 }
181}
182
Brian Anderson33294c72011-06-27 22:20:17183
184// Item info table encoding
Marijn Haverbeke72591492012-02-13 19:55:23185fn encode_family(ebml_w: ebml::writer, c: char) {
Niko Matsakisf3ca50c2012-02-14 23:21:53186 ebml_w.start_tag(tag_items_data_item_family);
Marijn Haverbeke72591492012-02-13 19:55:23187 ebml_w.writer.write([c as u8]);
Niko Matsakisf3ca50c2012-02-14 23:21:53188 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17189}
190
Marijn Haverbekefc6b7c82011-09-12 09:27:30191fn def_to_str(did: def_id) -> str { ret #fmt["%d:%d", did.crate, did.node]; }
Brian Anderson33294c72011-06-27 22:20:17192
Marijn Haverbeke1ed6a272011-12-28 16:50:12193fn encode_type_param_bounds(ebml_w: ebml::writer, ecx: @encode_ctxt,
194 params: [ty_param]) {
195 let ty_str_ctxt = @{ds: def_to_str,
196 tcx: ecx.ccx.tcx,
197 abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
198 for param in params {
Niko Matsakisf3ca50c2012-02-14 23:21:53199 ebml_w.start_tag(tag_items_data_item_ty_param_bounds);
Marijn Haverbeke3a1710d2012-01-02 11:13:26200 let bs = ecx.ccx.tcx.ty_param_bounds.get(param.id);
Marijn Haverbeke34d7f052012-01-11 14:15:54201 tyencode::enc_bounds(ebml_w.writer, ty_str_ctxt, bs);
Niko Matsakisf3ca50c2012-02-14 23:21:53202 ebml_w.end_tag();
Graydon Hoare59c441a2011-07-29 23:40:23203 }
Brian Anderson33294c72011-06-27 22:20:17204}
205
Marijn Haverbekefc6b7c82011-09-12 09:27:30206fn encode_variant_id(ebml_w: ebml::writer, vid: def_id) {
Niko Matsakisf3ca50c2012-02-14 23:21:53207 ebml_w.start_tag(tag_items_data_item_variant);
Brian Andersonab6bb032011-09-02 00:27:58208 ebml_w.writer.write(str::bytes(def_to_str(vid)));
Niko Matsakisf3ca50c2012-02-14 23:21:53209 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17210}
211
Marijn Haverbeke6559aa82012-01-05 09:57:19212fn write_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
Marijn Haverbekedf7f21d2011-07-27 12:19:39213 let ty_str_ctxt =
Marijn Haverbeke1ed6a272011-12-28 16:50:12214 @{ds: def_to_str,
Marijn Haverbekedf7f21d2011-07-27 12:19:39215 tcx: ecx.ccx.tcx,
216 abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
Marijn Haverbeke34d7f052012-01-11 14:15:54217 tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
Marijn Haverbeke6559aa82012-01-05 09:57:19218}
219
220fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
Niko Matsakisf3ca50c2012-02-14 23:21:53221 ebml_w.start_tag(tag_items_data_item_type);
Marijn Haverbeke6559aa82012-01-05 09:57:19222 write_type(ecx, ebml_w, typ);
Niko Matsakisf3ca50c2012-02-14 23:21:53223 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17224}
225
Marijn Haverbekefc6b7c82011-09-12 09:27:30226fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml::writer, id: node_id) {
Niko Matsakisf3ca50c2012-02-14 23:21:53227 ebml_w.start_tag(tag_items_data_item_symbol);
Brian Andersonab6bb032011-09-02 00:27:58228 ebml_w.writer.write(str::bytes(ecx.ccx.item_symbols.get(id)));
Niko Matsakisf3ca50c2012-02-14 23:21:53229 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17230}
231
Marijn Haverbekefc6b7c82011-09-12 09:27:30232fn encode_discriminant(ecx: @encode_ctxt, ebml_w: ebml::writer, id: node_id) {
Niko Matsakisf3ca50c2012-02-14 23:21:53233 ebml_w.start_tag(tag_items_data_item_symbol);
Brian Andersonab6bb032011-09-02 00:27:58234 ebml_w.writer.write(str::bytes(ecx.ccx.discrim_symbols.get(id)));
Niko Matsakisf3ca50c2012-02-14 23:21:53235 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17236}
237
Kevin Atkinson08abf8d2012-01-10 21:50:40238fn encode_disr_val(_ecx: @encode_ctxt, ebml_w: ebml::writer, disr_val: int) {
Niko Matsakisf3ca50c2012-02-14 23:21:53239 ebml_w.start_tag(tag_disr_val);
Kevin Atkinson08abf8d2012-01-10 21:50:40240 ebml_w.writer.write(str::bytes(int::to_str(disr_val,10u)));
Niko Matsakisf3ca50c2012-02-14 23:21:53241 ebml_w.end_tag();
Kevin Atkinson08abf8d2012-01-10 21:50:40242}
243
Marijn Haverbeke2c8c50d2012-03-08 22:13:57244fn encode_parent_item(ebml_w: ebml::writer, id: def_id) {
245 ebml_w.start_tag(tag_items_data_parent_item);
Brian Andersonab6bb032011-09-02 00:27:58246 ebml_w.writer.write(str::bytes(def_to_str(id)));
Niko Matsakisf3ca50c2012-02-14 23:21:53247 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17248}
249
Marijn Haverbeke76aabbe2012-01-25 13:34:31250fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
Niko Matsakisfdddf8f2012-02-10 14:01:32251 id: node_id, variants: [variant],
Marijn Haverbekefe90c182012-03-08 22:37:45252 path: ast_map::path, index: @mutable [entry<int>],
Niko Matsakisfdddf8f2012-02-10 14:01:32253 ty_params: [ty_param]) {
Kevin Atkinson08abf8d2012-01-10 21:50:40254 let disr_val = 0;
Kevin Atkinsone1c50c42012-01-16 09:36:47255 let i = 0;
Marijn Haverbeke76aabbe2012-01-25 13:34:31256 let vi = ty::enum_variants(ecx.ccx.tcx, {crate: local_crate, node: id});
Lindsey Kuperf91351a2011-08-16 04:54:52257 for variant: variant in variants {
Marijn Haverbekefe90c182012-03-08 22:37:45258 *index += [{val: variant.node.id, pos: ebml_w.writer.tell()}];
Niko Matsakisf3ca50c2012-02-14 23:21:53259 ebml_w.start_tag(tag_items_data_item);
Brian Anderson33294c72011-06-27 22:20:17260 encode_def_id(ebml_w, local_def(variant.node.id));
Marijn Haverbeke72591492012-02-13 19:55:23261 encode_family(ebml_w, 'v');
Niko Matsakisa83ad1b2012-01-16 05:42:10262 encode_name(ebml_w, variant.node.name);
Marijn Haverbeke2c8c50d2012-03-08 22:13:57263 encode_parent_item(ebml_w, local_def(id));
Brian Andersond0a432f2011-07-08 06:55:41264 encode_type(ecx, ebml_w,
Marijn Haverbeke86d473a2012-01-30 16:28:30265 node_id_to_type(ecx.ccx.tcx, variant.node.id));
Marijn Haverbeke168398b2012-03-08 12:30:22266 if vec::len(variant.node.args) > 0u && ty_params.len() == 0u {
Brian Andersond0a432f2011-07-08 06:55:41267 encode_symbol(ecx, ebml_w, variant.node.id);
Brian Anderson33294c72011-06-27 22:20:17268 }
Brian Andersond0a432f2011-07-08 06:55:41269 encode_discriminant(ecx, ebml_w, variant.node.id);
Kevin Atkinsone1c50c42012-01-16 09:36:47270 if vi[i].disr_val != disr_val {
271 encode_disr_val(ecx, ebml_w, vi[i].disr_val);
272 disr_val = vi[i].disr_val;
Kevin Atkinson08abf8d2012-01-10 21:50:40273 }
Marijn Haverbeke1ed6a272011-12-28 16:50:12274 encode_type_param_bounds(ebml_w, ecx, ty_params);
Niko Matsakisfdddf8f2012-02-10 14:01:32275 encode_path(ebml_w, path, ast_map::path_name(variant.node.name));
Niko Matsakisf3ca50c2012-02-14 23:21:53276 ebml_w.end_tag();
Kevin Atkinson08abf8d2012-01-10 21:50:40277 disr_val += 1;
Kevin Atkinsone1c50c42012-01-16 09:36:47278 i += 1;
Brian Anderson33294c72011-06-27 22:20:17279 }
280}
281
Niko Matsakisfdddf8f2012-02-10 14:01:32282fn encode_path(ebml_w: ebml::writer,
283 path: ast_map::path,
284 name: ast_map::path_elt) {
285 fn encode_path_elt(ebml_w: ebml::writer, elt: ast_map::path_elt) {
286 let (tag, name) = alt elt {
287 ast_map::path_mod(name) { (tag_path_elt_mod, name) }
288 ast_map::path_name(name) { (tag_path_elt_name, name) }
289 };
290
Niko Matsakisf3ca50c2012-02-14 23:21:53291 ebml_w.wr_tagged_str(tag, name);
Niko Matsakisfdddf8f2012-02-10 14:01:32292 }
293
294 ebml_w.wr_tag(tag_path) {||
Niko Matsakisf3ca50c2012-02-14 23:21:53295 ebml_w.wr_tagged_u32(tag_path_len, (vec::len(path) + 1u) as u32);
Niko Matsakisfdddf8f2012-02-10 14:01:32296 vec::iter(path) {|pe| encode_path_elt(ebml_w, pe); }
297 encode_path_elt(ebml_w, name);
298 }
299}
300
Marijn Haverbekec590bde2012-01-26 16:33:12301fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
Niko Matsakisfdddf8f2012-02-10 14:01:32302 id: node_id, path: ast_map::path, name: ident) {
Niko Matsakisf3ca50c2012-02-14 23:21:53303 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbeke58a81a62011-12-16 13:41:12304 encode_def_id(ebml_w, local_def(id));
Marijn Haverbeke72591492012-02-13 19:55:23305 encode_family(ebml_w, 'm');
Haitao Libd300632011-12-19 19:30:23306 encode_name(ebml_w, name);
Niko Matsakisf3ca50c2012-02-14 23:21:53307 alt ecx.ccx.maps.impl_map.get(id) {
Marijn Haverbekec590bde2012-01-26 16:33:12308 list::cons(impls, @list::nil) {
309 for i in *impls {
Marijn Haverbeke58a81a62011-12-16 13:41:12310 if ast_util::is_exported(i.ident, md) {
Niko Matsakisf3ca50c2012-02-14 23:21:53311 ebml_w.wr_tagged_str(tag_mod_impl, def_to_str(i.did));
Marijn Haverbeke58a81a62011-12-16 13:41:12312 }
Marijn Haverbeke58a81a62011-12-16 13:41:12313 }
Marijn Haverbekec590bde2012-01-26 16:33:12314 }
Tim Chevalierfba35e12012-01-31 05:00:57315 _ { ecx.ccx.tcx.sess.bug("encode_info_for_mod: \
316 undocumented invariant"); }
Marijn Haverbeke58a81a62011-12-16 13:41:12317 }
Niko Matsakisfdddf8f2012-02-10 14:01:32318 encode_path(ebml_w, path, ast_map::path_mod(name));
Niko Matsakisf3ca50c2012-02-14 23:21:53319 ebml_w.end_tag();
Marijn Haverbeke58a81a62011-12-16 13:41:12320}
321
Marijn Haverbeke6c9d95a2012-02-13 17:56:09322fn purity_fn_family(p: purity) -> char {
Brian Anderson6943b382012-02-10 21:39:15323 alt p {
324 unsafe_fn { 'u' }
325 pure_fn { 'p' }
326 impure_fn { 'f' }
327 crust_fn { 'c' }
328 }
Marijn Haverbeke6c9d95a2012-02-13 17:56:09329}
330
Marijn Haverbekefc6b7c82011-09-12 09:27:30331fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
Marijn Haverbekefe90c182012-03-08 22:37:45332 index: @mutable [entry<int>], path: ast_map::path) {
Niko Matsakis0416a942012-03-02 21:14:10333
334 fn should_inline(attrs: [attribute]) -> bool {
335 alt attr::find_inline_attr(attrs) {
336 attr::ia_none { false }
337 attr::ia_hint | attr::ia_always { true }
338 }
339 }
340
Marijn Haverbeke3a20dda2012-01-05 12:57:27341 let tcx = ecx.ccx.tcx;
Marijn Haverbeke4650e8b2012-03-08 20:16:04342 let must_write = alt item.node { item_enum(_, _) { true } _ { false } };
Marijn Haverbekefe90c182012-03-08 22:37:45343 if !must_write && !ecx.reachable.contains_key(item.id) { ret; }
344 *index += [{val: item.id, pos: ebml_w.writer.tell()}];
Marijn Haverbekefb61b8f2012-03-06 11:52:13345
Marijn Haverbekedf7f21d2011-07-27 12:19:39346 alt item.node {
347 item_const(_, _) {
Niko Matsakisf3ca50c2012-02-14 23:21:53348 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39349 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23350 encode_family(ebml_w, 'c');
Marijn Haverbeke86d473a2012-01-30 16:28:30351 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Marijn Haverbekedf7f21d2011-07-27 12:19:39352 encode_symbol(ecx, ebml_w, item.id);
Niko Matsakisfdddf8f2012-02-10 14:01:32353 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53354 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39355 }
Marijn Haverbeke0490c362011-12-22 16:49:54356 item_fn(decl, tps, _) {
Niko Matsakisf3ca50c2012-02-14 23:21:53357 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39358 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23359 encode_family(ebml_w, purity_fn_family(decl.purity));
Marijn Haverbeke1ed6a272011-12-28 16:50:12360 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke86d473a2012-01-30 16:28:30361 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Niko Matsakisfdddf8f2012-02-10 14:01:32362 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Marijn Haverbekec67679e2012-03-08 09:58:23363 if tps.len() > 0u || should_inline(item.attrs) {
Niko Matsakis6473a872012-03-02 03:37:52364 astencode::encode_inlined_item(ecx, ebml_w, path, ii_item(item));
Marijn Haverbeke168398b2012-03-08 12:30:22365 } else {
366 encode_symbol(ecx, ebml_w, item.id);
Niko Matsakisf3ca50c2012-02-14 23:21:53367 }
368 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39369 }
Marijn Haverbeke0a362612011-12-16 13:17:52370 item_mod(m) {
Niko Matsakisfdddf8f2012-02-10 14:01:32371 encode_info_for_mod(ecx, ebml_w, m, item.id, path, item.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39372 }
373 item_native_mod(_) {
Niko Matsakisf3ca50c2012-02-14 23:21:53374 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39375 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23376 encode_family(ebml_w, 'n');
Haitao Libd300632011-12-19 19:30:23377 encode_name(ebml_w, item.ident);
Niko Matsakisfdddf8f2012-02-10 14:01:32378 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53379 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39380 }
381 item_ty(_, tps) {
Niko Matsakisf3ca50c2012-02-14 23:21:53382 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39383 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23384 encode_family(ebml_w, 'y');
Marijn Haverbeke1ed6a272011-12-28 16:50:12385 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke86d473a2012-01-30 16:28:30386 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Marijn Haverbeke619d7c32011-12-19 12:52:58387 encode_name(ebml_w, item.ident);
Niko Matsakisfdddf8f2012-02-10 14:01:32388 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53389 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39390 }
Marijn Haverbeke76aabbe2012-01-25 13:34:31391 item_enum(variants, tps) {
Niko Matsakisf3ca50c2012-02-14 23:21:53392 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39393 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23394 encode_family(ebml_w, 't');
Marijn Haverbeke1ed6a272011-12-28 16:50:12395 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke86d473a2012-01-30 16:28:30396 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Marijn Haverbeke619d7c32011-12-19 12:52:58397 encode_name(ebml_w, item.ident);
Lindsey Kuperf91351a2011-08-16 04:54:52398 for v: variant in variants {
Marijn Haverbekedf7f21d2011-07-27 12:19:39399 encode_variant_id(ebml_w, local_def(v.node.id));
Brian Anderson33294c72011-06-27 22:20:17400 }
Marijn Haverbeke2c8c50d2012-03-08 22:13:57401 astencode::encode_inlined_item(ecx, ebml_w, path, ii_item(item));
Niko Matsakisfdddf8f2012-02-10 14:01:32402 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53403 ebml_w.end_tag();
Niko Matsakisfdddf8f2012-02-10 14:01:32404 encode_enum_variant_info(ecx, ebml_w, item.id, variants,
405 path, index, tps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39406 }
Tim Chevaliere2fa6f02012-03-04 01:49:23407 item_class(_,_,_) {
Tim Chevalierf3343b32012-02-01 03:30:40408 fail "encode: implement item_class";
409 }
Marijn Haverbeke0490c362011-12-22 16:49:54410 item_res(_, tps, _, _, ctor_id) {
Marijn Haverbeke86d473a2012-01-30 16:28:30411 let fn_ty = node_id_to_type(tcx, ctor_id);
Brian Anderson33294c72011-06-27 22:20:17412
Niko Matsakisf3ca50c2012-02-14 23:21:53413 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39414 encode_def_id(ebml_w, local_def(ctor_id));
Marijn Haverbeke72591492012-02-13 19:55:23415 encode_family(ebml_w, 'y');
Marijn Haverbeke1ed6a272011-12-28 16:50:12416 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke8673c4f2012-02-03 14:15:28417 encode_type(ecx, ebml_w, ty::ty_fn_ret(fn_ty));
Marijn Haverbeke619d7c32011-12-19 12:52:58418 encode_name(ebml_w, item.ident);
Marijn Haverbeke2c8c50d2012-03-08 22:13:57419 astencode::encode_inlined_item(ecx, ebml_w, path, ii_item(item));
Niko Matsakisfdddf8f2012-02-10 14:01:32420 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53421 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17422
Marijn Haverbekefe90c182012-03-08 22:37:45423 *index += [{val: ctor_id, pos: ebml_w.writer.tell()}];
Niko Matsakisf3ca50c2012-02-14 23:21:53424 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39425 encode_def_id(ebml_w, local_def(ctor_id));
Marijn Haverbeke72591492012-02-13 19:55:23426 encode_family(ebml_w, 'f');
Marijn Haverbeke1ed6a272011-12-28 16:50:12427 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39428 encode_type(ecx, ebml_w, fn_ty);
Marijn Haverbeke2c8c50d2012-03-08 22:13:57429 encode_parent_item(ebml_w, local_def(item.id));
Niko Matsakisfdddf8f2012-02-10 14:01:32430 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53431 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39432 }
Marijn Haverbeke6559aa82012-01-05 09:57:19433 item_impl(tps, ifce, _, methods) {
Niko Matsakisf3ca50c2012-02-14 23:21:53434 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbeke0a362612011-12-16 13:17:52435 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23436 encode_family(ebml_w, 'i');
Marijn Haverbeke1ed6a272011-12-28 16:50:12437 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke86d473a2012-01-30 16:28:30438 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Marijn Haverbeke58a81a62011-12-16 13:41:12439 encode_name(ebml_w, item.ident);
Marijn Haverbeke0a362612011-12-16 13:17:52440 for m in methods {
Niko Matsakisf3ca50c2012-02-14 23:21:53441 ebml_w.start_tag(tag_item_method);
Marijn Haverbeke0490c362011-12-22 16:49:54442 ebml_w.writer.write(str::bytes(def_to_str(local_def(m.id))));
Niko Matsakisf3ca50c2012-02-14 23:21:53443 ebml_w.end_tag();
Marijn Haverbeke0a362612011-12-16 13:17:52444 }
Marijn Haverbeke6559aa82012-01-05 09:57:19445 alt ifce {
Marijn Haverbekec71306b2012-03-07 11:54:00446 some(t) {
Marijn Haverbekec71306b2012-03-07 11:54:00447 let i_ty = alt check t.node {
448 ty_path(_, id) { ty::node_id_to_type(tcx, id) }
449 };
Niko Matsakisf3ca50c2012-02-14 23:21:53450 ebml_w.start_tag(tag_impl_iface);
Marijn Haverbeke3a20dda2012-01-05 12:57:27451 write_type(ecx, ebml_w, i_ty);
Niko Matsakisf3ca50c2012-02-14 23:21:53452 ebml_w.end_tag();
Marijn Haverbeke6559aa82012-01-05 09:57:19453 }
454 _ {}
455 }
Niko Matsakisfdddf8f2012-02-10 14:01:32456 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53457 ebml_w.end_tag();
Marijn Haverbeke0a362612011-12-16 13:17:52458
Niko Matsakisfdddf8f2012-02-10 14:01:32459 let impl_path = path + [ast_map::path_name(item.ident)];
Marijn Haverbeke0a362612011-12-16 13:17:52460 for m in methods {
Marijn Haverbekefe90c182012-03-08 22:37:45461 *index += [{val: m.id, pos: ebml_w.writer.tell()}];
Niko Matsakisf3ca50c2012-02-14 23:21:53462 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbeke0490c362011-12-22 16:49:54463 encode_def_id(ebml_w, local_def(m.id));
Marijn Haverbeke72591492012-02-13 19:55:23464 encode_family(ebml_w, purity_fn_family(m.decl.purity));
Marijn Haverbeke1ed6a272011-12-28 16:50:12465 encode_type_param_bounds(ebml_w, ecx, tps + m.tps);
Marijn Haverbeke6c9d95a2012-02-13 17:56:09466 encode_type(ecx, ebml_w, node_id_to_type(tcx, m.id));
Marijn Haverbeke0490c362011-12-22 16:49:54467 encode_name(ebml_w, m.ident);
Niko Matsakisfdddf8f2012-02-10 14:01:32468 encode_path(ebml_w, impl_path, ast_map::path_name(m.ident));
Marijn Haverbeke5e647d72012-03-08 11:15:02469 if tps.len() > 0u || m.tps.len() > 0u || should_inline(m.attrs) {
Niko Matsakisd3a0f7e2012-03-02 04:32:00470 astencode::encode_inlined_item(
471 ecx, ebml_w, impl_path,
472 ii_method(local_def(item.id), m));
Marijn Haverbeke168398b2012-03-08 12:30:22473 } else {
474 encode_symbol(ecx, ebml_w, m.id);
Niko Matsakisd3a0f7e2012-03-02 04:32:00475 }
Niko Matsakisf3ca50c2012-02-14 23:21:53476 ebml_w.end_tag();
Marijn Haverbeke0a362612011-12-16 13:17:52477 }
478 }
Marijn Haverbeke3a20dda2012-01-05 12:57:27479 item_iface(tps, ms) {
Niko Matsakisf3ca50c2012-02-14 23:21:53480 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbeke3a20dda2012-01-05 12:57:27481 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23482 encode_family(ebml_w, 'I');
Marijn Haverbeke3a20dda2012-01-05 12:57:27483 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke86d473a2012-01-30 16:28:30484 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Marijn Haverbeke3a20dda2012-01-05 12:57:27485 encode_name(ebml_w, item.ident);
486 let i = 0u;
487 for mty in *ty::iface_methods(tcx, local_def(item.id)) {
Niko Matsakisf3ca50c2012-02-14 23:21:53488 ebml_w.start_tag(tag_item_method);
Marijn Haverbeke3a20dda2012-01-05 12:57:27489 encode_name(ebml_w, mty.ident);
490 encode_type_param_bounds(ebml_w, ecx, ms[i].tps);
491 encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty));
Marijn Haverbeke72591492012-02-13 19:55:23492 encode_family(ebml_w, purity_fn_family(mty.purity));
Niko Matsakisf3ca50c2012-02-14 23:21:53493 ebml_w.end_tag();
Marijn Haverbeke3a20dda2012-01-05 12:57:27494 i += 1u;
495 }
Niko Matsakisfdddf8f2012-02-10 14:01:32496 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53497 ebml_w.end_tag();
Marijn Haverbeke3a20dda2012-01-05 12:57:27498 }
Brian Anderson33294c72011-06-27 22:20:17499 }
500}
501
Marijn Haverbekefc6b7c82011-09-12 09:27:30502fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
Marijn Haverbekefe90c182012-03-08 22:37:45503 nitem: @native_item,
504 index: @mutable [entry<int>],
Marijn Haverbekeb6ad34b2012-03-09 12:35:20505 path: ast_map::path, abi: native_abi) {
Marijn Haverbekefe90c182012-03-08 22:37:45506 if !ecx.reachable.contains_key(nitem.id) { ret; }
507 *index += [{val: nitem.id, pos: ebml_w.writer.tell()}];
508
Niko Matsakisf3ca50c2012-02-14 23:21:53509 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39510 alt nitem.node {
Haitao Li3b683f52011-11-14 13:06:39511 native_item_fn(fn_decl, tps) {
Marijn Haverbekedf7f21d2011-07-27 12:19:39512 encode_def_id(ebml_w, local_def(nitem.id));
Marijn Haverbeke72591492012-02-13 19:55:23513 encode_family(ebml_w, purity_fn_family(fn_decl.purity));
Marijn Haverbeke1ed6a272011-12-28 16:50:12514 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbekeb6ad34b2012-03-09 12:35:20515 if abi == native_abi_rust_intrinsic {
516 ebml_w.start_tag(tag_item_is_intrinsic);
517 ebml_w.end_tag();
518 }
Marijn Haverbeke86d473a2012-01-30 16:28:30519 encode_type(ecx, ebml_w, node_id_to_type(ecx.ccx.tcx, nitem.id));
Marijn Haverbekedf7f21d2011-07-27 12:19:39520 encode_symbol(ecx, ebml_w, nitem.id);
Niko Matsakisfdddf8f2012-02-10 14:01:32521 encode_path(ebml_w, path, ast_map::path_name(nitem.ident));
Marijn Haverbekedf7f21d2011-07-27 12:19:39522 }
Brian Anderson33294c72011-06-27 22:20:17523 }
Niko Matsakisf3ca50c2012-02-14 23:21:53524 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17525}
526
Marijn Haverbeke58a81a62011-12-16 13:41:12527fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
Marijn Haverbekefe90c182012-03-08 22:37:45528 crate: @crate) -> [entry<int>] {
529 let index = @mutable [];
Niko Matsakisf3ca50c2012-02-14 23:21:53530 ebml_w.start_tag(tag_items_data);
Marijn Haverbekefe90c182012-03-08 22:37:45531 *index += [{val: crate_node_id, pos: ebml_w.writer.tell()}];
532 encode_info_for_mod(ecx, ebml_w, crate.node.module,
533 crate_node_id, [], "");
534 visit::visit_crate(*crate, (), visit::mk_vt(@{
535 visit_expr: {|_e, _cx, _v|},
536 visit_item: {|i, cx, v|
537 visit::visit_item(i, cx, v);
Marijn Haverbekeb6ad34b2012-03-09 12:35:20538 alt check ecx.ccx.tcx.items.get(i.id) {
539 ast_map::node_item(_, pt) {
540 encode_info_for_item(ecx, ebml_w, i, index, *pt);
541 }
542 }
Marijn Haverbekefe90c182012-03-08 22:37:45543 },
544 visit_native_item: {|ni, cx, v|
545 visit::visit_native_item(ni, cx, v);
Marijn Haverbekeb6ad34b2012-03-09 12:35:20546 alt check ecx.ccx.tcx.items.get(ni.id) {
547 ast_map::node_native_item(_, abi, pt) {
548 encode_info_for_native_item(ecx, ebml_w, ni, index, *pt, abi);
549 }
550 }
Marijn Haverbekefe90c182012-03-08 22:37:45551 }
552 with *visit::default_visitor()
553 }));
Niko Matsakisf3ca50c2012-02-14 23:21:53554 ebml_w.end_tag();
Marijn Haverbekefe90c182012-03-08 22:37:45555 ret *index;
Brian Anderson33294c72011-06-27 22:20:17556}
557
558
559// Path and definition ID indexing
560
Niko Matsakis455f8b02012-01-11 17:58:05561fn create_index<T: copy>(index: [entry<T>], hash_fn: fn@(T) -> uint) ->
Erick Tryzelaare4a0f992011-08-12 14:15:18562 [@[entry<T>]] {
Brian Anderson518dc522011-08-19 22:16:48563 let buckets: [@mutable [entry<T>]] = [];
Marijn Haverbeke6bcb4a42011-10-21 10:31:48564 uint::range(0u, 256u) {|_i| buckets += [@mutable []]; };
Erick Tryzelaare4a0f992011-08-12 14:15:18565 for elt: entry<T> in index {
Marijn Haverbekedf7f21d2011-07-27 12:19:39566 let h = hash_fn(elt.val);
Brian Anderson518dc522011-08-19 22:16:48567 *buckets[h % 256u] += [elt];
Brian Anderson33294c72011-06-27 22:20:17568 }
Patrick Walton1a6419b2011-07-14 21:25:43569
Brian Anderson518dc522011-08-19 22:16:48570 let buckets_frozen = [];
Erick Tryzelaare4a0f992011-08-12 14:15:18571 for bucket: @mutable [entry<T>] in buckets {
Brian Anderson518dc522011-08-19 22:16:48572 buckets_frozen += [@*bucket];
Patrick Walton1a6419b2011-07-14 21:25:43573 }
574 ret buckets_frozen;
Brian Anderson33294c72011-06-27 22:20:17575}
576
Marijn Haverbekefc6b7c82011-09-12 09:27:30577fn encode_index<T>(ebml_w: ebml::writer, buckets: [@[entry<T>]],
Niko Matsakis5e13d192012-01-23 22:59:00578 write_fn: fn(io::writer, T)) {
Niko Matsakis3f3bfee2012-01-11 20:52:25579 let writer = ebml_w.writer;
Niko Matsakisf3ca50c2012-02-14 23:21:53580 ebml_w.start_tag(tag_index);
Brian Anderson518dc522011-08-19 22:16:48581 let bucket_locs: [uint] = [];
Niko Matsakisf3ca50c2012-02-14 23:21:53582 ebml_w.start_tag(tag_index_buckets);
Erick Tryzelaare4a0f992011-08-12 14:15:18583 for bucket: @[entry<T>] in buckets {
Brian Anderson518dc522011-08-19 22:16:48584 bucket_locs += [ebml_w.writer.tell()];
Niko Matsakisf3ca50c2012-02-14 23:21:53585 ebml_w.start_tag(tag_index_buckets_bucket);
Erick Tryzelaare4a0f992011-08-12 14:15:18586 for elt: entry<T> in *bucket {
Niko Matsakisf3ca50c2012-02-14 23:21:53587 ebml_w.start_tag(tag_index_buckets_bucket_elt);
Marijn Haverbekeaea53772011-07-26 12:06:02588 writer.write_be_uint(elt.pos, 4u);
589 write_fn(writer, elt.val);
Niko Matsakisf3ca50c2012-02-14 23:21:53590 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17591 }
Niko Matsakisf3ca50c2012-02-14 23:21:53592 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17593 }
Niko Matsakisf3ca50c2012-02-14 23:21:53594 ebml_w.end_tag();
595 ebml_w.start_tag(tag_index_table);
Lindsey Kuperf91351a2011-08-16 04:54:52596 for pos: uint in bucket_locs { writer.write_be_uint(pos, 4u); }
Niko Matsakisf3ca50c2012-02-14 23:21:53597 ebml_w.end_tag();
598 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17599}
600
Marijn Haverbeke33167f72011-10-10 11:54:03601fn write_str(writer: io::writer, &&s: str) { writer.write_str(s); }
Brian Anderson33294c72011-06-27 22:20:17602
Marijn Haverbekef9fbd862011-10-06 10:26:12603fn write_int(writer: io::writer, &&n: int) {
Brian Anderson33294c72011-06-27 22:20:17604 writer.write_be_uint(n as uint, 4u);
605}
606
Marijn Haverbekefc6b7c82011-09-12 09:27:30607fn encode_meta_item(ebml_w: ebml::writer, mi: meta_item) {
Marijn Haverbekedf7f21d2011-07-27 12:19:39608 alt mi.node {
609 meta_word(name) {
Niko Matsakisf3ca50c2012-02-14 23:21:53610 ebml_w.start_tag(tag_meta_item_word);
611 ebml_w.start_tag(tag_meta_item_name);
Brian Andersonab6bb032011-09-02 00:27:58612 ebml_w.writer.write(str::bytes(name));
Niko Matsakisf3ca50c2012-02-14 23:21:53613 ebml_w.end_tag();
614 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39615 }
616 meta_name_value(name, value) {
617 alt value.node {
Brian Anderson9c173f12011-09-02 05:08:59618 lit_str(value) {
Niko Matsakisf3ca50c2012-02-14 23:21:53619 ebml_w.start_tag(tag_meta_item_name_value);
620 ebml_w.start_tag(tag_meta_item_name);
Brian Andersonab6bb032011-09-02 00:27:58621 ebml_w.writer.write(str::bytes(name));
Niko Matsakisf3ca50c2012-02-14 23:21:53622 ebml_w.end_tag();
623 ebml_w.start_tag(tag_meta_item_value);
Brian Andersonab6bb032011-09-02 00:27:58624 ebml_w.writer.write(str::bytes(value));
Niko Matsakisf3ca50c2012-02-14 23:21:53625 ebml_w.end_tag();
626 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39627 }
628 _ {/* FIXME (#611) */ }
Brian Andersonf53c4f72011-06-28 02:41:48629 }
Marijn Haverbekedf7f21d2011-07-27 12:19:39630 }
631 meta_list(name, items) {
Niko Matsakisf3ca50c2012-02-14 23:21:53632 ebml_w.start_tag(tag_meta_item_list);
633 ebml_w.start_tag(tag_meta_item_name);
Brian Andersonab6bb032011-09-02 00:27:58634 ebml_w.writer.write(str::bytes(name));
Niko Matsakisf3ca50c2012-02-14 23:21:53635 ebml_w.end_tag();
Lindsey Kuperf91351a2011-08-16 04:54:52636 for inner_item: @meta_item in items {
Marijn Haverbekedf7f21d2011-07-27 12:19:39637 encode_meta_item(ebml_w, *inner_item);
638 }
Niko Matsakisf3ca50c2012-02-14 23:21:53639 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39640 }
Brian Andersonf53c4f72011-06-28 02:41:48641 }
Brian Andersonf53c4f72011-06-28 02:41:48642}
643
Marijn Haverbekefc6b7c82011-09-12 09:27:30644fn encode_attributes(ebml_w: ebml::writer, attrs: [attribute]) {
Niko Matsakisf3ca50c2012-02-14 23:21:53645 ebml_w.start_tag(tag_attributes);
Lindsey Kuperf91351a2011-08-16 04:54:52646 for attr: attribute in attrs {
Niko Matsakisf3ca50c2012-02-14 23:21:53647 ebml_w.start_tag(tag_attribute);
Brian Andersonf53c4f72011-06-28 02:41:48648 encode_meta_item(ebml_w, attr.node.value);
Niko Matsakisf3ca50c2012-02-14 23:21:53649 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17650 }
Niko Matsakisf3ca50c2012-02-14 23:21:53651 ebml_w.end_tag();
Brian Andersonf53c4f72011-06-28 02:41:48652}
653
Graydon Hoarec796a8f2011-06-29 22:11:20654// So there's a special crate attribute called 'link' which defines the
655// metadata that Rust cares about for linking crates. This attribute requires
Brian Anderson70a28dc2011-07-01 00:03:08656// 'name' and 'vers' items, so if the user didn't provide them we will throw
Graydon Hoarec796a8f2011-06-29 22:11:20657// them in anyway with default values.
Marijn Haverbekefc6b7c82011-09-12 09:27:30658fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: @crate) -> [attribute] {
Brian Anderson29afe1a2011-06-29 21:17:23659
Marijn Haverbekefc6b7c82011-09-12 09:27:30660 fn synthesize_link_attr(ecx: @encode_ctxt, items: [@meta_item]) ->
Marijn Haverbekedf7f21d2011-07-27 12:19:39661 attribute {
Brian Anderson29afe1a2011-06-29 21:17:23662
Brian Anderson5c49e4f2011-09-02 22:34:58663 assert (ecx.ccx.link_meta.name != "");
664 assert (ecx.ccx.link_meta.vers != "");
Brian Anderson29afe1a2011-06-29 21:17:23665
Marijn Haverbekedf7f21d2011-07-27 12:19:39666 let name_item =
Brian Anderson5c49e4f2011-09-02 22:34:58667 attr::mk_name_value_item_str("name", ecx.ccx.link_meta.name);
Marijn Haverbekedf7f21d2011-07-27 12:19:39668 let vers_item =
Brian Anderson5c49e4f2011-09-02 22:34:58669 attr::mk_name_value_item_str("vers", ecx.ccx.link_meta.vers);
Brian Anderson29afe1a2011-06-29 21:17:23670
Marijn Haverbekedf7f21d2011-07-27 12:19:39671 let other_items =
672 {
Brian Anderson5c49e4f2011-09-02 22:34:58673 let tmp = attr::remove_meta_items_by_name(items, "name");
674 attr::remove_meta_items_by_name(tmp, "vers")
Marijn Haverbekedf7f21d2011-07-27 12:19:39675 };
Brian Anderson29afe1a2011-06-29 21:17:23676
Brian Anderson518dc522011-08-19 22:16:48677 let meta_items = [name_item, vers_item] + other_items;
Brian Anderson5c49e4f2011-09-02 22:34:58678 let link_item = attr::mk_list_item("link", meta_items);
Brian Anderson29afe1a2011-06-29 21:17:23679
Brian Anderson70a28dc2011-07-01 00:03:08680 ret attr::mk_attr(link_item);
Brian Anderson29afe1a2011-06-29 21:17:23681 }
682
Brian Anderson518dc522011-08-19 22:16:48683 let attrs: [attribute] = [];
Marijn Haverbekedf7f21d2011-07-27 12:19:39684 let found_link_attr = false;
Lindsey Kuperf91351a2011-08-16 04:54:52685 for attr: attribute in crate.node.attrs {
Marijn Haverbekedf7f21d2011-07-27 12:19:39686 attrs +=
Brian Anderson5c49e4f2011-09-02 22:34:58687 if attr::get_attr_name(attr) != "link" {
Brian Anderson518dc522011-08-19 22:16:48688 [attr]
Marijn Haverbekedf7f21d2011-07-27 12:19:39689 } else {
690 alt attr.node.value.node {
691 meta_list(n, l) {
Marijn Haverbekefc6b7c82011-09-12 09:27:30692 found_link_attr = true;;
Brian Anderson518dc522011-08-19 22:16:48693 [synthesize_link_attr(ecx, l)]
Marijn Haverbekedf7f21d2011-07-27 12:19:39694 }
Brian Anderson518dc522011-08-19 22:16:48695 _ { [attr] }
Brian Anderson29afe1a2011-06-29 21:17:23696 }
Marijn Haverbeke7298b8f2011-09-15 07:48:39697 };
Brian Anderson29afe1a2011-06-29 21:17:23698 }
699
Brian Anderson518dc522011-08-19 22:16:48700 if !found_link_attr { attrs += [synthesize_link_attr(ecx, [])]; }
Brian Anderson29afe1a2011-06-29 21:17:23701
702 ret attrs;
703}
704
Marijn Haverbekefc6b7c82011-09-12 09:27:30705fn encode_crate_deps(ebml_w: ebml::writer, cstore: cstore::cstore) {
Brian Anderson30704392011-07-08 18:29:56706
Marijn Haverbekefc6b7c82011-09-12 09:27:30707 fn get_ordered_names(cstore: cstore::cstore) -> [str] {
Marijn Haverbekedf7f21d2011-07-27 12:19:39708 type hashkv = @{key: crate_num, val: cstore::crate_metadata};
Brian Anderson5c49e4f2011-09-02 22:34:58709 type numname = {crate: crate_num, ident: str};
Brian Anderson30704392011-07-08 18:29:56710
711 // Pull the cnums and names out of cstore
Brian Anderson518dc522011-08-19 22:16:48712 let pairs: [mutable numname] = [mutable];
Marijn Haverbeke4ebbbe52011-10-21 10:21:27713 cstore::iter_crate_data(cstore) {|key, val|
714 pairs += [mutable {crate: key, ident: val.name}];
715 };
Brian Anderson30704392011-07-08 18:29:56716
717 // Sort by cnum
Marijn Haverbekefc6b7c82011-09-12 09:27:30718 fn lteq(kv1: numname, kv2: numname) -> bool { kv1.crate <= kv2.crate }
Brian Anderson7625ed52011-08-12 05:48:08719 std::sort::quick_sort(lteq, pairs);
Brian Anderson30704392011-07-08 18:29:56720
721 // Sanity-check the crate numbers
Marijn Haverbekedf7f21d2011-07-27 12:19:39722 let expected_cnum = 1;
Lindsey Kuperf91351a2011-08-16 04:54:52723 for n: numname in pairs {
Marijn Haverbekedf7f21d2011-07-27 12:19:39724 assert (n.crate == expected_cnum);
Brian Anderson30704392011-07-08 18:29:56725 expected_cnum += 1;
726 }
727
728 // Return just the names
Marijn Haverbekefc6b7c82011-09-12 09:27:30729 fn name(kv: numname) -> str { kv.ident }
Brian Andersonf05a91a2011-08-15 23:38:23730 // mutable -> immutable hack for vec::map
731 let immpairs = vec::slice(pairs, 0u, vec::len(pairs));
Niko Matsakis2833ca42011-12-16 14:27:50732 ret vec::map(immpairs, name);
Brian Anderson30704392011-07-08 18:29:56733 }
734
735 // We're just going to write a list of crate names, with the assumption
736 // that they are numbered 1 to n.
737 // FIXME: This is not nearly enough to support correct versioning
738 // but is enough to get transitive crate dependencies working.
Niko Matsakisf3ca50c2012-02-14 23:21:53739 ebml_w.start_tag(tag_crate_deps);
Brian Anderson5c49e4f2011-09-02 22:34:58740 for cname: str in get_ordered_names(cstore) {
Niko Matsakisf3ca50c2012-02-14 23:21:53741 ebml_w.start_tag(tag_crate_dep);
Brian Andersonab6bb032011-09-02 00:27:58742 ebml_w.writer.write(str::bytes(cname));
Niko Matsakisf3ca50c2012-02-14 23:21:53743 ebml_w.end_tag();
Brian Anderson30704392011-07-08 18:29:56744 }
Niko Matsakisf3ca50c2012-02-14 23:21:53745 ebml_w.end_tag();
Brian Anderson30704392011-07-08 18:29:56746}
747
Haitao Lif3c206c2011-12-11 15:23:38748fn encode_hash(ebml_w: ebml::writer, hash: str) {
Niko Matsakisf3ca50c2012-02-14 23:21:53749 ebml_w.start_tag(tag_crate_hash);
Haitao Lif3c206c2011-12-11 15:23:38750 ebml_w.writer.write(str::bytes(hash));
Niko Matsakisf3ca50c2012-02-14 23:21:53751 ebml_w.end_tag();
Haitao Lif3c206c2011-12-11 15:23:38752}
753
Patrick Walton273c5e52012-03-15 00:31:16754fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> [u8] {
Brian Andersond0a432f2011-07-08 06:55:41755
Marijn Haverbekefb61b8f2012-03-06 11:52:13756 let reachable = reachable::find_reachable(cx, crate.node.module);
Marijn Haverbeke3ee630b2011-12-22 13:24:36757 let abbrevs = ty::new_ty_hash();
Marijn Haverbekefb61b8f2012-03-06 11:52:13758 let ecx = @{ccx: cx,
759 type_abbrevs: abbrevs,
760 reachable: reachable};
Brian Andersond0a432f2011-07-08 06:55:41761
Niko Matsakisb30cb8e2012-03-13 14:55:45762 let buf = io::mem_buffer();
Marijn Haverbeke34d7f052012-01-11 14:15:54763 let buf_w = io::mem_buffer_writer(buf);
Brian Andersoncd72b1f2012-03-12 22:52:30764 let ebml_w = ebml::writer(buf_w);
Brian Anderson33294c72011-06-27 22:20:17765
Haitao Lif3c206c2011-12-11 15:23:38766 encode_hash(ebml_w, cx.link_meta.extras_hash);
767
Marijn Haverbekedf7f21d2011-07-27 12:19:39768 let crate_attrs = synthesize_crate_attrs(ecx, crate);
Brian Anderson29afe1a2011-06-29 21:17:23769 encode_attributes(ebml_w, crate_attrs);
Brian Anderson30704392011-07-08 18:29:56770
Marijn Haverbekeefb9df12012-01-12 16:59:49771 encode_crate_deps(ebml_w, cx.sess.cstore);
Brian Anderson30704392011-07-08 18:29:56772
Brian Anderson33294c72011-06-27 22:20:17773 // Encode and index the paths.
Niko Matsakisf3ca50c2012-02-14 23:21:53774 ebml_w.start_tag(tag_paths);
Haitao Li9bb290c2011-12-15 10:42:27775 let paths_index = encode_item_paths(ebml_w, ecx, crate);
Marijn Haverbekedf7f21d2011-07-27 12:19:39776 let paths_buckets = create_index(paths_index, hash_path);
Marijn Haverbekee949aab2011-07-25 13:07:48777 encode_index(ebml_w, paths_buckets, write_str);
Niko Matsakisf3ca50c2012-02-14 23:21:53778 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17779
Marijn Haverbeke34d7f052012-01-11 14:15:54780 // Encode and index the items.
Niko Matsakisf3ca50c2012-02-14 23:21:53781 ebml_w.start_tag(tag_items);
Marijn Haverbekefe90c182012-03-08 22:37:45782 let items_index = encode_info_for_items(ecx, ebml_w, crate);
Marijn Haverbekedf7f21d2011-07-27 12:19:39783 let items_buckets = create_index(items_index, hash_node_id);
Marijn Haverbekee949aab2011-07-25 13:07:48784 encode_index(ebml_w, items_buckets, write_int);
Niko Matsakisf3ca50c2012-02-14 23:21:53785 ebml_w.end_tag();
Marijn Haverbeke34d7f052012-01-11 14:15:54786
Brian Anderson33294c72011-06-27 22:20:17787 // Pad this, since something (LLVM, presumably) is cutting off the
Brian Anderson2e7e5882011-08-11 23:36:20788 // remaining % 4 bytes.
Brian Anderson518dc522011-08-19 22:16:48789 buf_w.write([0u8, 0u8, 0u8, 0u8]);
Kevin Cantu4d7c2972012-01-26 06:27:29790 io::mem_buffer_buf(buf)
Brian Anderson33294c72011-06-27 22:20:17791}
Brian Anderson894e2222011-06-28 02:16:16792
Brian Anderson7d26d1d2011-07-07 19:47:39793// Get the encoded string for a type
Marijn Haverbekefc6b7c82011-09-12 09:27:30794fn encoded_ty(tcx: ty::ctxt, t: ty::t) -> str {
Marijn Haverbekedf7f21d2011-07-27 12:19:39795 let cx = @{ds: def_to_str, tcx: tcx, abbrevs: tyencode::ac_no_abbrevs};
Niko Matsakisb30cb8e2012-03-13 14:55:45796 let buf = io::mem_buffer();
Marijn Haverbeke34d7f052012-01-11 14:15:54797 tyencode::enc_ty(io::mem_buffer_writer(buf), cx, t);
798 ret io::mem_buffer_str(buf);
Brian Anderson7d26d1d2011-07-07 19:47:39799}
800
Brian Anderson894e2222011-06-28 02:16:16801
802// Local Variables:
803// mode: rust
804// fill-column: 78;
805// indent-tabs-mode: nil
806// c-basic-offset: 4
807// buffer-file-coding-system: utf-8-unix
Brian Anderson894e2222011-06-28 02:16:16808// End: