@@ -49,7 +49,7 @@ public static RuntimeScalar pos(RuntimeScalar perlVariable) {
4949 if (cachedEntry == null || cachedEntry .valueHash != code ) {
5050 // If the position is not cached or the value has changed,
5151 // create a new undefined RuntimeScalar to represent the position
52- position = new RuntimeScalar ( );
52+ position = new PosLvalueScalar ( perlVariable );
5353 // Cache the new position with the current hash of the value
5454 positionCache .put (perlVariable , new CacheEntry (code , position ));
5555 } else {
@@ -59,6 +59,60 @@ public static RuntimeScalar pos(RuntimeScalar perlVariable) {
5959 return position ;
6060 }
6161
62+ private static void clearZeroLengthMatchTracking (RuntimeScalar perlVariable ) {
63+ CacheEntry cachedEntry = positionCache .get (perlVariable );
64+ if (cachedEntry != null ) {
65+ cachedEntry .lastMatchWasZeroLength = false ;
66+ cachedEntry .lastMatchPosition = -1 ;
67+ cachedEntry .lastMatchPattern = null ;
68+ }
69+ }
70+
71+ private static class PosLvalueScalar extends RuntimeScalar {
72+ private final RuntimeScalar target ;
73+
74+ private PosLvalueScalar (RuntimeScalar target ) {
75+ super ();
76+ this .target = target ;
77+ }
78+
79+ @ Override
80+ public RuntimeScalar set (RuntimeScalar value ) {
81+ RuntimePosLvalue .clearZeroLengthMatchTracking (target );
82+ return super .set (value );
83+ }
84+
85+ @ Override
86+ public RuntimeScalar set (int value ) {
87+ RuntimePosLvalue .clearZeroLengthMatchTracking (target );
88+ return super .set (value );
89+ }
90+
91+ @ Override
92+ public RuntimeScalar set (long value ) {
93+ RuntimePosLvalue .clearZeroLengthMatchTracking (target );
94+ return super .set (value );
95+ }
96+
97+ @ Override
98+ public RuntimeScalar set (boolean value ) {
99+ RuntimePosLvalue .clearZeroLengthMatchTracking (target );
100+ return super .set (value );
101+ }
102+
103+ @ Override
104+ public RuntimeScalar set (String value ) {
105+ RuntimePosLvalue .clearZeroLengthMatchTracking (target );
106+ return super .set (value );
107+ }
108+
109+ @ Override
110+ public RuntimeScalar set (Object value ) {
111+ RuntimePosLvalue .clearZeroLengthMatchTracking (target );
112+ return super .set (value );
113+ }
114+ }
115+
62116 /**
63117 * Check if the last match at this position was zero-length with the given pattern.
64118 * This is used to prevent infinite loops in global regex matches.
0 commit comments