/// <summary>A macro for _ilg.Emit(OpCodes.Ldc_I8).</summary>
protected void LdcI8(long i) => _ilg!.Emit(OpCodes.Ldc_I8, i);
- /// <summary>A macro for _ilg.Emit(OpCodes.Dup).</summary>
- private void Dup() => _ilg!.Emit(OpCodes.Dup);
-
/// <summary>A macro for _ilg.Emit(OpCodes.Ret).</summary>
protected void Ret() => _ilg!.Emit(OpCodes.Ret);
/// <summary>A macro for _ilg.Emit(OpCodes.Shr).</summary>
private void Shr() => _ilg!.Emit(OpCodes.Shr);
- /// <summary>A macro for _ilg.Emit(OpCodes.Ldloc_S).</summary>
- private void Ldloc(LocalBuilder lt) => _ilg!.Emit(OpCodes.Ldloc_S, lt);
+ /// <summary>A macro for _ilg.Emit(OpCodes.Ldloc).</summary>
+ /// <remarks>ILGenerator will switch to the optimal form based on the local's index.</remarks>
+ private void Ldloc(LocalBuilder lt) => _ilg!.Emit(OpCodes.Ldloc, lt);
/// <summary>A macro for _ilg.Emit(OpCodes.Ldloca).</summary>
+ /// <remarks>ILGenerator will switch to the optimal form based on the local's index.</remarks>
private void Ldloca(LocalBuilder lt) => _ilg!.Emit(OpCodes.Ldloca, lt);
/// <summary>A macro for _ilg.Emit(OpCodes.Ldind_U2).</summary>
/// <summary>A macro for _ilg.Emit(OpCodes.Unaligned).</summary>
private void Unaligned(byte alignment) => _ilg!.Emit(OpCodes.Unaligned, alignment);
- /// <summary>A macro for _ilg.Emit(OpCodes.Stloc_S).</summary>
- private void Stloc(LocalBuilder lt) => _ilg!.Emit(OpCodes.Stloc_S, lt);
+ /// <summary>A macro for _ilg.Emit(OpCodes.Stloc).</summary>
+ /// <remarks>ILGenerator will switch to the optimal form based on the local's index.</remarks>
+ private void Stloc(LocalBuilder lt) => _ilg!.Emit(OpCodes.Stloc, lt);
/// <summary>A macro for _ilg.Emit(OpCodes.Ldarg_0).</summary>
protected void Ldthis() => _ilg!.Emit(OpCodes.Ldarg_0);
/// <summary>A macro for _ilg.Emit(OpCodes.Bge_S) (short jump).</summary>
private void Bge(Label l) => _ilg!.Emit(OpCodes.Bge_S, l);
+ /// <summary>A macro for _ilg.Emit(OpCodes.Bge_Un_S) (short jump).</summary>
+ private void BgeUn(Label l) => _ilg!.Emit(OpCodes.Bge_Un_S, l);
+
/// <summary>A macro for _ilg.Emit(OpCodes.Bgt_S) (short jump).</summary>
private void Bgt(Label l) => _ilg!.Emit(OpCodes.Bgt_S, l);
{
Ldloc(_runtextLocal!);
Ldloc(_runtextposLocal!);
- Callvirt(s_stringGetCharsMethod);
+ Call(s_stringGetCharsMethod);
}
/// <summary>Loads the char to the right of the current position and advances the current position.</summary>
{
Ldloc(_runtextLocal!);
Ldloc(_runtextposLocal!);
- Callvirt(s_stringGetCharsMethod);
+ Call(s_stringGetCharsMethod);
Ldloc(_runtextposLocal!);
Ldc(1);
Add();
Ldloc(_runtextposLocal!);
Ldc(1);
Sub();
- Callvirt(s_stringGetCharsMethod);
+ Call(s_stringGetCharsMethod);
}
/// <summary>Loads the char to the left of the current position and advances (leftward).</summary>
private void Leftcharnext()
{
- Ldloc(_runtextLocal!);
Ldloc(_runtextposLocal!);
Ldc(1);
Sub();
- Dup();
Stloc(_runtextposLocal!);
- Callvirt(s_stringGetCharsMethod);
+ Ldloc(_runtextLocal!);
+ Ldloc(_runtextposLocal!);
+ Call(s_stringGetCharsMethod);
}
/// <summary>Creates a backtrack note and pushes the switch index it on the tracking stack.</summary>
/// <summary>Prologue to code that will push an element on the tracking stack.</summary>
private void ReadyPushTrack()
{
- Ldloc(_runtrackLocal!);
Ldloc(_runtrackposLocal!);
Ldc(1);
Sub();
- Dup();
Stloc(_runtrackposLocal!);
+ Ldloc(_runtrackLocal!);
+ Ldloc(_runtrackposLocal!);
}
/// <summary>Pops an element off the tracking stack (leave it on the operand stack).</summary>
Ldloc(_runtrackLocal!);
Ldloc(_runtrackposLocal!);
LdelemI4();
+ using RentedLocalBuilder tmp = RentInt32Local();
+ Stloc(tmp);
Ldloc(_runtrackposLocal!);
Ldc(1);
Add();
Stloc(_runtrackposLocal!);
+ Ldloc(tmp);
}
/// <summary>Retrieves the top entry on the tracking stack without popping.</summary>
/// <summary>Prologue to code that will push an element on the grouping stack.</summary>
private void ReadyPushStack()
{
- Ldloc(_runstackLocal!);
Ldloc(_runstackposLocal!);
Ldc(1);
Sub();
- Dup();
Stloc(_runstackposLocal!);
+ Ldloc(_runstackLocal!);
+ Ldloc(_runstackposLocal!);
}
/// <summary>Retrieves the top entry on the stack without popping.</summary>
/// <summary>Pops an element off the grouping stack (leave it on the operand stack).</summary>
private void PopStack()
{
+ using RentedLocalBuilder elementLocal = RentInt32Local();
Ldloc(_runstackLocal!);
Ldloc(_runstackposLocal!);
LdelemI4();
+ Stloc(elementLocal);
Ldloc(_runstackposLocal!);
Ldc(1);
Add();
Stloc(_runstackposLocal!);
+ Ldloc(elementLocal);
}
/// <summary>Pops 1 element off the grouping stack and discards it.</summary>
Bge(afterDoubleStack);
Mvlocfld(_runstackposLocal!, s_runstackposField);
Ldthis();
- Callvirt(s_doubleStackMethod);
+ Call(s_doubleStackMethod);
Mvfldloc(s_runstackposField, _runstackposLocal!);
Mvfldloc(s_runstackField, _runstackLocal!);
MarkLabel(afterDoubleStack);
Bge(afterDoubleTrack);
Mvlocfld(_runtrackposLocal!, s_runtrackposField);
Ldthis();
- Callvirt(s_doubleTrackMethod);
+ Call(s_doubleTrackMethod);
Mvfldloc(s_runtrackposField, _runtrackposLocal!);
Mvfldloc(s_runtrackField, _runtrackLocal!);
MarkLabel(afterDoubleTrack);
Beq(l2);
Ldthisfld(s_runtextField);
Ldloc(_runtextposLocal);
- Callvirt(s_stringGetCharsMethod);
+ Call(s_stringGetCharsMethod);
Ldc('\n');
Beq(l2);
MarkLabel(l1);
// if (runtextpos > runtextbeg...
Ldloc(_runtextposLocal!);
Ldthisfld(s_runtextbegField);
- BleFar(atBeginningOfLine);
+ Ble(atBeginningOfLine);
// ... && runtext[runtextpos - 1] != '\n') { ... }
Ldthisfld(s_runtextField);
Ldloc(_runtextposLocal);
Ldc(1);
Sub();
- Callvirt(s_stringGetCharsMethod);
+ Call(s_stringGetCharsMethod);
Ldc('\n');
- BeqFar(atBeginningOfLine);
+ Beq(atBeginningOfLine);
// int tmp = runtext.IndexOf('\n', runtextpos);
Ldthisfld(s_runtextField);
Ldc('\n');
Ldloc(_runtextposLocal);
Call(s_stringIndexOfCharInt);
- Dup();
-
- // if (tmp == -1)
- // {
- // runtextpos = runtextend;
- // return false;
- // }
- Label foundNextLine = DefineLabel();
- Ldc(-1);
- BneFar(foundNextLine);
- Pop();
- BrFar(returnFalse);
+ using (RentedLocalBuilder newlinePos = RentInt32Local())
+ {
+ Stloc(newlinePos);
+
+ // if (newlinePos == -1)
+ // {
+ // runtextpos = runtextend;
+ // return false;
+ // }
+ Label foundNextLine = DefineLabel();
+ Ldloc(newlinePos);
+ Ldc(-1);
+ Bne(foundNextLine);
+ BrFar(returnFalse);
- // runtextpos = tmp + 1;
- MarkLabel(foundNextLine);
- Ldc(1);
- Add();
- Stloc(_runtextposLocal);
+ // runtextpos = newlinePos + 1;
+ MarkLabel(foundNextLine);
+ Ldloc(newlinePos);
+ Ldc(1);
+ Add();
+ Stloc(_runtextposLocal);
+ }
MarkLabel(atBeginningOfLine);
}
{
CallToLower();
}
- Dup();
Label lPartialMatch = DefineLabel();
using (RentedLocalBuilder chLocal = RentInt32Local())
{
Stloc(chLocal);
+ Ldloc(chLocal);
Ldc(chLast);
BeqFar(lPartialMatch);
Ldloc(chLocal);
Ldc(_boyerMoorePrefix.LowASCII);
Sub();
- Dup();
Stloc(chLocal);
+ Ldloc(chLocal);
Ldc(_boyerMoorePrefix.HighASCII - _boyerMoorePrefix.LowASCII);
BgtUn(lDefaultAdvance);
Debug.Assert(_boyerMoorePrefix.Pattern.Length <= char.MaxValue, "RegexBoyerMoore should have limited the size allowed.");
string negativeLookup = string.Create(negativeRange, (thisRef: this, beforefirst), (span, state) =>
{
- // Store the offsets into the string. RightToLeft has negative offsets, so to support it with chars (unsigned), we negate
- // the values to be stored in the string, and then at run time after looking up the offset in the string, negate it again.
- for (int i = 0; i < span.Length; i++)
+ // Store the offsets into the string. RightToLeft has negative offsets, so to support it with chars (unsigned), we negate
+ // the values to be stored in the string, and then at run time after looking up the offset in the string, negate it again.
+ for (int i = 0; i < span.Length; i++)
{
int offset = state.thisRef._boyerMoorePrefix!.NegativeASCII[i + state.thisRef._boyerMoorePrefix.LowASCII];
if (offset == state.beforefirst)
// goto Advance;
Ldstr(negativeLookup);
Ldloc(chLocal);
- Callvirt(s_stringGetCharsMethod);
+ Call(s_stringGetCharsMethod);
if (_code.RightToLeft)
{
Neg();
Ldloc(testLocal);
Ldc(1);
Sub(_code.RightToLeft);
- Dup();
Stloc(testLocal);
- Callvirt(s_stringGetCharsMethod);
+ Ldloc(testLocal);
+ Call(s_stringGetCharsMethod);
if (_boyerMoorePrefix.CaseInsensitive && ParticipatesInCaseConversion(_boyerMoorePrefix.Pattern[charindex]))
{
CallToLower();
if (!RegexCharClass.IsSingleton(_leadingCharClasses[0].CharClass))
{
EmitMatchCharacterClass(_leadingCharClasses[0].CharClass, _leadingCharClasses[0].CaseInsensitive);
- BrtrueFar(l2);
+ Brtrue(l2);
}
else
{
}
Ldc(0);
- BrFar(l3);
+ Br(l3);
MarkLabel(l2);
break;
}
- // i = tmp; // or i += tmp if there's a loop
- // if (tmp < 0) goto returnFalse;
- Dup();
if (needLoop)
{
+ // i += tmp;
+ // if (tmp < 0) goto returnFalse;
+ using (RentedLocalBuilder tmp = RentInt32Local())
+ {
+ Stloc(tmp);
+ Ldloc(iLocal);
+ Ldloc(tmp);
+ Add();
+ Stloc(iLocal);
+ Ldloc(tmp);
+ Ldc(0);
+ BltFar(returnFalse);
+ }
+ }
+ else
+ {
+ // i = tmp;
+ // if (i < 0) goto returnFalse;
+ Stloc(iLocal);
Ldloc(iLocal);
- Add();
+ Ldc(0);
+ BltFar(returnFalse);
}
- Stloc(iLocal);
- Ldc(0);
- BltFar(returnFalse);
// if (i >= textSpan.Length - (_leadingCharClasses.Length - 1)) goto returnFalse;
if (_leadingCharClasses.Length > 1)
Mvfldloc(s_runtextField, runtextLocal);
Mvfldloc(s_runtextendField, runtextendLocal);
- // int runtextpos;
- // int originalruntextpos = runtextpos = this.runtextpos;
+ // int runtextpos = this.runtextpos;
+ // int originalruntextpos = this.runtextpos;
Ldthisfld(s_runtextposField);
- Dup();
Stloc(runtextposLocal);
+ Ldloc(runtextposLocal);
Stloc(originalruntextposLocal);
// The implementation tries to use const indexes into the span wherever possible, which we can do
Ldc(0);
Ldloc(originalruntextposLocal);
Ldloc(runtextposLocal);
- Callvirt(s_captureMethod);
+ Call(s_captureMethod);
// If the graph contained captures, undo any remaining to handle failed matches.
if ((node.Options & HasCapturesFlag) != 0)
Br(condition);
MarkLabel(body);
Ldthis();
- Callvirt(s_uncaptureMethod);
+ Call(s_uncaptureMethod);
MarkLabel(condition);
Ldthis();
- Callvirt(s_crawlposMethod);
+ Call(s_crawlposMethod);
Brtrue(body);
// Done:
{
startingCrawlpos = RentInt32Local();
Ldthis();
- Callvirt(s_crawlposMethod);
+ Call(s_crawlposMethod);
Stloc(startingCrawlpos);
}
Ldc(capnum);
Ldloc(startingRunTextPos);
Ldloc(runtextposLocal);
- Callvirt(s_captureMethod);
+ Call(s_captureMethod);
}
// Emits code to unwind the capture stack until the crawl position specified in the provided local.
Br(condition);
MarkLabel(body);
Ldthis();
- Callvirt(s_uncaptureMethod);
+ Call(s_uncaptureMethod);
MarkLabel(condition);
Ldthis();
- Callvirt(s_crawlposMethod);
+ Call(s_crawlposMethod);
Ldloc(startingCrawlpos);
Bne(body);
}
switch (node.Type)
{
case RegexNode.Boundary:
- Callvirt(s_isBoundaryMethod);
+ Call(s_isBoundaryMethod);
BrfalseFar(doneLabel);
break;
case RegexNode.NonBoundary:
- Callvirt(s_isBoundaryMethod);
+ Call(s_isBoundaryMethod);
BrtrueFar(doneLabel);
break;
case RegexNode.ECMABoundary:
- Callvirt(s_isECMABoundaryMethod);
+ Call(s_isECMABoundaryMethod);
BrfalseFar(doneLabel);
break;
default:
Debug.Assert(node.Type == RegexNode.NonECMABoundary);
- Callvirt(s_isECMABoundaryMethod);
+ Call(s_isECMABoundaryMethod);
BrtrueFar(doneLabel);
break;
}
Ldloc(runtextposLocal);
Ldc(1);
Sub();
- Callvirt(s_stringGetCharsMethod);
+ Call(s_stringGetCharsMethod);
Ldc('\n');
BneFar(doneLabel);
MarkLabel(success);
Ldc(textSpanPos);
Ldloca(textSpanLocal);
Call(s_spanGetLengthMethod);
- BgeUnFar(success);
+ BgeUn(success);
Ldloca(textSpanLocal);
Ldc(textSpanPos);
Call(s_spanGetItemMethod);
if (_hasTimeout)
{
Ldthis();
- Callvirt(s_checkTimeoutMethod);
+ Call(s_checkTimeoutMethod);
}
// Now generate the IL for the RegEx code saved in _regexopcode.
//: break Backward;
Ldthis();
Ldc(Operand(0));
- Callvirt(s_isMatchedMethod);
+ Call(s_isMatchedMethod);
BrfalseFar(_backtrack);
break;
//: Textto(Stacked(0));
ReadyPushTrack();
PopStack();
- Dup();
Stloc(_runtextposLocal!);
+ Ldloc(_runtextposLocal!);
DoPush();
Track();
{
Ldthis();
Ldc(Operand(1));
- Callvirt(s_isMatchedMethod);
+ Call(s_isMatchedMethod);
BrfalseFar(_backtrack);
}
Ldc(Operand(1));
Ldloc(stackedLocal);
Ldloc(_runtextposLocal!);
- Callvirt(s_transferCaptureMethod);
+ Call(s_transferCaptureMethod);
}
else
{
Ldc(Operand(0));
Ldloc(stackedLocal);
Ldloc(_runtextposLocal!);
- Callvirt(s_captureMethod);
+ Call(s_captureMethod);
}
PushTrack(stackedLocal);
PopTrack();
DoPush();
Ldthis();
- Callvirt(s_uncaptureMethod);
+ Call(s_uncaptureMethod);
if (Operand(0) != -1 && Operand(1) != -1)
{
Ldthis();
- Callvirt(s_uncaptureMethod);
+ Call(s_uncaptureMethod);
}
Back();
break;
Label l1 = DefineLabel();
PopStack();
- Dup();
using (RentedLocalBuilder mark = RentInt32Local())
{
Stloc(mark); // Stacked(0) -> temp
PushTrack(mark);
+ Ldloc(mark);
}
Ldloc(_runtextposLocal!);
Beq(l1); // mark == textpos -> branch
using (RentedLocalBuilder mark = RentInt32Local())
{
PopStack();
- Dup();
- Stloc(mark!); // Stacked(0) -> temp
+ Stloc(mark); // Stacked(0) -> temp
// if (oldMarkPos != -1)
Label l2 = DefineLabel();
// if (Textpos() != mark)
Label l1 = DefineLabel();
Ldloc(_runtextposLocal!);
+ Ldloc(mark);
Beq(l1); // mark == textpos -> branch
PushTrack(_runtextposLocal!);
Track();
PopStack();
Stloc(count); // count -> temp
PopStack();
- Dup();
using (RentedLocalBuilder mark = RentInt32Local())
{
Stloc(mark); // mark -> temp2
PushTrack(mark);
+ Ldloc(mark);
}
Label l1 = DefineLabel();
PopStack();
Ldc(1);
Sub();
- Dup();
- Stloc(count!);
+ Stloc(count);
+ Ldloc(count);
Ldc(0);
Blt(l1);
PopTrack();
Stloc(_runtextposLocal!);
PopTrack();
- Dup();
Stloc(cLocal);
+ Ldloc(cLocal);
Ldc(Operand(1));
Bge(l1); // Tracked(1) >= Operand(1) -> l1
DoPush();
ReadyPushStack();
Ldthis();
- Callvirt(s_crawlposMethod);
+ Call(s_crawlposMethod);
DoPush();
TrackUnique(Stackpop2);
break;
Label l1 = DefineLabel();
Label l2 = DefineLabel();
- PopStack();
- Ldthisfld(s_runtrackField);
- Ldlen();
- PopStack();
- Sub();
- Stloc(_runtrackposLocal!);
- Dup();
- Ldthis();
- Callvirt(s_crawlposMethod);
- Beq(l2);
+ using (RentedLocalBuilder stackedLocal = RentInt32Local())
+ {
+ PopStack();
+ Stloc(stackedLocal);
+ Ldthisfld(s_runtrackField);
+ Ldlen();
+ PopStack();
+ Sub();
+ Stloc(_runtrackposLocal!);
- MarkLabel(l1);
- Ldthis();
- Callvirt(s_uncaptureMethod);
- Dup();
- Ldthis();
- Callvirt(s_crawlposMethod);
- Bne(l1);
+ MarkLabel(l1);
+ Ldthis();
+ Call(s_crawlposMethod);
+ Ldloc(stackedLocal);
+ Beq(l2);
+ Ldthis();
+ Call(s_uncaptureMethod);
+ Br(l1);
+ }
MarkLabel(l2);
- Pop();
Back();
break;
}
Label l1 = DefineLabel();
Label l2 = DefineLabel();
- PopTrack();
-
- Dup();
- Ldthis();
- Callvirt(s_crawlposMethod);
- Beq(l2);
+ using (RentedLocalBuilder trackedLocal = RentInt32Local())
+ {
+ PopTrack();
+ Stloc(trackedLocal);
- MarkLabel(l1);
- Ldthis();
- Callvirt(s_uncaptureMethod);
- Dup();
- Ldthis();
- Callvirt(s_crawlposMethod);
- Bne(l1);
+ MarkLabel(l1);
+ Ldthis();
+ Call(s_crawlposMethod);
+ Ldloc(trackedLocal);
+ Beq(l2);
+ Ldthis();
+ Call(s_uncaptureMethod);
+ Br(l1);
+ }
MarkLabel(l2);
- Pop();
Back();
break;
}
Ldloc(_runtextposLocal!);
Ldloc(_runtextbegLocal!);
Ldloc(_runtextendLocal!);
- Callvirt(s_isBoundaryMethod);
+ Call(s_isBoundaryMethod);
if (Code() == RegexCode.Boundary)
{
BrfalseFar(_backtrack);
Ldloc(_runtextposLocal!);
Ldloc(_runtextbegLocal!);
Ldloc(_runtextendLocal!);
- Callvirt(s_isECMABoundaryMethod);
+ Call(s_isECMABoundaryMethod);
if (Code() == RegexCode.ECMABoundary)
{
BrfalseFar(_backtrack);
Ldc(i);
Add();
}
- Callvirt(s_stringGetCharsMethod);
+ Call(s_stringGetCharsMethod);
if (IsCaseInsensitive() && ParticipatesInCaseConversion(str[i]))
{
CallToLower();
Ldloc(_runtextposLocal!);
Ldc(str.Length - i);
Sub();
- Callvirt(s_stringGetCharsMethod);
+ Call(s_stringGetCharsMethod);
if (IsCaseInsensitive() && ParticipatesInCaseConversion(str[i]))
{
CallToLower();
Ldthis();
Ldc(Operand(0));
- Callvirt(s_isMatchedMethod);
+ Call(s_isMatchedMethod);
if ((_options & RegexOptions.ECMAScript) != 0)
{
Brfalse(AdvanceLabel());
Ldthis();
Ldc(Operand(0));
- Callvirt(s_matchLengthMethod);
- Dup();
+ Call(s_matchLengthMethod);
Stloc(lenLocal);
+ Ldloc(lenLocal);
if (!IsRightToLeft())
{
Ldloc(_runtextendLocal!);
Ldthis();
Ldc(Operand(0));
- Callvirt(s_matchIndexMethod);
+ Call(s_matchIndexMethod);
if (!IsRightToLeft())
{
Ldloc(lenLocal);
{
Ldc(1);
Sub();
- Dup();
Stloc(lenLocal);
+ Ldloc(lenLocal);
}
Sub(IsRightToLeft());
- Callvirt(s_stringGetCharsMethod);
+ Call(s_stringGetCharsMethod);
if (IsCaseInsensitive())
{
CallToLower();
Ldloc(lenLocal);
if (!IsRightToLeft())
{
- Dup();
+ Ldloc(lenLocal);
Ldc(1);
Sub();
Stloc(lenLocal);
}
Sub(IsRightToLeft());
- Callvirt(s_stringGetCharsMethod);
+ Call(s_stringGetCharsMethod);
if (IsCaseInsensitive())
{
CallToLower();
{
Ldc(1);
Sub();
- Dup();
Stloc(lenLocal);
+ Ldloc(lenLocal);
Add();
}
else
{
- Dup();
+ Ldloc(lenLocal);
Ldc(1);
Sub();
Stloc(lenLocal);
Sub();
}
- Callvirt(s_stringGetCharsMethod);
+ Call(s_stringGetCharsMethod);
if (Code() == RegexCode.Setrep)
{
Ldloc(_runtextbegLocal!);
}
Sub();
+ Stloc(lenLocal);
if (c != int.MaxValue)
{
Label l4 = DefineLabel();
- Dup();
+ Ldloc(lenLocal);
Ldc(c);
Blt(l4);
- Pop();
Ldc(c);
+ Stloc(lenLocal);
MarkLabel(l4);
}
- Stloc(lenLocal);
Label loopEnd = DefineLabel();
string? set = Code() == RegexCode.Setloop || Code() == RegexCode.Setloopatomic ? _strings![Operand(0)] : null;
Ldloc(iLocal);
Ldc(1);
Sub();
- Dup();
Stloc(iLocal);
+ Ldloc(iLocal);
Ldc(0);
if (Code() == RegexCode.Setloop || Code() == RegexCode.Setloopatomic)
{
Ldloc(_runtextbegLocal!);
}
Sub();
- if (c != int.MaxValue)
- {
- Label l4 = DefineLabel();
- Dup();
- Ldc(c);
- Blt(l4);
- Pop();
- Ldc(c);
- MarkLabel(l4);
- }
- Dup();
using (RentedLocalBuilder cLocal = RentInt32Local())
{
Stloc(cLocal);
+ if (c != int.MaxValue)
+ {
+ Label l4 = DefineLabel();
+ Ldloc(cLocal);
+ Ldc(c);
+ Blt(l4);
+ Ldc(c);
+ Stloc(cLocal);
+ MarkLabel(l4);
+ }
+ Ldloc(cLocal);
Ldc(0);
Ble(AdvanceLabel());
ReadyPushTrack();
}
}
+ using RentedLocalBuilder resultLocal = RentInt32Local();
+
// Analyze the character set more to determine what code to generate.
RegexCharClass.CharClassAnalysisResults analysis = RegexCharClass.Analyze(charClass);
}
Ldstr(charClass);
Call(s_charInClassMethod);
+ Stloc(resultLocal);
}
Label doneLabel = DefineLabel();
Br(doneLabel);
MarkLabel(comparisonLabel);
Ldc(0);
+ Stloc(resultLocal);
MarkLabel(doneLabel);
+ Ldloc(resultLocal);
return;
}
Br(doneLabel);
MarkLabel(comparisonLabel);
Ldc(1);
+ Stloc(resultLocal);
MarkLabel(doneLabel);
+ Ldloc(resultLocal);
return;
}
}
And();
Ldc(0);
CgtUn();
+ Stloc(resultLocal);
Br(doneLabel);
MarkLabel(comparisonLabel);
// character class were [A-Za-z0-9], so since the ch is now known to be >= 128, we
// can just fail the comparison.
Ldc(0);
+ Stloc(resultLocal);
}
else if (analysis.AllNonAsciiContained)
{
// class were [^\r\n], so since we just determined the ch to be >= 128, we can just
// give back success.
Ldc(1);
+ Stloc(resultLocal);
}
else
{
EmitCharInClass();
}
MarkLabel(doneLabel);
+ Ldloc(resultLocal);
}
/// <summary>Emits a timeout check.</summary>
RemUn();
Brtrue(label);
Ldthis();
- Callvirt(s_checkTimeoutMethod);
+ Call(s_checkTimeoutMethod);
MarkLabel(label);
}
Mvlocfld(_runtrackposLocal!, s_runtrackposField);
Mvlocfld(_runstackposLocal!, s_runstackposField);
Ldthis();
- Callvirt(s_dumpStateM);
+ Call(s_dumpStateM);
var sb = new StringBuilder();
if (_backpos > 0)