From 8cffc6f84c1553fb7075d465f918d2ac335b15b1 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 27 Feb 2012 14:05:19 -0800 Subject: [PATCH] add debugging mode which emits more verbose info --- src/libstd/serialization.rs | 72 ++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 13 deletions(-) diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs index c1c862cd386..8130492cff9 100644 --- a/src/libstd/serialization.rs +++ b/src/libstd/serialization.rs @@ -7,6 +7,10 @@ Support code for serialization. import list::list; import ebml::writer; +// Set to true to generate more debugging in EBML serialization. +// Totally lame approach. +const debug: bool = true; + iface serializer { // Primitive types: fn emit_nil(); @@ -86,7 +90,9 @@ enum ebml_serializer_tag { es_str, es_f64, es_f32, es_float, es_enum, es_enum_vid, es_enum_body, - es_vec, es_vec_len, es_vec_elt + es_vec, es_vec_len, es_vec_elt, + + es_label // Used only when debugging } impl of serializer for ebml::writer { @@ -98,6 +104,16 @@ impl of serializer for ebml::writer { self.wr_tagged_u32(t as uint, v as u32); } + fn _emit_label(label: str) { + // There are various strings that we have access to, such as + // the name of a record field, which do not actually appear in + // the serialized EBML (normally). This is just for + // efficiency. When debugging, though, we can emit such + // labels and then they will be checked by deserializer to + // try and check failures more quickly. + if debug { self.wr_tagged_str(es_label as uint, label) } + } + fn emit_uint(v: uint) { self.wr_tagged_u64(es_uint as uint, v as u64); } fn emit_u64(v: u64) { self.wr_tagged_u64(es_u64 as uint, v); } fn emit_u32(v: u32) { self.wr_tagged_u32(es_u32 as uint, v); } @@ -118,7 +134,8 @@ impl of serializer for ebml::writer { fn emit_str(v: str) { self.wr_tagged_str(es_str as uint, v) } - fn emit_enum(_name: str, f: fn()) { + fn emit_enum(name: str, f: fn()) { + self._emit_label(name); self.wr_tag(es_enum as uint, f) } fn emit_enum_variant(_v_name: str, v_id: uint, _cnt: uint, f: fn()) { @@ -138,14 +155,13 @@ impl of serializer for ebml::writer { self.wr_tag(es_vec_elt as uint, f) } - fn emit_vec_elt(_idx: uint, f: fn()) { - self.wr_tag(es_vec_elt as uint, f) - } - fn emit_box(f: fn()) { f() } fn emit_uniq(f: fn()) { f() } fn emit_rec(f: fn()) { f() } - fn emit_rec_field(_f_name: str, _f_idx: uint, f: fn()) { f() } + fn emit_rec_field(f_name: str, _f_idx: uint, f: fn()) { + self._emit_label(f_name); + f() + } fn emit_tup(_sz: uint, f: fn()) { f() } fn emit_tup_elt(_idx: uint, f: fn()) { f() } } @@ -158,7 +174,22 @@ fn mk_ebml_deserializer(d: ebml::doc) -> ebml_deserializer { } impl of deserializer for ebml_deserializer { + fn _check_label(lbl: str) { + if self.pos < self.parent.end { + let {tag: r_tag, doc: r_doc} = + ebml::doc_at(self.parent.data, self.pos); + if r_tag == (es_label as uint) { + self.pos = r_doc.end; + let str = ebml::doc_as_str(r_doc); + if lbl != str { + fail #fmt["Expected label %s but found %s", lbl, str]; + } + } + } + } + fn next_doc(exp_tag: ebml_serializer_tag) -> ebml::doc { + #debug[". next_doc(exp_tag=%?)", exp_tag]; if self.pos >= self.parent.end { fail "no more documents in current node!"; } @@ -231,53 +262,68 @@ impl of deserializer for ebml_deserializer { fn read_str() -> str { ebml::doc_as_str(self.next_doc(es_str)) } // Compound types: - fn read_enum(_name: str, f: fn() -> T) -> T { + fn read_enum(name: str, f: fn() -> T) -> T { + #debug["read_enum(%s)", name]; + self._check_label(name); self.push_doc(self.next_doc(es_enum), f) } fn read_enum_variant(f: fn(uint) -> T) -> T { + #debug["read_enum_variant()"]; let idx = self._next_uint(es_enum_vid); + #debug[" idx=%u", idx]; self.push_doc(self.next_doc(es_enum_body)) {|| f(idx) } } - fn read_enum_variant_arg(_idx: uint, f: fn() -> T) -> T { + fn read_enum_variant_arg(idx: uint, f: fn() -> T) -> T { + #debug["read_enum_variant_arg(idx=%u)", idx]; f() } fn read_vec(f: fn(uint) -> T) -> T { + #debug["read_vec()"]; self.push_doc(self.next_doc(es_vec)) {|| let len = self._next_uint(es_vec_len); + #debug[" len=%u", len]; f(len) } } - fn read_vec_elt(_idx: uint, f: fn() -> T) -> T { + fn read_vec_elt(idx: uint, f: fn() -> T) -> T { + #debug["read_vec_elt(idx=%u)", idx]; self.push_doc(self.next_doc(es_vec_elt), f) } fn read_box(f: fn() -> T) -> T { + #debug["read_box()"]; f() } fn read_uniq(f: fn() -> T) -> T { + #debug["read_uniq()"]; f() } fn read_rec(f: fn() -> T) -> T { + #debug["read_rec()"]; f() } - fn read_rec_field(_f_name: str, _f_idx: uint, f: fn() -> T) -> T { + fn read_rec_field(f_name: str, f_idx: uint, f: fn() -> T) -> T { + #debug["read_rec_field(%s, idx=%u)", f_name, f_idx]; + self._check_label(f_name); f() } - fn read_tup(_sz: uint, f: fn() -> T) -> T { + fn read_tup(sz: uint, f: fn() -> T) -> T { + #debug["read_tup(sz=%u)", sz]; f() } - fn read_tup_elt(_idx: uint, f: fn() -> T) -> T { + fn read_tup_elt(idx: uint, f: fn() -> T) -> T { + #debug["read_tup_elt(idx=%u)", idx]; f() } }