Skip to content

Make opaque::Encoder append-only and make it infallible #51356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/librustc/ich/fingerprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ impl Fingerprint {
pub fn encode_opaque(&self, encoder: &mut Encoder) -> EncodeResult {
let bytes: [u8; 16] = unsafe { mem::transmute([self.0.to_le(), self.1.to_le()]) };

encoder.emit_raw_bytes(&bytes)
encoder.emit_raw_bytes(&bytes);
Ok(())
}

pub fn decode_opaque<'a>(decoder: &mut Decoder<'a>) -> Result<Fingerprint, String> {
Expand Down Expand Up @@ -92,7 +93,7 @@ impl serialize::UseSpecializedEncodable for Fingerprint { }

impl serialize::UseSpecializedDecodable for Fingerprint { }

impl<'a> serialize::SpecializedEncoder<Fingerprint> for serialize::opaque::Encoder<'a> {
impl serialize::SpecializedEncoder<Fingerprint> for serialize::opaque::Encoder {
fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
f.encode_opaque(self)
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub trait TyEncoder: Encoder {
fn position(&self) -> usize;
}

impl<'buf> TyEncoder for opaque::Encoder<'buf> {
impl TyEncoder for opaque::Encoder {
#[inline]
fn position(&self) -> usize {
self.position()
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/query/on_disk_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -979,7 +979,7 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder<NodeId> for CacheEncoder<'enc, 'a, 't
}

impl<'enc, 'a, 'tcx> SpecializedEncoder<Fingerprint>
for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder<'enc>>
for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder>
{
fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
f.encode_opaque(&mut self.encoder)
Expand Down Expand Up @@ -1057,7 +1057,7 @@ impl IntEncodedWithFixedSize {
impl UseSpecializedEncodable for IntEncodedWithFixedSize {}
impl UseSpecializedDecodable for IntEncodedWithFixedSize {}

impl<'enc> SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder<'enc> {
impl SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder {
fn specialized_encode(&mut self, x: &IntEncodedWithFixedSize) -> Result<(), Self::Error> {
let start_pos = self.position();
for i in 0 .. IntEncodedWithFixedSize::ENCODED_SIZE {
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_codegen_llvm/back/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,7 @@ impl WasmEncoder {
}

fn u32(&mut self, val: u32) {
let at = self.data.len();
leb128::write_u32_leb128(&mut self.data, at, val);
leb128::write_u32_leb128(&mut self.data, val);
}

fn byte(&mut self, val: u8) {
Expand Down
15 changes: 7 additions & 8 deletions src/librustc_incremental/persist/file_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use std::fs;
use std::env;

use rustc::session::config::nightly_options;
use rustc_serialize::opaque::Encoder;

/// The first few bytes of files generated by incremental compilation
const FILE_MAGIC: &'static [u8] = b"RSIC";
Expand All @@ -37,17 +38,15 @@ const HEADER_FORMAT_VERSION: u16 = 0;
/// the git commit hash.
const RUSTC_VERSION: Option<&'static str> = option_env!("CFG_VERSION");

pub fn write_file_header<W: io::Write>(stream: &mut W) -> io::Result<()> {
stream.write_all(FILE_MAGIC)?;
stream.write_all(&[(HEADER_FORMAT_VERSION >> 0) as u8,
(HEADER_FORMAT_VERSION >> 8) as u8])?;
pub fn write_file_header(stream: &mut Encoder) {
stream.emit_raw_bytes(FILE_MAGIC);
stream.emit_raw_bytes(&[(HEADER_FORMAT_VERSION >> 0) as u8,
(HEADER_FORMAT_VERSION >> 8) as u8]);

let rustc_version = rustc_version();
assert_eq!(rustc_version.len(), (rustc_version.len() as u8) as usize);
stream.write_all(&[rustc_version.len() as u8])?;
stream.write_all(rustc_version.as_bytes())?;

Ok(())
stream.emit_raw_bytes(&[rustc_version.len() as u8]);
stream.emit_raw_bytes(rustc_version.as_bytes());
}

/// Reads the contents of a file with a file header as defined in this module.
Expand Down
39 changes: 13 additions & 26 deletions src/librustc_incremental/persist/save.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::join;
use rustc_serialize::Encodable as RustcEncodable;
use rustc_serialize::opaque::Encoder;
use std::io::{self, Cursor};
use std::fs;
use std::path::PathBuf;

Expand Down Expand Up @@ -98,7 +97,7 @@ pub fn save_work_product_index(sess: &Session,
}

fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
where F: FnOnce(&mut Encoder) -> io::Result<()>
where F: FnOnce(&mut Encoder)
{
debug!("save: storing data in {}", path_buf.display());

Expand All @@ -121,20 +120,12 @@ fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
}

// generate the data in a memory buffer
let mut wr = Cursor::new(Vec::new());
file_format::write_file_header(&mut wr).unwrap();
match encode(&mut Encoder::new(&mut wr)) {
Ok(()) => {}
Err(err) => {
sess.err(&format!("could not encode dep-graph to `{}`: {}",
path_buf.display(),
err));
return;
}
}
let mut encoder = Encoder::new(Vec::new());
file_format::write_file_header(&mut encoder);
encode(&mut encoder);

// write the data out
let data = wr.into_inner();
let data = encoder.into_inner();
match fs::write(&path_buf, data) {
Ok(_) => {
debug!("save: data written to disk successfully");
Expand All @@ -149,10 +140,9 @@ fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
}

fn encode_dep_graph(tcx: TyCtxt,
encoder: &mut Encoder)
-> io::Result<()> {
encoder: &mut Encoder) {
// First encode the commandline arguments hash
tcx.sess.opts.dep_tracking_hash().encode(encoder)?;
tcx.sess.opts.dep_tracking_hash().encode(encoder).unwrap();

// Encode the graph data.
let serialized_graph = time(tcx.sess, "getting serialized graph", || {
Expand Down Expand Up @@ -234,14 +224,12 @@ fn encode_dep_graph(tcx: TyCtxt,
}

time(tcx.sess, "encoding serialized graph", || {
serialized_graph.encode(encoder)
})?;

Ok(())
serialized_graph.encode(encoder).unwrap();
});
}

fn encode_work_product_index(work_products: &FxHashMap<WorkProductId, WorkProduct>,
encoder: &mut Encoder) -> io::Result<()> {
encoder: &mut Encoder) {
let serialized_products: Vec<_> = work_products
.iter()
.map(|(id, work_product)| {
Expand All @@ -252,13 +240,12 @@ fn encode_work_product_index(work_products: &FxHashMap<WorkProductId, WorkProduc
})
.collect();

serialized_products.encode(encoder)
serialized_products.encode(encoder).unwrap();
}

fn encode_query_cache(tcx: TyCtxt,
encoder: &mut Encoder)
-> io::Result<()> {
encoder: &mut Encoder) {
time(tcx.sess, "serialize query result cache", || {
tcx.serialize_query_result_cache(encoder)
tcx.serialize_query_result_cache(encoder).unwrap();
})
}
24 changes: 11 additions & 13 deletions src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ use rustc_data_structures::stable_hasher::StableHasher;
use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};

use std::hash::Hash;
use std::io::prelude::*;
use std::io::Cursor;
use std::path::Path;
use rustc_data_structures::sync::Lrc;
use std::u32;
Expand All @@ -52,7 +50,7 @@ use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
use rustc::hir::intravisit;

pub struct EncodeContext<'a, 'tcx: 'a> {
opaque: opaque::Encoder<'a>,
opaque: opaque::Encoder,
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &'a LinkMeta,

Expand All @@ -76,7 +74,7 @@ macro_rules! encoder_methods {
}

impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
type Error = <opaque::Encoder<'a> as Encoder>::Error;
type Error = <opaque::Encoder as Encoder>::Error;

fn emit_nil(&mut self) -> Result<(), Self::Error> {
Ok(())
Expand Down Expand Up @@ -480,7 +478,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {

// Index the items
i = self.position();
let index = items.write_index(&mut self.opaque.cursor);
let index = items.write_index(&mut self.opaque);
let index_bytes = self.position() - i;

let attrs = tcx.hir.krate_attrs();
Expand Down Expand Up @@ -537,7 +535,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {

if self.tcx.sess.meta_stats() {
let mut zero_bytes = 0;
for e in self.opaque.cursor.get_ref() {
for e in self.opaque.data.iter() {
if *e == 0 {
zero_bytes += 1;
}
Expand Down Expand Up @@ -1797,15 +1795,15 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta)
-> EncodedMetadata
{
let mut cursor = Cursor::new(vec![]);
cursor.write_all(METADATA_HEADER).unwrap();
let mut encoder = opaque::Encoder::new(vec![]);
encoder.emit_raw_bytes(METADATA_HEADER);

// Will be filled with the root position after encoding everything.
cursor.write_all(&[0, 0, 0, 0]).unwrap();
encoder.emit_raw_bytes(&[0, 0, 0, 0]);

let root = {
let (root, mut result) = {
let mut ecx = EncodeContext {
opaque: opaque::Encoder::new(&mut cursor),
opaque: encoder,
tcx,
link_meta,
lazy_state: LazyState::NoNode,
Expand All @@ -1821,9 +1819,9 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

// Encode all the entries and extra information in the crate,
// culminating in the `CrateRoot` which points to all of it.
ecx.encode_crate_root()
let root = ecx.encode_crate_root();
(root, ecx.opaque.into_inner())
};
let mut result = cursor.into_inner();

// Encode the root position.
let header = METADATA_HEADER.len();
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_metadata/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use schema::*;

use rustc::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace};
use std::io::{Cursor, Write};
use rustc_serialize::opaque::Encoder;
use std::slice;
use std::u32;

Expand Down Expand Up @@ -54,15 +54,15 @@ impl Index {
self.positions[space_index][array_index] = position.to_le();
}

pub fn write_index(&self, buf: &mut Cursor<Vec<u8>>) -> LazySeq<Index> {
pub fn write_index(&self, buf: &mut Encoder) -> LazySeq<Index> {
let pos = buf.position();

// First we write the length of the lower range ...
buf.write_all(words_to_bytes(&[(self.positions[0].len() as u32).to_le()])).unwrap();
buf.emit_raw_bytes(words_to_bytes(&[(self.positions[0].len() as u32).to_le()]));
// ... then the values in the lower range ...
buf.write_all(words_to_bytes(&self.positions[0][..])).unwrap();
buf.emit_raw_bytes(words_to_bytes(&self.positions[0][..]));
// ... then the values in the higher range.
buf.write_all(words_to_bytes(&self.positions[1][..])).unwrap();
buf.emit_raw_bytes(words_to_bytes(&self.positions[1][..]));
LazySeq::with_position_and_length(pos as usize,
self.positions[0].len() + self.positions[1].len() + 1)
}
Expand Down
38 changes: 11 additions & 27 deletions src/libserialize/leb128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,8 @@
// except according to those terms.

#[inline]
pub fn write_to_vec(vec: &mut Vec<u8>, position: usize, byte: u8) {
if position == vec.len() {
vec.push(byte);
} else {
vec[position] = byte;
}
pub fn write_to_vec(vec: &mut Vec<u8>, byte: u8) {
vec.push(byte);
}

#[cfg(target_pointer_width = "32")]
Expand All @@ -33,24 +29,20 @@ macro_rules! leb128_size {
macro_rules! impl_write_unsigned_leb128 {
($fn_name:ident, $int_ty:ident) => (
#[inline]
pub fn $fn_name(out: &mut Vec<u8>, start_position: usize, mut value: $int_ty) -> usize {
let mut position = start_position;
pub fn $fn_name(out: &mut Vec<u8>, mut value: $int_ty) {
for _ in 0 .. leb128_size!($int_ty) {
let mut byte = (value & 0x7F) as u8;
value >>= 7;
if value != 0 {
byte |= 0x80;
}

write_to_vec(out, position, byte);
position += 1;
write_to_vec(out, byte);

if value == 0 {
break;
}
}

position - start_position
}
)
}
Expand Down Expand Up @@ -105,11 +97,9 @@ impl_read_unsigned_leb128!(read_usize_leb128, usize);
/// The callback `write` is called once for each position
/// that is to be written to with the byte to be encoded
/// at that position.
pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W) -> usize
where W: FnMut(usize, u8)
pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W)
where W: FnMut(u8)
{
let mut position = 0;

loop {
let mut byte = (value as u8) & 0x7f;
value >>= 7;
Expand All @@ -120,18 +110,16 @@ pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W) -> usize
byte |= 0x80; // Mark this byte to show that more bytes will follow.
}

write(position, byte);
position += 1;
write(byte);

if !more {
break;
}
}
position
}

pub fn write_signed_leb128(out: &mut Vec<u8>, start_position: usize, value: i128) -> usize {
write_signed_leb128_to(value, |i, v| write_to_vec(out, start_position+i, v))
pub fn write_signed_leb128(out: &mut Vec<u8>, value: i128) {
write_signed_leb128_to(value, |v| write_to_vec(out, v))
}

#[inline]
Expand Down Expand Up @@ -167,9 +155,7 @@ macro_rules! impl_test_unsigned_leb128 {
let mut stream = Vec::new();

for x in 0..62 {
let pos = stream.len();
let bytes_written = $write_fn_name(&mut stream, pos, (3u64 << x) as $int_ty);
assert_eq!(stream.len(), pos + bytes_written);
$write_fn_name(&mut stream, (3u64 << x) as $int_ty);
}

let mut position = 0;
Expand All @@ -195,9 +181,7 @@ fn test_signed_leb128() {
let values: Vec<_> = (-500..500).map(|i| i * 0x12345789ABCDEF).collect();
let mut stream = Vec::new();
for &x in &values {
let pos = stream.len();
let bytes_written = write_signed_leb128(&mut stream, pos, x);
assert_eq!(stream.len(), pos + bytes_written);
write_signed_leb128(&mut stream, x);
}
let mut pos = 0;
for &x in &values {
Expand Down
1 change: 1 addition & 0 deletions src/libserialize/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Core encoding and decoding interfaces.
#![feature(box_syntax)]
#![feature(core_intrinsics)]
#![feature(specialization)]
#![feature(never_type)]
#![cfg_attr(test, feature(test))]

pub use self::serialize::{Decoder, Encoder, Decodable, Encodable};
Expand Down
Loading