From ee9b6cb9f189465ad3af1442843f1956e0a5f013 Mon Sep 17 00:00:00 2001 From: The Major Date: Wed, 6 Nov 2024 23:07:15 +0000 Subject: [PATCH] implement rb_enc_interned_str --- CHANGELOG.md | 1 + .../truffleruby/truffleruby-abi-version.h | 2 +- spec/ruby/optional/capi/ext/string_spec.c | 6 +++ spec/ruby/optional/capi/string_spec.rb | 45 +++++++++++++++++++ src/main/c/cext/string.c | 5 +++ 5 files changed, 58 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df5b12c4c604..197a39f11ef6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Compatibility: * Support the index/length arguments for the string argument to `String#bytesplice` added in 3.3 (#3656, @rwstauner). * Implement `rb_str_strlen()` (#3697, @Th3-M4jor). * Support `Time.new` with String argument and error when invalid (#3693, @rwstauner). +* Implement `rb_enc_interned_str()` (#3703, @Th3-M4jor). Performance: diff --git a/lib/cext/include/truffleruby/truffleruby-abi-version.h b/lib/cext/include/truffleruby/truffleruby-abi-version.h index 5c54215b2f61..6bdaae61d315 100644 --- a/lib/cext/include/truffleruby/truffleruby-abi-version.h +++ b/lib/cext/include/truffleruby/truffleruby-abi-version.h @@ -20,6 +20,6 @@ // $RUBY_VERSION must be the same as TruffleRuby.LANGUAGE_VERSION. // $ABI_NUMBER starts at 1 and is incremented for every ABI-incompatible change. -#define TRUFFLERUBY_ABI_VERSION "3.2.4.5" +#define TRUFFLERUBY_ABI_VERSION "3.2.4.6" #endif diff --git a/spec/ruby/optional/capi/ext/string_spec.c b/spec/ruby/optional/capi/ext/string_spec.c index 94f412267ff7..a140c86347ca 100644 --- a/spec/ruby/optional/capi/ext/string_spec.c +++ b/spec/ruby/optional/capi/ext/string_spec.c @@ -581,6 +581,11 @@ static VALUE string_spec_rb_enc_interned_str_cstr(VALUE self, VALUE str, VALUE e return rb_enc_interned_str_cstr(RSTRING_PTR(str), e); } +static VALUE string_spec_rb_enc_interned_str(VALUE self, VALUE str, VALUE len, VALUE enc) { + rb_encoding *e = NIL_P(enc) ? 0 : rb_to_encoding(enc); + return rb_enc_interned_str(RSTRING_PTR(str), FIX2LONG(len), e); +} + static VALUE string_spec_rb_str_to_interned_str(VALUE self, VALUE str) { return rb_str_to_interned_str(str); } @@ -687,6 +692,7 @@ void Init_string_spec(void) { rb_define_method(cls, "rb_str_locktmp", string_spec_rb_str_locktmp, 1); rb_define_method(cls, "rb_str_unlocktmp", string_spec_rb_str_unlocktmp, 1); rb_define_method(cls, "rb_enc_interned_str_cstr", string_spec_rb_enc_interned_str_cstr, 2); + rb_define_method(cls, "rb_enc_interned_str", string_spec_rb_enc_interned_str, 3); rb_define_method(cls, "rb_str_to_interned_str", string_spec_rb_str_to_interned_str, 1); } diff --git a/spec/ruby/optional/capi/string_spec.rb b/spec/ruby/optional/capi/string_spec.rb index d43dddeacf12..834620b0aa43 100644 --- a/spec/ruby/optional/capi/string_spec.rb +++ b/spec/ruby/optional/capi/string_spec.rb @@ -1261,6 +1261,51 @@ def inspect end end + describe "rb_enc_interned_str" do + it "returns a frozen string" do + str = "hello" + val = @s.rb_enc_interned_str(str, str.bytesize, Encoding::US_ASCII) + + val.should.is_a?(String) + val.encoding.should == Encoding::US_ASCII + val.should.frozen? + end + + it "returns the same frozen string" do + str = "hello" + result1 = @s.rb_enc_interned_str(str, str.bytesize, Encoding::US_ASCII) + result2 = @s.rb_enc_interned_str(str, str.bytesize, Encoding::US_ASCII) + result1.should.equal?(result2) + end + + it "returns different frozen strings for different encodings" do + str = "hello" + result1 = @s.rb_enc_interned_str(str, str.bytesize, Encoding::US_ASCII) + result2 = @s.rb_enc_interned_str(str, str.bytesize, Encoding::UTF_8) + result1.should_not.equal?(result2) + end + + it 'returns the same string when using non-ascii characters' do + str = 'こんにちは' + result1 = @s.rb_enc_interned_str(str, str.bytesize, Encoding::UTF_8) + result2 = @s.rb_enc_interned_str(str, str.bytesize, Encoding::UTF_8) + result1.should.equal?(result2) + end + + it "returns the same string as String#-@" do + str = "hello" + @s.rb_enc_interned_str(str, str.bytesize, Encoding::UTF_8).should.equal?(-str) + end + + ruby_bug "#20322", ""..."3.4" do + it "uses the default encoding if encoding is null" do + str = "hello" + val = @s.rb_enc_interned_str(str, str.bytesize, nil) + val.encoding.should == Encoding::ASCII_8BIT + end + end + end + describe "rb_str_to_interned_str" do it "returns a frozen string" do str = "hello" diff --git a/src/main/c/cext/string.c b/src/main/c/cext/string.c index 96b49287ac39..c4a4106f9c66 100644 --- a/src/main/c/cext/string.c +++ b/src/main/c/cext/string.c @@ -437,6 +437,11 @@ VALUE rb_enc_interned_str_cstr(const char *ptr, rb_encoding *enc) { return rb_str_to_interned_str(str); } +VALUE rb_enc_interned_str(const char *ptr, long len, rb_encoding *enc) { + VALUE str = rb_enc_str_new(ptr, len, enc ? enc : rb_ascii8bit_encoding()); + return rb_str_to_interned_str(str); +} + VALUE rb_str_to_interned_str(VALUE str) { return RUBY_INVOKE(str, "-@"); }