In essence it comes down to this, yes, but we're talking about low level code here. An interface has a different Self parameter than its instance, so that needs to be adjusted and then the correct method needs to be put into the VMT. All that done with as less code as possible (e.g. your example would generate a full stack frame merely for calling the function while interface stubs contain the offset adjustment and a jmp instruction). But as I said, the last time I looked at that code I was far more novice regarding the compiler's internals...
In case of delegation we can't use adjustment of Self (such as "ADD Self, offset VMT - offset IInterface1VMT"), as we do, when interface is implemented in current object - we need to pass Object2 as Self. So it should be simple:
procedure TObject1.DoSomething(X:TSomeType);
asm
{All, we actually need - to pass the same parameters to another routine.
This can actually be done by code optimizer.
Assembler is expected to use automatic [] brackets, as TASM do for example.}
MOV Self, Self.Object2 {Self should be register}
JMP TObject2.DoSomething {In case of static method}
end;
I don't know. It's hard to implement complex features, when every feature has to have "raw" straight through implementation. It's always better, when you can implement one feature on the top of another already existing one. In this case all you would need - to have some code templates, that would be injected into program and handled by lower layer of abstraction. As I know, Delphi uses this approach. Have you seen that bunch of "code templates" in their System module? They use simple approach: use optimized assembler templates, if possible, and if not - use pure Pascal.
For example, Object2 - is actually property. Therefore it can be both static field or getter method. Also it can be object or interface. TObject2.DoSomething - can also be virtual or even dynamic method. Too many things to take into account, especially if all this code is already implemented elsewhere. It's always better to use high level template, so existing lower level of abstraction would handle all this problems for you. Delphi simply uses some inline template routines, like CallDynaMethod.
P.S. Question about Lazarus. Is assembler code debugging possible in Lazarus? When I open Debug->CPU window in Delphi - F7/F8 buttons start to work per asm instruction, like if I would debug my program in Turbo Debugger. But in Lazarus they continue to work per source line.