-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
MethodBind::get_hash() fails to hash default arguments #81386
Comments
CC @godotengine/gdextension |
Looking at other callers of godot/core/object/class_db.cpp Lines 224 to 228 in 8449592
And for reference, this looks correct: godot/core/object/class_db.cpp Lines 441 to 445 in 8449592
|
Eep! Thanks for catching this Have you tried fixing the bug and seeing how many hashes change? If it's a manageable number, we could possibly add a version of We had a similar issue in Godot 4.0.2 when a hashing bug was fixed - see #75779 For that issue, we also discussed registering compatibility methods with an explicit hash, but that time we decided it wasn't worth it. But since this has now come up twice, maybe this is a tool we need? Personally, I'd really love not to break compatibility in Godot 4.2, if possible. |
An explicit hash sounds like a reasonable approach. Fixing the bug and diffing the extension_api.json shows 817 changed hashes (out of 13042). Wouldn't want to write all that manually, but should be doable with a script. EDIT: Corrected the number of hashes |
Oof, 817 is quite a few, but relatively speaking only ~6%.
Yeah, I think with a script we could generate the It'll just be a question of whether or not the other contributors/maintainers are OK with adding all of that. |
Sounds like we'd be generating |
Well, if this turns out to be unacceptable, we could try to consolidate all these particular fixes into a single file? Or, we could add something in Personally, I'm open to any option that'll be acceptable to everyone else and means we don't have to break compatibility again for Godot 4.2 :-) |
That sounds like an interesting approach. |
The primary downside of that approach is that it would add the compatibility registration for any method that could generate an incorrect hash (meaning, any method with default arguments where not all arguments have a default) regardless of whether it had a bad hash in Godot 4.1 or not. So, like, even in Godot 4.9, if we add a method that has two arguments and only one default, this approach would lead to registering the compatibility method with a Godot 4.1 hash, even though we don't really need it, since the method didn't even exist in Godot 4.1. Whereas any approach where we specifically register compatibility hashes for the affected methods would target this only where needed. That said, this may be an acceptable downside if bloating the code with all the specific instances is a blocker :-) |
The other option I thought of would be to modify This avoids adding hundreds of compatibility methods, but --validate-extension-api would complain about the missing compatibility. I'm not sure if anything else would break. |
Yeah, that's also a possibility. Although, I think |
Can we make a single hashmap with the precomputed old and new hashes, kept in a single file, to use in |
Yeah, I think there's a couple of ways we could keep all the ones from this issue in a single file. I may not have a chance to for a couple days, but there's a few ideas I want to experiment with. |
Discussed at the GDExtension meeting, and we agree that some approach that isolates the changes to a single place and specifically addresses this problem is the way to go. |
Godot version
v4.2.dev.custom_build [8449592]
System information
Godot v4.2.dev (8449592) - Windows 10.0.22621 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 4070 Ti (NVIDIA; 31.0.15.3713) - 13th Gen Intel(R) Core(TM) i5-13600K (20 Threads)
Issue description
The GDExtension method hash is supposed to include the values of its default arguments. This works for methods where every argument has a default, but fails when there are some arguments without a default.
This is because
MethodBind::get_hash()
starts counting at 0:godot/core/object/method_bind.cpp
Lines 49 to 53 in 8449592
But
get_default_argument
expects the absolute index of the argument in the function signature:godot/core/object/method_bind.h
Lines 82 to 90 in 8449592
So instead of hashing the actual default value, we end up hashing a nil Variant.
Fixing this would be a major compatibility break because the method hashes will change, so it probably requires some discussion.
Steps to reproduce
In the godot-cpp test project, add call to one of the affected methods. For example:
add_child(memnew(Node));
Set a debugger breakpoint inside
MethodBind::get_default_argument
with a condition ofidx < 0
.Minimal reproduction project
N/A
The text was updated successfully, but these errors were encountered: