I implemented support for calling a superclass implementation of a method - it uses Java syntax:
class CallA
{
virtual Void foo(Str s) { val = s }
Str val;
}
class CallB extends CallA
{
override Void foo(Str s) { super.foo(s); val = "[" + val + "]" }
}
For this scenerio we require an opcode for invoking CallA.foo in CallB which isn't virtual - otherwise the super call to foo will be virtual which will in turn invoke CallB.foo and we get a stack overflow. So I renamed CallInstance to CallVirtual, and added a new CallNonVirtual opcode.
Then thinking I would be clever I switched the assembler to use CallNonVirtual whenever the method wasn't virtual (since this is the common case in Fan). However I was disappointed to learn that Java's invokespecial opcode is really stupid. It doesn't really work as a true invoke non-virtual, but has some extra verification rules: "Each invokespecial instruction must name an instance initialization method, a method in the current class, or a method in a superclass of the current class". So I had to make Fan's assembler follow those rules too - if the target is super or the target is this and the method is non-virtual, then I will use CallNonVirtual, otherwise CallVirtual (even if the method isn't virtual).
I have no idea how these rules will work out for John's code in the CLR. They just have call, calli, and callvirt opcodes - I suspect mapping every CallVirtual to callvirt won't work. But if John has to resolve every method anyways it may be a moot issue.
brian Mon 13 Mar 2006
I implemented support for calling a superclass implementation of a method - it uses Java syntax:
For this scenerio we require an opcode for invoking CallA.foo in CallB which isn't virtual - otherwise the super call to foo will be virtual which will in turn invoke CallB.foo and we get a stack overflow. So I renamed CallInstance to CallVirtual, and added a new CallNonVirtual opcode.
Then thinking I would be clever I switched the assembler to use CallNonVirtual whenever the method wasn't virtual (since this is the common case in Fan). However I was disappointed to learn that Java's invokespecial opcode is really stupid. It doesn't really work as a true invoke non-virtual, but has some extra verification rules: "Each invokespecial instruction must name an instance initialization method, a method in the current class, or a method in a superclass of the current class". So I had to make Fan's assembler follow those rules too - if the target is super or the target is this and the method is non-virtual, then I will use CallNonVirtual, otherwise CallVirtual (even if the method isn't virtual).
I have no idea how these rules will work out for John's code in the CLR. They just have call, calli, and callvirt opcodes - I suspect mapping every CallVirtual to callvirt won't work. But if John has to resolve every method anyways it may be a moot issue.