From 61fdb436abf75b42c01812e8d09359800b49b1fb Mon Sep 17 00:00:00 2001 From: Jose Narvaez Date: Wed, 4 Dec 2024 22:57:46 +0000 Subject: [PATCH] Implemented StableApiDefinition::rstring_interned_p methods for TruffleRuby. (#456) * Implemented StableApiDefinition::rstring_interned_p. * Added tests. Also, C is not Rust xD. * Use ternary. * A bit more succint. * Removed file included by my LSP. --- crates/rb-sys-tests/src/stable_api_test.rs | 18 ++++++++++++++++++ crates/rb-sys/src/stable_api.rs | 8 ++++++++ crates/rb-sys/src/stable_api/compiled.c | 7 +++++++ crates/rb-sys/src/stable_api/compiled.rs | 7 +++++++ crates/rb-sys/src/stable_api/ruby_2_6.rs | 10 ++++++++++ crates/rb-sys/src/stable_api/ruby_2_7.rs | 10 ++++++++++ crates/rb-sys/src/stable_api/ruby_3_0.rs | 10 ++++++++++ crates/rb-sys/src/stable_api/ruby_3_1.rs | 10 ++++++++++ crates/rb-sys/src/stable_api/ruby_3_2.rs | 10 ++++++++++ crates/rb-sys/src/stable_api/ruby_3_3.rs | 10 ++++++++++ crates/rb-sys/src/stable_api/ruby_3_4.rs | 10 ++++++++++ 11 files changed, 110 insertions(+) diff --git a/crates/rb-sys-tests/src/stable_api_test.rs b/crates/rb-sys-tests/src/stable_api_test.rs index cff4203c..93cb078d 100644 --- a/crates/rb-sys-tests/src/stable_api_test.rs +++ b/crates/rb-sys-tests/src/stable_api_test.rs @@ -535,3 +535,21 @@ parity_test!( }, expected: false ); + +parity_test!( + name: test_rb_string_interned_p, + func: rstring_interned_p, + data_factory: { + ruby_eval!("'foo'") + }, + expected: false +); + +parity_test!( + name: test_rb_string_interned_p_frozen_str, + func: rstring_interned_p, + data_factory: { + ruby_eval!("'foo'.freeze") + }, + expected: true +); diff --git a/crates/rb-sys/src/stable_api.rs b/crates/rb-sys/src/stable_api.rs index d2c4bd57..d97204da 100644 --- a/crates/rb-sys/src/stable_api.rs +++ b/crates/rb-sys/src/stable_api.rs @@ -132,6 +132,14 @@ pub trait StableApiDefinition { /// This function is unsafe because it could dereference a raw pointer when /// attemping to access the underlying [`RBasic`] struct. unsafe fn rb_type(&self, obj: VALUE) -> crate::ruby_value_type; + + /// Check if a Ruby string is interned (akin to `RSTRING_FSTR`). + /// + /// # Safety + /// This function is unsafe because it dereferences a raw pointer to get + /// access to underlying flags of the RString. The caller must ensure that + /// the `VALUE` is a valid pointer to an RString. + unsafe fn rstring_interned_p(&self, obj: VALUE) -> bool; } #[cfg(stable_api_enable_compiled_mod)] diff --git a/crates/rb-sys/src/stable_api/compiled.c b/crates/rb-sys/src/stable_api/compiled.c index 915331c9..a877f7cd 100644 --- a/crates/rb-sys/src/stable_api/compiled.c +++ b/crates/rb-sys/src/stable_api/compiled.c @@ -87,3 +87,10 @@ int impl_integer_type_p(VALUE obj) { return RB_INTEGER_TYPE_P(obj); } + +int +impl_rstring_interned_p(VALUE obj) { + Check_Type(obj, T_STRING); + + return !(FL_TEST(obj, RSTRING_FSTR) == 0); +} diff --git a/crates/rb-sys/src/stable_api/compiled.rs b/crates/rb-sys/src/stable_api/compiled.rs index 0f5b8694..418cb836 100644 --- a/crates/rb-sys/src/stable_api/compiled.rs +++ b/crates/rb-sys/src/stable_api/compiled.rs @@ -57,6 +57,9 @@ extern "C" { #[link_name = "impl_integer_type_p"] fn impl_integer_type_p(obj: VALUE) -> bool; + + #[link_name = "impl_rstring_interned_p"] + fn impl_rstring_interned_p(obj: VALUE) -> bool; } pub struct Definition; @@ -154,4 +157,8 @@ impl StableApiDefinition for Definition { unsafe fn integer_type_p(&self, obj: VALUE) -> bool { impl_integer_type_p(obj) } + + unsafe fn rstring_interned_p(&self, obj: VALUE) -> bool { + impl_rstring_interned_p(obj) + } } diff --git a/crates/rb-sys/src/stable_api/ruby_2_6.rs b/crates/rb-sys/src/stable_api/ruby_2_6.rs index 1e130479..408f096a 100644 --- a/crates/rb-sys/src/stable_api/ruby_2_6.rs +++ b/crates/rb-sys/src/stable_api/ruby_2_6.rs @@ -225,4 +225,14 @@ impl StableApiDefinition for Definition { self.builtin_type(obj) == value_type::RUBY_T_BIGNUM } } + + #[inline] + unsafe fn rstring_interned_p(&self, obj: VALUE) -> bool { + assert!(self.type_p(obj, value_type::RUBY_T_STRING)); + + let rstring: &RString = &*(obj as *const RString); + let flags = rstring.basic.flags; + + (flags & crate::ruby_rstring_flags::RSTRING_FSTR as VALUE) != 0 + } } diff --git a/crates/rb-sys/src/stable_api/ruby_2_7.rs b/crates/rb-sys/src/stable_api/ruby_2_7.rs index c48ea929..b9ef5225 100644 --- a/crates/rb-sys/src/stable_api/ruby_2_7.rs +++ b/crates/rb-sys/src/stable_api/ruby_2_7.rs @@ -225,4 +225,14 @@ impl StableApiDefinition for Definition { self.builtin_type(obj) == value_type::RUBY_T_BIGNUM } } + + #[inline] + unsafe fn rstring_interned_p(&self, obj: VALUE) -> bool { + assert!(self.type_p(obj, value_type::RUBY_T_STRING)); + + let rstring: &RString = &*(obj as *const RString); + let flags = rstring.basic.flags; + + (flags & crate::ruby_rstring_flags::RSTRING_FSTR as VALUE) != 0 + } } diff --git a/crates/rb-sys/src/stable_api/ruby_3_0.rs b/crates/rb-sys/src/stable_api/ruby_3_0.rs index 8df66d18..c2eb0bf0 100644 --- a/crates/rb-sys/src/stable_api/ruby_3_0.rs +++ b/crates/rb-sys/src/stable_api/ruby_3_0.rs @@ -233,4 +233,14 @@ impl StableApiDefinition for Definition { self.builtin_type(obj) == value_type::RUBY_T_BIGNUM } } + + #[inline] + unsafe fn rstring_interned_p(&self, obj: VALUE) -> bool { + assert!(self.type_p(obj, value_type::RUBY_T_STRING)); + + let rstring: &RString = &*(obj as *const RString); + let flags = rstring.basic.flags; + + (flags & crate::ruby_rstring_flags::RSTRING_FSTR as VALUE) != 0 + } } diff --git a/crates/rb-sys/src/stable_api/ruby_3_1.rs b/crates/rb-sys/src/stable_api/ruby_3_1.rs index ca11f46c..646fa5a3 100644 --- a/crates/rb-sys/src/stable_api/ruby_3_1.rs +++ b/crates/rb-sys/src/stable_api/ruby_3_1.rs @@ -226,4 +226,14 @@ impl StableApiDefinition for Definition { self.builtin_type(obj) == value_type::RUBY_T_BIGNUM } } + + #[inline] + unsafe fn rstring_interned_p(&self, obj: VALUE) -> bool { + assert!(self.type_p(obj, value_type::RUBY_T_STRING)); + + let rstring: &RString = &*(obj as *const RString); + let flags = rstring.basic.flags; + + (flags & crate::ruby_rstring_flags::RSTRING_FSTR as VALUE) != 0 + } } diff --git a/crates/rb-sys/src/stable_api/ruby_3_2.rs b/crates/rb-sys/src/stable_api/ruby_3_2.rs index 4f9ce63c..763158ae 100644 --- a/crates/rb-sys/src/stable_api/ruby_3_2.rs +++ b/crates/rb-sys/src/stable_api/ruby_3_2.rs @@ -224,4 +224,14 @@ impl StableApiDefinition for Definition { self.builtin_type(obj) == value_type::RUBY_T_BIGNUM } } + + #[inline] + unsafe fn rstring_interned_p(&self, obj: VALUE) -> bool { + assert!(self.type_p(obj, value_type::RUBY_T_STRING)); + + let rstring: &RString = &*(obj as *const RString); + let flags = rstring.basic.flags; + + (flags & crate::ruby_rstring_flags::RSTRING_FSTR as VALUE) != 0 + } } diff --git a/crates/rb-sys/src/stable_api/ruby_3_3.rs b/crates/rb-sys/src/stable_api/ruby_3_3.rs index 67afd05b..11afd1cd 100644 --- a/crates/rb-sys/src/stable_api/ruby_3_3.rs +++ b/crates/rb-sys/src/stable_api/ruby_3_3.rs @@ -217,4 +217,14 @@ impl StableApiDefinition for Definition { self.builtin_type(obj) == value_type::RUBY_T_BIGNUM } } + + #[inline] + unsafe fn rstring_interned_p(&self, obj: VALUE) -> bool { + assert!(self.type_p(obj, value_type::RUBY_T_STRING)); + + let rstring: &RString = &*(obj as *const RString); + let flags = rstring.basic.flags; + + (flags & crate::ruby_rstring_flags::RSTRING_FSTR as VALUE) != 0 + } } diff --git a/crates/rb-sys/src/stable_api/ruby_3_4.rs b/crates/rb-sys/src/stable_api/ruby_3_4.rs index 4d1b4dd7..9cd51405 100644 --- a/crates/rb-sys/src/stable_api/ruby_3_4.rs +++ b/crates/rb-sys/src/stable_api/ruby_3_4.rs @@ -217,4 +217,14 @@ impl StableApiDefinition for Definition { self.builtin_type(obj) == value_type::RUBY_T_BIGNUM } } + + #[inline] + unsafe fn rstring_interned_p(&self, obj: VALUE) -> bool { + assert!(self.type_p(obj, value_type::RUBY_T_STRING)); + + let rstring: &RString = &*(obj as *const RString); + let flags = rstring.basic.flags; + + (flags & crate::ruby_rstring_flags::RSTRING_FSTR as VALUE) != 0 + } }