+
+ emit' :: J.Instruction -> CodeGen e s (Maybe (Word32, TrapInfo))
+ emit' (INVOKESPECIAL cpidx) = emitInvoke cpidx True
+ emit' (INVOKESTATIC cpidx) = emitInvoke cpidx False
+ emit' (INVOKEVIRTUAL cpidx) = do
+ -- get methodInfo entry
+ let mi@(MethodInfo methodname objname msig@(MethodSignature args _)) = buildMethodID cls cpidx
+ newNamedLabel (show mi) >>= defineLabel
+ -- objref lives somewhere on the argument stack
+ mov eax (Disp ((*4) $ fromIntegral $ length args), esp)
+ -- get methodtable ref
+ mov eax (Disp 0, eax)
+ -- get method offset
+ let nameAndSig = methodname `B.append` (encode msig)
+ let offset = unsafePerformIO $ getMethodOffset objname nameAndSig
+ -- make actual (indirect) call
+ calladdr <- getCurrentOffset
+ call (Disp offset, eax)
+ -- discard arguments on stack (+4 for "this")
+ let argcnt = 4 + ((methodGetArgsCount cls cpidx) * 4)
+ when (argcnt > 0) (add esp argcnt)
+ -- push result on stack if method has a return value
+ when (methodHaveReturnValue cls cpidx) (push eax)
+ return $ Just $ (calladdr, MI mi)