-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Virtual functions invoked through Callable
aren't correctly dispatched to GDExtension
#99933
Comments
My initial feeling is that using a Also, looking at some of the examples in the OP, not all of them appear to deal with virtual methods. For example, the I think only Are there any other examples of this that you are aware of? |
No, in fact And as you see from my false-positive-riddled regex, there might be better approaches to finding others 😉 not sure how to do that systematically. Check for every method declared as virtual in |
I threw together draft PR #99981 that does what I described earlier to address
That sounds like it'd be a decent way to check! Of course, it only means that the right thing is being done at least once, not that there is no code doing the wrong thing, but it would have detected this case. |
That was super fast, thanks a lot! ❤️
So I extracted all virtual functions inside classes declared in Then, I extracted all cd path/to/godot
# Find all virtual calls in Godot code base
rg --no-filename --only-matching "GDVIRTUAL_CALL\([a-zA-Z0-9_]+" | sed 's/GDVIRTUAL_CALL(//' \
| sort | uniq > found-virtuals.txt Now I have two sorted unique files, I can get the difference. comm -23 api-declared-virtuals.txt found-virtuals.txt > never_called.txt
comm -13 api-declared-virtuals.txt found-virtuals.txt > called_but_not_exposed.txt There's a huge list for $ wc -l *.txt
1030 api-declared-virtuals.txt
4 called_but_not_exposed.txt
507 found-virtuals.txt
527 never_called.txt I checked a few and many have Here are the files, ran on commit 47bc374. |
@Bromeon: Thanks for doing this investigation!
Ah, I think you're missing the |
I just posted PR #100126 to address the ones in your called_but_not_exposed.txt. Two of them appear to be false positives ( (FYI, the |
Cool, thank you! I tried to look for rg --no-filename --only-matching "EXBIND[A-Za-z0-9_]+\([a-zA-Z0-9_]+, [a-zA-Z0-9_]+" | sd ".+, " "" > found-exbinds.txt
rg --no-filename --only-matching "EXBIND[A-Za-z0-9_]+\([a-zA-Z0-9_]+" | sd ".+, " "" > found-exbinds-2.txt With that (+previous list), I could limit the
Some of them seem to be false positives, e.g. my regex didn't catch the star here: EXBIND0R(PhysicsDirectSpaceState3D *, get_space_state) Could you maybe verify if those virtual methods are truly called or not? |
Could anyone verify if the remaining methods in my comment are registered correctly? |
Thanks for the reminder! I just went through all the items on your list, and most were false positives from
Error StreamPeerExtension::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) {
Error err;
if (GDVIRTUAL_CALL(_put_data, p_data, p_bytes, &r_sent, err)) {
return err;
}
WARN_PRINT_ONCE("StreamPeerExtension::_put_partial_data is unimplemented!");
return FAILED;
} I'll make a PR to fix it in a moment! |
Here's PR #100318 to fix that last issue |
Very good, thanks a lot for your help with hunting all those down! 💂♂ |
Tested versions
Issue description
Some virtual methods are not invoked via
GDVIRTUAL_CALL
, but using aCallable
:godot/editor/plugins/lightmap_gi_editor_plugin.cpp
Line 204 in 0f20e67
godot/editor/plugins/occluder_instance_3d_editor_plugin.cpp
Line 111 in 0f20e67
godot/modules/gdscript/gdscript_vm.cpp
Line 2570 in 0f20e67
godot/scene/resources/compositor.cpp
Line 108 in 0f20e67
godot/scene/resources/compositor.cpp
Line 185 in 0f20e67
(just briefly searched with regex
Callable\(.+, "_
, there might be more)Impact
This seems OK for GDScript, but for GDExtension this means that the call is not going through this API:
So a GDExtension binding that exposes a virtual method like
CompositorEffect._render_callback
will never have this method called. However, if the method is declared as a regular one, it works -- but this is quite unintuitive.Solution
I'm not sure what the best solution would be -- maybe an indirection?
I.e. could the
Callable
point to a function that invokesGDVIRTUAL_CALL
?The text was updated successfully, but these errors were encountered: