diff options
author | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2023-02-21 10:48:54 +0100 |
---|---|---|
committer | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2023-03-30 13:52:32 +0200 |
commit | 0f1723455cea2d51630be79aceddcfc3ed8a4771 (patch) | |
tree | fad56de75936bb6c4605bf8100023093c8e340f1 | |
parent | 3954270ee7fa782b64bc2f020056b7f6b58195b0 (diff) | |
download | gcc-0f1723455cea2d51630be79aceddcfc3ed8a4771.zip gcc-0f1723455cea2d51630be79aceddcfc3ed8a4771.tar.gz gcc-0f1723455cea2d51630be79aceddcfc3ed8a4771.tar.bz2 |
libproc_macro: Add string length to ffi
Rust string are not null terminated and the C++ part will require a
bound to know where a string type end. This means the length should be
given as an argument in all ffi functions.
ChangeLog:
* librust/proc_macro/rust/bridge/ident.rs: Add length to extern
C functions.
* librust/proc_macro/rust/bridge/literal.rs: Add length to
extern C functions.
* librust/proc_macro/rust/bridge/token_stream.rs: Add length to
extern C functions.
Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
-rw-r--r-- | librust/proc_macro/rust/bridge/ident.rs | 24 | ||||
-rw-r--r-- | librust/proc_macro/rust/bridge/literal.rs | 24 | ||||
-rw-r--r-- | librust/proc_macro/rust/bridge/token_stream.rs | 10 |
3 files changed, 36 insertions, 22 deletions
diff --git a/librust/proc_macro/rust/bridge/ident.rs b/librust/proc_macro/rust/bridge/ident.rs index 880cf77..1c08a00 100644 --- a/librust/proc_macro/rust/bridge/ident.rs +++ b/librust/proc_macro/rust/bridge/ident.rs @@ -1,10 +1,11 @@ use bridge::span::Span; -use std::ffi::{c_char, CStr, CString}; +use std::convert::TryInto; +use std::ffi::c_uchar; use std::fmt; extern "C" { - fn Ident__new(string: *const c_char) -> Ident; - fn Ident__new_raw(string: *const c_char) -> Ident; + fn Ident__new(string: *const c_uchar, len: u64) -> Ident; + fn Ident__new_raw(string: *const c_uchar, len: u64) -> Ident; fn Ident__drop(ident: *const Ident); } @@ -12,18 +13,17 @@ extern "C" { #[derive(Clone, Debug)] pub struct Ident { pub(crate) is_raw: bool, - pub(crate) val: *const c_char, + pub(crate) val: *const c_uchar, + len: u64, } impl Ident { pub fn new(string: &str, _span: Span) -> Self { - let string = CString::new(string).expect("Cannot convert to CString"); - unsafe { Ident__new(string.as_ptr()) } + unsafe { Ident__new(string.as_ptr(), string.len().try_into().unwrap()) } } pub fn new_raw(string: &str, _span: Span) -> Self { - let string = CString::new(string).expect("Cannot convert to CString"); - unsafe { Ident__new_raw(string.as_ptr()) } + unsafe { Ident__new_raw(string.as_ptr(), string.len().try_into().unwrap()) } } pub fn span(&self) -> Span { @@ -49,9 +49,11 @@ impl fmt::Display for Ident { } fmt::Display::fmt( unsafe { - CStr::from_ptr(self.val) - .to_str() - .expect("Cannot convert back to rust string") + std::str::from_utf8(std::slice::from_raw_parts( + self.val, + self.len.try_into().unwrap(), + )) + .unwrap() }, f, ) diff --git a/librust/proc_macro/rust/bridge/literal.rs b/librust/proc_macro/rust/bridge/literal.rs index 27aa2ef..e883e6b 100644 --- a/librust/proc_macro/rust/bridge/literal.rs +++ b/librust/proc_macro/rust/bridge/literal.rs @@ -7,9 +7,9 @@ use LexError; extern "C" { fn Literal__drop(literal: *const Literal); - fn Literal__string(str: *const c_uchar) -> Literal; - fn Literal__byte_string(bytes: *const u8) -> Literal; - fn Literal__from_string(str: *const c_uchar, lit: *mut Literal) -> bool; + fn Literal__string(str: *const c_uchar, len: u64) -> Literal; + fn Literal__byte_string(bytes: *const u8, len: u64) -> Literal; + fn Literal__from_string(str: *const c_uchar, len: u64, lit: *mut Literal) -> bool; } #[repr(C)] @@ -46,7 +46,7 @@ pub enum Literal { #[allow(dead_code)] String { data: *const c_uchar, - size: u64, + len: u64, }, /// Bytestring literal internal representation /// @@ -206,7 +206,7 @@ impl Literal { } pub fn string(string: &str) -> Self { - unsafe { Literal__string(string.as_ptr()) } + unsafe { Literal__string(string.as_ptr(), string.len().try_into().unwrap()) } } pub fn character(c: char) -> Self { @@ -214,7 +214,7 @@ impl Literal { } pub fn byte_string(bytes: &[u8]) -> Self { - unsafe { Literal__byte_string(bytes.as_ptr()) } + unsafe { Literal__byte_string(bytes.as_ptr(), bytes.len().try_into().unwrap()) } } pub fn span(&self) -> Span { @@ -240,9 +240,9 @@ impl Drop for Literal { impl fmt::Display for Literal { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Literal::String { data, size } => { + Literal::String { data, len } => { let slice = - unsafe { std::slice::from_raw_parts(*data, (*size).try_into().unwrap()) }; + unsafe { std::slice::from_raw_parts(*data, (*len).try_into().unwrap()) }; f.write_str("\"")?; f.write_str(std::str::from_utf8(slice).unwrap())?; f.write_str("\"")?; @@ -370,7 +370,13 @@ impl FromStr for Literal { let mut lit = Literal::Char(0); // TODO: We might want to pass a LexError by reference to retrieve // error information - if unsafe { Literal__from_string(string.as_ptr(), &mut lit as *mut Literal) } { + if unsafe { + Literal__from_string( + string.as_ptr(), + string.len().try_into().unwrap(), + &mut lit as *mut Literal, + ) + } { Err(LexError) } else { Ok(lit) diff --git a/librust/proc_macro/rust/bridge/token_stream.rs b/librust/proc_macro/rust/bridge/token_stream.rs index c33806f..afd986f 100644 --- a/librust/proc_macro/rust/bridge/token_stream.rs +++ b/librust/proc_macro/rust/bridge/token_stream.rs @@ -13,7 +13,7 @@ extern "C" { fn TokenStream__new() -> TokenStream; fn TokenStream__with_capacity(capacity: u64) -> TokenStream; fn TokenStream__push(stream: *mut TokenStream, tree: TokenTree); - fn TokenStream__from_string(str: *const c_uchar, ts: *mut TokenStream) -> bool; + fn TokenStream__from_string(str: *const c_uchar, len: u64, ts: *mut TokenStream) -> bool; } // TODO: There surely is a better way to achieve this. I don't like this @@ -138,7 +138,13 @@ impl FromStr for TokenStream { type Err = LexError; fn from_str(string: &str) -> Result<Self, LexError> { let mut ts = TokenStream::new(); - if unsafe { TokenStream__from_string(string.as_ptr(), &mut ts as *mut TokenStream) } { + if unsafe { + TokenStream__from_string( + string.as_ptr(), + string.len().try_into().unwrap(), + &mut ts as *mut TokenStream, + ) + } { Err(LexError) } else { Ok(ts) |