Skip to content

Commit 83b73dc

Browse files
committed
[GR-20446] Implement rb_backref_set
PullRequest: truffleruby/2694
2 parents e6e7a0e + 29da838 commit 83b73dc

File tree

8 files changed

+54
-7
lines changed

8 files changed

+54
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Compatibility:
3333
* Implemented `Enumerator::Lazy#filter_map` (#2356).
3434
* Fix LLVM toolchain issue on macOS 10.13 (#2352, [oracle/graal#3383](https://github.com/oracle/graal/issues/3383)).
3535
* Implemented `Enumerator::Lazy#with_index` (#2356).
36+
* Implement `rb_backref_set`.
3637

3738
Performance:
3839

lib/cext/ABI_version.txt

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

lib/truffle/truffle/cext.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,6 +1738,10 @@ def rb_backref_get
17381738
Primitive.regexp_last_match_get(Truffle::ThreadOperations.ruby_caller_special_variables([Truffle::CExt, Truffle::Interop.singleton_class]))
17391739
end
17401740

1741+
def rb_backref_set(value)
1742+
Truffle::RegexpOperations::LAST_MATCH_SET.call(value, Truffle::ThreadOperations.ruby_caller_special_variables([Truffle::CExt, Truffle::Interop.singleton_class]))
1743+
end
1744+
17411745
def rb_gv_set(name, value)
17421746
binding.eval("#{name} = value")
17431747
end

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ VALUE regexp_spec_backref_get(VALUE self) {
3535
return rb_backref_get();
3636
}
3737

38+
static VALUE regexp_spec_backref_set(VALUE self, VALUE backref) {
39+
rb_backref_set(backref);
40+
return Qnil;
41+
}
42+
3843
VALUE regexp_spec_reg_match_backref_get(VALUE self, VALUE re, VALUE str) {
3944
rb_reg_match(re, str);
4045
return rb_backref_get();
@@ -51,6 +56,7 @@ void Init_regexp_spec(void) {
5156
rb_define_method(cls, "a_re_1st_match", regexp_spec_reg_1st_match, 1);
5257
rb_define_method(cls, "rb_reg_match", regexp_spec_reg_match, 2);
5358
rb_define_method(cls, "rb_backref_get", regexp_spec_backref_get, 0);
59+
rb_define_method(cls, "rb_backref_set", regexp_spec_backref_set, 1);
5460
rb_define_method(cls, "rb_reg_match_backref_get", regexp_spec_reg_match_backref_get, 2);
5561
rb_define_method(cls, "rb_reg_options", regexp_spec_rb_reg_options, 1);
5662
rb_define_method(cls, "rb_reg_regcomp", regexp_spec_rb_reg_regcomp, 1);

spec/ruby/optional/capi/regexp_spec.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,33 @@
8080
@p.rb_reg_match_backref_get(/a/, 'ab')[0].should == 'a'
8181
end
8282
end
83+
84+
describe "rb_backref_set" do
85+
before :each do
86+
@md = "foo".match(/foo/)
87+
$~ = nil
88+
end
89+
90+
it "sets the value of $~" do
91+
@p.rb_backref_set(@md)
92+
@p.rb_backref_get.should == @md
93+
$~.should == @md
94+
end
95+
96+
it "sets a Thread-local value" do
97+
running = false
98+
99+
thr = Thread.new do
100+
@p.rb_backref_set(@md)
101+
@p.rb_backref_get.should == @md
102+
$~.should == @md
103+
running = true
104+
end
105+
106+
Thread.pass while thr.status and !running
107+
$~.should be_nil
108+
109+
thr.join
110+
end
111+
end
83112
end

src/main/c/cext/regexp.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ VALUE rb_backref_get(void) {
1515
return RUBY_CEXT_INVOKE("rb_backref_get");
1616
}
1717

18+
void rb_backref_set(VALUE str) {
19+
RUBY_CEXT_INVOKE("rb_backref_set", str);
20+
}
21+
1822
VALUE rb_reg_match_pre(VALUE match) {
1923
return RUBY_CEXT_INVOKE("rb_reg_match_pre", match);
2024
}

src/main/ruby/truffleruby/core/regexp.rb

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -363,12 +363,7 @@ def to_s
363363
Truffle::KernelOperations.define_hooked_variable(
364364
:$~,
365365
-> s { Primitive.regexp_last_match_get(s) },
366-
-> v, s {
367-
unless Primitive.nil?(v) || Primitive.object_kind_of?(v, MatchData)
368-
raise TypeError, "Wrong argument type #{v} (expected MatchData)"
369-
end
370-
Primitive.regexp_last_match_set(s, v)
371-
})
366+
Truffle::RegexpOperations::LAST_MATCH_SET)
372367

373368
Truffle::KernelOperations.define_hooked_variable(
374369
:'$`',

src/main/ruby/truffleruby/core/truffle/regexp_operations.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@
1111
module Truffle
1212
module RegexpOperations
1313

14+
LAST_MATCH_SET = -> v, s {
15+
unless Primitive.nil?(v) || Primitive.object_kind_of?(v, MatchData)
16+
raise TypeError, "Wrong argument type #{v} (expected MatchData)"
17+
end
18+
Primitive.regexp_last_match_set(s, v)
19+
}
20+
21+
1422
def self.search_region(re, str, start_index, end_index, forward)
1523
raise TypeError, 'uninitialized regexp' unless Primitive.regexp_initialized?(re)
1624
raise ArgumentError, "invalid byte sequence in #{str.encoding}" unless str.valid_encoding?

0 commit comments

Comments
 (0)