์๋ ์๋ค์!
์ด์ ๊ฐ์ ์ธํฐํ์ด์ค ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๋งค์ฐ ๊ฐ๋จํ ์ฑ์ด ์์ต๋๋ค.
namespace InterfaceCalls
{
public interface IFoo
{
int Bar();
}
class Program
{
public static int M1(IFoo foo)
{
return foo.Bar();
}
static void Main(string[] args)
{
M1(null);
}
}
}
๊ทธ๋ฌ๋ฉด 2.2์ ๋ํด ๋ค์ ASM์ด ์์ฑ๋ฉ๋๋ค(3.0์๋ add rsp,30h ๋์ lea rsp,[rbp]๊ฐ ์์).
return foo.Bar();
00007FFE7B521846 mov rcx,rsi
00007FFE7B521849 mov r11,7FFE7B410028h
00007FFE7B521853 cmp dword ptr [rcx],ecx
00007FFE7B521855 call qword ptr [7FFE7B410028h]
00007FFE7B52185B nop
00007FFE7B52185C add rsp,30h
00007FFE7B521860 pop rsi
00007FFE7B521861 ret
์ ์ฌ์ ์ผ๋ก ๋งค์ฐ ๋ฉ์ฒญํ๊ณ ์ด๋ณด์ ์ธ ์ง๋ฌธ์ ๋ํด ์ฃ์กํฉ๋๋ค :) ํ์ง๋ง ๋๊ตฐ๊ฐ ๋์๊ฒ ํํธ๋ฅผ ์ค ์ ์์ต๋๊น?
1 ์ฌ๊ธฐ์์ cmp ๋ช
๋ น์ด ํ์ํ ์ด์ (cmp ์ดํ์๋ ์กฐ๊ฑด๋ถ ์ ํ๊ฐ ์์)
2 7FFE7B410028h๋ ๋ฌด์์ด๋ฉฐ ์ฌ๊ธฐ์์ r11์ ๋ก๋ํ๋ ์ด์
3 ์ธํฐํ์ด์ค ํธ์ถ๋น cmp๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋๋ฌด ๋น์ธ์ง ์์ต๋๊น(์ด ๊ฒฝ์ฐ cml๋ก ์ธํด ๋ถ๊ธฐ ์์ธก์ด ๋๋ฝ๋ ์ ์์ต๋๊น?)
์ ๋ง ๊ณ ๋ง์!
cmp ๋ ์ด๊ธฐ null ๊ฒ์ฌ์
๋๋ค.
์ฌ๊ธฐ์์ ์ธํฐํ์ด์ค ๋์คํจ์น์ ๋ํด ์ฝ์ ์ ์์ต๋๋ค. https://github.com/dotnet/coreclr/blob/master/Documentation/botr/virtual-stub-dispatch.md
์ฌ๊ธฐ์์ cmp ๋ช ๋ น์ด ํ์ํ ์ด์ (cmp ์ดํ์๋ ์กฐ๊ฑด๋ถ ์ ํ๊ฐ ์์)
this
์ด null
this
๋ ํธ์ถ ์ง์ ์์ NullReferenceException
๋ฅผ ํธ๋ฆฌ๊ฑฐํ๋ ค๋ฉด.
7FFE7B410028h๋ ๋ฌด์์ด๋ฉฐ ์ฌ๊ธฐ์์ r11์ ๋ก๋ํ๋ ์ด์
์ธํฐํ์ด์ค ๊ตฌํ ๋ฉ์๋๋ฅผ ํ์ธํ๊ณ ํธ์ถํ๋ ์คํ ์ ๊ฐ๋ฆฌํค๋ "๊ฐ์ ์ "์ ์ฃผ์์ ๋๋ค. ๋ถํํ๋ ์ธํฐํ์ด์ค ๋ฉ์๋๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ "์ธ๋ผ์ธ"์ผ๋ก ์ํํ ์ ์๋ ๋น๊ต์ ๋ณต์กํ ์์ ์ ๋๋ค.
์ฒ์์๋ https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/coreclr/src/vm/amd64/VirtualCallStubAMD64.asm#L28์ ๊ฐ๋ฆฌํต๋๋ค.
์ผ๋ถ ๋ฌธ์๋ ์ฌ๊ธฐ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค(์ต์ ์ ๋ณด์ธ์ง๋ ํ์คํ์ง ์์).
https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md
๋น ๋ฅธ ๊ฐ์๋ฅผ ๋ณด๋ ค๋ฉด https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md#stubs ๋ก ๋ฐ๋ก ๊ฑด๋๋ธ ์ ์์ต๋๋ค.
์ธํฐํ์ด์ค ํธ์ถ๋น cmp๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋๋ฌด ๋น์ธ์ง ์์ต๋๊น(์ด ๊ฒฝ์ฐ cml๋ก ์ธํด ๋ถ๊ธฐ ์์ธก์ด ๋๋ฝ๋ ์ ์์ต๋๊น?)
์กฐ๊ฑด ๋ถ๊ธฐ ๋ช ๋ น์ด ์๋ ๋น๊ต ๋ช ๋ น์ด๋ฏ๋ก ๋ถ๊ธฐ ์์ธก๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ค์ ์ธํฐํ์ด์ค ํธ์ถ ๋น์ฉ์ ๋นํด ๋งค์ฐ ์ ๋ ดํฉ๋๋ค.
@mikedn @omariom ๊ฐ์ฌํฉ๋๋ค
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
this
์ดnull
this
๋ ํธ์ถ ์ง์ ์์NullReferenceException
๋ฅผ ํธ๋ฆฌ๊ฑฐํ๋ ค๋ฉด.์ธํฐํ์ด์ค ๊ตฌํ ๋ฉ์๋๋ฅผ ํ์ธํ๊ณ ํธ์ถํ๋ ์คํ ์ ๊ฐ๋ฆฌํค๋ "๊ฐ์ ์ "์ ์ฃผ์์ ๋๋ค. ๋ถํํ๋ ์ธํฐํ์ด์ค ๋ฉ์๋๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ "์ธ๋ผ์ธ"์ผ๋ก ์ํํ ์ ์๋ ๋น๊ต์ ๋ณต์กํ ์์ ์ ๋๋ค.
์ฒ์์๋ https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/coreclr/src/vm/amd64/VirtualCallStubAMD64.asm#L28์ ๊ฐ๋ฆฌํต๋๋ค.
์ผ๋ถ ๋ฌธ์๋ ์ฌ๊ธฐ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค(์ต์ ์ ๋ณด์ธ์ง๋ ํ์คํ์ง ์์).
https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md
๋น ๋ฅธ ๊ฐ์๋ฅผ ๋ณด๋ ค๋ฉด https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md#stubs ๋ก ๋ฐ๋ก ๊ฑด๋๋ธ ์ ์์ต๋๋ค.
์กฐ๊ฑด ๋ถ๊ธฐ ๋ช ๋ น์ด ์๋ ๋น๊ต ๋ช ๋ น์ด๋ฏ๋ก ๋ถ๊ธฐ ์์ธก๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ค์ ์ธํฐํ์ด์ค ํธ์ถ ๋น์ฉ์ ๋นํด ๋งค์ฐ ์ ๋ ดํฉ๋๋ค.