From b63c8063efae6e0435fffce3dab2625b4287666e Mon Sep 17 00:00:00 2001 From: Tobba Date: Tue, 8 Apr 2014 01:08:49 +0200 Subject: [PATCH] Made libflate functions return Options instead of outright failing --- src/libflate/lib.rs | 34 ++++++++++++++++++------------- src/librustc/back/link.rs | 7 +++++-- src/librustc/back/lto.rs | 5 ++++- src/librustc/metadata/loader.rs | 9 +++++--- src/librustc/middle/trans/base.rs | 5 ++++- 5 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 97e03561b871..753a3120c215 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -54,43 +54,49 @@ static LZ_NORM : c_int = 0x80; // LZ with 128 probes, "normal" static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum -fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> CVec { +fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option> { unsafe { let mut outsz : size_t = 0; let res = rustrt::tdefl_compress_mem_to_heap(bytes.as_ptr() as *c_void, bytes.len() as size_t, &mut outsz, flags); - assert!(!res.is_null()); - CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res)) + if !res.is_null() { + Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res))) + } else { + None + } } } -pub fn deflate_bytes(bytes: &[u8]) -> CVec { +pub fn deflate_bytes(bytes: &[u8]) -> Option> { deflate_bytes_internal(bytes, LZ_NORM) } -pub fn deflate_bytes_zlib(bytes: &[u8]) -> CVec { +pub fn deflate_bytes_zlib(bytes: &[u8]) -> Option> { deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER) } -fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> CVec { +fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option> { unsafe { let mut outsz : size_t = 0; let res = rustrt::tinfl_decompress_mem_to_heap(bytes.as_ptr() as *c_void, bytes.len() as size_t, &mut outsz, flags); - assert!(!res.is_null()); - CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res)) + if !res.is_null() { + Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res))) + } else { + None + } } } -pub fn inflate_bytes(bytes: &[u8]) -> CVec { +pub fn inflate_bytes(bytes: &[u8]) -> Option> { inflate_bytes_internal(bytes, 0) } -pub fn inflate_bytes_zlib(bytes: &[u8]) -> CVec { +pub fn inflate_bytes_zlib(bytes: &[u8]) -> Option> { inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER) } @@ -117,8 +123,8 @@ mod tests { } debug!("de/inflate of {} bytes of random word-sequences", input.len()); - let cmp = deflate_bytes(input); - let out = inflate_bytes(cmp.as_slice()); + let cmp = deflate_bytes(input).expect("deflation failed"); + let out = inflate_bytes(cmp.as_slice()).expect("inflation failed"); debug!("{} bytes deflated to {} ({:.1f}% size)", input.len(), cmp.len(), 100.0 * ((cmp.len() as f64) / (input.len() as f64))); @@ -129,8 +135,8 @@ mod tests { #[test] fn test_zlib_flate() { let bytes = vec!(1, 2, 3, 4, 5); - let deflated = deflate_bytes(bytes.as_slice()); - let inflated = inflate_bytes(deflated.as_slice()); + let deflated = deflate_bytes(bytes.as_slice()).expect("deflation failed"); + let inflated = inflate_bytes(deflated.as_slice()).expect("inflation failed"); assert_eq!(inflated.as_slice(), bytes.as_slice()); } } diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 61725bc27d12..0946e375e4f7 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -945,11 +945,14 @@ fn link_rlib<'a>(sess: &'a Session, let bc_deflated = obj_filename.with_extension("bc.deflate"); match fs::File::open(&bc).read_to_end().and_then(|data| { fs::File::create(&bc_deflated) - .write(flate::deflate_bytes(data.as_slice()).as_slice()) + .write(match flate::deflate_bytes(data.as_slice()) { + Some(compressed) => compressed, + None => sess.fatal("failed to compress bytecode") + }.as_slice()) }) { Ok(()) => {} Err(e) => { - sess.err(format!("failed to compress bytecode: {}", e)); + sess.err(format!("failed to write compressed bytecode: {}", e)); sess.abort_if_errors() } } diff --git a/src/librustc/back/lto.rs b/src/librustc/back/lto.rs index 3171114985e1..8319be02bdbc 100644 --- a/src/librustc/back/lto.rs +++ b/src/librustc/back/lto.rs @@ -56,7 +56,10 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, archive.read(format!("{}.bc.deflate", name))); let bc = bc.expect("missing compressed bytecode in archive!"); let bc = time(sess.time_passes(), format!("inflate {}.bc", name), (), |_| - flate::inflate_bytes(bc)); + match flate::inflate_bytes(bc) { + Some(bc) => bc, + None => sess.fatal(format!("failed to decompress bc of `{}`", name)) + }); let ptr = bc.as_slice().as_ptr(); debug!("linking {}", name); time(sess.time_passes(), format!("ll link {}", name), (), |()| unsafe { diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 4f4ef31e15b3..8dea36d8152a 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -494,14 +494,17 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Result found = Ok(MetadataVec(inflated)), + None => found = Err(format!("failed to decompress metadata for: '{}'", + filename.display())) + } }); if found.is_ok() { return found; diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index e48b8fc9db4c..58edb717bf0b 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2236,7 +2236,10 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec { let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item); let metadata = encoder::encode_metadata(encode_parms, krate); let compressed = encoder::metadata_encoding_version + - flate::deflate_bytes(metadata.as_slice()).as_slice(); + match flate::deflate_bytes(metadata.as_slice()) { + Some(compressed) => compressed, + None => cx.sess().fatal(format!("failed to compress metadata", )) + }.as_slice(); let llmeta = C_bytes(cx, compressed); let llconst = C_struct(cx, [llmeta], false); let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.crateid.name,