@@ -300,34 +300,43 @@ protected RubyArray getIndex(RubyMatchData matchData, int index, int length,
300
300
301
301
@ Specialization (
302
302
guards = {
303
- "name != null" ,
304
- "getRegexp(matchData) == regexp" ,
305
- "cachedIndex == index" })
306
- protected Object getIndexSymbolSingleMatch (RubyMatchData matchData , RubySymbol index , NotProvided length ,
307
- @ Cached ("index" ) RubySymbol cachedIndex ,
308
- @ Cached ("getRegexp(matchData)" ) RubyRegexp regexp ,
309
- @ Cached ("findNameEntry(regexp, index)" ) NameEntry name ,
310
- @ Cached ("numBackRefs(name)" ) int backRefs ,
311
- @ Cached ("backRefIndex(name)" ) int backRefIndex ) {
303
+ "nameEntry != null" ,
304
+ "getRegexp(matchData) == cachedRegexp" ,
305
+ "symbol == cachedSymbol" })
306
+ protected Object getIndexSymbolKnownRegexp (RubyMatchData matchData , RubySymbol symbol , NotProvided length ,
307
+ @ Cached ("symbol" ) RubySymbol cachedSymbol ,
308
+ @ Cached ("getRegexp(matchData)" ) RubyRegexp cachedRegexp ,
309
+ @ Cached ("findNameEntry(cachedRegexp, cachedSymbol)" ) NameEntry nameEntry ,
310
+ @ Cached ("numBackRefs(nameEntry)" ) int backRefs ,
311
+ @ Cached ("backRefIndex(nameEntry)" ) int backRefIndex ,
312
+ @ Cached ConditionProfile lazyProfile ,
313
+ @ CachedLibrary (limit = "getInteropCacheLimit()" ) InteropLibrary libInterop ) {
312
314
if (backRefs == 1 ) {
313
315
return executeGetIndex (matchData , backRefIndex , NotProvided .INSTANCE );
314
316
} else {
315
- final int i = getBackRef (matchData , regexp , name );
317
+ final int i = getBackRef (matchData , cachedRegexp , cachedSymbol . getRope (), lazyProfile , libInterop );
316
318
return executeGetIndex (matchData , i , NotProvided .INSTANCE );
317
319
}
318
320
}
319
321
320
322
@ Specialization
321
- protected Object getIndexSymbol (RubyMatchData matchData , RubySymbol index , NotProvided length ) {
322
- return executeGetIndex (matchData , getBackRefFromSymbol (matchData , index ), NotProvided .INSTANCE );
323
+ protected Object getIndexSymbol (RubyMatchData matchData , RubySymbol symbol , NotProvided length ,
324
+ @ Cached ConditionProfile lazyProfile ,
325
+ @ CachedLibrary (limit = "getInteropCacheLimit()" ) InteropLibrary libInterop ) {
326
+ return executeGetIndex (
327
+ matchData ,
328
+ getBackRef (matchData , getRegexp (matchData ), symbol .getRope (), lazyProfile , libInterop ),
329
+ NotProvided .INSTANCE );
323
330
}
324
331
325
332
@ Specialization (guards = "libIndex.isRubyString(index)" )
326
333
protected Object getIndexString (RubyMatchData matchData , Object index , NotProvided length ,
327
- @ CachedLibrary (limit = "2" ) RubyStringLibrary libIndex ) {
334
+ @ CachedLibrary (limit = "2" ) RubyStringLibrary libIndex ,
335
+ @ Cached ConditionProfile lazyProfile ,
336
+ @ CachedLibrary (limit = "getInteropCacheLimit()" ) InteropLibrary libInterop ) {
328
337
return executeGetIndex (
329
338
matchData ,
330
- getBackRefFromRope (matchData , libIndex .getRope (index )),
339
+ getBackRef (matchData , getRegexp ( matchData ), libIndex .getRope (index ), lazyProfile , libInterop ),
331
340
NotProvided .INSTANCE );
332
341
}
333
342
@@ -387,42 +396,41 @@ protected RubyRegexp getRegexp(RubyMatchData matchData) {
387
396
return regexpNode .executeGetRegexp (matchData );
388
397
}
389
398
390
- @ TruffleBoundary
391
- private int getBackRefFromSymbol (RubyMatchData matchData , RubySymbol index ) {
392
- return getBackRefFromRope (matchData , index .getRope ());
399
+ private int getBackRef (RubyMatchData matchData , RubyRegexp regexp , Rope name ,
400
+ ConditionProfile lazyProfile , InteropLibrary libInterop ) {
401
+ if (lazyProfile .profile (matchData .tRegexResult != null )) {
402
+ // force the calculation of lazy capture group results before invoking nameToBackrefNumber()
403
+ forceLazyMatchData (matchData , libInterop );
404
+ }
405
+ return nameToBackrefNumber (matchData , regexp , name );
393
406
}
394
407
395
408
@ TruffleBoundary
396
- private int getBackRefFromRope (RubyMatchData matchData , Rope value ) {
409
+ private int nameToBackrefNumber (RubyMatchData matchData , RubyRegexp regexp , Rope name ) {
397
410
try {
398
- return getRegexp ( matchData ) .regex .nameToBackrefNumber (
399
- value .getBytes (),
411
+ return regexp .regex .nameToBackrefNumber (
412
+ name .getBytes (),
400
413
0 ,
401
- value .byteLength (),
414
+ name .byteLength (),
402
415
matchData .region );
403
416
} catch (ValueException e ) {
404
417
throw new RaiseException (
405
418
getContext (),
406
419
coreExceptions ().indexError (
407
420
StringUtils
408
- .format ("undefined group name reference: %s" , RopeOperations .decodeRope (value )),
421
+ .format ("undefined group name reference: %s" , RopeOperations .decodeRope (name )),
409
422
this ));
410
423
}
411
424
}
412
425
413
426
@ TruffleBoundary
414
- private int getBackRef (RubyMatchData matchData , RubyRegexp regexp , NameEntry name ) {
415
- return regexp .regex .nameToBackrefNumber (name .name , name .nameP , name .nameEnd , matchData .region );
416
- }
417
-
418
- @ TruffleBoundary
419
- protected static int numBackRefs (NameEntry name ) {
420
- return name == null ? 0 : name .getBackRefs ().length ;
427
+ protected static int numBackRefs (NameEntry nameEntry ) {
428
+ return nameEntry == null ? 0 : nameEntry .getBackRefs ().length ;
421
429
}
422
430
423
431
@ TruffleBoundary
424
- protected static int backRefIndex (NameEntry name ) {
425
- return name == null ? 0 : name .getBackRefs ()[0 ];
432
+ protected static int backRefIndex (NameEntry nameEntry ) {
433
+ return nameEntry == null ? 0 : nameEntry .getBackRefs ()[0 ];
426
434
}
427
435
428
436
@ TruffleBoundary
0 commit comments