Skip to content

Commit eb9ae18

Browse files
authored
Introduce an adapter from joni 2.1 to 2.2 (#55)
JOni 2.2 will hide these public fields and the direct constructors for Region, so these adapters will bridge the gap until the new API is widely available. The adapter and calls to it can be removed once JRuby has shipped a few releases of 9.4 (and possibly 9.3) with the updated JOni.
1 parent 0856e23 commit eb9ae18

File tree

1 file changed

+111
-23
lines changed

1 file changed

+111
-23
lines changed

ext/jruby/org/jruby/ext/strscan/RubyStringScanner.java

Lines changed: 111 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
package org.jruby.ext.strscan;
2929

30+
import jnr.a64asm.REG;
3031
import org.jcodings.Encoding;
3132
import org.joni.Matcher;
3233
import org.joni.NameEntry;
@@ -102,6 +103,93 @@ public static RubyClass createScannerClass(final Ruby runtime) {
102103
return scannerClass;
103104
}
104105

106+
// Provided temporarily to bridge the gap between joni 2.1 and 2.2
107+
private static final RegionAdapter REGION_ADAPTER;
108+
static {
109+
RegionAdapter adapter;
110+
try {
111+
Region.class.getMethod("newRegion", int.class, int.class);
112+
// ok, proceed with factory-based adapter
113+
adapter = new FactoryRegionAdapter();
114+
} catch (NoSuchMethodException | SecurityException ex) {
115+
adapter = new OldRegionAdapter();
116+
}
117+
REGION_ADAPTER = adapter;
118+
}
119+
120+
private interface RegionAdapter {
121+
Region newRegion(int beg, int end);
122+
int getBeg(Region region, int index);
123+
int getEnd(Region region, int index);
124+
int setBeg(Region region, int index, int value);
125+
int setEnd(Region region, int index, int value);
126+
int getNumRegs(Region region);
127+
}
128+
129+
private static class OldRegionAdapter implements RegionAdapter {
130+
@Override
131+
public Region newRegion(int beg, int end) {
132+
return new Region(beg, end);
133+
}
134+
135+
@Override
136+
public int getBeg(Region region, int index) {
137+
return region.beg[index];
138+
}
139+
140+
@Override
141+
public int getEnd(Region region, int index) {
142+
return region.end[index];
143+
}
144+
145+
@Override
146+
public int setBeg(Region region, int index, int value) {
147+
return region.beg[index] = value;
148+
}
149+
150+
@Override
151+
public int setEnd(Region region, int index, int value) {
152+
return region.end[index] = value;
153+
}
154+
155+
@Override
156+
public int getNumRegs(Region region) {
157+
return region.numRegs;
158+
}
159+
}
160+
161+
private static class FactoryRegionAdapter implements RegionAdapter {
162+
@Override
163+
public Region newRegion(int beg, int end) {
164+
return Region.newRegion(beg, end);
165+
}
166+
167+
@Override
168+
public int getBeg(Region region, int index) {
169+
return region.getBeg(index);
170+
}
171+
172+
@Override
173+
public int getEnd(Region region, int index) {
174+
return region.getEnd(index);
175+
}
176+
177+
@Override
178+
public int setBeg(Region region, int index, int value) {
179+
return region.setBeg(index, value);
180+
}
181+
182+
@Override
183+
public int setEnd(Region region, int index, int value) {
184+
return region.setEnd(index, value);
185+
}
186+
187+
@Override
188+
public int getNumRegs(Region region) {
189+
return region.getNumRegs();
190+
}
191+
}
192+
105193
private void clearMatched() {
106194
scannerFlags &= ~MATCHED_STR_SCN_F;
107195
}
@@ -131,7 +219,7 @@ public IRubyObject initialize(ThreadContext context, IRubyObject string) {
131219
public IRubyObject initialize(ThreadContext context, IRubyObject string, IRubyObject dupOrOpts) {
132220
this.str = string.convertToString();
133221
this.fixedAnchor = ArgsUtil.extractKeywordArg(context, "fixed_anchor", dupOrOpts).isTrue();
134-
this.regs = new Region(0, 0);
222+
this.regs = REGION_ADAPTER.newRegion(0, 0);
135223

136224
return this;
137225
}
@@ -313,7 +401,7 @@ private IRubyObject scan(ThreadContext context, IRubyObject regex, boolean succp
313401

314402
Region matchRegion = matcher.getRegion();
315403
if (matchRegion == null) {
316-
regs = new Region(matcher.getBegin(), matcher.getEnd());
404+
regs = REGION_ADAPTER.newRegion(matcher.getBegin(), matcher.getEnd());
317405
} else {
318406
regs = matchRegion;
319407
}
@@ -359,17 +447,17 @@ private IRubyObject scan(ThreadContext context, IRubyObject regex, boolean succp
359447

360448
private int lastMatchLength() {
361449
if (fixedAnchor) {
362-
return regs.end[0] - prev;
450+
return REGION_ADAPTER.getEnd(regs, 0) - prev;
363451
} else {
364-
return regs.end[0];
452+
return REGION_ADAPTER.getEnd(regs, 0);
365453
}
366454
}
367455

368456
private void succ() {
369457
if (fixedAnchor) {
370-
this.curr = this.regs.end[0];
458+
this.curr = REGION_ADAPTER.getEnd(regs, 0);
371459
} else {
372-
this.curr += this.regs.end[0];
460+
this.curr += REGION_ADAPTER.getEnd(regs, 0);
373461
}
374462
}
375463

@@ -392,9 +480,9 @@ private int restLen() {
392480
// MRI: set_registers
393481
private void setRegisters(int length) {
394482
if (fixedAnchor) {
395-
regs = new Region(curr, curr + length);
483+
regs = REGION_ADAPTER.newRegion(curr, curr + length);
396484
} else {
397-
regs = new Region(0, length);
485+
regs = REGION_ADAPTER.newRegion(0, length);
398486
}
399487
}
400488

@@ -451,9 +539,9 @@ public IRubyObject search_full(ThreadContext context, IRubyObject regex, IRubyOb
451539
// MRI: adjust_register_to_matched
452540
private void adjustRegisters() {
453541
if (fixedAnchor) {
454-
regs = new Region(prev, curr);
542+
regs = REGION_ADAPTER.newRegion(prev, curr);
455543
} else {
456-
regs = new Region(0, curr - prev);
544+
regs = REGION_ADAPTER.newRegion(0, curr - prev);
457545
}
458546
}
459547

@@ -485,8 +573,8 @@ public IRubyObject getchCommon(ThreadContext context) {
485573
adjustRegisters();
486574

487575
return extractRange(runtime,
488-
prev + regs.beg[0],
489-
prev + regs.end[0]);
576+
prev + REGION_ADAPTER.getBeg(regs, 0),
577+
prev + REGION_ADAPTER.getEnd(regs, 0));
490578
}
491579

492580
@JRubyMethod(name = "get_byte")
@@ -501,7 +589,7 @@ public IRubyObject get_byte(ThreadContext context) {
501589
setMatched();
502590
adjustRegisters();
503591

504-
return extractRange(context.runtime, prev + regs.beg[0], prev + regs.end[0]);
592+
return extractRange(context.runtime, prev + REGION_ADAPTER.getBeg(regs, 0), prev + REGION_ADAPTER.getEnd(regs, 0));
505593
}
506594

507595
@JRubyMethod(name = "getbyte")
@@ -596,14 +684,14 @@ public RubyBoolean matched_p(ThreadContext context) {
596684
public IRubyObject matched(ThreadContext context) {
597685
check(context);
598686
if (!isMatched()) return context.nil;
599-
return extractRange(context.runtime, prev + regs.beg[0], prev + regs.end[0]);
687+
return extractRange(context.runtime, prev + REGION_ADAPTER.getBeg(regs, 0), prev + REGION_ADAPTER.getEnd(regs, 0));
600688
}
601689

602690
@JRubyMethod(name = "matched_size")
603691
public IRubyObject matched_size(ThreadContext context) {
604692
check(context);
605693
if (!isMatched()) return context.nil;
606-
return RubyFixnum.newFixnum(context.runtime, regs.end[0] - regs.beg[0]);
694+
return RubyFixnum.newFixnum(context.runtime, REGION_ADAPTER.getEnd(regs, 0) - REGION_ADAPTER.getBeg(regs, 0));
607695
}
608696

609697
@JRubyMethod(name = "matchedsize")
@@ -635,14 +723,14 @@ public IRubyObject op_aref(ThreadContext context, IRubyObject idx) {
635723
}
636724

637725
private IRubyObject extractRegion(ThreadContext context, int i) {
638-
int numRegs = regs.numRegs;
726+
int numRegs = REGION_ADAPTER.getNumRegs(regs);
639727

640728
if (i < 0) i += numRegs;
641-
if (i < 0 || i >= numRegs || regs.beg[i] == -1) {
729+
if (i < 0 || i >= numRegs || REGION_ADAPTER.getBeg(regs, i) == -1) {
642730
return context.nil;
643731
}
644732

645-
return extractRange(context.runtime, prev + regs.beg[i], prev + regs.end[i]);
733+
return extractRange(context.runtime, prev + REGION_ADAPTER.getBeg(regs, i), prev + REGION_ADAPTER.getEnd(regs, i));
646734
}
647735

648736
@JRubyMethod(name = "pre_match")
@@ -651,7 +739,7 @@ public IRubyObject pre_match(ThreadContext context) {
651739
if (!isMatched()) {
652740
return context.nil;
653741
}
654-
return extractRange(context.runtime, 0, prev + regs.beg[0]);
742+
return extractRange(context.runtime, 0, prev + REGION_ADAPTER.getBeg(regs, 0));
655743
}
656744

657745
@JRubyMethod(name = "post_match")
@@ -662,7 +750,7 @@ public IRubyObject post_match(ThreadContext context) {
662750
return context.nil;
663751
}
664752

665-
return extractRange(context.runtime, prev + regs.end[0], str.getByteList().getRealSize());
753+
return extractRange(context.runtime, prev + REGION_ADAPTER.getEnd(regs, 0), str.getByteList().getRealSize());
666754
}
667755

668756
@JRubyMethod(name = "rest")
@@ -769,7 +857,7 @@ private IRubyObject inspect2() {
769857
@JRubyMethod(name = "size")
770858
public IRubyObject size(ThreadContext context) {
771859
if (!isMatched()) return context.nil;
772-
return context.runtime.newFixnum(regs.numRegs);
860+
return context.runtime.newFixnum(REGION_ADAPTER.getNumRegs(regs));
773861
}
774862

775863
@JRubyMethod(name = "captures")
@@ -781,11 +869,11 @@ public IRubyObject captures(ThreadContext context) {
781869

782870
Ruby runtime = context.runtime;
783871

784-
numRegs = regs.numRegs;
872+
numRegs = REGION_ADAPTER.getNumRegs(regs);
785873
newAry = RubyArray.newArray(runtime, numRegs);
786874

787875
for (i = 1; i < numRegs; i++) {
788-
IRubyObject str = extractRange(runtime, prev + regs.beg[i], prev + regs.end[i]);
876+
IRubyObject str = extractRange(runtime, prev + REGION_ADAPTER.getBeg(regs, i), prev + REGION_ADAPTER.getEnd(regs, i));
789877
newAry.push(str);
790878
}
791879

0 commit comments

Comments
 (0)