|
1 | 1 | import std._str;
|
2 | 2 | import std._uint;
|
3 | 3 | import std._vec;
|
| 4 | +import std.map.hashmap; |
4 | 5 | import std.ebml;
|
5 | 6 | import std.io;
|
6 | 7 | import std.option;
|
| 8 | +import std.option.some; |
| 9 | +import std.option.none; |
7 | 10 |
|
8 | 11 | import front.ast;
|
9 | 12 | import middle.fold;
|
@@ -48,119 +51,185 @@ const uint tag_index_table = 0x15u;
|
48 | 51 | // Extra parameters are for converting to/from def_ids in the string rep.
|
49 | 52 | // Whatever format you choose should not contain pipe characters.
|
50 | 53 |
|
| 54 | +type ty_abbrev = rec(uint pos, uint len, str s); |
| 55 | + |
51 | 56 | mod Encode {
|
52 | 57 |
|
53 | 58 | type ctxt = rec(
|
54 |
| - fn(ast.def_id) -> str ds, // Callback to translate defs to strs. |
55 |
| - ty.ctxt tcx // The type context. |
| 59 | + fn(ast.def_id) -> str ds, // Def -> str Callback. |
| 60 | + ty.ctxt tcx, // The type context. |
| 61 | + bool use_abbrevs, |
| 62 | + hashmap[ty.t, ty_abbrev] abbrevs // Type abbrevs. |
56 | 63 | );
|
57 | 64 |
|
58 | 65 | fn ty_str(@ctxt cx, ty.t t) -> str {
|
59 |
| - ret sty_str(cx, ty.struct(cx.tcx, t)); |
| 66 | + check (! cx.use_abbrevs); |
| 67 | + auto sw = io.string_writer(); |
| 68 | + enc_ty(sw.get_writer(), cx, t); |
| 69 | + ret sw.get_str(); |
| 70 | + } |
| 71 | + |
| 72 | + fn enc_ty(io.writer w, @ctxt cx, ty.t t) { |
| 73 | + if (cx.use_abbrevs) { |
| 74 | + alt (cx.abbrevs.find(t)) { |
| 75 | + case (some[ty_abbrev](?a)) { |
| 76 | + w.write_str(a.s); |
| 77 | + ret; |
| 78 | + } |
| 79 | + case (none[ty_abbrev]) { |
| 80 | + auto pos = w.get_buf_writer().tell(); |
| 81 | + auto ss = enc_sty(w, cx, ty.struct(cx.tcx, t)); |
| 82 | + auto end = w.get_buf_writer().tell(); |
| 83 | + auto len = end-pos; |
| 84 | + fn estimate_sz(uint u) -> uint { |
| 85 | + auto n = u; |
| 86 | + auto len = 0u; |
| 87 | + while (n != 0u) { |
| 88 | + len += 1u; |
| 89 | + n = n >> 4u; |
| 90 | + } |
| 91 | + ret len; |
| 92 | + } |
| 93 | + auto abbrev_len = |
| 94 | + 3u + estimate_sz(pos) + estimate_sz(len); |
| 95 | + |
| 96 | + if (abbrev_len < len) { |
| 97 | + // I.e. it's actually an abbreviation. |
| 98 | + auto s = ("#" |
| 99 | + + _uint.to_str(pos, 16u) + ":" |
| 100 | + + _uint.to_str(len, 16u) + "#"); |
| 101 | + auto a = rec(pos=pos, len=len, s=s); |
| 102 | + cx.abbrevs.insert(t, a); |
| 103 | + } |
| 104 | + ret; |
| 105 | + } |
| 106 | + } |
| 107 | + } |
| 108 | + enc_sty(w, cx, ty.struct(cx.tcx, t)); |
60 | 109 | }
|
61 | 110 |
|
62 |
| - fn mt_str(@ctxt cx, &ty.mt mt) -> str { |
63 |
| - auto mut_str; |
| 111 | + fn enc_mt(io.writer w, @ctxt cx, &ty.mt mt) { |
64 | 112 | alt (mt.mut) {
|
65 |
| - case (ast.imm) { mut_str = ""; } |
66 |
| - case (ast.mut) { mut_str = "m"; } |
67 |
| - case (ast.maybe_mut) { mut_str = "?"; } |
| 113 | + case (ast.imm) { } |
| 114 | + case (ast.mut) { w.write_char('m'); } |
| 115 | + case (ast.maybe_mut) { w.write_char('?'); } |
68 | 116 | }
|
69 |
| - ret mut_str + ty_str(cx, mt.ty); |
| 117 | + enc_ty(w, cx, mt.ty); |
70 | 118 | }
|
71 | 119 |
|
72 |
| - fn sty_str(@ctxt cx, ty.sty st) -> str { |
| 120 | + fn enc_sty(io.writer w, @ctxt cx, ty.sty st) { |
73 | 121 | alt (st) {
|
74 |
| - case (ty.ty_nil) {ret "n";} |
75 |
| - case (ty.ty_bool) {ret "b";} |
76 |
| - case (ty.ty_int) {ret "i";} |
77 |
| - case (ty.ty_uint) {ret "u";} |
78 |
| - case (ty.ty_float) {ret "l";} |
| 122 | + case (ty.ty_nil) { w.write_char('n'); } |
| 123 | + case (ty.ty_bool) { w.write_char('b'); } |
| 124 | + case (ty.ty_int) { w.write_char('i'); } |
| 125 | + case (ty.ty_uint) { w.write_char('u'); } |
| 126 | + case (ty.ty_float) { w.write_char('l'); } |
79 | 127 | case (ty.ty_machine(?mach)) {
|
80 | 128 | alt (mach) {
|
81 |
| - case (common.ty_u8) {ret "Mb";} |
82 |
| - case (common.ty_u16) {ret "Mw";} |
83 |
| - case (common.ty_u32) {ret "Ml";} |
84 |
| - case (common.ty_u64) {ret "Md";} |
85 |
| - case (common.ty_i8) {ret "MB";} |
86 |
| - case (common.ty_i16) {ret "MW";} |
87 |
| - case (common.ty_i32) {ret "ML";} |
88 |
| - case (common.ty_i64) {ret "MD";} |
89 |
| - case (common.ty_f32) {ret "Mf";} |
90 |
| - case (common.ty_f64) {ret "MF";} |
| 129 | + case (common.ty_u8) { w.write_str("Mb"); } |
| 130 | + case (common.ty_u16) { w.write_str("Mw"); } |
| 131 | + case (common.ty_u32) { w.write_str("Ml"); } |
| 132 | + case (common.ty_u64) { w.write_str("Md"); } |
| 133 | + case (common.ty_i8) { w.write_str("MB"); } |
| 134 | + case (common.ty_i16) { w.write_str("MW"); } |
| 135 | + case (common.ty_i32) { w.write_str("ML"); } |
| 136 | + case (common.ty_i64) { w.write_str("MD"); } |
| 137 | + case (common.ty_f32) { w.write_str("Mf"); } |
| 138 | + case (common.ty_f64) { w.write_str("MF"); } |
91 | 139 | }
|
92 | 140 | }
|
93 |
| - case (ty.ty_char) {ret "c";} |
94 |
| - case (ty.ty_str) {ret "s";} |
| 141 | + case (ty.ty_char) {w.write_char('c');} |
| 142 | + case (ty.ty_str) {w.write_char('s');} |
95 | 143 | case (ty.ty_tag(?def,?tys)) { // TODO restore def_id
|
96 |
| - auto acc = "t[" + cx.ds(def) + "|"; |
97 |
| - for (ty.t t in tys) {acc += ty_str(cx, t);} |
98 |
| - ret acc + "]"; |
| 144 | + w.write_str("t["); |
| 145 | + w.write_str(cx.ds(def)); |
| 146 | + w.write_char('|'); |
| 147 | + for (ty.t t in tys) { |
| 148 | + enc_ty(w, cx, t); |
| 149 | + } |
| 150 | + w.write_char(']'); |
99 | 151 | }
|
100 |
| - case (ty.ty_box(?mt)) {ret "@" + mt_str(cx, mt);} |
101 |
| - case (ty.ty_vec(?mt)) {ret "V" + mt_str(cx, mt);} |
102 |
| - case (ty.ty_port(?t)) {ret "P" + ty_str(cx, t);} |
103 |
| - case (ty.ty_chan(?t)) {ret "C" + ty_str(cx, t);} |
| 152 | + case (ty.ty_box(?mt)) {w.write_char('@'); enc_mt(w, cx, mt); } |
| 153 | + case (ty.ty_vec(?mt)) {w.write_char('V'); enc_mt(w, cx, mt); } |
| 154 | + case (ty.ty_port(?t)) {w.write_char('P'); enc_ty(w, cx, t); } |
| 155 | + case (ty.ty_chan(?t)) {w.write_char('C'); enc_ty(w, cx, t); } |
104 | 156 | case (ty.ty_tup(?mts)) {
|
105 |
| - auto acc = "T["; |
106 |
| - for (ty.mt mt in mts) {acc += mt_str(cx, mt);} |
107 |
| - ret acc + "]"; |
| 157 | + w.write_str("T["); |
| 158 | + for (ty.mt mt in mts) { |
| 159 | + enc_mt(w, cx, mt); |
| 160 | + } |
| 161 | + w.write_char(']'); |
108 | 162 | }
|
109 | 163 | case (ty.ty_rec(?fields)) {
|
110 |
| - auto acc = "R["; |
| 164 | + w.write_str("R["); |
111 | 165 | for (ty.field field in fields) {
|
112 |
| - acc += field.ident + "="; |
113 |
| - acc += mt_str(cx, field.mt); |
| 166 | + w.write_str(field.ident); |
| 167 | + w.write_char('='); |
| 168 | + enc_mt(w, cx, field.mt); |
114 | 169 | }
|
115 |
| - ret acc + "]"; |
| 170 | + w.write_char(']'); |
116 | 171 | }
|
117 | 172 | case (ty.ty_fn(?proto,?args,?out)) {
|
118 |
| - ret proto_str(proto) + ty_fn_str(cx, args, out); |
| 173 | + enc_proto(w, proto); |
| 174 | + enc_ty_fn(w, cx, args, out); |
119 | 175 | }
|
120 | 176 | case (ty.ty_native_fn(?abi,?args,?out)) {
|
121 |
| - auto abistr; |
| 177 | + w.write_char('N'); |
122 | 178 | alt (abi) {
|
123 |
| - case (ast.native_abi_rust) {abistr = "r";} |
124 |
| - case (ast.native_abi_cdecl) {abistr = "c";} |
125 |
| - case (ast.native_abi_llvm) {abistr = "l";} |
| 179 | + case (ast.native_abi_rust) { w.write_char('r'); } |
| 180 | + case (ast.native_abi_cdecl) { w.write_char('c'); } |
| 181 | + case (ast.native_abi_llvm) { w.write_char('l'); } |
126 | 182 | }
|
127 |
| - ret "N" + abistr + ty_fn_str(cx, args, out); |
| 183 | + enc_ty_fn(w, cx, args, out); |
128 | 184 | }
|
129 | 185 | case (ty.ty_obj(?methods)) {
|
130 |
| - auto acc = "O["; |
| 186 | + w.write_str("O["); |
131 | 187 | for (ty.method m in methods) {
|
132 |
| - acc += proto_str(m.proto); |
133 |
| - acc += m.ident; |
134 |
| - acc += ty_fn_str(cx, m.inputs, m.output); |
| 188 | + enc_proto(w, m.proto); |
| 189 | + w.write_str(m.ident); |
| 190 | + enc_ty_fn(w, cx, m.inputs, m.output); |
135 | 191 | }
|
136 |
| - ret acc + "]"; |
| 192 | + w.write_char(']'); |
| 193 | + } |
| 194 | + case (ty.ty_var(?id)) { |
| 195 | + w.write_char('X'); |
| 196 | + w.write_str(common.istr(id)); |
137 | 197 | }
|
138 |
| - case (ty.ty_var(?id)) {ret "X" + common.istr(id);} |
139 |
| - case (ty.ty_native) {ret "E";} |
140 |
| - case (ty.ty_param(?id)) {ret "p" + common.uistr(id);} |
141 |
| - case (ty.ty_type) {ret "Y";} |
| 198 | + case (ty.ty_native) {w.write_char('E');} |
| 199 | + case (ty.ty_param(?id)) { |
| 200 | + w.write_char('p'); |
| 201 | + w.write_str(common.uistr(id)); |
| 202 | + } |
| 203 | + case (ty.ty_type) {w.write_char('Y');} |
142 | 204 |
|
143 | 205 | // These two don't appear in crate metadata, but are here because
|
144 | 206 | // `hash_ty()` uses this function.
|
145 |
| - case (ty.ty_bound_param(?id)) {ret "o" + common.uistr(id);} |
146 |
| - case (ty.ty_local(?def)) {ret "L" + cx.ds(def);} |
| 207 | + case (ty.ty_bound_param(?id)) { |
| 208 | + w.write_char('o'); |
| 209 | + w.write_str(common.uistr(id)); |
| 210 | + } |
| 211 | + case (ty.ty_local(?def)) { |
| 212 | + w.write_char('L'); |
| 213 | + w.write_str(cx.ds(def)); |
| 214 | + } |
147 | 215 | }
|
148 | 216 | }
|
149 | 217 |
|
150 |
| - fn proto_str(ast.proto proto) -> str { |
| 218 | + fn enc_proto(io.writer w, ast.proto proto) { |
151 | 219 | alt (proto) {
|
152 |
| - case (ast.proto_iter) {ret "W";} |
153 |
| - case (ast.proto_fn) {ret "F";} |
| 220 | + case (ast.proto_iter) { w.write_char('W'); } |
| 221 | + case (ast.proto_fn) { w.write_char('F'); } |
154 | 222 | }
|
155 | 223 | }
|
156 | 224 |
|
157 |
| - fn ty_fn_str(@ctxt cx, vec[ty.arg] args, ty.t out) -> str { |
158 |
| - auto acc = "["; |
| 225 | + fn enc_ty_fn(io.writer w, @ctxt cx, vec[ty.arg] args, ty.t out) { |
| 226 | + w.write_char('['); |
159 | 227 | for (ty.arg arg in args) {
|
160 |
| - if (arg.mode == ast.alias) {acc += "&";} |
161 |
| - acc += ty_str(cx, arg.ty); |
| 228 | + if (arg.mode == ast.alias) { w.write_char('&'); } |
| 229 | + enc_ty(w, cx, arg.ty); |
162 | 230 | }
|
163 |
| - ret acc + "]" + ty_str(cx, out); |
| 231 | + w.write_char(']'); |
| 232 | + enc_ty(w, cx, out); |
164 | 233 | }
|
165 | 234 |
|
166 | 235 | }
|
@@ -336,9 +405,9 @@ fn encode_type(@trans.crate_ctxt cx, &ebml.writer ebml_w, ty.t typ) {
|
336 | 405 | ebml.start_tag(ebml_w, tag_items_data_item_type);
|
337 | 406 |
|
338 | 407 | auto f = def_to_str;
|
339 |
| - auto ty_str_ctxt = @rec(ds=f, tcx=cx.tcx); |
340 |
| - ebml_w.writer.write(_str.bytes(Encode.ty_str(ty_str_ctxt, typ))); |
341 |
| - |
| 408 | + auto ty_str_ctxt = @rec(ds=f, tcx=cx.tcx, |
| 409 | + use_abbrevs=true, abbrevs=cx.type_abbrevs); |
| 410 | + Encode.enc_ty(io.new_writer_(ebml_w.writer), ty_str_ctxt, typ); |
342 | 411 | ebml.end_tag(ebml_w);
|
343 | 412 | }
|
344 | 413 |
|
@@ -565,7 +634,6 @@ fn encode_index[T](&ebml.writer ebml_w, vec[vec[tup(T, uint)]] buckets,
|
565 | 634 | ebml.end_tag(ebml_w);
|
566 | 635 | }
|
567 | 636 |
|
568 |
| - |
569 | 637 | fn write_str(io.writer writer, &str s) {
|
570 | 638 | writer.write_str(s);
|
571 | 639 | }
|
|
0 commit comments