Is it done at compile time? Because the index into the MethodTable of the method to call could be determined at compile time.
Or ist it done at runtime?
And what is the method token argument to callvirt?
I've done a blog post about how callvirt works at runtime.
At compile time, the argument to the callvirt
instruction takes a concrete MethodDef
or MemberRef
token, referring to the 'base' method to call (this defines the method arguments, among other things)
At runtime, as part of doing type initialization, the CLR works out which methods override each other, and assigns a slot in the MethodTable
vtable for each virtual 'base' method. Each type then fills that slot with a pointer to whatever actual method implementation should be used for virtual calls to that base method for instances of that type. That is then used to do the virtual call, as described in my post.