-
Notifications
You must be signed in to change notification settings - Fork 241
Async state machine incorrect translation #1041
Comments
Hm, that's an interesting one. Thanks for spotting it |
Based on ILSpy decompilation, we try to jump into middle of switch. Looks like, it is root cause of problem. |
Might be a case where it would be easier to stop relying on ILSpy for control flow, and just do asm.js-style goto for anything other than if statements and for loops. |
Look like I was able to simplify example. Test case: //@useroslyn
//@compileroption /optimize
using System;
public static class Program {
public static void Main (string[] args) {
MoveNext();
}
private static void MoveNext () {
int state = -1;
switch (state) {
case 2:
goto LABEL_2;
case 0:
state = -1;
break;
case 1:
state = -1;
goto LABEL_1;
default:
Console.WriteLine("1");
break;
}
Console.WriteLine("2");
LABEL_1:
Console.WriteLine("3");
LABEL_2:
Console.WriteLine("4");
}
} Output: function Program_MoveNext () {
var $label0 = 0;
$labelgroup0:
while (true) {
switch ($label0) {
case 0: /* $entry0 */
switch (-1) {
case 0:
break;
case 1:
$label0 = 3 /* goto IL_32 */ ;
continue $labelgroup0;
case 2:
$label0 = 1 /* goto IL_3C */ ;
continue $labelgroup0;
default:
$T01().WriteLine("1");
break;
}
$label0 = 2 /* goto $switchExit0 */ ;
continue $labelgroup0;
case 1: /* IL_3C */
$T01().WriteLine("4");
return;
$label0 = 2 /* goto $switchExit0 */ ;
continue $labelgroup0;
case 2: /* $switchExit0 */
$label0 = 3 /* goto IL_32 */ ;
continue $labelgroup0;
case 3: /* IL_32 */
$T01().WriteLine("3");
$label0 = 1 /* goto IL_3C */ ;
continue $labelgroup0;
}
}
/* Original label $exit0 */
$T01().WriteLine("2");
}; So, it skipped |
After ILSpy it looks like: private static void MoveNext2()
{
switch (-1)
{
case 0:
break;
case 1:
goto IL_32;
case 2:
IL_3C:
Console.WriteLine("4");
return;
default:
Console.WriteLine("1");
break;
}
Console.WriteLine("2");
IL_32:
Console.WriteLine("3");
goto IL_3C;
} So, once again we try to do goto inside switch block. Looks like |
It seems like maybe LabelAnalyzer could merge the labels for |
We have one more issue with incorrect goto translation in Roslyn compiled state machine. Issue only reproducible within assemblies compiled with optimizations.
Test case:
Method that translated incorrect:
Expected output:
Lock\nDispose\nLock\nwork\nDispose
Actualoutput:
Lock\nwork\nDispose
The text was updated successfully, but these errors were encountered: