#49 Call opcodes

brian Mon 13 Mar 2006

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.

Login or Signup to reply.