From 0863012fb9b709aee34190d902f0fce5d34eef9e Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Thu, 1 Sep 2016 16:55:33 +0300 Subject: [PATCH] Remove librbml and the RBML-tagged auto-encoder/decoder. --- mk/crates.mk | 9 +- mk/tests.mk | 2 +- src/librbml/Cargo.toml | 13 - src/librbml/lib.rs | 63 --- src/librustc/Cargo.toml | 1 - src/librustc/lib.rs | 1 - src/librustc/middle/cstore.rs | 6 +- src/librustc_incremental/Cargo.toml | 3 +- src/librustc_incremental/lib.rs | 1 - src/librustc_incremental/persist/hash.rs | 5 +- src/librustc_incremental/persist/load.rs | 5 +- src/librustc_incremental/persist/save.rs | 2 +- src/librustc_metadata/Cargo.toml | 1 - src/librustc_metadata/astencode.rs | 2 +- src/librustc_metadata/common.rs | 9 +- src/librustc_metadata/csearch.rs | 19 +- src/librustc_metadata/decoder.rs | 59 ++- src/librustc_metadata/encoder.rs | 246 +++++---- src/librustc_metadata/index.rs | 6 +- src/librustc_metadata/index_builder.rs | 13 +- src/librustc_metadata/lib.rs | 3 - src/librustc_metadata/rbml/reader.rs | 595 ++-------------------- src/librustc_metadata/rbml/writer.rs | 379 ++------------ src/librustc_metadata/tydecode.rs | 2 +- src/librustc_metadata/tyencode.rs | 5 +- src/librustc_trans/base.rs | 3 +- src/{librbml => libserialize}/leb128.rs | 0 src/libserialize/lib.rs | 3 + src/{librbml => libserialize}/opaque.rs | 260 +--------- src/libserialize/serialize.rs | 194 ++++--- src/rustc/Cargo.lock | 11 - src/test/run-pass-fulldeps/issue-11881.rs | 6 +- 32 files changed, 411 insertions(+), 1516 deletions(-) delete mode 100644 src/librbml/Cargo.toml delete mode 100644 src/librbml/lib.rs rename src/{librbml => libserialize}/leb128.rs (100%) rename src/{librbml => libserialize}/opaque.rs (64%) diff --git a/mk/crates.mk b/mk/crates.mk index d2c79441d86..86bb3a8ca0c 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -61,7 +61,7 @@ RUSTC_CRATES := rustc rustc_typeck rustc_mir rustc_borrowck rustc_resolve rustc_ rustc_plugin rustc_metadata rustc_passes rustc_save_analysis \ rustc_const_eval rustc_const_math rustc_incremental rustc_macro HOST_CRATES := syntax syntax_ext proc_macro syntax_pos $(RUSTC_CRATES) rustdoc fmt_macros \ - flate arena graphviz rbml log serialize + flate arena graphviz log serialize TOOLS := compiletest rustdoc rustc rustbook error_index_generator DEPS_core := @@ -96,7 +96,6 @@ DEPS_getopts := std DEPS_graphviz := std DEPS_log := std DEPS_num := std -DEPS_rbml := std log serialize DEPS_serialize := std log DEPS_term := std DEPS_test := std getopts term native:rust_test_helpers @@ -110,7 +109,7 @@ DEPS_rustc_const_math := std syntax log serialize DEPS_rustc_const_eval := rustc_const_math rustc syntax log serialize \ rustc_back graphviz syntax_pos -DEPS_rustc := syntax fmt_macros flate arena serialize getopts rbml \ +DEPS_rustc := syntax fmt_macros flate arena serialize getopts \ log graphviz rustc_llvm rustc_back rustc_data_structures\ rustc_const_math syntax_pos rustc_errors DEPS_rustc_back := std syntax flate log libc @@ -126,7 +125,7 @@ DEPS_rustc_errors := log libc serialize syntax_pos DEPS_rustc_lint := rustc log syntax syntax_pos rustc_const_eval DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags DEPS_rustc_macro := std syntax -DEPS_rustc_metadata := rustc syntax syntax_pos rustc_errors rbml rustc_const_math \ +DEPS_rustc_metadata := rustc syntax syntax_pos rustc_errors rustc_const_math \ rustc_macro syntax_ext DEPS_rustc_passes := syntax syntax_pos rustc core rustc_const_eval rustc_errors DEPS_rustc_mir := rustc syntax syntax_pos rustc_const_math rustc_const_eval rustc_bitflags @@ -137,7 +136,7 @@ DEPS_rustc_privacy := rustc log syntax syntax_pos DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \ log syntax serialize rustc_llvm rustc_platform_intrinsics \ rustc_const_math rustc_const_eval rustc_incremental rustc_errors syntax_pos -DEPS_rustc_incremental := rbml rustc syntax_pos serialize rustc_data_structures +DEPS_rustc_incremental := rustc syntax_pos serialize rustc_data_structures DEPS_rustc_save_analysis := rustc log syntax syntax_pos serialize DEPS_rustc_typeck := rustc syntax syntax_pos rustc_platform_intrinsics rustc_const_math \ rustc_const_eval rustc_errors diff --git a/mk/tests.mk b/mk/tests.mk index c135aa9b8fb..fc1f4b5561a 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -27,7 +27,7 @@ TEST_TARGET_CRATES = $(filter-out core rustc_unicode alloc_system libc \ panic_abort,$(TARGET_CRATES)) \ collectionstest coretest TEST_DOC_CRATES = $(DOC_CRATES) arena flate fmt_macros getopts graphviz \ - log rand rbml serialize syntax term test + log rand serialize syntax term test TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_resolve \ rustc_trans rustc_lint,\ $(HOST_CRATES)) diff --git a/src/librbml/Cargo.toml b/src/librbml/Cargo.toml deleted file mode 100644 index ab89ac2b7a1..00000000000 --- a/src/librbml/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rbml" -version = "0.0.0" - -[lib] -name = "rbml" -path = "lib.rs" -crate-type = ["dylib"] - -[dependencies] -log = { path = "../liblog" } -serialize = { path = "../libserialize" } diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs deleted file mode 100644 index 65259f903a9..00000000000 --- a/src/librbml/lib.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Skeleton of RBML (Really Bad Markup Language). -//! See `src/librustc_metadata/reader.rs` for more details. - -#![crate_name = "rbml"] -#![unstable(feature = "rustc_private", issue = "27812")] -#![crate_type = "rlib"] -#![crate_type = "dylib"] -#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://doc.rust-lang.org/favicon.ico", - html_root_url = "https://doc.rust-lang.org/nightly/", - html_playground_url = "https://play.rust-lang.org/", - test(attr(deny(warnings))))] -#![cfg_attr(not(stage0), deny(warnings))] - -#![feature(rustc_private)] -#![feature(staged_api)] -#![feature(question_mark)] - -#![cfg_attr(test, feature(test))] - -extern crate serialize; - -#[cfg(test)] -extern crate serialize as rustc_serialize; // Used by RustcEncodable - -#[macro_use] -extern crate log; - -#[cfg(test)] -extern crate test; - -pub mod opaque; -pub mod leb128; - -pub use self::Error::*; - -use std::fmt; - -#[derive(Debug)] -pub enum Error { - IntTooBig(usize), - InvalidTag(usize), - Expected(String), - IoError(std::io::Error), - ApplicationError(String), -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // FIXME: this should be a more useful display form - fmt::Debug::fmt(self, f) - } -} diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index aaef8e8423c..578ef68b003 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -14,7 +14,6 @@ flate = { path = "../libflate" } fmt_macros = { path = "../libfmt_macros" } graphviz = { path = "../libgraphviz" } log = { path = "../liblog" } -rbml = { path = "../librbml" } rustc_back = { path = "../librustc_back" } rustc_bitflags = { path = "../librustc_bitflags" } rustc_const_math = { path = "../librustc_const_math" } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index d2a2f8a972d..c34286f0195 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -50,7 +50,6 @@ extern crate fmt_macros; extern crate getopts; extern crate graphviz; extern crate libc; -extern crate rbml; extern crate rustc_llvm as llvm; extern crate rustc_back; extern crate rustc_data_structures; diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 513fa30861a..1d6047579f6 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -265,8 +265,7 @@ pub trait CrateStore<'tcx> { reexports: &def::ExportMap, link_meta: &LinkMeta, reachable: &NodeSet, - mir_map: &MirMap<'tcx>, - krate: &hir::Crate) -> Vec; + mir_map: &MirMap<'tcx>) -> Vec; fn metadata_encoding_version(&self) -> &[u8]; } @@ -472,8 +471,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { reexports: &def::ExportMap, link_meta: &LinkMeta, reachable: &NodeSet, - mir_map: &MirMap<'tcx>, - krate: &hir::Crate) -> Vec { vec![] } + mir_map: &MirMap<'tcx>) -> Vec { vec![] } fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") } } diff --git a/src/librustc_incremental/Cargo.toml b/src/librustc_incremental/Cargo.toml index 7db1a6348b2..e3ee7527545 100644 --- a/src/librustc_incremental/Cargo.toml +++ b/src/librustc_incremental/Cargo.toml @@ -10,10 +10,9 @@ crate-type = ["dylib"] [dependencies] graphviz = { path = "../libgraphviz" } -rbml = { path = "../librbml" } rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } serialize = { path = "../libserialize" } log = { path = "../liblog" } syntax = { path = "../libsyntax" } -syntax_pos = { path = "../libsyntax_pos" } \ No newline at end of file +syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 1f823eedda0..42b5657e212 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -27,7 +27,6 @@ #![feature(core_intrinsics)] extern crate graphviz; -extern crate rbml; #[macro_use] extern crate rustc; extern crate rustc_data_structures; extern crate serialize as rustc_serialize; diff --git a/src/librustc_incremental/persist/hash.rs b/src/librustc_incremental/persist/hash.rs index 6dcf2c28891..5a4716e45f6 100644 --- a/src/librustc_incremental/persist/hash.rs +++ b/src/librustc_incremental/persist/hash.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rbml::Error; -use rbml::opaque::Decoder; use rustc::dep_graph::DepNode; use rustc::hir::def_id::{CrateNum, DefId}; use rustc::hir::svh::Svh; @@ -17,6 +15,7 @@ use rustc::ty::TyCtxt; use rustc_data_structures::fnv::FnvHashMap; use rustc_data_structures::flock; use rustc_serialize::Decodable; +use rustc_serialize::opaque::Decoder; use std::io::{ErrorKind, Read}; use std::fs::File; @@ -188,7 +187,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> { fn load_from_data(&mut self, cnum: CrateNum, data: &[u8], - expected_svh: Svh) -> Result<(), Error> { + expected_svh: Svh) -> Result<(), String> { debug!("load_from_data(cnum={})", cnum); // Load up the hashes for the def-ids from this crate. diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs index 6e6464e4968..b051e6c5ab7 100644 --- a/src/librustc_incremental/persist/load.rs +++ b/src/librustc_incremental/persist/load.rs @@ -10,14 +10,13 @@ //! Code to save/load the dep-graph from files. -use rbml::Error; -use rbml::opaque::Decoder; use rustc::dep_graph::DepNode; use rustc::hir::def_id::DefId; use rustc::session::Session; use rustc::ty::TyCtxt; use rustc_data_structures::fnv::FnvHashSet; use rustc_serialize::Decodable as RustcDecodable; +use rustc_serialize::opaque::Decoder; use std::io::Read; use std::fs::{self, File}; use std::path::{Path}; @@ -121,7 +120,7 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, incremental_hashes_map: &IncrementalHashesMap, dep_graph_data: &[u8], work_products_data: &[u8]) - -> Result<(), Error> + -> Result<(), String> { // Decode the list of work_products let mut work_product_decoder = Decoder::new(work_products_data, 0); diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index 41212d8e138..5b45874840f 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rbml::opaque::Encoder; use rustc::dep_graph::DepNode; use rustc::hir::def_id::DefId; use rustc::hir::svh::Svh; @@ -16,6 +15,7 @@ use rustc::session::Session; use rustc::ty::TyCtxt; use rustc_data_structures::fnv::FnvHashMap; use rustc_serialize::Encodable as RustcEncodable; +use rustc_serialize::opaque::Encoder; use std::hash::{Hash, Hasher, SipHasher}; use std::io::{self, Cursor, Write}; use std::fs::{self, File}; diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index d70510896b9..fede6f66341 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -11,7 +11,6 @@ crate-type = ["dylib"] [dependencies] flate = { path = "../libflate" } log = { path = "../liblog" } -rbml = { path = "../librbml" } rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_bitflags = { path = "../librustc_bitflags" } diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index ce15ec6a29d..f00c4b82a85 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -217,7 +217,7 @@ fn encode_side_tables_for_id(ecx: &mut EncodeContext, id: ast::NodeId) { } fn decode_side_tables(dcx: &mut DecodeContext, ast_doc: rbml::Doc) { - while dcx.position() < ast_doc.end { + while dcx.opaque.position() < ast_doc.end { let table = Decodable::decode(dcx).unwrap(); let id = Decodable::decode(dcx).unwrap(); debug!("decode_side_tables: entry for id={}, table={:?}", id, table); diff --git a/src/librustc_metadata/common.rs b/src/librustc_metadata/common.rs index 512f4ca6584..3b63ee6b5fa 100644 --- a/src/librustc_metadata/common.rs +++ b/src/librustc_metadata/common.rs @@ -10,12 +10,9 @@ #![allow(non_camel_case_types, non_upper_case_globals)] -// RBML enum definitions and utils shared by the encoder and decoder -// -// 0x00..0x1f: reserved for RBML generic type tags -// 0x20..0xef: free for use, preferred for frequent tags -// 0xf0..0xff: internally used by RBML to encode 0x100..0xfff in two bytes -// 0x100..0xfff: free for use, preferred for infrequent tags +pub const tag_opaque: usize = 0x00; + +// GAP 0x01...0x19 pub const tag_items: usize = 0x100; // top-level only diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index aae87005bf4..b291c4927aa 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -13,7 +13,6 @@ use common; use decoder; use encoder; use loader; -use rbml; use middle::cstore::{InlinedItem, CrateStore, CrateSource, ChildItem, ExternCrate, DefLike}; use middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference}; @@ -30,7 +29,6 @@ use rustc::mir::mir_map::MirMap; use rustc::util::nodemap::{FnvHashMap, NodeSet, DefIdMap}; use rustc::session::config::PanicStrategy; -use std::cell::RefCell; use std::rc::Rc; use std::path::PathBuf; use syntax::ast; @@ -697,22 +695,9 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { reexports: &def::ExportMap, link_meta: &LinkMeta, reachable: &NodeSet, - mir_map: &MirMap<'tcx>, - krate: &hir::Crate) -> Vec + mir_map: &MirMap<'tcx>) -> Vec { - let type_abbrevs = RefCell::new(FnvHashMap()); - let ecx = encoder::EncodeContext { - rbml_w: rbml::writer::Encoder::new(), - tcx: tcx, - reexports: reexports, - link_meta: link_meta, - cstore: self, - reachable: reachable, - mir_map: mir_map, - type_abbrevs: &type_abbrevs, - }; - encoder::encode_metadata(ecx, krate) - + encoder::encode_metadata(tcx, self, reexports, link_meta, reachable, mir_map) } fn metadata_encoding_version(&self) -> &[u8] diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 1bec365e472..ba593e5be99 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -45,14 +45,14 @@ use rustc_const_math::ConstInt; use rustc::mir::repr::Mir; use std::io; -use std::ops::{Deref, DerefMut}; use std::rc::Rc; use std::str; use std::u32; use rbml::reader; use rbml; -use rustc_serialize::{Decodable, SpecializedDecoder}; +use rustc_serialize::{Decodable, SpecializedDecoder, opaque}; +use rustc_serialize as serialize; use syntax::attr; use syntax::parse::token; use syntax::ast::{self, NodeId}; @@ -60,7 +60,7 @@ use syntax::print::pprust; use syntax_pos::{self, Span, BytePos, NO_EXPANSION}; pub struct DecodeContext<'a, 'tcx: 'a> { - rbml_r: rbml::reader::Decoder<'a>, + pub opaque: opaque::Decoder<'a>, pub tcx: Option>, pub cdata: Option<&'a cstore::CrateMetadata>, pub from_id_range: IdRange, @@ -76,7 +76,7 @@ impl<'doc> rbml::Doc<'doc> { max: NodeId::from_u32(u32::MAX) }; DecodeContext { - rbml_r: reader::Decoder::new(self), + opaque: opaque::Decoder::new(self.data, self.start), cdata: None, tcx: None, from_id_range: id_range, @@ -98,24 +98,49 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> { fn read_ty_encoded(&mut self, op: F) -> R where F: for<'x> FnOnce(&mut TyDecoder<'x,'tcx>) -> R { - self.read_opaque(|this, doc| { - Ok(op(&mut TyDecoder::with_doc( - this.tcx(), this.cdata().cnum, doc, - &mut |d| translate_def_id(this.cdata(), d)))) - }).unwrap() + let pos = self.opaque.position(); + let doc = rbml::Doc::at(self.opaque.data, pos); + self.opaque.advance(doc.end - pos); + op(&mut TyDecoder::with_doc(self.tcx(), self.cdata().cnum, doc, + &mut |d| translate_def_id(self.cdata(), d))) } } -impl<'a, 'tcx> Deref for DecodeContext<'a, 'tcx> { - type Target = rbml::reader::Decoder<'a>; - fn deref(&self) -> &Self::Target { - &self.rbml_r +macro_rules! decoder_methods { + ($($name:ident -> $ty:ty;)*) => { + $(fn $name(&mut self) -> Result<$ty, Self::Error> { + self.opaque.$name() + })* } } -impl<'a, 'tcx> DerefMut for DecodeContext<'a, 'tcx> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.rbml_r +impl<'doc, 'tcx> serialize::Decoder for ::decoder::DecodeContext<'doc, 'tcx> { + type Error = as serialize::Decoder>::Error; + + decoder_methods! { + read_nil -> (); + + read_u64 -> u64; + read_u32 -> u32; + read_u16 -> u16; + read_u8 -> u8; + read_usize -> usize; + + read_i64 -> i64; + read_i32 -> i32; + read_i16 -> i16; + read_i8 -> i8; + read_isize -> isize; + + read_bool -> bool; + read_f64 -> f64; + read_f32 -> f32; + read_char -> char; + read_str -> String; + } + + fn error(&mut self, err: &str) -> Self::Error { + self.opaque.error(err) } } @@ -256,7 +281,7 @@ pub type Cmd<'a> = &'a CrateMetadata; impl CrateMetadata { fn get_item(&self, item_id: DefIndex) -> Option { self.index.lookup_item(self.data(), item_id).map(|pos| { - reader::doc_at(self.data(), pos as usize).unwrap().doc + rbml::Doc::at(self.data(), pos as usize) }) } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 409982289d8..4b603fcb105 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -35,9 +35,10 @@ use rustc::mir::mir_map::MirMap; use rustc::session::config::{self, PanicStrategy, CrateTypeRustcMacro}; use rustc::util::nodemap::{FnvHashMap, NodeSet}; -use rustc_serialize::{Encodable, SpecializedEncoder}; +use rustc_serialize::{Encodable, SpecializedEncoder, opaque}; +use rustc_serialize as serialize; use std::io::prelude::*; -use std::io::SeekFrom; +use std::io::Cursor; use std::ops::{Deref, DerefMut}; use std::rc::Rc; use std::u32; @@ -55,7 +56,7 @@ use rustc::hir::map::DefKey; use super::index_builder::{FromId, IndexBuilder, ItemContentBuilder, Untracked, XRef}; pub struct EncodeContext<'a, 'tcx: 'a> { - pub rbml_w: rbml::writer::Encoder, + pub rbml_w: rbml::writer::Encoder<'a>, pub tcx: TyCtxt<'a, 'tcx, 'tcx>, pub reexports: &'a def::ExportMap, pub link_meta: &'a LinkMeta, @@ -66,7 +67,7 @@ pub struct EncodeContext<'a, 'tcx: 'a> { } impl<'a, 'tcx> Deref for EncodeContext<'a, 'tcx> { - type Target = rbml::writer::Encoder; + type Target = rbml::writer::Encoder<'a>; fn deref(&self) -> &Self::Target { &self.rbml_w } @@ -78,21 +79,61 @@ impl<'a, 'tcx> DerefMut for EncodeContext<'a, 'tcx> { } } +macro_rules! encoder_methods { + ($($name:ident($ty:ty);)*) => { + $(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> { + self.opaque.$name(value) + })* + } +} + +impl<'a, 'tcx> serialize::Encoder for ::encoder::EncodeContext<'a, 'tcx> { + type Error = as serialize::Encoder>::Error; + + fn emit_nil(&mut self) -> Result<(), Self::Error> { + Ok(()) + } + + encoder_methods! { + emit_usize(usize); + emit_u64(u64); + emit_u32(u32); + emit_u16(u16); + emit_u8(u8); + + emit_isize(isize); + emit_i64(i64); + emit_i32(i32); + emit_i16(i16); + emit_i8(i8); + + emit_bool(bool); + emit_f64(f64); + emit_f32(f32); + emit_char(char); + emit_str(&str); + } +} + impl<'a, 'tcx> SpecializedEncoder> for EncodeContext<'a, 'tcx> { fn specialized_encode(&mut self, ty: &Ty<'tcx>) -> Result<(), Self::Error> { let cx = self.ty_str_ctxt(); - self.emit_opaque(|opaque_encoder| { - Ok(tyencode::enc_ty(opaque_encoder.cursor, &cx, ty)) - }) + + self.start_tag(tag_opaque)?; + tyencode::enc_ty(&mut self.rbml_w.opaque.cursor, &cx, ty); + self.mark_stable_position(); + self.end_tag() } } impl<'a, 'tcx> SpecializedEncoder<&'tcx Substs<'tcx>> for EncodeContext<'a, 'tcx> { fn specialized_encode(&mut self, substs: &&'tcx Substs<'tcx>) -> Result<(), Self::Error> { let cx = self.ty_str_ctxt(); - self.emit_opaque(|opaque_encoder| { - Ok(tyencode::enc_substs(opaque_encoder.cursor, &cx, substs)) - }) + + self.start_tag(tag_opaque)?; + tyencode::enc_substs(&mut self.rbml_w.opaque.cursor, &cx, substs); + self.mark_stable_position(); + self.end_tag() } } @@ -124,7 +165,7 @@ fn encode_trait_ref<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>, tag: usize) { let cx = ecx.ty_str_ctxt(); ecx.start_tag(tag); - tyencode::enc_trait_ref(&mut ecx.writer, &cx, trait_ref); + tyencode::enc_trait_ref(&mut ecx.opaque.cursor, &cx, trait_ref); ecx.mark_stable_position(); ecx.end_tag(); } @@ -173,7 +214,7 @@ fn encode_variant_id(ecx: &mut EncodeContext, vid: DefId) { fn write_closure_type<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>, closure_type: &ty::ClosureTy<'tcx>) { let cx = ecx.ty_str_ctxt(); - tyencode::enc_closure_ty(&mut ecx.writer, &cx, closure_type); + tyencode::enc_closure_ty(&mut ecx.opaque.cursor, &cx, closure_type); ecx.mark_stable_position(); } @@ -181,7 +222,7 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { fn encode_type(&mut self, typ: Ty<'tcx>) { let cx = self.ty_str_ctxt(); self.start_tag(tag_items_data_item_type); - tyencode::enc_ty(&mut self.writer, &cx, typ); + tyencode::enc_ty(&mut self.opaque.cursor, &cx, typ); self.mark_stable_position(); self.end_tag(); } @@ -480,7 +521,7 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { { let cx = self.ty_str_ctxt(); self.start_tag(tag_item_generics); - tyencode::enc_generics(&mut self.writer, &cx, generics); + tyencode::enc_generics(&mut self.opaque.cursor, &cx, generics); self.mark_stable_position(); self.end_tag(); self.encode_predicates(predicates, tag_item_predicates); @@ -829,7 +870,7 @@ fn encode_xrefs<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>, xref_positions[id as usize] = ecx.mark_stable_position() as u32; match xref { XRef::Predicate(p) => { - tyencode::enc_predicate(&mut ecx.writer, &cx, &p) + tyencode::enc_predicate(&mut ecx.opaque.cursor, &cx, &p) } } } @@ -837,7 +878,7 @@ fn encode_xrefs<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>, ecx.end_tag(); ecx.start_tag(tag_xref_index); - index::write_dense_index(xref_positions, &mut ecx.writer); + index::write_dense_index(xref_positions, &mut ecx.opaque.cursor); ecx.end_tag(); } @@ -1396,7 +1437,7 @@ fn encode_info_for_items<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>) fn encode_item_index(ecx: &mut EncodeContext, index: IndexData) { ecx.start_tag(tag_index); - index.write_index(&mut ecx.writer); + index.write_index(&mut ecx.opaque.cursor); ecx.end_tag(); } @@ -1710,15 +1751,33 @@ fn encode_panic_strategy(ecx: &mut EncodeContext) { } } -pub fn encode_metadata(mut ecx: EncodeContext, krate: &hir::Crate) -> Vec { - encode_metadata_inner(&mut ecx, krate); +pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + cstore: &cstore::CStore, + reexports: &def::ExportMap, + link_meta: &LinkMeta, + reachable: &NodeSet, + mir_map: &MirMap<'tcx>) -> Vec { + let mut cursor = Cursor::new(vec![]); + cursor.write_all(&[0, 0, 0, 0]).unwrap(); + cursor.write_all(metadata_encoding_version).unwrap(); + // Will be filed with the length after encoding the crate. + cursor.write_all(&[0, 0, 0, 0]).unwrap(); + + encode_metadata_inner(&mut EncodeContext { + rbml_w: rbml::writer::Encoder::new(&mut cursor), + tcx: tcx, + reexports: reexports, + link_meta: link_meta, + cstore: cstore, + reachable: reachable, + mir_map: mir_map, + type_abbrevs: &Default::default(), + }); // RBML compacts the encoded bytes whenever appropriate, // so there are some garbages left after the end of the data. - let metalen = ecx.rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() as usize; - let mut v = ecx.rbml_w.writer.into_inner(); - v.truncate(metalen); - assert_eq!(v.len(), metalen); + let meta_len = cursor.position() as usize; + cursor.get_mut().truncate(meta_len); // And here we run into yet another obscure archive bug: in which metadata // loaded from archives may have trailing garbage bytes. Awhile back one of @@ -1744,55 +1803,17 @@ pub fn encode_metadata(mut ecx: EncodeContext, krate: &hir::Crate) -> Vec { // this metadata, there are 4 zero bytes at the start, which are // treated as a length of 0 by old compilers. - let len = v.len(); - let mut result = vec![]; - result.push(0); - result.push(0); - result.push(0); - result.push(0); - result.extend(metadata_encoding_version.iter().cloned()); - result.push((len >> 24) as u8); - result.push((len >> 16) as u8); - result.push((len >> 8) as u8); - result.push((len >> 0) as u8); - result.extend(v); + let meta_start = 8 + ::common::metadata_encoding_version.len(); + let len = meta_len - meta_start; + let mut result = cursor.into_inner(); + result[meta_start - 4] = (len >> 24) as u8; + result[meta_start - 3] = (len >> 16) as u8; + result[meta_start - 2] = (len >> 8) as u8; + result[meta_start - 1] = (len >> 0) as u8; result } -fn encode_metadata_inner(ecx: &mut EncodeContext, krate: &hir::Crate) { - struct Stats { - attr_bytes: u64, - dep_bytes: u64, - lang_item_bytes: u64, - native_lib_bytes: u64, - plugin_registrar_fn_bytes: u64, - codemap_bytes: u64, - macro_defs_bytes: u64, - impl_bytes: u64, - reachable_bytes: u64, - item_bytes: u64, - index_bytes: u64, - xref_bytes: u64, - zero_bytes: u64, - total_bytes: u64, - } - let mut stats = Stats { - attr_bytes: 0, - dep_bytes: 0, - lang_item_bytes: 0, - native_lib_bytes: 0, - plugin_registrar_fn_bytes: 0, - codemap_bytes: 0, - macro_defs_bytes: 0, - impl_bytes: 0, - reachable_bytes: 0, - item_bytes: 0, - index_bytes: 0, - xref_bytes: 0, - zero_bytes: 0, - total_bytes: 0, - }; - +fn encode_metadata_inner(ecx: &mut EncodeContext) { encode_rustc_version(ecx); let tcx = ecx.tcx; @@ -1804,89 +1825,92 @@ fn encode_metadata_inner(ecx: &mut EncodeContext, krate: &hir::Crate) { encode_dylib_dependency_formats(ecx); encode_panic_strategy(ecx); - let mut i = ecx.writer.seek(SeekFrom::Current(0)).unwrap(); - encode_attributes(ecx, &krate.attrs); - stats.attr_bytes = ecx.writer.seek(SeekFrom::Current(0)).unwrap() - i; + let krate = tcx.map.krate(); - i = ecx.writer.seek(SeekFrom::Current(0)).unwrap(); + let mut i = ecx.position(); + encode_attributes(ecx, &krate.attrs); + let attr_bytes = ecx.position() - i; + + i = ecx.position(); encode_crate_deps(ecx, ecx.cstore); - stats.dep_bytes = ecx.writer.seek(SeekFrom::Current(0)).unwrap() - i; + let dep_bytes = ecx.position() - i; // Encode the language items. - i = ecx.writer.seek(SeekFrom::Current(0)).unwrap(); + i = ecx.position(); encode_lang_items(ecx); - stats.lang_item_bytes = ecx.writer.seek(SeekFrom::Current(0)).unwrap() - i; + let lang_item_bytes = ecx.position() - i; // Encode the native libraries used - i = ecx.writer.seek(SeekFrom::Current(0)).unwrap(); + i = ecx.position(); encode_native_libraries(ecx); - stats.native_lib_bytes = ecx.writer.seek(SeekFrom::Current(0)).unwrap() - i; + let native_lib_bytes = ecx.position() - i; // Encode the plugin registrar function - i = ecx.writer.seek(SeekFrom::Current(0)).unwrap(); + i = ecx.position(); encode_plugin_registrar_fn(ecx); - stats.plugin_registrar_fn_bytes = ecx.writer.seek(SeekFrom::Current(0)).unwrap() - i; + let plugin_registrar_fn_bytes = ecx.position() - i; // Encode codemap - i = ecx.writer.seek(SeekFrom::Current(0)).unwrap(); + i = ecx.position(); encode_codemap(ecx); - stats.codemap_bytes = ecx.writer.seek(SeekFrom::Current(0)).unwrap() - i; + let codemap_bytes = ecx.position() - i; // Encode macro definitions - i = ecx.writer.seek(SeekFrom::Current(0)).unwrap(); + i = ecx.position(); encode_macro_defs(ecx, krate); - stats.macro_defs_bytes = ecx.writer.seek(SeekFrom::Current(0)).unwrap() - i; + let macro_defs_bytes = ecx.position() - i; // Encode the def IDs of impls, for coherence checking. - i = ecx.writer.seek(SeekFrom::Current(0)).unwrap(); + i = ecx.position(); encode_impls(ecx, krate); - stats.impl_bytes = ecx.writer.seek(SeekFrom::Current(0)).unwrap() - i; + let impl_bytes = ecx.position() - i; // Encode reachability info. - i = ecx.writer.seek(SeekFrom::Current(0)).unwrap(); + i = ecx.position(); encode_reachable(ecx); - stats.reachable_bytes = ecx.writer.seek(SeekFrom::Current(0)).unwrap() - i; + let reachable_bytes = ecx.position() - i; // Encode and index the items. ecx.start_tag(tag_items); - i = ecx.writer.seek(SeekFrom::Current(0)).unwrap(); + i = ecx.position(); let (items, xrefs) = encode_info_for_items(ecx); - stats.item_bytes = ecx.writer.seek(SeekFrom::Current(0)).unwrap() - i; + let item_bytes = ecx.position() - i; ecx.end_tag(); - i = ecx.writer.seek(SeekFrom::Current(0)).unwrap(); + i = ecx.position(); encode_item_index(ecx, items); - stats.index_bytes = ecx.writer.seek(SeekFrom::Current(0)).unwrap() - i; + let index_bytes = ecx.position() - i; - i = ecx.writer.seek(SeekFrom::Current(0)).unwrap(); + i = ecx.position(); encode_xrefs(ecx, xrefs); - stats.xref_bytes = ecx.writer.seek(SeekFrom::Current(0)).unwrap() - i; + let xref_bytes = ecx.position() - i; encode_struct_field_attrs(ecx, krate); - stats.total_bytes = ecx.writer.seek(SeekFrom::Current(0)).unwrap(); + let total_bytes = ecx.position(); if ecx.tcx.sess.meta_stats() { - for e in ecx.writer.get_ref() { + let mut zero_bytes = 0; + for e in ecx.opaque.cursor.get_ref() { if *e == 0 { - stats.zero_bytes += 1; + zero_bytes += 1; } } println!("metadata stats:"); - println!(" attribute bytes: {}", stats.attr_bytes); - println!(" dep bytes: {}", stats.dep_bytes); - println!(" lang item bytes: {}", stats.lang_item_bytes); - println!(" native bytes: {}", stats.native_lib_bytes); - println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes); - println!(" codemap bytes: {}", stats.codemap_bytes); - println!(" macro def bytes: {}", stats.macro_defs_bytes); - println!(" impl bytes: {}", stats.impl_bytes); - println!(" reachable bytes: {}", stats.reachable_bytes); - println!(" item bytes: {}", stats.item_bytes); - println!(" index bytes: {}", stats.index_bytes); - println!(" xref bytes: {}", stats.xref_bytes); - println!(" zero bytes: {}", stats.zero_bytes); - println!(" total bytes: {}", stats.total_bytes); + println!(" attribute bytes: {}", attr_bytes); + println!(" dep bytes: {}", dep_bytes); + println!(" lang item bytes: {}", lang_item_bytes); + println!(" native bytes: {}", native_lib_bytes); + println!("plugin registrar bytes: {}", plugin_registrar_fn_bytes); + println!(" codemap bytes: {}", codemap_bytes); + println!(" macro def bytes: {}", macro_defs_bytes); + println!(" impl bytes: {}", impl_bytes); + println!(" reachable bytes: {}", reachable_bytes); + println!(" item bytes: {}", item_bytes); + println!(" index bytes: {}", index_bytes); + println!(" xref bytes: {}", xref_bytes); + println!(" zero bytes: {}", zero_bytes); + println!(" total bytes: {}", total_bytes); } } diff --git a/src/librustc_metadata/index.rs b/src/librustc_metadata/index.rs index b850073462f..63d7f1b58bb 100644 --- a/src/librustc_metadata/index.rs +++ b/src/librustc_metadata/index.rs @@ -73,15 +73,15 @@ impl IndexData { } } - pub fn record(&mut self, def_id: DefId, position: u64) { + pub fn record(&mut self, def_id: DefId, position: usize) { assert!(def_id.is_local()); self.record_index(def_id.index, position); } - pub fn record_index(&mut self, item: DefIndex, position: u64) { + pub fn record_index(&mut self, item: DefIndex, position: usize) { let item = item.as_usize(); - assert!(position < (u32::MAX as u64)); + assert!(position < (u32::MAX as usize)); let position = position as u32; assert!(self.positions[item] == u32::MAX, diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index de2f1c4fb0c..fd25128575f 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -28,10 +28,9 @@ //! incremental compilation purposes. //! //! The `IndexBuilder` facilitates both of these. It is created -//! with an RBML encoder isntance (`rbml_w`) along with an -//! `EncodingContext` (`ecx`), which it encapsulates. It has one main -//! method, `record()`. You invoke `record` like so to create a new -//! `data_item` element in the list: +//! with an `EncodingContext` (`ecx`), which it encapsulates. +//! It has one main method, `record()`. You invoke `record` +//! like so to create a new `data_item` element in the list: //! //! ``` //! index.record(some_def_id, callback_fn, data) @@ -43,9 +42,9 @@ //! returns, the `common::data_item` tag will be closed. //! //! The `ItemContentBuilder` is another type that just offers access -//! to the `ecx` and `rbml_w` that were given in, as well as -//! maintaining a list of `xref` instances, which are used to extract -//! common data so it is not re-serialized. +//! to the `ecx` that was given in, as well as maintaining a list of +//! `xref` instances, which are used to extract common data so it is +//! not re-serialized. //! //! `ItemContentBuilder` is a distinct type which does not offer the //! `record` method, so that we can ensure that `common::data_item` elements diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 428b33f2bfa..7205a88618f 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -51,9 +51,6 @@ extern crate rustc_const_math; extern crate test; pub mod rbml { - pub extern crate rbml as rbml_crate; - pub use self::rbml_crate::{Error, leb128, opaque}; - pub mod writer; pub mod reader; pub use self::reader::Doc; diff --git a/src/librustc_metadata/rbml/reader.rs b/src/librustc_metadata/rbml/reader.rs index d66ca38e624..9bbeb73ce3e 100644 --- a/src/librustc_metadata/rbml/reader.rs +++ b/src/librustc_metadata/rbml/reader.rs @@ -45,87 +45,13 @@ //! **Data** can be either binary bytes or zero or more nested RBML documents. //! Nested documents cannot overflow, and should be entirely contained //! within a parent document. -//! -//! # Predefined Tags -//! -//! Most RBML tags are defined by the application. -//! (For the rust object metadata, see also `rustc::metadata::common`.) -//! RBML itself does define a set of predefined tags however, -//! intended for the auto-serialization implementation. -//! -//! Predefined tags with an implicit length: -//! -//! - `U8` (`00`): 1-byte unsigned integer. -//! - `U16` (`01`): 2-byte big endian unsigned integer. -//! - `U32` (`02`): 4-byte big endian unsigned integer. -//! - `U64` (`03`): 8-byte big endian unsigned integer. -//! Any of `U*` tags can be used to encode primitive unsigned integer types, -//! as long as it is no greater than the actual size. -//! For example, `u8` can only be represented via the `U8` tag. -//! -//! - `I8` (`04`): 1-byte signed integer. -//! - `I16` (`05`): 2-byte big endian signed integer. -//! - `I32` (`06`): 4-byte big endian signed integer. -//! - `I64` (`07`): 8-byte big endian signed integer. -//! Similar to `U*` tags. Always uses two's complement encoding. -//! -//! - `Bool` (`08`): 1-byte boolean value, `00` for false and `01` for true. -//! -//! - `Char` (`09`): 4-byte big endian Unicode scalar value. -//! Surrogate pairs or out-of-bound values are invalid. -//! -//! - `F32` (`0a`): 4-byte big endian unsigned integer representing -//! IEEE 754 binary32 floating-point format. -//! - `F64` (`0b`): 8-byte big endian unsigned integer representing -//! IEEE 754 binary64 floating-point format. -//! -//! - `Sub8` (`0c`): 1-byte unsigned integer for supplementary information. -//! - `Sub32` (`0d`): 4-byte unsigned integer for supplementary information. -//! Those two tags normally occur as the first subdocument of certain tags, -//! namely `Enum`, `Vec` and `Map`, to provide a variant or size information. -//! They can be used interchangeably. -//! -//! Predefined tags with an explicit length: -//! -//! - `Str` (`10`): A UTF-8-encoded string. -//! -//! - `Enum` (`11`): An enum. -//! The first subdocument should be `Sub*` tags with a variant ID. -//! Subsequent subdocuments, if any, encode variant arguments. -//! -//! - `Vec` (`12`): A vector (sequence). -//! - `VecElt` (`13`): A vector element. -//! The first subdocument should be `Sub*` tags with the number of elements. -//! Subsequent subdocuments should be `VecElt` tag per each element. -//! -//! - `Map` (`14`): A map (associated array). -//! - `MapKey` (`15`): A key part of the map entry. -//! - `MapVal` (`16`): A value part of the map entry. -//! The first subdocument should be `Sub*` tags with the number of entries. -//! Subsequent subdocuments should be an alternating sequence of -//! `MapKey` and `MapVal` tags per each entry. -//! -//! - `Opaque` (`17`): An opaque, custom-format tag. -//! Used to wrap ordinary custom tags or data in the auto-serialized context. -//! Rustc typically uses this to encode type information. -//! -//! First 0x20 tags are reserved by RBML; custom tags start at 0x20. #[cfg(test)] use test::Bencher; -pub use self::EbmlEncoderTag::*; - -use std::char; -use std::isize; -use std::mem::transmute; +use std::fmt; use std::str; -use rustc_serialize as serialize; - -use rbml::Error; -use rbml::Error::*; - #[derive(Clone, Copy)] pub struct Doc<'a> { pub data: &'a [u8], @@ -142,6 +68,17 @@ impl<'doc> Doc<'doc> { } } + pub fn at(data: &'doc [u8], start: usize) -> Doc<'doc> { + let elt_tag = tag_at(data, start).unwrap(); + let elt_size = tag_len_at(data, elt_tag.next).unwrap(); + let end = elt_size.next + elt_size.val; + Doc { + data: data, + start: elt_size.next, + end: end, + } + } + pub fn get(&self, tag: usize) -> Doc<'doc> { get_doc(*self, tag) } @@ -159,54 +96,19 @@ impl<'doc> Doc<'doc> { } } -pub struct TaggedDoc<'a> { - tag: usize, - pub doc: Doc<'a>, +#[derive(Debug)] +pub enum Error { + IntTooBig(usize), + InvalidTag(usize) } -pub type DecodeResult = Result; - -#[derive(Copy, Clone, Debug)] -pub enum EbmlEncoderTag { - // tags 00..1f are reserved for auto-serialization. - // first NUM_IMPLICIT_TAGS tags are implicitly sized and lengths are not encoded. - EsU8 = 0x00, // + 1 byte - EsU16 = 0x01, // + 2 bytes - EsU32 = 0x02, // + 4 bytes - EsU64 = 0x03, // + 8 bytes - EsI8 = 0x04, // + 1 byte - EsI16 = 0x05, // + 2 bytes - EsI32 = 0x06, // + 4 bytes - EsI64 = 0x07, // + 8 bytes - EsBool = 0x08, // + 1 byte - EsChar = 0x09, // + 4 bytes - EsF32 = 0x0a, // + 4 bytes - EsF64 = 0x0b, // + 8 bytes - EsSub8 = 0x0c, // + 1 byte - EsSub32 = 0x0d, // + 4 bytes - // 0x0e and 0x0f are reserved - EsStr = 0x10, - EsEnum = 0x11, // encodes the variant id as the first EsSub* - EsVec = 0x12, // encodes the # of elements as the first EsSub* - EsVecElt = 0x13, - EsMap = 0x14, // encodes the # of pairs as the first EsSub* - EsMapKey = 0x15, - EsMapVal = 0x16, - EsOpaque = 0x17, +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // FIXME: this should be a more useful display form + fmt::Debug::fmt(self, f) + } } -pub const NUM_IMPLICIT_TAGS: usize = 0x0e; - -#[cfg_attr(rustfmt, rustfmt_skip)] -static TAG_IMPLICIT_LEN: [i8; NUM_IMPLICIT_TAGS] = [ - 1, 2, 4, 8, // EsU* - 1, 2, 4, 8, // ESI* - 1, // EsBool - 4, // EsChar - 4, 8, // EsF* - 1, 4, // EsSub* -]; - // rbml reading macro_rules! try_or { @@ -227,7 +129,7 @@ pub struct Res { pub next: usize, } -pub fn tag_at(data: &[u8], start: usize) -> DecodeResult { +pub fn tag_at(data: &[u8], start: usize) -> Result { let v = data[start] as usize; if v < 0xf0 { Ok(Res { @@ -241,12 +143,12 @@ pub fn tag_at(data: &[u8], start: usize) -> DecodeResult { }) } else { // every tag starting with byte 0xf0 is an overlong form, which is prohibited. - Err(InvalidTag(v)) + Err(Error::InvalidTag(v)) } } #[inline(never)] -fn vuint_at_slow(data: &[u8], start: usize) -> DecodeResult { +fn vuint_at_slow(data: &[u8], start: usize) -> Result { let a = data[start]; if a & 0x80 != 0 { return Ok(Res { @@ -275,10 +177,10 @@ fn vuint_at_slow(data: &[u8], start: usize) -> DecodeResult { next: start + 4, }); } - Err(IntTooBig(a as usize)) + Err(Error::IntTooBig(a as usize)) } -pub fn vuint_at(data: &[u8], start: usize) -> DecodeResult { +pub fn vuint_at(data: &[u8], start: usize) -> Result { if data.len() - start < 4 { return vuint_at_slow(data, start); } @@ -332,36 +234,15 @@ pub fn vuint_at(data: &[u8], start: usize) -> DecodeResult { } } -pub fn tag_len_at(data: &[u8], tag: Res) -> DecodeResult { - if tag.val < NUM_IMPLICIT_TAGS && TAG_IMPLICIT_LEN[tag.val] >= 0 { - Ok(Res { - val: TAG_IMPLICIT_LEN[tag.val] as usize, - next: tag.next, - }) - } else { - vuint_at(data, tag.next) - } -} - -pub fn doc_at<'a>(data: &'a [u8], start: usize) -> DecodeResult> { - let elt_tag = tag_at(data, start)?; - let elt_size = tag_len_at(data, elt_tag)?; - let end = elt_size.next + elt_size.val; - Ok(TaggedDoc { - tag: elt_tag.val, - doc: Doc { - data: data, - start: elt_size.next, - end: end, - }, - }) +pub fn tag_len_at(data: &[u8], next: usize) -> Result { + vuint_at(data, next) } pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: usize) -> Option> { let mut pos = d.start; while pos < d.end { let elt_tag = try_or!(tag_at(d.data, pos), None); - let elt_size = try_or!(tag_len_at(d.data, elt_tag), None); + let elt_size = try_or!(tag_len_at(d.data, elt_tag.next), None); pos = elt_size.next + elt_size.val; if elt_tag.val == tg { return Some(Doc { @@ -378,8 +259,7 @@ pub fn get_doc<'a>(d: Doc<'a>, tg: usize) -> Doc<'a> { match maybe_get_doc(d, tg) { Some(d) => d, None => { - error!("failed to find block with tag {:?}", tg); - panic!(); + bug!("failed to find block with tag {:?}", tg); } } } @@ -404,7 +284,7 @@ impl<'a> Iterator for DocsIterator<'a> { self.d.start = self.d.end; None }); - let elt_size = try_or!(tag_len_at(self.d.data, elt_tag), { + let elt_size = try_or!(tag_len_at(self.d.data, elt_tag.next), { self.d.start = self.d.end; None }); @@ -509,419 +389,6 @@ pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } -pub struct Decoder<'a> { - parent: Doc<'a>, - pos: usize, -} - -impl<'doc> Decoder<'doc> { - pub fn new(d: Doc<'doc>) -> Decoder<'doc> { - Decoder { - parent: d, - pos: d.start, - } - } - - fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult> { - debug!(". next_doc(exp_tag={:?})", exp_tag); - if self.pos >= self.parent.end { - return Err(Expected(format!("no more documents in current node!"))); - } - let TaggedDoc { tag: r_tag, doc: r_doc } = doc_at(self.parent.data, self.pos)?; - debug!("self.parent={:?}-{:?} self.pos={:?} r_tag={:?} r_doc={:?}-{:?}", - self.parent.start, - self.parent.end, - self.pos, - r_tag, - r_doc.start, - r_doc.end); - if r_tag != (exp_tag as usize) { - return Err(Expected(format!("expected EBML doc with tag {:?} but found tag {:?}", - exp_tag, - r_tag))); - } - if r_doc.end > self.parent.end { - return Err(Expected(format!("invalid EBML, child extends to {:#x}, parent to \ - {:#x}", - r_doc.end, - self.parent.end))); - } - self.pos = r_doc.end; - Ok(r_doc) - } - - fn _next_sub(&mut self) -> DecodeResult { - // empty vector/map optimization - if self.parent.is_empty() { - return Ok(0); - } - - let TaggedDoc { tag: r_tag, doc: r_doc } = doc_at(self.parent.data, self.pos)?; - let r = if r_tag == (EsSub8 as usize) { - doc_as_u8(r_doc) as usize - } else if r_tag == (EsSub32 as usize) { - doc_as_u32(r_doc) as usize - } else { - return Err(Expected(format!("expected EBML doc with tag {:?} or {:?} but found \ - tag {:?}", - EsSub8, - EsSub32, - r_tag))); - }; - if r_doc.end > self.parent.end { - return Err(Expected(format!("invalid EBML, child extends to {:#x}, parent to \ - {:#x}", - r_doc.end, - self.parent.end))); - } - self.pos = r_doc.end; - debug!("_next_sub result={:?}", r); - Ok(r) - } - - // variable-length unsigned integer with different tags. - // `last_tag` should be the largest allowed unsigned integer tag. - // all tags between them should be valid, in the order of u8, u16, u32 and u64. - fn next_uint(&mut self, - last_tag: EbmlEncoderTag) - -> DecodeResult { - if self.pos >= self.parent.end { - return Err(Expected(format!("no more documents in current node!"))); - } - - let TaggedDoc { tag: r_tag, doc: r_doc } = doc_at(self.parent.data, self.pos)?; - let r = if EsU8 as usize <= r_tag && r_tag <= last_tag as usize { - match r_tag - EsU8 as usize { - 0 => doc_as_u8(r_doc) as u64, - 1 => doc_as_u16(r_doc) as u64, - 2 => doc_as_u32(r_doc) as u64, - 3 => doc_as_u64(r_doc), - _ => unreachable!(), - } - } else { - return Err(Expected(format!("expected EBML doc with tag EsU8 through {:?} but \ - found tag {:?}", - last_tag, - r_tag))); - }; - if r_doc.end > self.parent.end { - return Err(Expected(format!("invalid EBML, child extends to {:#x}, parent to \ - {:#x}", - r_doc.end, - self.parent.end))); - } - self.pos = r_doc.end; - debug!("next_uint({:?}) result={:?}", last_tag, r); - Ok(r) - } - - // variable-length signed integer with different tags. - // `last_tag` should be the largest allowed signed integer tag. - // all tags between them should be valid, in the order of i8, i16, i32 and i64. - fn next_int(&mut self, - last_tag: EbmlEncoderTag) - -> DecodeResult { - if self.pos >= self.parent.end { - return Err(Expected(format!("no more documents in current node!"))); - } - - let TaggedDoc { tag: r_tag, doc: r_doc } = doc_at(self.parent.data, self.pos)?; - let r = if EsI8 as usize <= r_tag && r_tag <= last_tag as usize { - match r_tag - EsI8 as usize { - 0 => doc_as_i8(r_doc) as i64, - 1 => doc_as_i16(r_doc) as i64, - 2 => doc_as_i32(r_doc) as i64, - 3 => doc_as_i64(r_doc), - _ => unreachable!(), - } - } else { - return Err(Expected(format!("expected EBML doc with tag EsI8 through {:?} but \ - found tag {:?}", - last_tag, - r_tag))); - }; - if r_doc.end > self.parent.end { - return Err(Expected(format!("invalid EBML, child extends to {:#x}, parent to \ - {:#x}", - r_doc.end, - self.parent.end))); - } - self.pos = r_doc.end; - debug!("next_int({:?}) result={:?}", last_tag, r); - Ok(r) - } - - pub fn position(&self) -> usize { - self.pos - } - - pub fn advance(&mut self, bytes: usize) { - self.pos += bytes; - } -} - -impl<'doc, 'tcx> ::decoder::DecodeContext<'doc, 'tcx> { - pub fn read_opaque(&mut self, op: F) -> DecodeResult - where F: FnOnce(&mut Self, Doc) -> DecodeResult - { - let doc = self.next_doc(EsOpaque)?; - op(self, doc) - } - - fn push_doc(&mut self, exp_tag: EbmlEncoderTag, f: F) -> DecodeResult - where F: FnOnce(&mut Self) -> DecodeResult - { - let d = self.next_doc(exp_tag)?; - let old_parent = self.parent; - let old_pos = self.pos; - self.parent = d; - self.pos = d.start; - let r = f(self)?; - self.parent = old_parent; - self.pos = old_pos; - Ok(r) - } -} - -impl<'doc, 'tcx> serialize::Decoder for ::decoder::DecodeContext<'doc, 'tcx> { - type Error = Error; - fn read_nil(&mut self) -> DecodeResult<()> { - Ok(()) - } - - fn read_u64(&mut self) -> DecodeResult { - self.next_uint(EsU64) - } - fn read_u32(&mut self) -> DecodeResult { - Ok(self.next_uint(EsU32)? as u32) - } - fn read_u16(&mut self) -> DecodeResult { - Ok(self.next_uint(EsU16)? as u16) - } - fn read_u8(&mut self) -> DecodeResult { - Ok(doc_as_u8(self.next_doc(EsU8)?)) - } - fn read_usize(&mut self) -> DecodeResult { - let v = self.read_u64()?; - if v > (::std::usize::MAX as u64) { - Err(IntTooBig(v as usize)) - } else { - Ok(v as usize) - } - } - - fn read_i64(&mut self) -> DecodeResult { - Ok(self.next_int(EsI64)? as i64) - } - fn read_i32(&mut self) -> DecodeResult { - Ok(self.next_int(EsI32)? as i32) - } - fn read_i16(&mut self) -> DecodeResult { - Ok(self.next_int(EsI16)? as i16) - } - fn read_i8(&mut self) -> DecodeResult { - Ok(doc_as_u8(self.next_doc(EsI8)?) as i8) - } - fn read_isize(&mut self) -> DecodeResult { - let v = self.next_int(EsI64)? as i64; - if v > (isize::MAX as i64) || v < (isize::MIN as i64) { - debug!("FIXME \\#6122: Removing this makes this function miscompile"); - Err(IntTooBig(v as usize)) - } else { - Ok(v as isize) - } - } - - fn read_bool(&mut self) -> DecodeResult { - Ok(doc_as_u8(self.next_doc(EsBool)?) != 0) - } - - fn read_f64(&mut self) -> DecodeResult { - let bits = doc_as_u64(self.next_doc(EsF64)?); - Ok(unsafe { transmute(bits) }) - } - fn read_f32(&mut self) -> DecodeResult { - let bits = doc_as_u32(self.next_doc(EsF32)?); - Ok(unsafe { transmute(bits) }) - } - fn read_char(&mut self) -> DecodeResult { - Ok(char::from_u32(doc_as_u32(self.next_doc(EsChar)?)).unwrap()) - } - fn read_str(&mut self) -> DecodeResult { - Ok(self.next_doc(EsStr)?.to_string()) - } - - // Compound types: - fn read_enum(&mut self, name: &str, f: F) -> DecodeResult - where F: FnOnce(&mut Self) -> DecodeResult - { - debug!("read_enum({})", name); - - let doc = self.next_doc(EsEnum)?; - - let (old_parent, old_pos) = (self.parent, self.pos); - self.parent = doc; - self.pos = self.parent.start; - - let result = f(self)?; - - self.parent = old_parent; - self.pos = old_pos; - Ok(result) - } - - fn read_enum_variant(&mut self, _: &[&str], mut f: F) -> DecodeResult - where F: FnMut(&mut Self, usize) -> DecodeResult - { - debug!("read_enum_variant()"); - let idx = self._next_sub()?; - debug!(" idx={}", idx); - - f(self, idx) - } - - fn read_enum_variant_arg(&mut self, idx: usize, f: F) -> DecodeResult - where F: FnOnce(&mut Self) -> DecodeResult - { - debug!("read_enum_variant_arg(idx={})", idx); - f(self) - } - - fn read_enum_struct_variant(&mut self, _: &[&str], mut f: F) -> DecodeResult - where F: FnMut(&mut Self, usize) -> DecodeResult - { - debug!("read_enum_struct_variant()"); - let idx = self._next_sub()?; - debug!(" idx={}", idx); - - f(self, idx) - } - - fn read_enum_struct_variant_field(&mut self, - name: &str, - idx: usize, - f: F) - -> DecodeResult - where F: FnOnce(&mut Self) -> DecodeResult - { - debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx); - f(self) - } - - fn read_struct(&mut self, name: &str, _: usize, f: F) -> DecodeResult - where F: FnOnce(&mut Self) -> DecodeResult - { - debug!("read_struct(name={})", name); - f(self) - } - - fn read_struct_field(&mut self, name: &str, idx: usize, f: F) -> DecodeResult - where F: FnOnce(&mut Self) -> DecodeResult - { - debug!("read_struct_field(name={}, idx={})", name, idx); - f(self) - } - - fn read_tuple(&mut self, tuple_len: usize, f: F) -> DecodeResult - where F: FnOnce(&mut Self) -> DecodeResult - { - debug!("read_tuple()"); - self.read_seq(move |d, len| { - if len == tuple_len { - f(d) - } else { - Err(Expected(format!("Expected tuple of length `{}`, found tuple of length \ - `{}`", - tuple_len, - len))) - } - }) - } - - fn read_tuple_arg(&mut self, idx: usize, f: F) -> DecodeResult - where F: FnOnce(&mut Self) -> DecodeResult - { - debug!("read_tuple_arg(idx={})", idx); - self.read_seq_elt(idx, f) - } - - fn read_tuple_struct(&mut self, name: &str, len: usize, f: F) -> DecodeResult - where F: FnOnce(&mut Self) -> DecodeResult - { - debug!("read_tuple_struct(name={})", name); - self.read_tuple(len, f) - } - - fn read_tuple_struct_arg(&mut self, idx: usize, f: F) -> DecodeResult - where F: FnOnce(&mut Self) -> DecodeResult - { - debug!("read_tuple_struct_arg(idx={})", idx); - self.read_tuple_arg(idx, f) - } - - fn read_option(&mut self, mut f: F) -> DecodeResult - where F: FnMut(&mut Self, bool) -> DecodeResult - { - debug!("read_option()"); - self.read_enum("Option", move |this| { - this.read_enum_variant(&["None", "Some"], move |this, idx| { - match idx { - 0 => f(this, false), - 1 => f(this, true), - _ => Err(Expected(format!("Expected None or Some"))), - } - }) - }) - } - - fn read_seq(&mut self, f: F) -> DecodeResult - where F: FnOnce(&mut Self, usize) -> DecodeResult - { - debug!("read_seq()"); - self.push_doc(EsVec, move |d| { - let len = d._next_sub()?; - debug!(" len={}", len); - f(d, len) - }) - } - - fn read_seq_elt(&mut self, idx: usize, f: F) -> DecodeResult - where F: FnOnce(&mut Self) -> DecodeResult - { - debug!("read_seq_elt(idx={})", idx); - self.push_doc(EsVecElt, f) - } - - fn read_map(&mut self, f: F) -> DecodeResult - where F: FnOnce(&mut Self, usize) -> DecodeResult - { - debug!("read_map()"); - self.push_doc(EsMap, move |d| { - let len = d._next_sub()?; - debug!(" len={}", len); - f(d, len) - }) - } - - fn read_map_elt_key(&mut self, idx: usize, f: F) -> DecodeResult - where F: FnOnce(&mut Self) -> DecodeResult - { - debug!("read_map_elt_key(idx={})", idx); - self.push_doc(EsMapKey, f) - } - - fn read_map_elt_val(&mut self, idx: usize, f: F) -> DecodeResult - where F: FnOnce(&mut Self) -> DecodeResult - { - debug!("read_map_elt_val(idx={})", idx); - self.push_doc(EsMapVal, f) - } - - fn error(&mut self, err: &str) -> Error { - ApplicationError(err.to_string()) - } -} - #[test] fn test_vuint_at() { let data = &[ diff --git a/src/librustc_metadata/rbml/writer.rs b/src/librustc_metadata/rbml/writer.rs index f22a9d1cd00..94e9b394f1f 100644 --- a/src/librustc_metadata/rbml/writer.rs +++ b/src/librustc_metadata/rbml/writer.rs @@ -12,19 +12,15 @@ use std::mem; use std::io::prelude::*; use std::io::{self, SeekFrom, Cursor}; -use rbml::opaque; -use rbml::reader::EbmlEncoderTag::*; -use rbml::reader::NUM_IMPLICIT_TAGS; - -use rustc_serialize as serialize; +use rustc_serialize::opaque; pub type EncodeResult = io::Result<()>; // rbml writing -pub struct Encoder { - pub writer: Cursor>, - size_positions: Vec, - relax_limit: u64, // do not move encoded bytes before this position +pub struct Encoder<'a> { + pub opaque: opaque::Encoder<'a>, + size_positions: Vec, + relax_limit: usize, // do not move encoded bytes before this position } const NUM_TAGS: usize = 0x1000; @@ -65,10 +61,10 @@ pub fn write_vuint(w: &mut W, n: usize) -> EncodeResult { Err(io::Error::new(io::ErrorKind::Other, &format!("isize too big: {}", n)[..])) } -impl Encoder { - pub fn new() -> Encoder { +impl<'a> Encoder<'a> { + pub fn new(cursor: &'a mut Cursor>) -> Encoder<'a> { Encoder { - writer: Cursor::new(vec![]), + opaque: opaque::Encoder::new(cursor), size_positions: vec![], relax_limit: 0, } @@ -76,23 +72,21 @@ impl Encoder { pub fn start_tag(&mut self, tag_id: usize) -> EncodeResult { debug!("Start tag {:?}", tag_id); - assert!(tag_id >= NUM_IMPLICIT_TAGS); // Write the enum ID: - write_tag(&mut self.writer, tag_id)?; + write_tag(&mut self.opaque.cursor, tag_id)?; // Write a placeholder four-byte size. - let cur_pos = self.writer.seek(SeekFrom::Current(0))?; + let cur_pos = self.position(); self.size_positions.push(cur_pos); - let zeroes: &[u8] = &[0, 0, 0, 0]; - self.writer.write_all(zeroes) + self.opaque.cursor.write_all(&[0, 0, 0, 0]) } pub fn end_tag(&mut self) -> EncodeResult { let last_size_pos = self.size_positions.pop().unwrap(); - let cur_pos = self.writer.seek(SeekFrom::Current(0))?; - self.writer.seek(SeekFrom::Start(last_size_pos))?; - let size = (cur_pos - last_size_pos - 4) as usize; + let cur_pos = self.position(); + self.opaque.cursor.seek(SeekFrom::Start(last_size_pos as u64))?; + let size = cur_pos - last_size_pos - 4; // relax the size encoding for small tags (bigger tags are costly to move). // we should never try to move the stable positions, however. @@ -101,18 +95,17 @@ impl Encoder { // we can't alter the buffer in place, so have a temporary buffer let mut buf = [0u8; RELAX_MAX_SIZE]; { - let last_size_pos = last_size_pos as usize; - let data = &self.writer.get_ref()[last_size_pos + 4..cur_pos as usize]; + let data = &self.opaque.cursor.get_ref()[last_size_pos + 4..cur_pos]; buf[..size].copy_from_slice(data); } // overwrite the size and data and continue - write_vuint(&mut self.writer, size)?; - self.writer.write_all(&buf[..size])?; + write_vuint(&mut self.opaque.cursor, size)?; + self.opaque.cursor.write_all(&buf[..size])?; } else { // overwrite the size with an overlong encoding and skip past the data - write_sized_vuint(&mut self.writer, size, 4)?; - self.writer.seek(SeekFrom::Start(cur_pos))?; + write_sized_vuint(&mut self.opaque.cursor, size, 4)?; + self.opaque.cursor.seek(SeekFrom::Start(cur_pos as u64))?; } debug!("End tag (size = {:?})", size); @@ -128,10 +121,9 @@ impl Encoder { } pub fn wr_tagged_bytes(&mut self, tag_id: usize, b: &[u8]) -> EncodeResult { - assert!(tag_id >= NUM_IMPLICIT_TAGS); - write_tag(&mut self.writer, tag_id)?; - write_vuint(&mut self.writer, b.len())?; - self.writer.write_all(b) + write_tag(&mut self.opaque.cursor, tag_id)?; + write_vuint(&mut self.opaque.cursor, b.len())?; + self.opaque.cursor.write_all(b) } pub fn wr_tagged_u64(&mut self, tag_id: usize, v: u64) -> EncodeResult { @@ -147,344 +139,37 @@ impl Encoder { self.wr_tagged_u64(tag_id, v as u64) } - #[inline] - pub fn wr_tagged_u16(&mut self, tag_id: usize, v: u16) -> EncodeResult { - self.wr_tagged_u64(tag_id, v as u64) - } - #[inline] pub fn wr_tagged_u8(&mut self, tag_id: usize, v: u8) -> EncodeResult { self.wr_tagged_bytes(tag_id, &[v]) } - #[inline] - pub fn wr_tagged_i64(&mut self, tag_id: usize, v: i64) -> EncodeResult { - self.wr_tagged_u64(tag_id, v as u64) - } - - #[inline] - pub fn wr_tagged_i32(&mut self, tag_id: usize, v: i32) -> EncodeResult { - self.wr_tagged_u32(tag_id, v as u32) - } - - #[inline] - pub fn wr_tagged_i16(&mut self, tag_id: usize, v: i16) -> EncodeResult { - self.wr_tagged_u16(tag_id, v as u16) - } - - #[inline] - pub fn wr_tagged_i8(&mut self, tag_id: usize, v: i8) -> EncodeResult { - self.wr_tagged_bytes(tag_id, &[v as u8]) - } - pub fn wr_tagged_str(&mut self, tag_id: usize, v: &str) -> EncodeResult { self.wr_tagged_bytes(tag_id, v.as_bytes()) } - // for auto-serialization - fn wr_tagged_raw_bytes(&mut self, tag_id: usize, b: &[u8]) -> EncodeResult { - write_tag(&mut self.writer, tag_id)?; - self.writer.write_all(b) - } - - fn wr_tagged_raw_u64(&mut self, tag_id: usize, v: u64) -> EncodeResult { - let bytes: [u8; 8] = unsafe { mem::transmute(v.to_be()) }; - self.wr_tagged_raw_bytes(tag_id, &bytes) - } - - fn wr_tagged_raw_u32(&mut self, tag_id: usize, v: u32) -> EncodeResult { - let bytes: [u8; 4] = unsafe { mem::transmute(v.to_be()) }; - self.wr_tagged_raw_bytes(tag_id, &bytes) - } - - fn wr_tagged_raw_u16(&mut self, tag_id: usize, v: u16) -> EncodeResult { - let bytes: [u8; 2] = unsafe { mem::transmute(v.to_be()) }; - self.wr_tagged_raw_bytes(tag_id, &bytes) - } - - fn wr_tagged_raw_u8(&mut self, tag_id: usize, v: u8) -> EncodeResult { - self.wr_tagged_raw_bytes(tag_id, &[v]) - } - - fn wr_tagged_raw_i64(&mut self, tag_id: usize, v: i64) -> EncodeResult { - self.wr_tagged_raw_u64(tag_id, v as u64) - } - - fn wr_tagged_raw_i32(&mut self, tag_id: usize, v: i32) -> EncodeResult { - self.wr_tagged_raw_u32(tag_id, v as u32) - } - - fn wr_tagged_raw_i16(&mut self, tag_id: usize, v: i16) -> EncodeResult { - self.wr_tagged_raw_u16(tag_id, v as u16) - } - - fn wr_tagged_raw_i8(&mut self, tag_id: usize, v: i8) -> EncodeResult { - self.wr_tagged_raw_bytes(tag_id, &[v as u8]) - } - pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult { debug!("Write {:?} bytes", b.len()); - self.writer.write_all(b) + self.opaque.cursor.write_all(b) } pub fn wr_str(&mut self, s: &str) -> EncodeResult { debug!("Write str: {:?}", s); - self.writer.write_all(s.as_bytes()) + self.opaque.cursor.write_all(s.as_bytes()) + } + + pub fn position(&mut self) -> usize { + self.opaque.position() as usize } /// Returns the current position while marking it stable, i.e. /// generated bytes so far wouldn't be affected by relaxation. - pub fn mark_stable_position(&mut self) -> u64 { - let pos = self.writer.seek(SeekFrom::Current(0)).unwrap(); + pub fn mark_stable_position(&mut self) -> usize { + let pos = self.position(); if self.relax_limit < pos { self.relax_limit = pos; } - pos - } - - // used internally to emit things like the vector length and so on - fn _emit_tagged_sub(&mut self, v: usize) -> EncodeResult { - if v as u8 as usize == v { - self.wr_tagged_raw_u8(EsSub8 as usize, v as u8) - } else if v as u32 as usize == v { - self.wr_tagged_raw_u32(EsSub32 as usize, v as u32) - } else { - Err(io::Error::new(io::ErrorKind::Other, - &format!("length or variant id too big: {}", v)[..])) - } - } - - pub fn emit_opaque(&mut self, f: F) -> EncodeResult - where F: FnOnce(&mut opaque::Encoder) -> EncodeResult - { - self.start_tag(EsOpaque as usize)?; - f(&mut opaque::Encoder::new(&mut self.writer))?; - self.mark_stable_position(); - self.end_tag() - } -} - -impl<'a, 'tcx> serialize::Encoder for ::encoder::EncodeContext<'a, 'tcx> { - type Error = io::Error; - - fn emit_nil(&mut self) -> EncodeResult { - Ok(()) - } - - fn emit_usize(&mut self, v: usize) -> EncodeResult { - self.emit_u64(v as u64) - } - fn emit_u64(&mut self, v: u64) -> EncodeResult { - if v as u32 as u64 == v { - self.emit_u32(v as u32) - } else { - self.wr_tagged_raw_u64(EsU64 as usize, v) - } - } - fn emit_u32(&mut self, v: u32) -> EncodeResult { - if v as u16 as u32 == v { - self.emit_u16(v as u16) - } else { - self.wr_tagged_raw_u32(EsU32 as usize, v) - } - } - fn emit_u16(&mut self, v: u16) -> EncodeResult { - if v as u8 as u16 == v { - self.emit_u8(v as u8) - } else { - self.wr_tagged_raw_u16(EsU16 as usize, v) - } - } - fn emit_u8(&mut self, v: u8) -> EncodeResult { - self.wr_tagged_raw_u8(EsU8 as usize, v) - } - - fn emit_isize(&mut self, v: isize) -> EncodeResult { - self.emit_i64(v as i64) - } - fn emit_i64(&mut self, v: i64) -> EncodeResult { - if v as i32 as i64 == v { - self.emit_i32(v as i32) - } else { - self.wr_tagged_raw_i64(EsI64 as usize, v) - } - } - fn emit_i32(&mut self, v: i32) -> EncodeResult { - if v as i16 as i32 == v { - self.emit_i16(v as i16) - } else { - self.wr_tagged_raw_i32(EsI32 as usize, v) - } - } - fn emit_i16(&mut self, v: i16) -> EncodeResult { - if v as i8 as i16 == v { - self.emit_i8(v as i8) - } else { - self.wr_tagged_raw_i16(EsI16 as usize, v) - } - } - fn emit_i8(&mut self, v: i8) -> EncodeResult { - self.wr_tagged_raw_i8(EsI8 as usize, v) - } - - fn emit_bool(&mut self, v: bool) -> EncodeResult { - self.wr_tagged_raw_u8(EsBool as usize, v as u8) - } - - fn emit_f64(&mut self, v: f64) -> EncodeResult { - let bits = unsafe { mem::transmute(v) }; - self.wr_tagged_raw_u64(EsF64 as usize, bits) - } - fn emit_f32(&mut self, v: f32) -> EncodeResult { - let bits = unsafe { mem::transmute(v) }; - self.wr_tagged_raw_u32(EsF32 as usize, bits) - } - fn emit_char(&mut self, v: char) -> EncodeResult { - self.wr_tagged_raw_u32(EsChar as usize, v as u32) - } - - fn emit_str(&mut self, v: &str) -> EncodeResult { - self.wr_tagged_str(EsStr as usize, v) - } - - fn emit_enum(&mut self, _name: &str, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - self.start_tag(EsEnum as usize)?; - f(self)?; - self.end_tag() - } - - fn emit_enum_variant(&mut self, _: &str, v_id: usize, _: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - self._emit_tagged_sub(v_id)?; - f(self) - } - - fn emit_enum_variant_arg(&mut self, _: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - f(self) - } - - fn emit_enum_struct_variant(&mut self, - v_name: &str, - v_id: usize, - cnt: usize, - f: F) - -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - self.emit_enum_variant(v_name, v_id, cnt, f) - } - - fn emit_enum_struct_variant_field(&mut self, _: &str, idx: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - self.emit_enum_variant_arg(idx, f) - } - - fn emit_struct(&mut self, _: &str, _len: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - f(self) - } - - fn emit_struct_field(&mut self, _name: &str, _: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - f(self) - } - - fn emit_tuple(&mut self, len: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - self.emit_seq(len, f) - } - fn emit_tuple_arg(&mut self, idx: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - self.emit_seq_elt(idx, f) - } - - fn emit_tuple_struct(&mut self, _: &str, len: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - self.emit_seq(len, f) - } - fn emit_tuple_struct_arg(&mut self, idx: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - self.emit_seq_elt(idx, f) - } - - fn emit_option(&mut self, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - self.emit_enum("Option", f) - } - fn emit_option_none(&mut self) -> EncodeResult { - self.emit_enum_variant("None", 0, 0, |_| Ok(())) - } - fn emit_option_some(&mut self, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - - self.emit_enum_variant("Some", 1, 1, f) - } - - fn emit_seq(&mut self, len: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - if len == 0 { - // empty vector optimization - return self.wr_tagged_bytes(EsVec as usize, &[]); - } - - self.start_tag(EsVec as usize)?; - self._emit_tagged_sub(len)?; - f(self)?; - self.end_tag() - } - - fn emit_seq_elt(&mut self, _idx: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - - self.start_tag(EsVecElt as usize)?; - f(self)?; - self.end_tag() - } - - fn emit_map(&mut self, len: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - if len == 0 { - // empty map optimization - return self.wr_tagged_bytes(EsMap as usize, &[]); - } - - self.start_tag(EsMap as usize)?; - self._emit_tagged_sub(len)?; - f(self)?; - self.end_tag() - } - - fn emit_map_elt_key(&mut self, _idx: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - - self.start_tag(EsMapKey as usize)?; - f(self)?; - self.end_tag() - } - - fn emit_map_elt_val(&mut self, _idx: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - self.start_tag(EsMapVal as usize)?; - f(self)?; - self.end_tag() + let meta_start = 8 + ::common::metadata_encoding_version.len(); + pos - meta_start } } diff --git a/src/librustc_metadata/tydecode.rs b/src/librustc_metadata/tydecode.rs index 6d3b8571d3c..28e7b8852b3 100644 --- a/src/librustc_metadata/tydecode.rs +++ b/src/librustc_metadata/tydecode.rs @@ -24,7 +24,7 @@ use rustc::ty::subst::{Kind, Substs}; use rustc::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rbml; -use rbml::leb128; +use rustc_serialize::leb128; use std::str; use syntax::abi; use syntax::ast; diff --git a/src/librustc_metadata/tyencode.rs b/src/librustc_metadata/tyencode.rs index 73996518a15..8cd18d1bfc7 100644 --- a/src/librustc_metadata/tyencode.rs +++ b/src/librustc_metadata/tyencode.rs @@ -28,7 +28,7 @@ use rustc::hir; use syntax::abi::Abi; use syntax::ast; -use rbml::leb128; +use rustc_serialize::leb128; use encoder; pub struct ctxt<'a, 'tcx: 'a> { @@ -186,9 +186,10 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Cursor>, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx abbrev.write_all(b"#"); { let start_position = abbrev.position() as usize; + let meta_start = 8 + ::common::metadata_encoding_version.len() as u64; let bytes_written = leb128::write_unsigned_leb128(abbrev.get_mut(), start_position, - pos); + pos - meta_start); abbrev.set_position((start_position + bytes_written) as u64); } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index a6581ae605b..a10f8c77ac0 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -1346,8 +1346,7 @@ fn write_metadata(cx: &SharedCrateContext, cx.export_map(), cx.link_meta(), reachable_ids, - cx.mir_map(), - cx.tcx().map.krate()); + cx.mir_map()); let mut compressed = cstore.metadata_encoding_version().to_vec(); compressed.extend_from_slice(&flate::deflate_bytes(&metadata)); diff --git a/src/librbml/leb128.rs b/src/libserialize/leb128.rs similarity index 100% rename from src/librbml/leb128.rs rename to src/libserialize/leb128.rs diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 7082ee5d292..7cb02e2412c 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -56,6 +56,9 @@ mod collection_impls; pub mod hex; pub mod json; +pub mod opaque; +pub mod leb128; + mod rustc_serialize { pub use serialize::*; } diff --git a/src/librbml/opaque.rs b/src/libserialize/opaque.rs similarity index 64% rename from src/librbml/opaque.rs rename to src/libserialize/opaque.rs index 55ab2afe445..e97834f63ce 100644 --- a/src/librbml/opaque.rs +++ b/src/libserialize/opaque.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use Error as DecodeError; use leb128::{read_signed_leb128, read_unsigned_leb128, write_signed_leb128, write_unsigned_leb128}; use std::io::{self, Write}; use serialize; @@ -125,131 +124,6 @@ impl<'a> serialize::Encoder for Encoder<'a> { let _ = self.cursor.write_all(v.as_bytes()); Ok(()) } - - fn emit_enum(&mut self, _name: &str, f: F) -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - f(self) - } - - fn emit_enum_variant(&mut self, - _v_name: &str, - v_id: usize, - _len: usize, - f: F) - -> EncodeResult - where F: FnOnce(&mut Self) -> EncodeResult - { - self.emit_usize(v_id)?; - f(self) - } - - fn emit_enum_variant_arg(&mut self, _: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - f(self) - } - - fn emit_enum_struct_variant(&mut self, - v_name: &str, - v_id: usize, - cnt: usize, - f: F) - -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - self.emit_enum_variant(v_name, v_id, cnt, f) - } - - fn emit_enum_struct_variant_field(&mut self, _: &str, idx: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - self.emit_enum_variant_arg(idx, f) - } - - fn emit_struct(&mut self, _: &str, _len: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - f(self) - } - - fn emit_struct_field(&mut self, _name: &str, _: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - f(self) - } - - fn emit_tuple(&mut self, len: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - self.emit_seq(len, f) - } - - fn emit_tuple_arg(&mut self, idx: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - self.emit_seq_elt(idx, f) - } - - fn emit_tuple_struct(&mut self, _: &str, len: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - self.emit_seq(len, f) - } - - fn emit_tuple_struct_arg(&mut self, idx: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - self.emit_seq_elt(idx, f) - } - - fn emit_option(&mut self, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - self.emit_enum("Option", f) - } - - fn emit_option_none(&mut self) -> EncodeResult { - self.emit_enum_variant("None", 0, 0, |_| Ok(())) - } - - fn emit_option_some(&mut self, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - self.emit_enum_variant("Some", 1, 1, f) - } - - fn emit_seq(&mut self, len: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - self.emit_usize(len)?; - f(self) - } - - fn emit_seq_elt(&mut self, _idx: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - f(self) - } - - fn emit_map(&mut self, len: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - self.emit_usize(len)?; - f(self) - } - - fn emit_map_elt_key(&mut self, _idx: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - f(self) - } - - fn emit_map_elt_val(&mut self, _idx: usize, f: F) -> EncodeResult - where F: FnOnce(&mut Encoder<'a>) -> EncodeResult - { - f(self) - } } impl<'a> Encoder<'a> { @@ -302,7 +176,7 @@ macro_rules! read_sleb128 { impl<'a> serialize::Decoder for Decoder<'a> { - type Error = DecodeError; + type Error = String; fn read_nil(&mut self) -> Result<(), Self::Error> { Ok(()) @@ -379,138 +253,8 @@ impl<'a> serialize::Decoder for Decoder<'a> { Ok(s.to_string()) } - fn read_enum(&mut self, _name: &str, f: F) -> Result - where F: FnOnce(&mut Decoder<'a>) -> Result - { - f(self) - } - - fn read_enum_variant(&mut self, _: &[&str], mut f: F) -> Result - where F: FnMut(&mut Decoder<'a>, usize) -> Result - { - let disr = self.read_usize()?; - f(self, disr) - } - - fn read_enum_variant_arg(&mut self, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Decoder<'a>) -> Result - { - f(self) - } - - fn read_enum_struct_variant(&mut self, _: &[&str], mut f: F) -> Result - where F: FnMut(&mut Decoder<'a>, usize) -> Result - { - let disr = self.read_usize()?; - f(self, disr) - } - - fn read_enum_struct_variant_field(&mut self, - _name: &str, - _idx: usize, - f: F) - -> Result - where F: FnOnce(&mut Decoder<'a>) -> Result - { - f(self) - } - - fn read_struct(&mut self, _name: &str, _: usize, f: F) -> Result - where F: FnOnce(&mut Decoder<'a>) -> Result - { - f(self) - } - - fn read_struct_field(&mut self, _name: &str, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Decoder<'a>) -> Result - { - f(self) - } - - fn read_tuple(&mut self, tuple_len: usize, f: F) -> Result - where F: FnOnce(&mut Decoder<'a>) -> Result - { - self.read_seq(move |d, len| { - if len == tuple_len { - f(d) - } else { - let err = format!("Invalid tuple length. Expected {}, found {}", - tuple_len, - len); - Err(DecodeError::Expected(err)) - } - }) - } - - fn read_tuple_arg(&mut self, idx: usize, f: F) -> Result - where F: FnOnce(&mut Decoder<'a>) -> Result - { - self.read_seq_elt(idx, f) - } - - fn read_tuple_struct(&mut self, _name: &str, len: usize, f: F) -> Result - where F: FnOnce(&mut Decoder<'a>) -> Result - { - self.read_tuple(len, f) - } - - fn read_tuple_struct_arg(&mut self, idx: usize, f: F) -> Result - where F: FnOnce(&mut Decoder<'a>) -> Result - { - self.read_tuple_arg(idx, f) - } - - fn read_option(&mut self, mut f: F) -> Result - where F: FnMut(&mut Decoder<'a>, bool) -> Result - { - self.read_enum("Option", move |this| { - this.read_enum_variant(&["None", "Some"], move |this, idx| { - match idx { - 0 => f(this, false), - 1 => f(this, true), - _ => { - let msg = format!("Invalid Option index: {}", idx); - Err(DecodeError::Expected(msg)) - } - } - }) - }) - } - - fn read_seq(&mut self, f: F) -> Result - where F: FnOnce(&mut Decoder<'a>, usize) -> Result - { - let len = self.read_usize()?; - f(self, len) - } - - fn read_seq_elt(&mut self, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Decoder<'a>) -> Result - { - f(self) - } - - fn read_map(&mut self, f: F) -> Result - where F: FnOnce(&mut Decoder<'a>, usize) -> Result - { - let len = self.read_usize()?; - f(self, len) - } - - fn read_map_elt_key(&mut self, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Decoder<'a>) -> Result - { - f(self) - } - - fn read_map_elt_val(&mut self, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Decoder<'a>) -> Result - { - f(self) - } - fn error(&mut self, err: &str) -> Self::Error { - DecodeError::ApplicationError(err.to_string()) + err.to_string() } } diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index ba6eefe82bb..88f6c12e980 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -42,66 +42,99 @@ pub trait Encoder { fn emit_str(&mut self, v: &str) -> Result<(), Self::Error>; // Compound types: - fn emit_enum(&mut self, name: &str, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + fn emit_enum(&mut self, _name: &str, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) } - fn emit_enum_variant(&mut self, v_name: &str, + fn emit_enum_variant(&mut self, _v_name: &str, v_id: usize, - len: usize, + _len: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - fn emit_enum_variant_arg(&mut self, a_idx: usize, f: F) + where F: FnOnce(&mut Self) -> Result<(), Self::Error> + { + self.emit_usize(v_id)?; + f(self) + } + fn emit_enum_variant_arg(&mut self, _a_idx: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) } fn emit_enum_struct_variant(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + where F: FnOnce(&mut Self) -> Result<(), Self::Error> + { + self.emit_enum_variant(v_name, v_id, len, f) + } fn emit_enum_struct_variant_field(&mut self, - f_name: &str, + _f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + where F: FnOnce(&mut Self) -> Result<(), Self::Error> + { + self.emit_enum_variant_arg(f_idx, f) + } - fn emit_struct(&mut self, name: &str, len: usize, f: F) + fn emit_struct(&mut self, _name: &str, _len: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - fn emit_struct_field(&mut self, f_name: &str, f_idx: usize, f: F) + where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) } + fn emit_struct_field(&mut self, _f_name: &str, _f_idx: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) } - fn emit_tuple(&mut self, len: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - fn emit_tuple_arg(&mut self, idx: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + fn emit_tuple(&mut self, _len: usize, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) } + fn emit_tuple_arg(&mut self, _idx: usize, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) } - fn emit_tuple_struct(&mut self, name: &str, len: usize, f: F) + fn emit_tuple_struct(&mut self, _name: &str, len: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + where F: FnOnce(&mut Self) -> Result<(), Self::Error> + { + self.emit_tuple(len, f) + } fn emit_tuple_struct_arg(&mut self, f_idx: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + where F: FnOnce(&mut Self) -> Result<(), Self::Error> + { + self.emit_tuple_arg(f_idx, f) + } // Specialized types: fn emit_option(&mut self, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - fn emit_option_none(&mut self) -> Result<(), Self::Error>; + where F: FnOnce(&mut Self) -> Result<(), Self::Error> + { + self.emit_enum("Option", f) + } + fn emit_option_none(&mut self) -> Result<(), Self::Error> { + self.emit_enum_variant("None", 0, 0, |_| Ok(())) + } fn emit_option_some(&mut self, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + where F: FnOnce(&mut Self) -> Result<(), Self::Error> + { + + self.emit_enum_variant("Some", 1, 1, f) + } fn emit_seq(&mut self, len: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - fn emit_seq_elt(&mut self, idx: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + where F: FnOnce(&mut Self) -> Result<(), Self::Error> + { + self.emit_usize(len)?; + f(self) + } + fn emit_seq_elt(&mut self, _idx: usize, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) } fn emit_map(&mut self, len: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - fn emit_map_elt_key(&mut self, idx: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - fn emit_map_elt_val(&mut self, idx: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + where F: FnOnce(&mut Self) -> Result<(), Self::Error> + { + self.emit_usize(len)?; + f(self) + } + fn emit_map_elt_key(&mut self, _idx: usize, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) } + fn emit_map_elt_val(&mut self, _idx: usize, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) } } pub trait Decoder { @@ -126,66 +159,101 @@ pub trait Decoder { fn read_str(&mut self) -> Result; // Compound types: - fn read_enum(&mut self, name: &str, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; + fn read_enum(&mut self, _name: &str, f: F) -> Result + where F: FnOnce(&mut Self) -> Result { f(self) } - fn read_enum_variant(&mut self, names: &[&str], f: F) + fn read_enum_variant(&mut self, _names: &[&str], mut f: F) -> Result - where F: FnMut(&mut Self, usize) -> Result; - fn read_enum_variant_arg(&mut self, a_idx: usize, f: F) + where F: FnMut(&mut Self, usize) -> Result + { + let disr = self.read_usize()?; + f(self, disr) + } + fn read_enum_variant_arg(&mut self, _a_idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; + where F: FnOnce(&mut Self) -> Result { f(self) } fn read_enum_struct_variant(&mut self, names: &[&str], f: F) -> Result - where F: FnMut(&mut Self, usize) -> Result; + where F: FnMut(&mut Self, usize) -> Result + { + self.read_enum_variant(names, f) + } fn read_enum_struct_variant_field(&mut self, - &f_name: &str, + _f_name: &str, f_idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; + where F: FnOnce(&mut Self) -> Result + { + self.read_enum_variant_arg(f_idx, f) + } - fn read_struct(&mut self, s_name: &str, len: usize, f: F) + fn read_struct(&mut self, _s_name: &str, _len: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; + where F: FnOnce(&mut Self) -> Result { f(self) } fn read_struct_field(&mut self, - f_name: &str, - f_idx: usize, + _f_name: &str, + _f_idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; + where F: FnOnce(&mut Self) -> Result { f(self) } - fn read_tuple(&mut self, len: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; - fn read_tuple_arg(&mut self, a_idx: usize, f: F) + fn read_tuple(&mut self, _len: usize, f: F) -> Result + where F: FnOnce(&mut Self) -> Result { f(self) } + fn read_tuple_arg(&mut self, _a_idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; + where F: FnOnce(&mut Self) -> Result { f(self) } - fn read_tuple_struct(&mut self, s_name: &str, len: usize, f: F) + fn read_tuple_struct(&mut self, _s_name: &str, len: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; + where F: FnOnce(&mut Self) -> Result + { + self.read_tuple(len, f) + } fn read_tuple_struct_arg(&mut self, a_idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; + where F: FnOnce(&mut Self) -> Result + { + self.read_tuple_arg(a_idx, f) + } // Specialized types: - fn read_option(&mut self, f: F) -> Result - where F: FnMut(&mut Self, bool) -> Result; + fn read_option(&mut self, mut f: F) -> Result + where F: FnMut(&mut Self, bool) -> Result + { + self.read_enum("Option", move |this| { + this.read_enum_variant(&["None", "Some"], move |this, idx| { + match idx { + 0 => f(this, false), + 1 => f(this, true), + _ => Err(this.error("read_option: expected 0 for None or 1 for Some")), + } + }) + }) + } fn read_seq(&mut self, f: F) -> Result - where F: FnOnce(&mut Self, usize) -> Result; - fn read_seq_elt(&mut self, idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; + where F: FnOnce(&mut Self, usize) -> Result + { + let len = self.read_usize()?; + f(self, len) + } + fn read_seq_elt(&mut self, _idx: usize, f: F) -> Result + where F: FnOnce(&mut Self) -> Result { f(self) } fn read_map(&mut self, f: F) -> Result - where F: FnOnce(&mut Self, usize) -> Result; - fn read_map_elt_key(&mut self, idx: usize, f: F) + where F: FnOnce(&mut Self, usize) -> Result + { + let len = self.read_usize()?; + f(self, len) + } + fn read_map_elt_key(&mut self, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; - fn read_map_elt_val(&mut self, idx: usize, f: F) + where F: FnOnce(&mut Self) -> Result { f(self) } + fn read_map_elt_val(&mut self, _idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; + where F: FnOnce(&mut Self) -> Result { f(self) } // Failure fn error(&mut self, err: &str) -> Self::Error; diff --git a/src/rustc/Cargo.lock b/src/rustc/Cargo.lock index 3377fc43d8a..d8a02badcee 100644 --- a/src/rustc/Cargo.lock +++ b/src/rustc/Cargo.lock @@ -50,14 +50,6 @@ dependencies = [ "syntax_pos 0.0.0", ] -[[package]] -name = "rbml" -version = "0.0.0" -dependencies = [ - "log 0.0.0", - "serialize 0.0.0", -] - [[package]] name = "rustc" version = "0.0.0" @@ -67,7 +59,6 @@ dependencies = [ "fmt_macros 0.0.0", "graphviz 0.0.0", "log 0.0.0", - "rbml 0.0.0", "rustc_back 0.0.0", "rustc_bitflags 0.0.0", "rustc_const_math 0.0.0", @@ -185,7 +176,6 @@ version = "0.0.0" dependencies = [ "graphviz 0.0.0", "log 0.0.0", - "rbml 0.0.0", "rustc 0.0.0", "rustc_data_structures 0.0.0", "serialize 0.0.0", @@ -227,7 +217,6 @@ version = "0.0.0" dependencies = [ "flate 0.0.0", "log 0.0.0", - "rbml 0.0.0", "rustc 0.0.0", "rustc_back 0.0.0", "rustc_bitflags 0.0.0", diff --git a/src/test/run-pass-fulldeps/issue-11881.rs b/src/test/run-pass-fulldeps/issue-11881.rs index 9da04f72355..8369d08db36 100644 --- a/src/test/run-pass-fulldeps/issue-11881.rs +++ b/src/test/run-pass-fulldeps/issue-11881.rs @@ -11,7 +11,6 @@ #![feature(rustc_private)] -extern crate rbml; extern crate serialize; use std::io::Cursor; @@ -21,8 +20,7 @@ use std::slice; use serialize::{Encodable, Encoder}; use serialize::json; - -use rbml::writer; +use serialize::opaque; #[derive(Encodable)] struct Foo { @@ -44,7 +42,7 @@ fn encode_json(val: &T, wr: &mut Cursor>) { write!(wr, "{}", json::as_json(val)); } fn encode_rbml(val: &T, wr: &mut Cursor>) { - let mut encoder = writer::Encoder::new(wr); + let mut encoder = opaque::Encoder::new(wr); val.encode(&mut encoder); }