Ich habe mich immer gefragt: Wie wird die berüchtigte VB.NET-Anweisung "On Error Resume Next" in CIL konvertiert? Umfasst es jede Zeile mit try ... Fängen?CIL-Implementierung von On Error Resume Next
Antwort
Gehe zu.
Sie können try-catch nicht mit der alten Fehlerbehandlung in einer Methode kombinieren. Wenn Sie On Error Resume Next
verwenden, erhält jede einzelne Codezeile in der Methode eine Bezeichnung sowie eine eindeutige Kennung. # -Code in pseudo-C:
int currentId = 0;
Label1:
currentId = 1;
Line1();
Label2:
currentId = 2;
Line2();
Label3:
currentId = 3;
Line3();
Exit:
Das gesamte Verfahren wird in einem Try-Catch gewickelt. Wenn die Ausnahmebedingung trifft, prüft der Catch-Handler currentId
und führt eine einfache goto
zum nächsten Label in Zeile (und ProjectError
ist gesetzt). In unserem Fall wäre es etwa so aussehen:
try
{
...
}
catch (Exception ex)
{
ProjectData.SetProjectError(ex);
if (currentId == 1) goto Label2;
if (currentId == 2) goto Label3;
if (currentId == 3) goto Exit;
}
Wohlgemerkt, dies ist nur eine Implementierung Detail I von decompiling einer VB.NET Anwendung bekam. Das einzige vertragliche Verhalten ist dasjenige, das in On Error Resume Next
definiert ist, was im Grunde darauf hinausläuft, "Projektfehler zu setzen und zur nächsten Anweisung fortzufahren".
Hier gehen Sie:
Public Sub A()
End Sub
Public Sub B()
End Sub
Public Sub C()
End Sub
Public Sub D()
End Sub
Public Sub E()
End Sub
Public Sub Test()
A()
On Error GoTo ErrorHandler
B()
Exit Sub
C()
ErrorHandler:
D()
Resume Next
E()
End Sub
Compiliert zu (ohne die zusätzlichen Methoden):
.method public static void Test() cil managed
{
// Code size 201 (0xc9)
.maxstack 3
.locals init (int32 V_0,
int32 V_1,
int32 V_2)
IL_0000: ldc.i4.1
IL_0001: stloc.2
IL_0002: call void VBTest.Program::A()
IL_0007: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_000c: ldc.i4.2
IL_000d: stloc.0
IL_000e: ldc.i4.3
IL_000f: stloc.2
IL_0010: call void VBTest.Program::B()
IL_0015: leave IL_00c0
IL_001a: ldc.i4.5
IL_001b: stloc.2
IL_001c: call void VBTest.Program::C()
IL_0021: ldc.i4.6
IL_0022: stloc.2
IL_0023: call void VBTest.Program::D()
IL_0028: ldc.i4.7
IL_0029: stloc.2
IL_002a: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_002f: ldloc.1
IL_0030: brtrue.s IL_0047
IL_0032: ldc.i4 0x800a0014
IL_0037: call class [mscorlib]System.Exception [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::CreateProjectError(int32)
IL_003c: throw
IL_003d: ldc.i4.s 9
IL_003f: stloc.2
IL_0040: call void VBTest.Program::E()
IL_0045: leave.s IL_00c0
IL_0047: ldloc.1
IL_0048: ldc.i4.1
IL_0049: add
IL_004a: ldc.i4.0
IL_004b: stloc.1
IL_004c: switch (
IL_007d,
IL_0000,
IL_0007,
IL_000e,
IL_0015,
IL_001a,
IL_0021,
IL_0028,
IL_003d,
IL_003d,
IL_0045)
IL_007d: leave.s IL_00b5
IL_007f: ldloc.2
IL_0080: stloc.1
IL_0081: ldloc.0
IL_0082: switch (
IL_0093,
IL_0047,
IL_0021)
IL_0093: leave.s IL_00b5
IL_0095: isinst [mscorlib]System.Exception
IL_009a: ldnull
IL_009b: cgt.un
IL_009d: ldloc.0
IL_009e: ldc.i4.0
IL_009f: cgt.un
IL_00a1: and
IL_00a2: ldloc.1
IL_00a3: ldc.i4.0
IL_00a4: ceq
IL_00a6: and
IL_00a7: endfilter
IL_00a9: castclass [mscorlib]System.Exception
IL_00ae: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(class [mscorlib]System.Exception)
IL_00b3: leave.s IL_007f
IL_00b5: ldc.i4 0x800a0033
.try IL_0000 to IL_0095 filter IL_0095 handler IL_00a9 to IL_00b5
IL_00ba: call class [mscorlib]System.Exception [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::CreateProjectError(int32)
IL_00bf: throw
IL_00c0: ldloc.1
IL_00c1: brfalse.s IL_00c8
IL_00c3: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_00c8: ret
} // end of method Program::Test
Diese abberation mit Reflektor auf diese dekompilierten wird:
public static void Test()
{
int num2;
try
{
int num3;
Label_0000:
num3 = 1;
A();
Label_0007:
ProjectData.ClearProjectError();
int num = 2;
Label_000E:
num3 = 3;
B();
goto Label_00C0;
Label_001A:
num3 = 5;
C();
Label_0021:
num3 = 6;
D();
Label_0028:
num3 = 7;
ProjectData.ClearProjectError();
if (num2 != 0)
{
goto Label_0047;
}
throw ProjectData.CreateProjectError(-2146828268);
Label_003D:
num3 = 9;
E();
goto Label_00C0;
Label_0047:
num2 = 0;
switch ((num2 + 1))
{
case 1:
goto Label_0000;
case 2:
goto Label_0007;
case 3:
goto Label_000E;
case 4:
case 10:
goto Label_00C0;
case 5:
goto Label_001A;
case 6:
goto Label_0021;
case 7:
goto Label_0028;
case 8:
case 9:
goto Label_003D;
default:
goto Label_00B5;
}
Label_007F:
num2 = num3;
switch (num)
{
case 0:
goto Label_00B5;
case 1:
goto Label_0047;
case 2:
goto Label_0021;
}
}
catch (object obj1) when (?)
{
ProjectData.SetProjectError((Exception) obj1);
goto Label_007F;
}
Label_00B5:
throw ProjectData.CreateProjectError(-2146828237);
Label_00C0:
if (num2 != 0)
{
ProjectData.ClearProjectError();
}
}
Abgesehen von den Tatsache, dass es eine Reihe von Schaltern und Gotos verwendet, ich habe keine Ahnung, was dieser Code tatsächlich tut.
- 1. Was macht die "On Error Resume Next" Anweisung?
- 2. On Error Resume Weiter in Javascript?
- 3. mit „On Error Resume Next“ im klassischen ASP, und wie Fehler all
- 4. Programmfehler Subscript out of Range ... Versuchen On Error Resume
- 5. VbScript Error-Objekt von On Error-Anweisung gelöscht
- 6. Schütteln Fehler ohne Verwendung "bei Fehler resume next"
- 7. On Error Goto 0 nicht zurücksetzen Fehlerbehandlung
- 8. Macro Error - Next ohne Für
- 9. Routing Error Keine Route stimmt überein [POST] "/ resume/58"
- 10. Gibt es auf Error Resume Label in Excel VBA?
- 11. Retry on SFTP Permission error
- 12. Wie verwende ich On Error GoTo?
- 13. Error " '(' erwartet" on line 5
- 14. C# Bei Fehler resume
- 15. Was ist der Unterschied zwischen next (err) und next (new Error (err)) in nodejs?
- 16. Resume Activity from Fragment
- 17. mod_dav_svn loading error on centos 5
- 18. Firebug: Gibt es einen Break On Next Tastaturkürzel?
- 19. Seite nicht gefunden (404) error on django
- 20. Sovren Resume Parser - Python
- 21. Resume Count in IsolatedStorageSettings
- 22. Resume Hintergrund App
- 23. Benachrichtigung Resume Aktivität
- 24. Resume Daten von URLSessionDownloadTask Immer Null
- 25. angular 2 on von submit error self.context.onSubmit ist keine Funktion
- 26. Resume shortlisting mit Neural Network
- 27. jQuery (dies) .find ('title'). Next(). Next(). Next(). Eq (0) .text();
- 28. lftp pause und resume herunterladen
- 29. Alternative zu Thread.suspend() und .resume()
- 30. Pausieren & Resume Android Repo Sync