Skip to content

Commit

Permalink
[GR-45621] Add C API rb_enc_interned_str_cstr function
Browse files Browse the repository at this point in the history
PullRequest: truffleruby/4149
  • Loading branch information
andrykonchin committed Feb 13, 2024
2 parents 1dff2df + eff94ef commit 88cbf96
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 28 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ Compatibility:
* Remove deprecated `FileTest.exists?` method (#3039, @andrykonchin).
* Fix {Method,Proc}#parameters and return `*`, `**` and `&` names for anonymous parameters (@andrykonchin).
* Remove deprecated `Fixnum` and `Bignum` constants (#3039, @andrykonchin).
* Add `rb_enc_interned_str_cstr` function (#3408, @goyox86, @thomasmarshall).
* Add `rb_str_to_interned_str` function (#3408, @thomasmarshall).

Performance:

Expand Down
2 changes: 1 addition & 1 deletion lib/cext/ABI_check.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
10
13
18 changes: 11 additions & 7 deletions spec/ruby/optional/capi/ext/string_spec.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@ VALUE string_spec_rb_str_set_len_RSTRING_LEN(VALUE self, VALUE str, VALUE len) {
return INT2FIX(RSTRING_LEN(str));
}

VALUE rb_fstring(VALUE str); /* internal.h, used in ripper */

VALUE string_spec_rb_str_fstring(VALUE self, VALUE str) {
return rb_fstring(str);
}

VALUE string_spec_rb_str_buf_new(VALUE self, VALUE len, VALUE str) {
VALUE buf;

Expand Down Expand Up @@ -578,11 +572,19 @@ static VALUE string_spec_rb_str_unlocktmp(VALUE self, VALUE str) {
return rb_str_unlocktmp(str);
}

static VALUE string_spec_rb_enc_interned_str_cstr(VALUE self, VALUE str, VALUE enc) {
rb_encoding *e = rb_to_encoding(enc);
return rb_enc_interned_str_cstr(RSTRING_PTR(str), e);
}

static VALUE string_spec_rb_str_to_interned_str(VALUE self, VALUE str) {
return rb_str_to_interned_str(str);
}

void Init_string_spec(void) {
VALUE cls = rb_define_class("CApiStringSpecs", rb_cObject);
rb_define_method(cls, "rb_cstr2inum", string_spec_rb_cstr2inum, 2);
rb_define_method(cls, "rb_cstr_to_inum", string_spec_rb_cstr_to_inum, 3);
rb_define_method(cls, "rb_fstring", string_spec_rb_str_fstring, 1);
rb_define_method(cls, "rb_str2inum", string_spec_rb_str2inum, 2);
rb_define_method(cls, "rb_str_append", string_spec_rb_str_append, 2);
rb_define_method(cls, "rb_str_buf_new", string_spec_rb_str_buf_new, 2);
Expand Down Expand Up @@ -679,6 +681,8 @@ void Init_string_spec(void) {
rb_define_method(cls, "rb_str_catf", string_spec_rb_str_catf, 1);
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_str_to_interned_str", string_spec_rb_str_to_interned_str, 1);
}

#ifdef __cplusplus
Expand Down
74 changes: 55 additions & 19 deletions spec/ruby/optional/capi/string_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -498,25 +498,6 @@ def inspect
end
end

describe "rb_fstring" do
it 'returns self if the String is frozen' do
input = 'foo'.freeze
output = @s.rb_fstring(input)

output.should equal(input)
output.should.frozen?
end

it 'returns a frozen copy if the String is not frozen' do
input = 'foo'
output = @s.rb_fstring(input)

output.should.frozen?
output.should_not equal(input)
output.should == 'foo'
end
end

describe "rb_str_subseq" do
it "returns a byte-indexed substring" do
str = "\x00\x01\x02\x03\x04".force_encoding("binary")
Expand Down Expand Up @@ -1227,4 +1208,59 @@ def inspect
-> { @s.rb_str_unlocktmp("test") }.should raise_error(RuntimeError, 'temporal unlocking already unlocked string')
end
end

describe "rb_enc_interned_str_cstr" do
it "returns a frozen string" do
str = "hello"
val = @s.rb_enc_interned_str_cstr(str, 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_cstr(str, Encoding::US_ASCII)
result2 = @s.rb_enc_interned_str_cstr(str, 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_cstr(str, Encoding::US_ASCII)
result2 = @s.rb_enc_interned_str_cstr(str, Encoding::UTF_8)
result1.should_not.equal?(result2)
end

it "returns the same string as String#-@" do
@s.rb_enc_interned_str_cstr("hello", Encoding::UTF_8).should.equal?(-"hello")
end
end

describe "rb_str_to_interned_str" do
it "returns a frozen string" do
str = "hello"
result = @s.rb_str_to_interned_str(str)
result.should.is_a?(String)
result.should.frozen?
end

it "returns the same frozen string" do
str = "hello"
result1 = @s.rb_str_to_interned_str(str)
result2 = @s.rb_str_to_interned_str(str)
result1.should.equal?(result2)
end

it "returns different frozen strings for different encodings" do
result1 = @s.rb_str_to_interned_str("hello".force_encoding(Encoding::US_ASCII))
result2 = @s.rb_str_to_interned_str("hello".force_encoding(Encoding::UTF_8))
result1.should_not.equal?(result2)
end

it "returns the same string as String#-@" do
@s.rb_str_to_interned_str("hello").should.equal?(-"hello")
end
end
end
11 changes: 10 additions & 1 deletion src/main/c/cext/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ VALUE rb_str_to_str(VALUE string) {
}

VALUE rb_fstring(VALUE str) {
return RUBY_INVOKE(str, "-@");
return rb_str_to_interned_str(str);
}

VALUE rb_str_buf_new(long capacity) {
Expand Down Expand Up @@ -437,3 +437,12 @@ long rb_str_coderange_scan_restartable(const char *s, const char *e, rb_encoding
*cr = ENC_CODERANGE_VALID;
return e - s;
}

VALUE rb_enc_interned_str_cstr(const char *ptr, rb_encoding *enc) {
VALUE str = rb_enc_str_new_cstr(ptr, enc);
return rb_str_to_interned_str(str);
}

VALUE rb_str_to_interned_str(VALUE str) {
return RUBY_INVOKE(str, "-@");
}
2 changes: 2 additions & 0 deletions src/main/java/org/truffleruby/cext/CExtNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,8 @@ RubyString rbStrNewNul(int byteLength,

}

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

Expand Down

0 comments on commit 88cbf96

Please sign in to comment.