In such case, instead of failing, it would call the other function that was looked up, since it matches in IID and DISPID. It won't crash, but I don't think it would be quite correct, either.
That's the whole point, the reason it's safe and I don't see why you think it's incorrect. BTW, IID is intentionally abstract in my proposal; a bit closer to the actual meaning would be to use something like prototype ID once we have those (interface ID is just already available and close enough).
Continuing the above, IMO the following would make it the most robust: we look it up as mentioned from the func_info_t's dispid and IID, and then compare to see if it's the same `func_info_t` pointer.
Sure, but it can't compare `func_info_t`s by a pointer, it would need to compare IID or something like that anyway. So in your proposal, the opaque pointer serves as (ID,IID) carrier, nothing else.
BTW, is there a reason you renamed `IWineJSDispatchHost` to just `IJSDispatchHost` when it's Wine's own interface? I thought it's better to avoid ambiguity with a native interface, especially if we're to extend it (obviously we can't touch native interfaces), makes it a lot more obvious.
It's all Wine code, I don't see how putting "wine" in random places makes it any cleaner, but it's not a strong preference and I won't insist either way.