aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>2023-02-21 10:48:54 +0100
committerPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>2023-03-30 13:52:32 +0200
commit0f1723455cea2d51630be79aceddcfc3ed8a4771 (patch)
treefad56de75936bb6c4605bf8100023093c8e340f1
parent3954270ee7fa782b64bc2f020056b7f6b58195b0 (diff)
downloadgcc-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.rs24
-rw-r--r--librust/proc_macro/rust/bridge/literal.rs24
-rw-r--r--librust/proc_macro/rust/bridge/token_stream.rs10
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)