rustc_codegen_llvm: use safe references for ArchiveChild.

This commit is contained in:
Irina Popa 2018-07-17 15:02:11 +03:00
parent e551ed9033
commit c7669dff2a
3 changed files with 56 additions and 38 deletions

View File

@ -14,7 +14,7 @@ use std::ffi::{CString, CStr};
use std::io; use std::io;
use std::mem; use std::mem;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::ptr::{self, NonNull}; use std::ptr;
use std::str; use std::str;
use back::bytecode::RLIB_BYTECODE_EXTENSION; use back::bytecode::RLIB_BYTECODE_EXTENSION;
@ -246,7 +246,7 @@ impl<'a> ArchiveBuilder<'a> {
let name = CString::new(child_name)?; let name = CString::new(child_name)?;
members.push(llvm::LLVMRustArchiveMemberNew(ptr::null(), members.push(llvm::LLVMRustArchiveMemberNew(ptr::null(),
name.as_ptr(), name.as_ptr(),
NonNull::new(child.raw()))); Some(child.raw)));
strings.push(name); strings.push(name);
} }
} }
@ -284,7 +284,7 @@ impl<'a> ArchiveBuilder<'a> {
let name = CString::new(child_name)?; let name = CString::new(child_name)?;
let m = llvm::LLVMRustArchiveMemberNew(ptr::null(), let m = llvm::LLVMRustArchiveMemberNew(ptr::null(),
name.as_ptr(), name.as_ptr(),
NonNull::new(child.raw())); Some(child.raw));
members.push(m); members.push(m);
strings.push(name); strings.push(name);
} }

View File

@ -11,24 +11,22 @@
//! A wrapper around LLVM's archive (.a) code //! A wrapper around LLVM's archive (.a) code
use std::ffi::CString; use std::ffi::CString;
use std::marker;
use std::path::Path; use std::path::Path;
use std::slice; use std::slice;
use std::str; use std::str;
pub struct ArchiveRO { pub struct ArchiveRO {
raw: &'static mut super::Archive, pub raw: &'static mut super::Archive,
} }
unsafe impl Send for ArchiveRO {} unsafe impl Send for ArchiveRO {}
pub struct Iter<'a> { pub struct Iter<'a> {
ptr: &'a mut super::ArchiveIterator<'a>, raw: &'a mut super::ArchiveIterator<'a>,
} }
pub struct Child<'a> { pub struct Child<'a> {
ptr: super::ArchiveChildRef, pub raw: &'a mut super::ArchiveChild<'a>,
_data: marker::PhantomData<&'a ArchiveRO>,
} }
impl ArchiveRO { impl ArchiveRO {
@ -59,14 +57,10 @@ impl ArchiveRO {
} }
} }
pub fn raw(&self) -> &super::Archive {
self.raw
}
pub fn iter(&self) -> Iter { pub fn iter(&self) -> Iter {
unsafe { unsafe {
Iter { Iter {
ptr: super::LLVMRustArchiveIteratorNew(self.raw), raw: super::LLVMRustArchiveIteratorNew(self.raw),
} }
} }
} }
@ -84,14 +78,11 @@ impl<'a> Iterator for Iter<'a> {
type Item = Result<Child<'a>, String>; type Item = Result<Child<'a>, String>;
fn next(&mut self) -> Option<Result<Child<'a>, String>> { fn next(&mut self) -> Option<Result<Child<'a>, String>> {
let ptr = unsafe { super::LLVMRustArchiveIteratorNext(self.ptr) }; unsafe {
if ptr.is_null() { match super::LLVMRustArchiveIteratorNext(self.raw) {
super::last_error().map(Err) Some(raw) => Some(Ok(Child { raw })),
} else { None => super::last_error().map(Err),
Some(Ok(Child { }
ptr,
_data: marker::PhantomData,
}))
} }
} }
} }
@ -99,7 +90,7 @@ impl<'a> Iterator for Iter<'a> {
impl<'a> Drop for Iter<'a> { impl<'a> Drop for Iter<'a> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
super::LLVMRustArchiveIteratorFree(&mut *(self.ptr as *mut _)); super::LLVMRustArchiveIteratorFree(&mut *(self.raw as *mut _));
} }
} }
} }
@ -108,7 +99,7 @@ impl<'a> Child<'a> {
pub fn name(&self) -> Option<&'a str> { pub fn name(&self) -> Option<&'a str> {
unsafe { unsafe {
let mut name_len = 0; let mut name_len = 0;
let name_ptr = super::LLVMRustArchiveChildName(self.ptr, &mut name_len); let name_ptr = super::LLVMRustArchiveChildName(self.raw, &mut name_len);
if name_ptr.is_null() { if name_ptr.is_null() {
None None
} else { } else {
@ -121,23 +112,19 @@ impl<'a> Child<'a> {
pub fn data(&self) -> &'a [u8] { pub fn data(&self) -> &'a [u8] {
unsafe { unsafe {
let mut data_len = 0; let mut data_len = 0;
let data_ptr = super::LLVMRustArchiveChildData(self.ptr, &mut data_len); let data_ptr = super::LLVMRustArchiveChildData(self.raw, &mut data_len);
if data_ptr.is_null() { if data_ptr.is_null() {
panic!("failed to read data from archive child"); panic!("failed to read data from archive child");
} }
slice::from_raw_parts(data_ptr as *const u8, data_len as usize) slice::from_raw_parts(data_ptr as *const u8, data_len as usize)
} }
} }
pub fn raw(&self) -> super::ArchiveChildRef {
self.ptr
}
} }
impl<'a> Drop for Child<'a> { impl<'a> Drop for Child<'a> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
super::LLVMRustArchiveChildFree(self.ptr); super::LLVMRustArchiveChildFree(&mut *(self.raw as *mut _));
} }
} }
} }

