私はC#で非常に単純なクラスを作成しました:
class DisposableClass : IDisposable {
public void Dispose() { }
}
static void UsingClass() { // line 31
using (var dc = new DisposableClass()) { // line 32
DoSomething(dc); // line 33
} // line 34
} // line 35
WinDBGを使用したJITの後にネイティブコードをダンプしました。
0:000> !u 000007fe87d30120
Normal JIT generated code
SimpleConsole.Program.UsingClass()
Begin 000007fe87d30120, size 80
c:\projects\SimpleConsole\SimpleConsole\Program.cs @ 32:
>>> 000007fe`87d30120 55 push rbp
000007fe`87d30121 4883ec30 sub rsp,30h
000007fe`87d30125 488d6c2420 lea rbp,[rsp+20h]
000007fe`87d3012a 48896500 mov qword ptr [rbp],rsp
000007fe`87d3012e 48c7450800000000 mov qword ptr [rbp+8],0
000007fe`87d30136 488d0d6b47eeff lea rcx,[000007fe`87c148a8]
000007fe`87d3013d e8fe24665f call clr+0x2640 (000007fe`e7392640) (JitHelp: CORINFO_HELP_NEWSFAST) // new DisposableClass()
000007fe`87d30142 48894508 mov qword ptr [rbp+8],rax
c:\projects\SimpleConsole\SimpleConsole\Program.cs @ 33:
000007fe`87d30146 488b4d08 mov rcx,qword ptr [rbp+8]
000007fe`87d3014a e8d1beeeff call 000007fe`87c1c020 (SimpleConsole.Program.DoSomething(System.Object), mdToken: 0000000006000012)
000007fe`87d3014f 90 nop
000007fe`87d30150 90 nop
c:\projects\SimpleConsole\SimpleConsole\Program.cs @ 35:
000007fe`87d30151 488b4d08 mov rcx,qword ptr [rbp+8]
000007fe`87d30155 4c8d1dc4feeeff lea r11,[000007fe`87c20020]
000007fe`87d3015c ff15befeeeff call qword ptr [000007fe`87c20020] // Call Dispose()
000007fe`87d30162 90 nop
000007fe`87d30163 488d6510 lea rsp,[rbp+10h]
000007fe`87d30167 5d pop rbp
000007fe`87d30168 c3 ret
// I could understand the code above (without exception thrown).
c:\projects\SimpleConsole\SimpleConsole\Program.cs @ 32:
000007fe`87d30169 55 push rbp
000007fe`87d3016a 4883ec30 sub rsp,30h
000007fe`87d3016e 488b6920 mov rbp,qword ptr [rcx+20h]
000007fe`87d30172 48896c2420 mov qword ptr [rsp+20h],rbp
000007fe`87d30177 488d6d20 lea rbp,[rbp+20h]
c:\projects\SimpleConsole\SimpleConsole\Program.cs @ 35:
000007fe`87d3017b 48837d0800 cmp qword ptr [rbp+8],0
000007fe`87d30180 7417 je 000007fe`87d30199
000007fe`87d30182 488d1597feeeff lea rdx,[000007fe`87c20020]
000007fe`87d30189 488b4508 mov rax,qword ptr [rbp+8]
000007fe`87d3018d 803800 cmp byte ptr [rax],0
000007fe`87d30190 488b4d08 mov rcx,qword ptr [rbp+8]
000007fe`87d30194 4c8bda mov r11,rdx
000007fe`87d30197 ff12 call qword ptr [rdx]
000007fe`87d30199 90 nop
000007fe`87d3019a 4883c430 add rsp,30h
000007fe`87d3019e 5d pop rbp
000007fe`87d3019f c3 ret
例外なくコードを理解できましたが(上記のコメント)、例外がスローされたときにコードはどのように機能しますか?コードはコメントの下のコードにどのように入りますか?
アップデート:
ILから始めるべきだと考える人もいるので、以下のコードを貼り付けました。
.method private hidebysig static
void UsingClass () cil managed noinlining
{
// Method begins at RVA 0x23bc
// Code size 25 (0x19)
.maxstack 1
.locals init (
[0] class SimpleConsole.DisposableClass dc
)
IL_0000: newobj instance void SimpleConsole.DisposableClass::.ctor()
IL_0005: stloc.0
.try
{
IL_0006: ldloc.0
IL_0007: call void SimpleConsole.Program::DoSomething(object)
IL_000c: leave.s IL_0018
} // end .try
finally
{
IL_000e: ldloc.0
IL_000f: brfalse.s IL_0017
IL_0011: ldloc.0
IL_0012: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0017: endfinally
} // end handler
IL_0018: ret
} // end of method Program::UsingClass
try...finally
しかし、ILは完全なステートメントのようにここC#でほとんどすべてを保持しているので、それが役立つとは思いません。私が理解したいのは、ネイティブコードがここで例外を処理する方法です。