Description
Currently, the compiler does not support virtual overloads of class members, as one would expect from JS, but instead resolves the respective member statically from the contextual class type. This is noted in the docs so far but we should aim at resolving this.
What's necessary here is to decide on a mechanism to resolve the virtual function or field at runtime, using the unique class ids we already have in RTTI plus, possibly, unique ids for each virtual member.
Let's say we have A#foo()
with foo
possibly being overloaded by a class B extends A
, the implementation must call B#foo()
here if the actual instance we are dealing with is a B
, not an A
. Interfaces are similar.
One mechanism I thought about so far is to use the unique class ids (here: of A
and B
), and give the foo
member another internal unique id, so we can generate a runtime lookup function that performs a (memberId, classId) -> functionIndex or fieldOffset
mapping through a compiler-generated big switch. The implementation on the compiler side should skip making a runtime lookup if it is not necessary (that is: the class has no subclasses or respective interfaces) for perf reasons. If it is necessary, calling a virtually overloaded functions becomes a call_indirect
.
This isn't exactly scientific but is solely based on what I think would work, so if this problem has already been solved in better ways in the past, feel free to comment :)