Skip to content

Commit e712a47

Browse files
committed
create serialization lib and update serializer to use it
1 parent 0263039 commit e712a47

File tree

5 files changed

+304
-39
lines changed

5 files changed

+304
-39
lines changed

src/comp/metadata/decoder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ fn lookup_hash(d: ebml::doc, eq_fn: fn@([u8]) -> bool, hash: uint) ->
4343
let table = ebml::get_doc(index, tag_index_table);
4444
let hash_pos = table.start + hash % 256u * 4u;
4545
let pos = ebml::be_uint_from_bytes(d.data, hash_pos, 4u);
46-
let bucket = ebml::doc_at(d.data, pos);
46+
let {tag:_, doc:bucket} = ebml::doc_at(d.data, pos);
4747
// Awkward logic because we can't ret from foreach yet
4848

4949
let result: [ebml::doc] = [];
5050
let belt = tag_index_buckets_bucket_elt;
5151
ebml::tagged_docs(bucket, belt) {|elt|
5252
let pos = ebml::be_uint_from_bytes(elt.data, elt.start, 4u);
5353
if eq_fn(vec::slice::<u8>(*elt.data, elt.start + 4u, elt.end)) {
54-
result += [ebml::doc_at(d.data, pos)];
54+
result += [ebml::doc_at(d.data, pos).doc];
5555
}
5656
};
5757
ret result;
@@ -500,7 +500,7 @@ fn iter_crate_items(bytes: @[u8], proc: fn(str, ast::def_id)) {
500500
let et = tag_index_buckets_bucket_elt;
501501
ebml::tagged_docs(bucket, et) {|elt|
502502
let data = read_path(elt);
503-
let def = ebml::doc_at(bytes, data.pos);
503+
let {tag:_, doc:def} = ebml::doc_at(bytes, data.pos);
504504
let did_doc = ebml::get_doc(def, tag_def_id);
505505
let did = parse_def_id(ebml::doc_data(did_doc));
506506
proc(data.path, did);

src/comp/middle/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2395,7 +2395,7 @@ fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
23952395
*path + [ast_map::path_name(nitem.ident)]
23962396
}
23972397

2398-
ast_map::node_method(method, path) {
2398+
ast_map::node_method(method, _, path) {
23992399
*path + [ast_map::path_name(method.ident)]
24002400
}
24012401

src/libstd/ebml.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ type ebml_state = {ebml_tag: ebml_tag, tag_pos: uint, data_pos: uint};
1717
// ebml reading
1818
type doc = {data: @[u8], start: uint, end: uint};
1919

20+
type tagged_doc = {tag: uint, doc: doc};
21+
2022
fn vint_at(data: [u8], start: uint) -> {val: uint, next: uint} {
2123
let a = data[start];
2224
if a & 0x80u8 != 0u8 {
@@ -43,11 +45,12 @@ fn new_doc(data: @[u8]) -> doc {
4345
ret {data: data, start: 0u, end: vec::len::<u8>(*data)};
4446
}
4547

46-
fn doc_at(data: @[u8], start: uint) -> doc {
48+
fn doc_at(data: @[u8], start: uint) -> tagged_doc {
4749
let elt_tag = vint_at(*data, start);
4850
let elt_size = vint_at(*data, elt_tag.next);
4951
let end = elt_size.next + elt_size.val;
50-
ret {data: data, start: elt_size.next, end: end};
52+
ret {tag: elt_tag.val,
53+
doc: {data: data, start: elt_size.next, end: end}};
5154
}
5255

5356
fn maybe_get_doc(d: doc, tg: uint) -> option<doc> {
@@ -120,18 +123,18 @@ fn doc_as_uint(d: doc) -> uint {
120123
// ebml writing
121124
type writer = {writer: io::writer, mutable size_positions: [uint]};
122125

123-
fn write_sized_vint(w: io::writer, n: uint, size: uint) {
126+
fn write_sized_vint(w: io::writer, n: u64, size: uint) {
124127
let buf: [u8];
125128
alt size {
126129
1u { buf = [0x80u8 | (n as u8)]; }
127-
2u { buf = [0x40u8 | ((n >> 8u) as u8), (n & 0xffu) as u8]; }
130+
2u { buf = [0x40u8 | ((n >> 8_u64) as u8), n as u8]; }
128131
3u {
129-
buf = [0x20u8 | ((n >> 16u) as u8), (n >> 8u & 0xffu) as u8,
130-
(n & 0xffu) as u8];
132+
buf = [0x20u8 | ((n >> 16_u64) as u8), (n >> 8_u64) as u8,
133+
n as u8];
131134
}
132135
4u {
133-
buf = [0x10u8 | ((n >> 24u) as u8), (n >> 16u & 0xffu) as u8,
134-
(n >> 8u & 0xffu) as u8, (n & 0xffu) as u8];
136+
buf = [0x10u8 | ((n >> 24_u64) as u8), (n >> 16_u64) as u8,
137+
(n >> 8_u64) as u8, n as u8];
135138
}
136139
_ { #error("vint to write too big"); fail; }
137140
}
@@ -156,7 +159,7 @@ fn create_writer(w: io::writer) -> writer {
156159
// TODO: Provide a function to write the standard ebml header.
157160
fn start_tag(w: writer, tag_id: uint) {
158161
// Write the enum ID:
159-
write_vint(w.writer, tag_id);
162+
write_vint(w.writer, tag_id as u64);
160163

161164
// Write a placeholder four-byte size.
162165
w.size_positions += [w.writer.tell()];
@@ -168,7 +171,7 @@ fn end_tag(w: writer) {
168171
let last_size_pos = vec::pop::<uint>(w.size_positions);
169172
let cur_pos = w.writer.tell();
170173
w.writer.seek(last_size_pos as int, io::seek_set);
171-
write_sized_vint(w.writer, cur_pos - last_size_pos - 4u, 4u);
174+
write_sized_vint(w.writer, (cur_pos - last_size_pos - 4u) as u64, 4u);
172175
w.writer.seek(cur_pos as int, io::seek_set);
173176
}
174177

@@ -179,12 +182,12 @@ impl writer_util for writer {
179182
end_tag(self);
180183
}
181184

182-
fn wr_uint(id: u64) {
185+
fn wr_u64(id: u64) {
183186
write_vint(self.writer, id);
184187
}
185188

186-
fn wr_int(id: uint) {
187-
write_vint(self.writer, id);
189+
fn wr_uint(id: uint) {
190+
self.wr_u64(id as u64);
188191
}
189192

190193
fn wr_bytes(b: [u8]) {

src/libstd/serialization.rs

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
/*
2+
Module: serialization
3+
4+
Support code for serialization.
5+
*/
6+
7+
import list::list;
8+
9+
iface serializer {
10+
// Primitive types:
11+
fn emit_nil();
12+
fn emit_u64(v: u64);
13+
fn emit_i64(v: u64);
14+
fn emit_bool(v: bool);
15+
fn emit_f64(v: f64);
16+
fn emit_str(v: str);
17+
18+
// Compound types:
19+
fn emit_enum(name: str, f: fn());
20+
fn emit_enum_variant(v_name: str, v_id: uint, sz: uint, f: fn());
21+
fn emit_enum_variant_arg(idx: uint, f: fn());
22+
fn emit_vec(len: uint, f: fn());
23+
fn emit_vec_elt(idx: uint, f: fn());
24+
fn emit_box(f: fn());
25+
fn emit_uniq(f: fn());
26+
fn emit_rec(f: fn());
27+
fn emit_rec_field(f_name: str, f_idx: uint, f: fn());
28+
fn emit_tup(sz: uint, f: fn());
29+
fn emit_tup_elt(idx: uint, f: fn());
30+
}
31+
32+
iface deserializer {
33+
// Primitive types:
34+
fn read_nil() -> ();
35+
fn read_u64() -> u64;
36+
fn read_i64() -> i64;
37+
fn read_bool() -> bool;
38+
fn read_f64() -> f64;
39+
fn read_str() -> str;
40+
41+
// Compound types:
42+
fn read_enum<T:copy>(name: str, f: fn() -> T) -> T;
43+
fn read_enum_variant<T:copy>(f: fn(uint) -> T) -> T;
44+
fn read_enum_variant_arg<T:copy>(idx: uint, f: fn() -> T) -> T;
45+
fn read_vec<T:copy>(f: fn(uint) -> T) -> T;
46+
fn read_vec_elt<T:copy>(idx: uint, f: fn() -> T) -> T;
47+
fn read_box<T:copy>(f: fn() -> T) -> T;
48+
fn read_uniq<T:copy>(f: fn() -> T) -> T;
49+
fn read_rec<T:copy>(f: fn() -> T) -> T;
50+
fn read_rec_field<T:copy>(f_name: str, f_idx: uint, f: fn() -> T) -> T;
51+
fn read_tup<T:copy>(sz: uint, f: fn() -> T) -> T;
52+
fn read_tup_elt<T:copy>(idx: uint, f: fn() -> T) -> T;
53+
}
54+
55+
/*
56+
type ppserializer = {
57+
writer: io::writer
58+
};
59+
60+
impl serializer for ppserializer {
61+
fn emit_nil() { self.writer.write_str("()") }
62+
63+
fn emit_u64(v: u64) { self.writer.write_str(#fmt["%lu", v]); }
64+
fn emit_i64(v: u64) { ebml::write_vint(self, v as uint) }
65+
fn emit_bool(v: bool) { ebml::write_vint(self, v as uint) }
66+
fn emit_f64(v: f64) { fail "float serialization not impl"; }
67+
fn emit_str(v: str) {
68+
self.wr_tag(es_str as uint) {|| self.wr_str(v) }
69+
}
70+
71+
fn emit_enum(name: str, f: fn()) {
72+
self.wr_tag(es_enum as uint) {|| f() }
73+
}
74+
fn emit_enum_variant(v_name: str, v_id: uint, f: fn()) {
75+
self.wr_tag(es_enum_vid as uint) {|| self.write_vint(v_id) }
76+
self.wr_tag(es_enum_body as uint) {|| f() }
77+
}
78+
79+
fn emit_vec(len: uint, f: fn()) {
80+
self.wr_tag(es_vec as uint) {||
81+
self.wr_tag(es_vec_len as uint) {|| self.write_vint(len) }
82+
f()
83+
}
84+
}
85+
86+
fn emit_vec_elt(idx: uint, f: fn()) {
87+
self.wr_tag(es_vec_elt as uint) {|| f() }
88+
}
89+
90+
fn emit_vec_elt(idx: uint, f: fn()) {
91+
self.wr_tag(es_vec_elt as uint) {|| f() }
92+
}
93+
94+
fn emit_box(f: fn()) { f() }
95+
fn emit_uniq(f: fn()) { f() }
96+
fn emit_rec_field(f_name: str, f_idx: uint, f: fn()) { f() }
97+
fn emit_tup(sz: uint, f: fn()) { f() }
98+
fn emit_tup_elt(idx: uint, f: fn()) { f() }
99+
}
100+
*/
101+
102+
enum ebml_serializer_tags {
103+
es_str,
104+
es_enum, es_enum_vid, es_enum_body,
105+
es_vec, es_vec_len, es_vec_elt
106+
}
107+
108+
impl of serializer for ebml::writer {
109+
fn emit_nil() {}
110+
111+
fn emit_u64(v: u64) { ebml::write_vint(self, v) }
112+
fn emit_i64(v: u64) { ebml::write_vint(self, v as uint) }
113+
fn emit_bool(v: bool) { ebml::write_vint(self, v as uint) }
114+
fn emit_f64(v: f64) { fail "float serialization not impl"; }
115+
fn emit_str(v: str) {
116+
self.wr_tag(es_str as uint) {|| self.wr_str(v) }
117+
}
118+
119+
fn emit_enum(name: str, f: fn()) {
120+
self.wr_tag(es_enum as uint) {|| f() }
121+
}
122+
fn emit_enum_variant(v_name: str, v_id: uint, f: fn()) {
123+
self.wr_tag(es_enum_vid as uint) {|| self.write_vint(v_id) }
124+
self.wr_tag(es_enum_body as uint) {|| f() }
125+
}
126+
fn emit_enum_variant_arg(idx: uint, f: fn()) { f() }
127+
128+
fn emit_vec(len: uint, f: fn()) {
129+
self.wr_tag(es_vec as uint) {||
130+
self.wr_tag(es_vec_len as uint) {|| self.write_vint(len) }
131+
f()
132+
}
133+
}
134+
135+
fn emit_vec_elt(idx: uint, f: fn()) {
136+
self.wr_tag(es_vec_elt as uint) {|| f() }
137+
}
138+
139+
fn emit_vec_elt(idx: uint, f: fn()) {
140+
self.wr_tag(es_vec_elt as uint) {|| f() }
141+
}
142+
143+
fn emit_box(f: fn()) { f() }
144+
fn emit_uniq(f: fn()) { f() }
145+
fn emit_rec(f: fn()) { f() }
146+
fn emit_rec_field(f_name: str, f_idx: uint, f: fn()) { f() }
147+
fn emit_tup(sz: uint, f: fn()) { f() }
148+
fn emit_tup_elt(idx: uint, f: fn()) { f() }
149+
}
150+
151+
type ebml_deserializer = {mutable parent: ebml::doc,
152+
mutable pos: uint};
153+
154+
fn mk_ebml_deserializer(d: ebml::doc) -> ebml_deserializer {
155+
{mutable parent: d, mutable pos: 0u}
156+
}
157+
158+
impl of deserializer for ebml_deserializer {
159+
fn next_doc(exp_tag: uint) -> ebml::doc {
160+
if self.pos >= self.parent.end {
161+
fail "no more documents in current node!";
162+
}
163+
let (r_tag, r_doc) = ebml::doc_at(self.parent.data, self.pos);
164+
if r_tag != exp_tag {
165+
fail #fmt["expected EMBL doc with tag %u but found tag %u",
166+
exp_tag, r_tag];
167+
}
168+
if r_doc.end >= self.parent.end {
169+
fail #fmt["invalid EBML, child extends to 0x%x, parent to 0x%x",
170+
r_doc.end, self.parent.end];
171+
}
172+
self.pos = result.end;
173+
ret result;
174+
}
175+
176+
fn push_doc<T: copy>(d: ebml::doc, f: fn() -> T) -> T{
177+
let old_parent = self.parent;
178+
let old_pos = self.pos;
179+
self.parent = d;
180+
self.pos = 0u;
181+
let r = f();
182+
self.parent = old_parent;
183+
self.pos = old_pos;
184+
ret r;
185+
}
186+
187+
fn next_u64(exp_tag: uint) {
188+
ebml::doc_as_uint(self.next_doc(exp_tag))
189+
}
190+
191+
fn read_nil() -> () { () }
192+
fn read_u64() -> u64 { next_u64(es_u64) }
193+
fn read_i64() -> i64 { next_u64(es_u64) as i64 }
194+
fn read_bool() -> bool { next_u64(es_u64) as bool }
195+
fn read_f64() -> f64 { fail "Float"; }
196+
fn read_str() -> str { ebml::doc_str(self.next_doc(es_str)) }
197+
198+
// Compound types:
199+
fn read_enum<T:copy>(name: str, f: fn() -> T) -> T {
200+
self.push_doc(self.next_doc(es_enum), f)
201+
}
202+
203+
fn read_enum_variant<T:copy>(f: fn(uint) -> T) -> T {
204+
let idx = self.next_u64(es_enum_vid);
205+
self.push_doc(self.next_doc(es_enum_body)) {||
206+
f(idx)
207+
}
208+
}
209+
210+
fn read_enum_variant_arg<T:copy>(_idx: uint, f: fn() -> T) -> T {
211+
f()
212+
}
213+
214+
fn read_vec<T:copy>(f: fn(uint) -> T) -> T {
215+
self.push_doc(self.next_doc(es_vec)) {||
216+
let len = self.next_u64(es_vec_len) as uint;
217+
f(len)
218+
}
219+
}
220+
221+
fn read_vec_elt<T:copy>(idx: uint, f: fn() -> T) -> T {
222+
self.push_doc(self.next_doc(es_vec_elt), f)
223+
}
224+
225+
fn read_box<T:copy>(f: fn() -> T) -> T {
226+
f()
227+
}
228+
229+
fn read_uniq<T:copy>(f: fn() -> T) -> T {
230+
f()
231+
}
232+
233+
fn read_rec<T:copy>(f: fn() -> T) -> T {
234+
f()
235+
}
236+
237+
fn read_rec_field<T:copy>(f_name: str, f_idx: uint, f: fn() -> T) -> T {
238+
f()
239+
}
240+
241+
fn read_tup<T:copy>(sz: uint, f: fn() -> T) -> T {
242+
f()
243+
}
244+
245+
fn read_tup_elt<T:copy>(idx: uint, f: fn() -> T) -> T {
246+
f()
247+
}
248+
}
249+
250+
// ___________________________________________________________________________
251+
// Testing
252+

0 commit comments

Comments
 (0)