-
-
Notifications
You must be signed in to change notification settings - Fork 20.2k
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
Refactored binding system for core types #42780
Refactored binding system for core types #42780
Conversation
5150aeb
to
8405443
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be really nice for GDScript
_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr) { | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this actually used? Or is it something necessary to make the template magic work?
Getting more warnings locally with GCC 10.2.0 which the CI somehow seemed to miss:
I'll see if I can fix them myself. |
8405443
to
328cddb
Compare
I force pushed an amend that should fix the remaining GCC warnings. Diff with the previous commit: diff --git a/core/callable_method_pointer.h b/core/callable_method_pointer.h
index a49e8b61ec..a2275452b4 100644
--- a/core/callable_method_pointer.h
+++ b/core/callable_method_pointer.h
@@ -116,7 +116,7 @@ struct VariantCasterAndValidate<const T &> {
#endif // DEBUG_METHODS_ENABLED
-// GCC 8 raises "parameter 'p_args' set but not used" here, probably using a
+// GCC raises "parameter 'p_args' set but not used" here, probably using a
// template version that does not have arguments and thus sees it unused, but
// obviously the template can be used for functions with and without them, and
// the optimizer will get rid of it anyway.
@@ -158,7 +158,8 @@ void call_with_ptr_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P..
PtrToArg<R>::encode(p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...), r_ret);
}
-#endif
+#endif // PTRCALL_ENABLED
+
template <class T, class... P, size_t... Is>
void call_with_validated_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
(p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
@@ -179,10 +180,6 @@ void call_with_validated_variant_args_static_retc_helper(T *p_instance, R (*p_me
VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
}
-#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
template <class T, class... P>
void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
#ifdef DEBUG_METHODS_ENABLED
@@ -223,7 +220,7 @@ void call_with_ptr_args_static_retc(T *p_instance, R (*p_method)(T *, P...), con
call_with_ptr_args_static_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-#endif
+#endif // PTRCALL_ENABLED
template <class T, class... P>
void call_with_validated_variant_args(Variant *base, void (T::*p_method)(P...), const Variant **p_args) {
@@ -255,18 +252,28 @@ void call_get_argument_type_helper(int p_arg, int &index, Variant::Type &type) {
index++;
}
+// GCC's warnings checker really doesn't like variadic voodoo.
+// It sees `index` unused below in some branches, so it raises a warning.
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+
template <class... P>
Variant::Type call_get_argument_type(int p_arg) {
Variant::Type type = Variant::NIL;
int index = 0;
- // I think rocket science is simpler than modern C++
+ // I think rocket science is simpler than modern C++.
using expand_type = int[];
expand_type a{ 0, (call_get_argument_type_helper<P>(p_arg, index, type), 0)... };
- (void)a; //supress warnings
- (void)index; //gcc is broken
+ (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
return type;
}
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
#else
template <class... P>
@@ -274,7 +281,7 @@ Variant::Type call_get_argument_type(int p_arg) {
return Variant::NIL;
}
-#endif
+#endif // DEBUG_METHODS_ENABLED
template <class T, class... P>
class CallableCustomMethodPointer : public CallableCustomMethodPointerBase {
@@ -331,15 +338,6 @@ Callable create_custom_callable_function_pointer(T *p_instance,
// VERSION WITH RETURN
-// GCC 8 raises "parameter 'p_args' set but not used" here, probably using a
-// template version that does not have arguments and thus sees it unused, but
-// obviously the template can be used for functions with and without them, and
-// the optimizer will get rid of it anyway.
-#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
-#endif
-
template <class T, class R, class... P, size_t... Is>
void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
r_error.error = Callable::CallError::CALL_OK;
@@ -351,10 +349,6 @@ void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), co
#endif
}
-#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
template <class T, class R, class... P>
void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
#ifdef DEBUG_METHODS_ENABLED
@@ -429,15 +423,6 @@ Callable create_custom_callable_function_pointer(T *p_instance,
// CONST VERSION WITH RETURN
-// GCC 8 raises "parameter 'p_args' set but not used" here, probably using a
-// template version that does not have arguments and thus sees it unused, but
-// obviously the template can be used for functions with and without them, and
-// the optimizer will get rid of it anyway.
-#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
-#endif
-
template <class T, class R, class... P, size_t... Is>
void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
r_error.error = Callable::CallError::CALL_OK;
@@ -449,10 +434,6 @@ void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) co
#endif
}
-#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
template <class T, class R, class... P>
void call_with_variant_args_retc(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
#ifdef DEBUG_METHODS_ENABLED
@@ -542,4 +523,8 @@ void call_with_variant_args_retc_static_helper(T *p_instance, R (*p_method)(T *,
#endif
}
+#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
#endif // CALLABLE_METHOD_POINTER_H
diff --git a/core/math/plane.h b/core/math/plane.h
index 6017cdb5c1..1386b0a2cb 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -61,7 +61,7 @@ public:
bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection) const;
bool intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 *p_intersection) const;
- //for Variant binding
+ // For Variant bindings.
Variant intersect_3_bind(const Plane &p_plane1, const Plane &p_plane2) const;
Variant intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const;
Variant intersects_segment_bind(const Vector3 &p_begin, const Vector3 &p_end) const;
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 98fd78a06f..27dab8db6e 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -4763,6 +4763,7 @@ Vector<uint8_t> String::to_utf8_buffer() const {
return retval;
}
+
Vector<uint8_t> String::to_utf16_buffer() const {
const String *s = this;
if (s->empty()) {
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 5bc5d543df..8246ccf2b0 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -108,6 +108,13 @@ struct _VariantCall {
size_t missing = sizeof...(P) - (size_t)p_argcount;
if (missing <= (size_t)default_values.size()) {
args = (const Variant **)alloca(sizeof...(P) * sizeof(const Variant *));
+ // GCC fails to see that `sizeof...(P)` cannot be 0 here given the previous
+ // conditions, so it raises a warning on the potential use of `i < 0` as the
+ // execution condition.
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#endif
for (size_t i = 0; i < sizeof...(P); i++) {
if (i < (size_t)p_argcount) {
args[i] = p_args[i];
@@ -115,6 +122,9 @@ struct _VariantCall {
args[i] = &default_values[i - p_argcount + (default_values.size() - missing)];
}
}
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
} else {
#ifdef DEBUG_ENABLED
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
@@ -298,6 +308,13 @@ struct _VariantCall {
size_t missing = sizeof...(P) - (size_t)p_argcount;
if (missing <= (size_t)default_values.size()) {
args = (const Variant **)alloca(sizeof...(P) * sizeof(const Variant *));
+ // GCC fails to see that `sizeof...(P)` cannot be 0 here given the previous
+ // conditions, so it raises a warning on the potential use of `i < 0` as the
+ // execution condition.
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#endif
for (size_t i = 0; i < sizeof...(P); i++) {
if (i < (size_t)p_argcount) {
args[i] = p_args[i];
@@ -305,6 +322,9 @@ struct _VariantCall {
args[i] = &default_values[i - p_argcount + (default_values.size() - missing)];
}
}
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
} else {
#ifdef DEBUG_ENABLED
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
@@ -392,6 +412,13 @@ struct _VariantCall {
size_t missing = sizeof...(P) - (size_t)p_argcount;
if (missing <= (size_t)default_values.size()) {
args = (const Variant **)alloca(sizeof...(P) * sizeof(const Variant *));
+ // GCC fails to see that `sizeof...(P)` cannot be 0 here given the previous
+ // conditions, so it raises a warning on the potential use of `i < 0` as the
+ // execution condition.
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#endif
for (size_t i = 0; i < sizeof...(P); i++) {
if (i < (size_t)p_argcount) {
args[i] = p_args[i];
@@ -399,6 +426,9 @@ struct _VariantCall {
args[i] = &default_values[i - p_argcount + (default_values.size() - missing)];
}
}
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
} else {
#ifdef DEBUG_ENABLED
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
45f5775
to
1b740fb
Compare
// I think rocket science is simpler than modern C++ | ||
using expand_type = int[]; | ||
expand_type a{ 0, (call_get_argument_type_helper<P>(p_arg, index, type), 0)... }; | ||
(void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the reference, I think the warning is valid here, as we do not use a
. But I assume this is an unavoidable hack to get things to work as intended (hence the rocket science comment).
We could silence it with a pragma, but then it needs to be handled for both GCC and Clang (and maybe MSVC?), so this hack is likely better.
1b740fb
to
3f2bba8
Compare
// GCC fails to see that `sizeof...(P)` cannot be 0 here given the previous | ||
// conditions, so it raises a warning on the potential use of `i < 0` as the | ||
// execution condition. | ||
#if defined(__GNUC__) && !defined(__clang__) | ||
#pragma GCC diagnostic push | ||
#pragma GCC diagnostic ignored "-Wtype-limits" | ||
#endif | ||
for (size_t i = 0; i < sizeof...(P); i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be worth a bug report to upstream GCC IMO, if anyone is motivated to write a minimal reproduction project (basically some code that uses variadic templates with a parameter pack that can be of size 0, but which has a check for its size before attempting to use it in a comparison with a size_t
).
Here's the output of running Lots of methods removed from core types, I guess the doc system is not compatible yet with this new binding system? It should be fixed in priority to avoid losing valuable descriptions when running |
98c685b
to
fba1843
Compare
Moved to a system using variadic templates, shared with CallableBind. New code is cleaner, faster and allows for much better optimization of core type functions from GDScript and GDNative. Added Variant::InternalMethod function for direct call access.
fba1843
to
b8c6418
Compare
Force pushed to fix a new warning introduced in recent changes. There are bugs in the |
Thanks! |
Moved to a system using variadic templates, shared with CallableBind.
New code is cleaner, faster and allows for much better optimization of core
type functions from GDScript and GDNative. Also adds support for prevalidated and pointer calls
to internal methods.
Added Variant::InternalMethod function for direct call access.
Note: while it should build ok this PR breaks release target (I think its broken already..), a subsequent PR refactoring method binds should fix it.