Skip to content

Commit 88cbf96

Browse files
committed
[GR-45621] Add C API rb_enc_interned_str_cstr function
PullRequest: truffleruby/4149
2 parents 1dff2df + eff94ef commit 88cbf96

File tree

6 files changed

+81
-28
lines changed

6 files changed

+81
-28
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ Compatibility:
5656
* Remove deprecated `FileTest.exists?` method (#3039, @andrykonchin).
5757
* Fix {Method,Proc}#parameters and return `*`, `**` and `&` names for anonymous parameters (@andrykonchin).
5858
* Remove deprecated `Fixnum` and `Bignum` constants (#3039, @andrykonchin).
59+
* Add `rb_enc_interned_str_cstr` function (#3408, @goyox86, @thomasmarshall).
60+
* Add `rb_str_to_interned_str` function (#3408, @thomasmarshall).
5961

6062
Performance:
6163

lib/cext/ABI_check.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
10
1+
13

spec/ruby/optional/capi/ext/string_spec.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,6 @@ VALUE string_spec_rb_str_set_len_RSTRING_LEN(VALUE self, VALUE str, VALUE len) {
5151
return INT2FIX(RSTRING_LEN(str));
5252
}
5353

54-
VALUE rb_fstring(VALUE str); /* internal.h, used in ripper */
55-
56-
VALUE string_spec_rb_str_fstring(VALUE self, VALUE str) {
57-
return rb_fstring(str);
58-
}
59-
6054
VALUE string_spec_rb_str_buf_new(VALUE self, VALUE len, VALUE str) {
6155
VALUE buf;
6256

@@ -578,11 +572,19 @@ static VALUE string_spec_rb_str_unlocktmp(VALUE self, VALUE str) {
578572
return rb_str_unlocktmp(str);
579573
}
580574

575+
static VALUE string_spec_rb_enc_interned_str_cstr(VALUE self, VALUE str, VALUE enc) {
576+
rb_encoding *e = rb_to_encoding(enc);
577+
return rb_enc_interned_str_cstr(RSTRING_PTR(str), e);
578+
}
579+
580+
static VALUE string_spec_rb_str_to_interned_str(VALUE self, VALUE str) {
581+
return rb_str_to_interned_str(str);
582+
}
583+
581584
void Init_string_spec(void) {
582585
VALUE cls = rb_define_class("CApiStringSpecs", rb_cObject);
583586
rb_define_method(cls, "rb_cstr2inum", string_spec_rb_cstr2inum, 2);
584587
rb_define_method(cls, "rb_cstr_to_inum", string_spec_rb_cstr_to_inum, 3);
585-
rb_define_method(cls, "rb_fstring", string_spec_rb_str_fstring, 1);
586588
rb_define_method(cls, "rb_str2inum", string_spec_rb_str2inum, 2);
587589
rb_define_method(cls, "rb_str_append", string_spec_rb_str_append, 2);
588590
rb_define_method(cls, "rb_str_buf_new", string_spec_rb_str_buf_new, 2);
@@ -679,6 +681,8 @@ void Init_string_spec(void) {
679681
rb_define_method(cls, "rb_str_catf", string_spec_rb_str_catf, 1);
680682
rb_define_method(cls, "rb_str_locktmp", string_spec_rb_str_locktmp, 1);
681683
rb_define_method(cls, "rb_str_unlocktmp", string_spec_rb_str_unlocktmp, 1);
684+
rb_define_method(cls, "rb_enc_interned_str_cstr", string_spec_rb_enc_interned_str_cstr, 2);
685+
rb_define_method(cls, "rb_str_to_interned_str", string_spec_rb_str_to_interned_str, 1);
682686
}
683687

684688
#ifdef __cplusplus

spec/ruby/optional/capi/string_spec.rb

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -498,25 +498,6 @@ def inspect
498498
end
499499
end
500500

501-
describe "rb_fstring" do
502-
it 'returns self if the String is frozen' do
503-
input = 'foo'.freeze
504-
output = @s.rb_fstring(input)
505-
506-
output.should equal(input)
507-
output.should.frozen?
508-
end
509-
510-
it 'returns a frozen copy if the String is not frozen' do
511-
input = 'foo'
512-
output = @s.rb_fstring(input)
513-
514-
output.should.frozen?
515-
output.should_not equal(input)
516-
output.should == 'foo'
517-
end
518-
end
519-
520501
describe "rb_str_subseq" do
521502
it "returns a byte-indexed substring" do
522503
str = "\x00\x01\x02\x03\x04".force_encoding("binary")
@@ -1227,4 +1208,59 @@ def inspect
12271208
-> { @s.rb_str_unlocktmp("test") }.should raise_error(RuntimeError, 'temporal unlocking already unlocked string')
12281209
end
12291210
end
1211+
1212+
describe "rb_enc_interned_str_cstr" do
1213+
it "returns a frozen string" do
1214+
str = "hello"
1215+
val = @s.rb_enc_interned_str_cstr(str, Encoding::US_ASCII)
1216+
1217+
val.should.is_a?(String)
1218+
val.encoding.should == Encoding::US_ASCII
1219+
val.should.frozen?
1220+
end
1221+
1222+
it "returns the same frozen string" do
1223+
str = "hello"
1224+
result1 = @s.rb_enc_interned_str_cstr(str, Encoding::US_ASCII)
1225+
result2 = @s.rb_enc_interned_str_cstr(str, Encoding::US_ASCII)
1226+
result1.should.equal?(result2)
1227+
end
1228+
1229+
it "returns different frozen strings for different encodings" do
1230+
str = "hello"
1231+
result1 = @s.rb_enc_interned_str_cstr(str, Encoding::US_ASCII)
1232+
result2 = @s.rb_enc_interned_str_cstr(str, Encoding::UTF_8)
1233+
result1.should_not.equal?(result2)
1234+
end
1235+
1236+
it "returns the same string as String#-@" do
1237+
@s.rb_enc_interned_str_cstr("hello", Encoding::UTF_8).should.equal?(-"hello")
1238+
end
1239+
end
1240+
1241+
describe "rb_str_to_interned_str" do
1242+
it "returns a frozen string" do
1243+
str = "hello"
1244+
result = @s.rb_str_to_interned_str(str)
1245+
result.should.is_a?(String)
1246+
result.should.frozen?
1247+
end
1248+
1249+
it "returns the same frozen string" do
1250+
str = "hello"
1251+
result1 = @s.rb_str_to_interned_str(str)
1252+
result2 = @s.rb_str_to_interned_str(str)
1253+
result1.should.equal?(result2)
1254+
end
1255+
1256+
it "returns different frozen strings for different encodings" do
1257+
result1 = @s.rb_str_to_interned_str("hello".force_encoding(Encoding::US_ASCII))
1258+
result2 = @s.rb_str_to_interned_str("hello".force_encoding(Encoding::UTF_8))
1259+
result1.should_not.equal?(result2)
1260+
end
1261+
1262+
it "returns the same string as String#-@" do
1263+
@s.rb_str_to_interned_str("hello").should.equal?(-"hello")
1264+
end
1265+
end
12301266
end

src/main/c/cext/string.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ VALUE rb_str_to_str(VALUE string) {
160160
}
161161

162162
VALUE rb_fstring(VALUE str) {
163-
return RUBY_INVOKE(str, "-@");
163+
return rb_str_to_interned_str(str);
164164
}
165165

166166
VALUE rb_str_buf_new(long capacity) {
@@ -437,3 +437,12 @@ long rb_str_coderange_scan_restartable(const char *s, const char *e, rb_encoding
437437
*cr = ENC_CODERANGE_VALID;
438438
return e - s;
439439
}
440+
441+
VALUE rb_enc_interned_str_cstr(const char *ptr, rb_encoding *enc) {
442+
VALUE str = rb_enc_str_new_cstr(ptr, enc);
443+
return rb_str_to_interned_str(str);
444+
}
445+
446+
VALUE rb_str_to_interned_str(VALUE str) {
447+
return RUBY_INVOKE(str, "-@");
448+
}

src/main/java/org/truffleruby/cext/CExtNodes.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,8 @@ RubyString rbStrNewNul(int byteLength,
796796

797797
}
798798

799+
/** Alternative to rb_str_new*() which does not copy the bytes from native memory, to use when the copy is
800+
* unnecessary. */
799801
@CoreMethod(names = "rb_tr_temporary_native_string", onSingleton = true, required = 3, lowerFixnum = 2)
800802
public abstract static class TemporaryNativeStringNode extends CoreMethodArrayArgumentsNode {
801803

0 commit comments

Comments
 (0)