View File

@ -25,7 +25,6 @@ use libc::{c_uint, c_int, size_t, c_char};
use libc::{c_ulonglong, c_void}; use libc::{c_ulonglong, c_void};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ptr::NonNull;
use super::RustString; use super::RustString;
@ -383,6 +382,7 @@ pub enum ThreadLocalMode {
} }
extern { type Opaque; } extern { type Opaque; }
#[repr(C)]
struct InvariantOpaque<'a> { struct InvariantOpaque<'a> {
_marker: PhantomData<&'a mut &'a ()>, _marker: PhantomData<&'a mut &'a ()>,
_opaque: Opaque, _opaque: Opaque,
@ -397,22 +397,27 @@ extern { pub type Metadata; }
extern { pub type BasicBlock; } extern { pub type BasicBlock; }
extern { pub type Builder; } extern { pub type Builder; }
extern { pub type MemoryBuffer; } extern { pub type MemoryBuffer; }
#[repr(C)]
pub struct PassManager<'a>(InvariantOpaque<'a>); pub struct PassManager<'a>(InvariantOpaque<'a>);
extern { pub type PassManagerBuilder; } extern { pub type PassManagerBuilder; }
extern { pub type ObjectFile; } extern { pub type ObjectFile; }
#[repr(C)]
pub struct SectionIterator<'a>(InvariantOpaque<'a>); pub struct SectionIterator<'a>(InvariantOpaque<'a>);
extern { pub type Pass; } extern { pub type Pass; }
extern { pub type TargetMachine; } extern { pub type TargetMachine; }
extern { pub type Archive; } extern { pub type Archive; }
#[repr(C)]
pub struct ArchiveIterator<'a>(InvariantOpaque<'a>); pub struct ArchiveIterator<'a>(InvariantOpaque<'a>);
extern { pub type ArchiveChild; } #[repr(C)]
pub type ArchiveChildRef = *mut ArchiveChild; pub struct ArchiveChild<'a>(InvariantOpaque<'a>);
extern { pub type Twine; } extern { pub type Twine; }
extern { pub type DiagnosticInfo; } extern { pub type DiagnosticInfo; }
extern { pub type SMDiagnostic; } extern { pub type SMDiagnostic; }
extern { pub type RustArchiveMember; } extern { pub type RustArchiveMember; }
pub type RustArchiveMemberRef = *mut RustArchiveMember; pub type RustArchiveMemberRef = *mut RustArchiveMember;
#[repr(C)]
pub struct OperandBundleDef<'a>(InvariantOpaque<'a>); pub struct OperandBundleDef<'a>(InvariantOpaque<'a>);
#[repr(C)]
pub struct Linker<'a>(InvariantOpaque<'a>); pub struct Linker<'a>(InvariantOpaque<'a>);
pub type DiagnosticHandler = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void); pub type DiagnosticHandler = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void);
@ -474,7 +479,6 @@ pub mod debuginfo {
extern { pub type ModuleBuffer; } extern { pub type ModuleBuffer; }
#[allow(improper_ctypes)] // TODO remove this (use for NonNull)
extern "C" { extern "C" {
// Create and destroy contexts. // Create and destroy contexts.
pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> &'static mut Context; pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> &'static mut Context;
@ -1403,10 +1407,15 @@ extern "C" {
-> &'a Value; -> &'a Value;
pub fn LLVMRustDIBuilderCreateOpDeref() -> i64; pub fn LLVMRustDIBuilderCreateOpDeref() -> i64;
pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64; pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64;
}
#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString.
extern "C" {
pub fn LLVMRustWriteTypeToString(Type: &Type, s: &RustString); pub fn LLVMRustWriteTypeToString(Type: &Type, s: &RustString);
pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString); pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString);
}
extern "C" {
pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>; pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>;
pub fn LLVMIsAConstantFP(value_ref: &Value) -> Option<&Value>; pub fn LLVMIsAConstantFP(value_ref: &Value) -> Option<&Value>;
@ -1471,21 +1480,29 @@ extern "C" {
pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>; pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>;
pub fn LLVMRustArchiveIteratorNew(AR: &'a Archive) -> &'a mut ArchiveIterator<'a>; pub fn LLVMRustArchiveIteratorNew(AR: &'a Archive) -> &'a mut ArchiveIterator<'a>;
pub fn LLVMRustArchiveIteratorNext(AIR: &ArchiveIterator) -> ArchiveChildRef; pub fn LLVMRustArchiveIteratorNext(AIR: &ArchiveIterator<'a>) -> Option<&'a mut ArchiveChild<'a>>;
pub fn LLVMRustArchiveChildName(ACR: ArchiveChildRef, size: &mut size_t) -> *const c_char; pub fn LLVMRustArchiveChildName(ACR: &ArchiveChild, size: &mut size_t) -> *const c_char;
pub fn LLVMRustArchiveChildData(ACR: ArchiveChildRef, size: &mut size_t) -> *const c_char; pub fn LLVMRustArchiveChildData(ACR: &ArchiveChild, size: &mut size_t) -> *const c_char;
pub fn LLVMRustArchiveChildFree(ACR: ArchiveChildRef); pub fn LLVMRustArchiveChildFree(ACR: &'a mut ArchiveChild<'a>);
pub fn LLVMRustArchiveIteratorFree(AIR: &'a mut ArchiveIterator<'a>); pub fn LLVMRustArchiveIteratorFree(AIR: &'a mut ArchiveIterator<'a>);
pub fn LLVMRustDestroyArchive(AR: &'static mut Archive); pub fn LLVMRustDestroyArchive(AR: &'static mut Archive);
pub fn LLVMRustGetSectionName(SI: &SectionIterator, data: &mut *const c_char) -> size_t; pub fn LLVMRustGetSectionName(SI: &SectionIterator, data: &mut *const c_char) -> size_t;
}
#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString.
extern "C" {
pub fn LLVMRustWriteTwineToString(T: &Twine, s: &RustString); pub fn LLVMRustWriteTwineToString(T: &Twine, s: &RustString);
}
extern "C" {
pub fn LLVMContextSetDiagnosticHandler(C: &Context, pub fn LLVMContextSetDiagnosticHandler(C: &Context,
Handler: DiagnosticHandler, Handler: DiagnosticHandler,
DiagnosticContext: *mut c_void); DiagnosticContext: *mut c_void);
}
#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString.
extern "C" {
pub fn LLVMRustUnpackOptimizationDiagnostic(DI: &'a DiagnosticInfo, pub fn LLVMRustUnpackOptimizationDiagnostic(DI: &'a DiagnosticInfo,
pass_name_out: &RustString, pass_name_out: &RustString,
function_out: &mut Option<&'a Value>, function_out: &mut Option<&'a Value>,
@ -1493,20 +1510,34 @@ extern "C" {
loc_column_out: &mut c_uint, loc_column_out: &mut c_uint,
loc_filename_out: &RustString, loc_filename_out: &RustString,
message_out: &RustString); message_out: &RustString);
}
extern "C" {
pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: &'a DiagnosticInfo, pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: &'a DiagnosticInfo,
cookie_out: &mut c_uint, cookie_out: &mut c_uint,
message_out: &mut Option<&'a Twine>, message_out: &mut Option<&'a Twine>,
instruction_out: &mut Option<&'a Value>); instruction_out: &mut Option<&'a Value>);
}
#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString.
extern "C" {
pub fn LLVMRustWriteDiagnosticInfoToString(DI: &DiagnosticInfo, s: &RustString); pub fn LLVMRustWriteDiagnosticInfoToString(DI: &DiagnosticInfo, s: &RustString);
}
extern "C" {
pub fn LLVMRustGetDiagInfoKind(DI: &DiagnosticInfo) -> DiagnosticKind; pub fn LLVMRustGetDiagInfoKind(DI: &DiagnosticInfo) -> DiagnosticKind;
pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: &Context, pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: &Context,
H: InlineAsmDiagHandler, H: InlineAsmDiagHandler,
CX: *mut c_void); CX: *mut c_void);
}
#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString.
extern "C" {
pub fn LLVMRustWriteSMDiagnosticToString(d: &SMDiagnostic, s: &RustString); pub fn LLVMRustWriteSMDiagnosticToString(d: &SMDiagnostic, s: &RustString);
}
extern "C" {
pub fn LLVMRustWriteArchive(Dst: *const c_char, pub fn LLVMRustWriteArchive(Dst: *const c_char,
NumMembers: size_t, NumMembers: size_t,
Members: *const RustArchiveMemberRef, Members: *const RustArchiveMemberRef,
@ -1515,7 +1546,7 @@ extern "C" {
-> LLVMRustResult; -> LLVMRustResult;
pub fn LLVMRustArchiveMemberNew(Filename: *const c_char, pub fn LLVMRustArchiveMemberNew(Filename: *const c_char,
Name: *const c_char, Name: *const c_char,
Child: Option<NonNull<ArchiveChild>>) Child: Option<&ArchiveChild>)
-> RustArchiveMemberRef; -> RustArchiveMemberRef;
pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef); pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef);