рд╣рд╛рдп рджреЛрд╕реНрддреЛрдВ!
рдПрдХ рдмрд╣реБрдд рд╣реА рд╕рд░рд▓ рдРрдк рд╣реИ, рдЗрд╕ рддрд░рд╣ рдХреЙрд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рдзрд┐ред
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 рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрдПрд╕рдПрдо рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ (3.0 рдХреЗ рд▓рд┐рдП рд▓реА рдЖрд░рдПрд╕рдкреА рд╣реИ, [рдЖрд░рдмреАрдкреА] рдЖрд░рдПрд╕рдкреА рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрдЬрд╛рдп, 30 рдПрдЪ)
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 рд╣рдореЗрдВ рдпрд╣рд╛рдВ рд╕реАрдПрдордкреА рдирд┐рд░реНрджреЗрд╢ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ (рд╕реАрдПрдордкреА рдХреЗ рдмрд╛рдж рдХреЛрдИ рд╕рд╢рд░реНрдд рдЫрд▓рд╛рдВрдЧ рдирд╣реАрдВ рд╣реИ)
2 7FFE7B410028h рдХреНрдпрд╛ рд╣реИ рдФрд░ рд╣рдо рдпрд╣рд╛рдВ r11 рдореЗрдВ рдХреНрдпреЛрдВ рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ
3 рдХреНрдпрд╛ рд╕реАрдПрдордкреА рдкреНрд░рддрд┐ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЙрд▓ рд╣реЛрдирд╛ рдмрд╣реБрдд рдорд╣рдВрдЧрд╛ рдирд╣реАрдВ рд╣реИ (рдХреНрдпрд╛ рдЙрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕реАрдПрдордПрд▓ рд╢рд╛рдЦрд╛ рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдорд┐рд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИ?)
рдЖрдкрдХрд╛ рдмрд╣реБрдд рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рдж!
рд╕реАрдПрдордкреА рдПрдХ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╢реВрдиреНрдп рдЬрд╛рдВрдЪ рд╣реИред
рдЖрдк рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░реЗрд╖рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдпрд╣рд╛рдБ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ https://github.com/dotnet/coreclr/blob/master/Documentation/botr/virtual-stub-dispatch.md
рд╣рдореЗрдВ рдпрд╣рд╛рдВ рд╕реАрдПрдордкреА рдирд┐рд░реНрджреЗрд╢ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ (рд╕реАрдПрдордкреА рдХреЗ рдмрд╛рдж рдХреЛрдИ рд╕рд╢рд░реНрдд рдЫрд▓рд╛рдВрдЧ рдирд╣реАрдВ рд╣реИ)
рдХреЙрд▓ рдХреЗ рдмрд┐рдВрджреБ рдкрд░ NullReferenceException
рдЯреНрд░рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрдм this
null
ред
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 рдкрд░ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдХреНрдпрд╛ рд╕реАрдПрдордкреА рдкреНрд░рддрд┐ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЙрд▓ рд╣реЛрдирд╛ рдмрд╣реБрдд рдорд╣рдВрдЧрд╛ рдирд╣реАрдВ рд╣реИ (рдХреНрдпрд╛ рдЙрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕реАрдПрдордПрд▓ рд╢рд╛рдЦрд╛ рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдорд┐рд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИ?)
рдпрд╣ рдПрдХ рддреБрд▓рдирд╛рддреНрдордХ рдирд┐рд░реНрджреЗрд╢ рд╣реИ, рд╕рд╢рд░реНрдд рд╢рд╛рдЦрд╛ рдирд┐рд░реНрджреЗрд╢ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХрд╛ рд╢рд╛рдЦрд╛ рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рд╕реЗ рдХреЛрдИ рд▓реЗрдирд╛-рджреЗрдирд╛ рдирд╣реАрдВ рд╣реИред рдФрд░ рдпрд╣ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЙрд▓ рд▓рд╛рдЧрдд рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рд╕рд╕реНрддрд╛ рд╣реИред
@mikedn @omariom рдзрдиреНрдпрд╡рд╛рдж
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рдХреЙрд▓ рдХреЗ рдмрд┐рдВрджреБ рдкрд░
NullReferenceException
рдЯреНрд░рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрдмthis
null
редрдПрдХ "рдЗрдирдбрд╛рдпрд░реЗрдХреНрд╢рди рд╕реЗрд▓" рдХрд╛ рдкрддрд╛ рдЬреЛ рдПрдХ рд╕реНрдЯрдм рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рдзрд┐ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд╣рд▓ рдХрд░рдирд╛ рдПрдХ рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдЬрдЯрд┐рд▓ рдСрдкрд░реЗрд╢рди рд╣реИ рдЬрд┐рд╕реЗ "рдЗрдирд▓рд╛рдЗрди" рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ рдпрд╣ 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 рдкрд░ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдпрд╣ рдПрдХ рддреБрд▓рдирд╛рддреНрдордХ рдирд┐рд░реНрджреЗрд╢ рд╣реИ, рд╕рд╢рд░реНрдд рд╢рд╛рдЦрд╛ рдирд┐рд░реНрджреЗрд╢ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХрд╛ рд╢рд╛рдЦрд╛ рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рд╕реЗ рдХреЛрдИ рд▓реЗрдирд╛-рджреЗрдирд╛ рдирд╣реАрдВ рд╣реИред рдФрд░ рдпрд╣ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЙрд▓ рд▓рд╛рдЧрдд рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рд╕рд╕реНрддрд╛ рд╣реИред