public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] libproc_macro: Add string length to ffi
@ 2023-04-06 21:32 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2023-04-06 21:32 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:0f1723455cea2d51630be79aceddcfc3ed8a4771

commit 0f1723455cea2d51630be79aceddcfc3ed8a4771
Author: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Date:   Tue Feb 21 10:48:54 2023 +0100

    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>

Diff:
---
 librust/proc_macro/rust/bridge/ident.rs        | 24 +++++++++++++-----------
 librust/proc_macro/rust/bridge/literal.rs      | 24 +++++++++++++++---------
 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 880cf77a411..1c08a003e02 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 27aa2efe9d5..e883e6b14e0 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 c33806f6527..afd986f68f5 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)

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-04-06 21:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-06 21:32 [gcc/devel/rust/master] libproc_macro: Add string length to ffi Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).