From 8fffe3b5586b4c61f1ccd63ff92cf9cdebead08d Mon Sep 17 00:00:00 2001
From: David Snopek <dsnopek@gmail.com>
Date: Fri, 28 Mar 2025 07:41:25 -0500
Subject: [PATCH 01/12] Fix stack smashing when Godot methods return
 `char32_t`, `char16_t` or `wchar_t`

(cherry picked from commit 035add9d4f4289724a2b5049c5edc5383038d105)
---
 include/godot_cpp/core/engine_ptrcall.hpp | 8 ++++----
 include/godot_cpp/core/method_ptrcall.hpp | 3 +++
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/include/godot_cpp/core/engine_ptrcall.hpp b/include/godot_cpp/core/engine_ptrcall.hpp
index 555806b8e..8679f2ca1 100644
--- a/include/godot_cpp/core/engine_ptrcall.hpp
+++ b/include/godot_cpp/core/engine_ptrcall.hpp
@@ -56,10 +56,10 @@ O *_call_native_mb_ret_obj(const GDExtensionMethodBindPtr mb, void *instance, co
 
 template <typename R, typename... Args>
 R _call_native_mb_ret(const GDExtensionMethodBindPtr mb, void *instance, const Args &...args) {
-	R ret;
+	typename PtrToArg<R>::EncodeT ret;
 	std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
 	internal::gdextension_interface_object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret);
-	return ret;
+	return static_cast<R>(ret);
 }
 
 template <typename... Args>
@@ -70,10 +70,10 @@ void _call_native_mb_no_ret(const GDExtensionMethodBindPtr mb, void *instance, c
 
 template <typename R, typename... Args>
 R _call_utility_ret(GDExtensionPtrUtilityFunction func, const Args &...args) {
-	R ret;
+	typename PtrToArg<R>::EncodeT ret;
 	std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
 	func(&ret, mb_args.data(), mb_args.size());
-	return ret;
+	return static_cast<R>(ret);
 }
 
 template <typename... Args>
diff --git a/include/godot_cpp/core/method_ptrcall.hpp b/include/godot_cpp/core/method_ptrcall.hpp
index 8889e8214..4878b755a 100644
--- a/include/godot_cpp/core/method_ptrcall.hpp
+++ b/include/godot_cpp/core/method_ptrcall.hpp
@@ -122,6 +122,9 @@ MAKE_PTRARGCONV(uint16_t, int64_t);
 MAKE_PTRARGCONV(int16_t, int64_t);
 MAKE_PTRARGCONV(uint32_t, int64_t);
 MAKE_PTRARGCONV(int32_t, int64_t);
+MAKE_PTRARGCONV(char16_t, int64_t);
+MAKE_PTRARGCONV(char32_t, int64_t);
+MAKE_PTRARGCONV(wchar_t, int64_t);
 MAKE_PTRARG(int64_t);
 MAKE_PTRARG(uint64_t);
 // Float types

From de7e5b9145fbfb57ddb24441e11824a65f5fa0ef Mon Sep 17 00:00:00 2001
From: Aaron Franke <arnfranke@yahoo.com>
Date: Fri, 14 Mar 2025 02:46:23 -0700
Subject: [PATCH 02/12] Add missing Projection constructor with 16 real_t
 values

(cherry picked from commit aa03c32b3e84e8342a6aecd9abc12a30b9b47c50)
---
 include/godot_cpp/variant/projection.hpp | 1 +
 src/variant/projection.cpp               | 7 +++++++
 2 files changed, 8 insertions(+)

diff --git a/include/godot_cpp/variant/projection.hpp b/include/godot_cpp/variant/projection.hpp
index cc715778e..079dff14a 100644
--- a/include/godot_cpp/variant/projection.hpp
+++ b/include/godot_cpp/variant/projection.hpp
@@ -153,6 +153,7 @@ struct [[nodiscard]] Projection {
 
 	Projection();
 	Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w);
+	Projection(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_xw, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_yw, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_zw, real_t p_wx, real_t p_wy, real_t p_wz, real_t p_ww);
 	Projection(const Transform3D &p_transform);
 	~Projection();
 };
diff --git a/src/variant/projection.cpp b/src/variant/projection.cpp
index ddedc93f9..a56b6e0f1 100644
--- a/src/variant/projection.cpp
+++ b/src/variant/projection.cpp
@@ -913,6 +913,13 @@ Projection::Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_
 	columns[3] = p_w;
 }
 
+Projection::Projection(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_xw, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_yw, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_zw, real_t p_wx, real_t p_wy, real_t p_wz, real_t p_ww) {
+	columns[0] = Vector4(p_xx, p_xy, p_xz, p_xw);
+	columns[1] = Vector4(p_yx, p_yy, p_yz, p_yw);
+	columns[2] = Vector4(p_zx, p_zy, p_zz, p_zw);
+	columns[3] = Vector4(p_wx, p_wy, p_wz, p_ww);
+}
+
 Projection::Projection(const Transform3D &p_transform) {
 	const Transform3D &tr = p_transform;
 	real_t *m = &columns[0][0];

From 888f46bbcce11d4478a7e7ea7ae19cc25d2e7b33 Mon Sep 17 00:00:00 2001
From: Thaddeus Crews <repiteo@outlook.com>
Date: Wed, 2 Apr 2025 12:34:03 -0500
Subject: [PATCH 03/12] SCons: Add `CPPEXTPATH` for external includes

(cherry picked from commit 30bfa6f215d12a2c4ac4d09e892c053385f7c09d)
---
 tools/godotcpp.py | 14 ++++++++++++++
 tools/windows.py  |  5 +++++
 2 files changed, 19 insertions(+)

diff --git a/tools/godotcpp.py b/tools/godotcpp.py
index fcc1ab1f9..cad14c8d2 100644
--- a/tools/godotcpp.py
+++ b/tools/godotcpp.py
@@ -2,6 +2,7 @@
 import platform
 import sys
 
+from SCons import __version__ as scons_raw_version
 from SCons.Action import Action
 from SCons.Builder import Builder
 from SCons.Errors import UserError
@@ -424,6 +425,8 @@ def make_doc_source(target, source, env):
 
 
 def generate(env):
+    env.scons_version = env._get_major_minor_revision(scons_raw_version)
+
     # Default num_jobs to local cpu count if not user specified.
     # SCons has a peculiarity where user-specified options won't be overridden
     # by SetOption, so we can rely on this to know if we should use our default.
@@ -481,6 +484,17 @@ def generate(env):
     else:  # Release
         opt_level = "speed"
 
+    # Allow marking includes as external/system to avoid raising warnings.
+    if env.scons_version < (4, 2):
+        env["_CPPEXTINCFLAGS"] = "${_concat(EXTINCPREFIX, CPPEXTPATH, EXTINCSUFFIX, __env__, RDirs, TARGET, SOURCE)}"
+    else:
+        env["_CPPEXTINCFLAGS"] = (
+            "${_concat(EXTINCPREFIX, CPPEXTPATH, EXTINCSUFFIX, __env__, RDirs, TARGET, SOURCE, affect_signature=False)}"
+        )
+    env["CPPEXTPATH"] = []
+    env["EXTINCPREFIX"] = "-isystem "
+    env["EXTINCSUFFIX"] = ""
+
     env["optimize"] = ARGUMENTS.get("optimize", opt_level)
     env["debug_symbols"] = get_cmdline_bool("debug_symbols", env.dev_build)
 
diff --git a/tools/windows.py b/tools/windows.py
index 490b9f718..347a8d786 100644
--- a/tools/windows.py
+++ b/tools/windows.py
@@ -125,6 +125,11 @@ def generate(env):
         if env["silence_msvc"] and not env.GetOption("clean"):
             silence_msvc(env)
 
+        if not env["use_llvm"]:
+            env.AppendUnique(CCFLAGS=["/experimental:external", "/external:anglebrackets"])
+        env.AppendUnique(CCFLAGS=["/external:W0"])
+        env["EXTINCPREFIX"] = "/external:I"
+
     elif (sys.platform == "win32" or sys.platform == "msys") and not env["mingw_prefix"]:
         env["use_mingw"] = True
         mingw.generate(env)

From 52937a3850376df891e6515955efb1c87d67f099 Mon Sep 17 00:00:00 2001
From: David Snopek <dsnopek@gmail.com>
Date: Fri, 25 Apr 2025 14:31:10 -0500
Subject: [PATCH 04/12] Fix classes without `_to_string()` always returning
 `"[Wrapped:0]"`

(cherry picked from commit f38c056b674b3d9eef5d92582e880a349e2ffe7b)
---
 binding_generator.py                  | 10 ++++++++++
 include/godot_cpp/classes/wrapped.hpp |  6 +-----
 test/project/main.gd                  |  3 +--
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/binding_generator.py b/binding_generator.py
index 3d5531615..765691efe 100644
--- a/binding_generator.py
+++ b/binding_generator.py
@@ -1591,6 +1591,16 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
         result.append(f"\t~{class_name}();")
         result.append("")
 
+    if class_name == "Object":
+        result.append('\tString _to_string() const { return "<" + get_class() + "#" + itos(get_instance_id()) + ">"; }')
+        result.append("")
+
+    if class_name == "Node":
+        result.append(
+            '\tString _to_string() const { return (!get_name().is_empty() ? String(get_name()) + ":" : "") + Object::_to_string(); }'
+        )
+        result.append("")
+
     result.append("public:")
 
     # Special cases.
diff --git a/include/godot_cpp/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp
index d27210818..0697fe54b 100644
--- a/include/godot_cpp/classes/wrapped.hpp
+++ b/include/godot_cpp/classes/wrapped.hpp
@@ -94,7 +94,7 @@ class Wrapped {
 	bool _property_can_revert(const StringName &p_name) const { return false; }
 	bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return false; }
 	void _validate_property(PropertyInfo &p_property) const {}
-	String _to_string() const { return "[" + String(get_class_static()) + ":" + itos(get_instance_id()) + "]"; }
+	String _to_string() const { return "<Wrapped#0>"; }
 
 	static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) {}
 	static GDExtensionBool set_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value) { return false; }
@@ -123,10 +123,6 @@ class Wrapped {
 		return string_name;
 	}
 
-	uint64_t get_instance_id() const {
-		return 0;
-	}
-
 	// Must be public but you should not touch this.
 	GodotObject *_owner = nullptr;
 };
diff --git a/test/project/main.gd b/test/project/main.gd
index b2625b9a0..cc2fad4a7 100644
--- a/test/project/main.gd
+++ b/test/project/main.gd
@@ -18,8 +18,7 @@ func _ready():
 
 	# To string.
 	assert_equal(example.to_string(),'[ GDExtension::Example <--> Instance ID:%s ]' % example.get_instance_id())
-	# It appears there's a bug with instance ids :-(
-	#assert_equal($Example/ExampleMin.to_string(), 'ExampleMin:[Wrapped:%s]' % $Example/ExampleMin.get_instance_id())
+	assert_equal($Example/ExampleMin.to_string(), 'ExampleMin:<ExampleMin#%s>' % $Example/ExampleMin.get_instance_id())
 
 	# Call static methods.
 	assert_equal(Example.test_static(9, 100), 109);

From 443c075fa3f512e6dcd4d2b13afdcd89633dfadd Mon Sep 17 00:00:00 2001
From: Ben Lubar <ben.lubar@gmail.com>
Date: Mon, 21 Apr 2025 18:45:05 -0500
Subject: [PATCH 05/12] fix iterators making unintended copies

(cherry picked from commit 7fd0999b3c042a245b72e8ffab0b4145612687f6)
---
 src/core/class_db.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/class_db.cpp b/src/core/class_db.cpp
index ae74f2c27..db1711609 100644
--- a/src/core/class_db.cpp
+++ b/src/core/class_db.cpp
@@ -389,7 +389,7 @@ void ClassDB::initialize_class(const ClassInfo &p_cl) {
 }
 
 void ClassDB::initialize(GDExtensionInitializationLevel p_level) {
-	for (const std::pair<StringName, ClassInfo> pair : classes) {
+	for (const std::pair<const StringName, ClassInfo> &pair : classes) {
 		const ClassInfo &cl = pair.second;
 		if (cl.level != p_level) {
 			continue;

From 48544896ee515bd131ea08327a6cbdf12c1a1c0e Mon Sep 17 00:00:00 2001
From: David Snopek <dsnopek@gmail.com>
Date: Tue, 1 Apr 2025 14:09:46 -0500
Subject: [PATCH 06/12] Stop referring to GDExtension as experimental in the
 README

(cherry picked from commit 7660dd28b3ac42178bbf578fe5fcddb181a6f65a)
---
 README.md | 23 +++++++++--------------
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/README.md b/README.md
index 843f7b34e..ac267733e 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,8 @@
 > from Godot's `master` branch.
 >
 > For users of stable branches, switch to the branch matching your target Godot version:
+> - [`4.4`](https://github.com/godotengine/godot-cpp/tree/4.4)
+> - [`4.3`](https://github.com/godotengine/godot-cpp/tree/4.3)
 > - [`4.2`](https://github.com/godotengine/godot-cpp/tree/4.2)
 > - [`4.1`](https://github.com/godotengine/godot-cpp/tree/4.1)
 > - [`4.0`](https://github.com/godotengine/godot-cpp/tree/4.0)
@@ -49,20 +51,13 @@ Godot version.**
 
 ## Compatibility
 
-> [!WARNING]
->
-> The GDExtension API is brand new in Godot 4.0, and is still
-considered in **beta** stage, despite Godot 4.0 itself being released.
->
-> This applies to both the GDExtension interface header, the API JSON, and this
-first-party `godot-cpp` extension.
->
-> Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
-> get more used, documented, and critical issues get resolved. See the
-> [Godot issue tracker](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aopen+label%3Atopic%3Agdextension)
-> and the [godot-cpp issue tracker](https://github.com/godotengine/godot-cpp/issues)
-> for a list of known issues, and be sure to provide feedback on issues and PRs
-> which affect your use of this extension.
+GDExtensions targeting an earlier version of Godot should work in later minor versions,
+but not vice-versa. For example, a GDExtension targeting Godot 4.2 should work just fine
+in Godot 4.3, but one targeting Godot 4.3 won't work in Godot 4.2.
+
+There is one exception to this: extensions targeting Godot 4.0 will _not_ work with
+Godot 4.1 and later.
+See [Updating your GDExtension for 4.1](https://docs.godotengine.org/en/latest/tutorials/migrating/upgrading_to_godot_4.1.html#updating-your-gdextension-for-godot-4-1).
 
 ## Contributing
 

From 6cdac999c2cc4f40f6f23737eeba89ef1190ebad Mon Sep 17 00:00:00 2001
From: Fabio Alessandrelli <fabio.alessandrelli@gmail.com>
Date: Wed, 21 May 2025 16:30:50 +0200
Subject: [PATCH 07/12] fix: Add iOS min SDK version link flags

This is required when publishing to the App Store, and consistent with
what we already do for the macOS deployment target.

(cherry picked from commit 4879eb7bd01716587f813dd97a27238ef92f3f9f)
---
 tools/ios.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/ios.py b/tools/ios.py
index 25c17db31..4e2a45c22 100644
--- a/tools/ios.py
+++ b/tools/ios.py
@@ -36,9 +36,11 @@ def generate(env):
     if env["ios_simulator"]:
         sdk_name = "iphonesimulator"
         env.Append(CCFLAGS=["-mios-simulator-version-min=" + env["ios_min_version"]])
+        env.Append(LINKFLAGS=["-mios-simulator-version-min=" + env["ios_min_version"]])
     else:
         sdk_name = "iphoneos"
         env.Append(CCFLAGS=["-miphoneos-version-min=" + env["ios_min_version"]])
+        env.Append(LINKFLAGS=["-miphoneos-version-min=" + env["ios_min_version"]])
 
     if sys.platform == "darwin":
         if env["IOS_SDK_PATH"] == "":

From 7b4ca64761065f76b375c10583ede9d678d274ad Mon Sep 17 00:00:00 2001
From: Lukas Tenbrink <lukas.tenbrink@gmail.com>
Date: Fri, 2 May 2025 17:12:32 +0200
Subject: [PATCH 08/12] Make ndk version configurable as a command-like
 argument.

(cherry picked from commit 16e47d7ae5bc45af90caeab16beecfe9ec4802c5)
---
 tools/android.py | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/tools/android.py b/tools/android.py
index fee4ed255..dbd38cdfb 100644
--- a/tools/android.py
+++ b/tools/android.py
@@ -11,6 +11,11 @@ def options(opts):
         "Target Android API level",
         "21",
     )
+    opts.Add(
+        "ndk_version",
+        "Fully qualified version of ndk to use for compilation.",
+        "23.2.8568313",
+    )
     opts.Add(
         "ANDROID_HOME",
         "Path to your Android SDK installation. By default, uses ANDROID_HOME from your defined environment variables.",
@@ -22,14 +27,9 @@ def exists(env):
     return get_android_ndk_root(env) is not None
 
 
-# This must be kept in sync with the value in https://github.com/godotengine/godot/blob/master/platform/android/detect.py#L58.
-def get_ndk_version():
-    return "23.2.8568313"
-
-
 def get_android_ndk_root(env):
     if env["ANDROID_HOME"]:
-        return env["ANDROID_HOME"] + "/ndk/" + get_ndk_version()
+        return env["ANDROID_HOME"] + "/ndk/" + env["ndk_version"]
     else:
         return os.environ.get("ANDROID_NDK_ROOT")
 
@@ -68,7 +68,7 @@ def generate(env):
 
     if not os.path.exists(toolchain):
         print("ERROR: Could not find NDK toolchain at " + toolchain + ".")
-        print("Make sure NDK version " + get_ndk_version() + " is installed.")
+        print("Make sure NDK version " + env["ndk_version"] + " is installed.")
         env.Exit(1)
 
     env.PrependENVPath("PATH", toolchain + "/bin")  # This does nothing half of the time, but we'll put it here anyways

From 9892f63abb2b8cd8f2de5f686fe0cc3fd4657f71 Mon Sep 17 00:00:00 2001
From: MJacred <loesch.benny92@gmx.de>
Date: Mon, 9 Jun 2025 11:49:03 +0200
Subject: [PATCH 09/12] Fix URL to gdextension cpp example in the official docs

(cherry picked from commit f25c4df5c477f58d6839d6a63a3768540940862f)
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index ac267733e..0b572bb98 100644
--- a/README.md
+++ b/README.md
@@ -140,4 +140,4 @@ See the [godot-cpp-template](https://github.com/godotengine/godot-cpp-template)
 generic reusable template.
 
 Or checkout the code for the [Summator example](https://github.com/paddy-exe/GDExtensionSummator)
-as shown in the [official documentation](https://docs.godotengine.org/en/latest/tutorials/scripting/gdextension/gdextension_cpp_example.html).
+as shown in the [official documentation](https://docs.godotengine.org/en/latest/tutorials/scripting/cpp/gdextension_cpp_example.html).

From a9abdb5f0cfe90d14725c9f56c0c6d2b57aefca4 Mon Sep 17 00:00:00 2001
From: Tom <tom_full@hotmail.co.uk>
Date: Sun, 20 Apr 2025 20:33:26 +0100
Subject: [PATCH 10/12] Cleaned up the MethodBind class

(cherry picked from commit ca5af3c86153aaa91250d7608a9d29932b38afbf)
---
 include/godot_cpp/core/method_bind.hpp | 100 +++++++++++++------------
 src/core/method_bind.cpp               |  30 ++++----
 2 files changed, 67 insertions(+), 63 deletions(-)

diff --git a/include/godot_cpp/core/method_bind.hpp b/include/godot_cpp/core/method_bind.hpp
index f2da66ce0..571205f94 100644
--- a/include/godot_cpp/core/method_bind.hpp
+++ b/include/godot_cpp/core/method_bind.hpp
@@ -48,14 +48,14 @@
 namespace godot {
 
 class MethodBind {
+	uint32_t hint_flags = METHOD_FLAGS_DEFAULT;
 	StringName name;
 	StringName instance_class;
 	int argument_count = 0;
-	uint32_t hint_flags = METHOD_FLAGS_DEFAULT;
 
 	bool _static = false;
-	bool _is_const = false;
-	bool _has_return = false;
+	bool _const = false;
+	bool _returns = false;
 	bool _vararg = false;
 
 	std::vector<StringName> argument_names;
@@ -63,20 +63,20 @@ class MethodBind {
 	std::vector<Variant> default_arguments;
 
 protected:
+	void _set_const(bool p_const);
+	void _set_static(bool p_static);
+	void _set_returns(bool p_returns);
+	void _set_vararg(bool p_vararg);
 	virtual GDExtensionVariantType gen_argument_type(int p_arg) const = 0;
 	virtual PropertyInfo gen_argument_type_info(int p_arg) const = 0;
-	void generate_argument_types(int p_count);
-	void set_const(bool p_const);
-	void set_return(bool p_return);
-	void set_static(bool p_static);
-	void set_vararg(bool p_vararg);
-	void set_argument_count(int p_count);
+	void _generate_argument_types(int p_count);
+
+	void set_argument_count(int p_count) { argument_count = p_count; }
 
 public:
-	StringName get_name() const;
-	void set_name(const StringName &p_name);
-	_FORCE_INLINE_ int get_default_argument_count() const { return (int)default_arguments.size(); }
 	_FORCE_INLINE_ const std::vector<Variant> &get_default_arguments() const { return default_arguments; }
+	_FORCE_INLINE_ int get_default_argument_count() const { return (int)default_arguments.size(); }
+
 	_FORCE_INLINE_ Variant has_default_argument(int p_arg) const {
 		const int num_default_args = (int)(default_arguments.size());
 		const int idx = p_arg - (argument_count - num_default_args);
@@ -97,19 +97,6 @@ class MethodBind {
 			return default_arguments[idx];
 		}
 	}
-	_FORCE_INLINE_ StringName get_instance_class() const { return instance_class; }
-	_FORCE_INLINE_ void set_instance_class(StringName p_class) { instance_class = p_class; }
-
-	_FORCE_INLINE_ int get_argument_count() const { return argument_count; }
-	_FORCE_INLINE_ bool is_const() const { return _is_const; }
-	_FORCE_INLINE_ bool is_static() const { return _static; }
-	_FORCE_INLINE_ bool is_vararg() const { return _vararg; }
-	_FORCE_INLINE_ bool has_return() const { return _has_return; }
-	_FORCE_INLINE_ uint32_t get_hint_flags() const { return hint_flags | (is_const() ? GDEXTENSION_METHOD_FLAG_CONST : 0) | (is_vararg() ? GDEXTENSION_METHOD_FLAG_VARARG : 0) | (is_static() ? GDEXTENSION_METHOD_FLAG_STATIC : 0); }
-	_FORCE_INLINE_ void set_hint_flags(uint32_t p_hint_flags) { hint_flags = p_hint_flags; }
-	void set_argument_names(const std::vector<StringName> &p_names);
-	std::vector<StringName> get_argument_names() const;
-	void set_default_arguments(const std::vector<Variant> &p_default_arguments) { default_arguments = p_default_arguments; }
 
 	_FORCE_INLINE_ GDExtensionVariantType get_argument_type(int p_argument) const {
 		ERR_FAIL_COND_V(p_argument < -1 || p_argument > argument_count, GDEXTENSION_VARIANT_TYPE_NIL);
@@ -117,7 +104,6 @@ class MethodBind {
 	}
 
 	PropertyInfo get_argument_info(int p_argument) const;
-	virtual GDExtensionClassMethodArgumentMetadata get_argument_metadata(int p_argument) const = 0;
 
 	std::vector<PropertyInfo> get_arguments_info_list() const {
 		std::vector<PropertyInfo> vec;
@@ -128,6 +114,31 @@ class MethodBind {
 		}
 		return vec;
 	}
+
+	void set_argument_names(const std::vector<StringName> &p_names);
+	std::vector<StringName> get_argument_names() const;
+
+	virtual GDExtensionClassMethodArgumentMetadata get_argument_metadata(int p_argument) const = 0;
+
+	_FORCE_INLINE_ void set_hint_flags(uint32_t p_hint_flags) { hint_flags = p_hint_flags; }
+	_FORCE_INLINE_ uint32_t get_hint_flags() const { return hint_flags | (is_const() ? GDEXTENSION_METHOD_FLAG_CONST : 0) | (is_vararg() ? GDEXTENSION_METHOD_FLAG_VARARG : 0) | (is_static() ? GDEXTENSION_METHOD_FLAG_STATIC : 0); }
+	_FORCE_INLINE_ StringName get_instance_class() const { return instance_class; }
+	_FORCE_INLINE_ void set_instance_class(StringName p_class) { instance_class = p_class; }
+
+	_FORCE_INLINE_ int get_argument_count() const { return argument_count; }
+
+	virtual Variant call(GDExtensionClassInstancePtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionCallError &r_error) const = 0;
+	virtual void ptrcall(GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_return) const = 0;
+
+	StringName get_name() const;
+	void set_name(const StringName &p_name);
+	_FORCE_INLINE_ bool is_const() const { return _const; }
+	_FORCE_INLINE_ bool is_static() const { return _static; }
+	_FORCE_INLINE_ bool is_vararg() const { return _vararg; }
+	_FORCE_INLINE_ bool has_return() const { return _returns; }
+
+	void set_default_arguments(const std::vector<Variant> &p_default_arguments) { default_arguments = p_default_arguments; }
+
 	std::vector<GDExtensionClassMethodArgumentMetadata> get_arguments_metadata_list() const {
 		std::vector<GDExtensionClassMethodArgumentMetadata> vec;
 		// First element is return value
@@ -138,9 +149,6 @@ class MethodBind {
 		return vec;
 	}
 
-	virtual Variant call(GDExtensionClassInstancePtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionCallError &r_error) const = 0;
-	virtual void ptrcall(GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_return) const = 0;
-
 	static void bind_call(void *p_method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
 	static void bind_ptrcall(void *p_method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_return);
 
@@ -182,8 +190,8 @@ class MethodBindVarArgBase : public MethodBind {
 			const MethodInfo &p_method_info,
 			bool p_return_nil_is_variant) :
 			method(p_method) {
-		set_vararg(true);
-		set_const(true);
+		_set_vararg(true);
+		_set_const(true);
 		set_argument_count(p_method_info.arguments.size());
 		if (p_method_info.arguments.size()) {
 			arguments = p_method_info.arguments;
@@ -196,8 +204,8 @@ class MethodBindVarArgBase : public MethodBind {
 			set_argument_names(names);
 		}
 
-		generate_argument_types((int)p_method_info.arguments.size());
-		set_return(should_returns);
+		_generate_argument_types((int)p_method_info.arguments.size());
+		_set_returns(should_returns);
 	}
 
 	~MethodBindVarArgBase() {}
@@ -334,7 +342,7 @@ class MethodBindT : public MethodBind {
 
 	MethodBindT(void (MB_T::*p_method)(P...)) {
 		method = p_method;
-		generate_argument_types(sizeof...(P));
+		_generate_argument_types(sizeof...(P));
 		set_argument_count(sizeof...(P));
 	}
 };
@@ -410,9 +418,9 @@ class MethodBindTC : public MethodBind {
 
 	MethodBindTC(void (MB_T::*p_method)(P...) const) {
 		method = p_method;
-		generate_argument_types(sizeof...(P));
+		_generate_argument_types(sizeof...(P));
 		set_argument_count(sizeof...(P));
-		set_const(true);
+		_set_const(true);
 	}
 };
 
@@ -493,9 +501,9 @@ class MethodBindTR : public MethodBind {
 
 	MethodBindTR(R (MB_T::*p_method)(P...)) {
 		method = p_method;
-		generate_argument_types(sizeof...(P));
+		_generate_argument_types(sizeof...(P));
 		set_argument_count(sizeof...(P));
-		set_return(true);
+		_set_returns(true);
 	}
 };
 
@@ -576,10 +584,10 @@ class MethodBindTRC : public MethodBind {
 
 	MethodBindTRC(R (MB_T::*p_method)(P...) const) {
 		method = p_method;
-		generate_argument_types(sizeof...(P));
+		_generate_argument_types(sizeof...(P));
 		set_argument_count(sizeof...(P));
-		set_return(true);
-		set_const(true);
+		_set_returns(true);
+		_set_const(true);
 	}
 };
 
@@ -648,9 +656,9 @@ class MethodBindTS : public MethodBind {
 
 	MethodBindTS(void (*p_function)(P...)) {
 		function = p_function;
-		generate_argument_types(sizeof...(P));
+		_generate_argument_types(sizeof...(P));
 		set_argument_count(sizeof...(P));
-		set_static(true);
+		_set_static(true);
 	}
 };
 
@@ -717,10 +725,10 @@ class MethodBindTRS : public MethodBind {
 
 	MethodBindTRS(R (*p_function)(P...)) {
 		function = p_function;
-		generate_argument_types(sizeof...(P));
+		_generate_argument_types(sizeof...(P));
 		set_argument_count(sizeof...(P));
-		set_static(true);
-		set_return(true);
+		_set_static(true);
+		_set_returns(true);
 	}
 };
 
diff --git a/src/core/method_bind.cpp b/src/core/method_bind.cpp
index 0b9b5ebac..734b2e692 100644
--- a/src/core/method_bind.cpp
+++ b/src/core/method_bind.cpp
@@ -32,32 +32,28 @@
 
 namespace godot {
 
-StringName MethodBind::get_name() const {
-	return name;
+void MethodBind::_set_const(bool p_const) {
+	_const = p_const;
 }
 
-void MethodBind::set_name(const StringName &p_name) {
-	name = p_name;
-}
-
-void MethodBind::set_argument_count(int p_count) {
-	argument_count = p_count;
+void MethodBind::_set_static(bool p_static) {
+	_static = p_static;
 }
 
-void MethodBind::set_const(bool p_const) {
-	_is_const = p_const;
+void MethodBind::_set_returns(bool p_returns) {
+	_returns = p_returns;
 }
 
-void MethodBind::set_return(bool p_return) {
-	_has_return = p_return;
+void MethodBind::_set_vararg(bool p_vararg) {
+	_vararg = p_vararg;
 }
 
-void MethodBind::set_static(bool p_static) {
-	_static = p_static;
+StringName MethodBind::get_name() const {
+	return name;
 }
 
-void MethodBind::set_vararg(bool p_vararg) {
-	_vararg = p_vararg;
+void MethodBind::set_name(const StringName &p_name) {
+	name = p_name;
 }
 
 void MethodBind::set_argument_names(const std::vector<StringName> &p_names) {
@@ -68,7 +64,7 @@ std::vector<StringName> MethodBind::get_argument_names() const {
 	return argument_names;
 }
 
-void MethodBind::generate_argument_types(int p_count) {
+void MethodBind::_generate_argument_types(int p_count) {
 	set_argument_count(p_count);
 
 	if (argument_types != nullptr) {

From 53caa6adbcdb2d3581f2fdd2a534e1ea8e960ac7 Mon Sep 17 00:00:00 2001
From: David Snopek <dsnopek@gmail.com>
Date: Tue, 24 Jun 2025 14:45:01 -0500
Subject: [PATCH 11/12] Update CI to use `ubuntu-22.04`

---
 .github/workflows/ci.yml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8b526b9d7..52680916f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -21,7 +21,7 @@ jobs:
       matrix:
         include:
           - name: 🐧 Linux (GCC)
-            os: ubuntu-20.04
+            os: ubuntu-22.04
             platform: linux
             artifact-name: godot-cpp-linux-glibc2.27-x86_64-release
             artifact-path: bin/libgodot-cpp.linux.template_release.x86_64.a
@@ -29,7 +29,7 @@ jobs:
             cache-name: linux-x86_64
 
           - name: 🐧 Linux (GCC, Double Precision)
-            os: ubuntu-20.04
+            os: ubuntu-22.04
             platform: linux
             artifact-name: godot-cpp-linux-glibc2.27-x86_64-double-release
             artifact-path: bin/libgodot-cpp.linux.template_release.double.x86_64.a
@@ -64,7 +64,7 @@ jobs:
             cache-name: macos-universal
 
           - name: 🤖 Android (arm64)
-            os: ubuntu-20.04
+            os: ubuntu-22.04
             platform: android
             artifact-name: godot-cpp-android-arm64-release
             artifact-path: bin/libgodot-cpp.android.template_release.arm64.a
@@ -82,7 +82,7 @@ jobs:
             cache-name: ios-arm64
 
           - name: 🌐 Web (wasm32)
-            os: ubuntu-20.04
+            os: ubuntu-22.04
             platform: web
             artifact-name: godot-cpp-web-wasm32-release
             artifact-path: bin/libgodot-cpp.web.template_release.wasm32.a
@@ -183,7 +183,7 @@ jobs:
 
   linux-cmake:
     name: 🐧 Build (Linux, GCC, CMake)
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-22.04
     steps:
       - name: Checkout
         uses: actions/checkout@v4
@@ -207,7 +207,7 @@ jobs:
 
   linux-cmake-ninja:
     name: 🐧 Build (Linux, GCC, CMake Ninja)
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-22.04
     steps:
       - name: Checkout
         uses: actions/checkout@v4

From b1e2ac5cbbb998b98ccace0bc18f9a5074173881 Mon Sep 17 00:00:00 2001
From: David Snopek <dsnopek@gmail.com>
Date: Tue, 24 Jun 2025 14:47:40 -0500
Subject: [PATCH 12/12] Update CI to use `windows-2022`

(cherry picked from commit 8938e7e4e3bdcc12c25dc5e542e65880c73d9369)
---
 .github/workflows/ci.yml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 52680916f..5b3e8b9b1 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -38,7 +38,7 @@ jobs:
             cache-name: linux-x86_64-f64
 
           - name: 🏁 Windows (x86_64, MSVC)
-            os: windows-2019
+            os: windows-2022
             platform: windows
             artifact-name: godot-cpp-windows-msvc2019-x86_64-release
             artifact-path: bin/libgodot-cpp.windows.template_release.x86_64.lib
@@ -46,7 +46,7 @@ jobs:
             cache-name: windows-x86_64-msvc
 
           - name: 🏁 Windows (x86_64, MinGW)
-            os: windows-2019
+            os: windows-2022
             platform: windows
             artifact-name: godot-cpp-linux-mingw-x86_64-release
             artifact-path: bin/libgodot-cpp.windows.template_release.x86_64.a
@@ -231,7 +231,7 @@ jobs:
 
   windows-msvc-cmake:
     name: 🏁 Build (Windows, MSVC, CMake)
-    runs-on: windows-2019
+    runs-on: windows-2022
     steps:
       - name: Checkout
         uses: actions/checkout@v4
@@ -240,10 +240,10 @@ jobs:
 
       - name: Build godot-cpp
         run: |
-          cmake -DCMAKE_BUILD_TYPE=Release -G"Visual Studio 16 2019" .
+          cmake -DCMAKE_BUILD_TYPE=Release -G"Visual Studio 17 2022" .
           cmake --build . --verbose --config Release
 
       - name: Build test GDExtension library
         run: |
-          cd test && cmake -DCMAKE_BUILD_TYPE=Release -DGODOT_HEADERS_PATH="../godot-headers" -DCPP_BINDINGS_PATH=".." -G"Visual Studio 16 2019" .
+          cd test && cmake -DCMAKE_BUILD_TYPE=Release -DGODOT_HEADERS_PATH="../godot-headers" -DCPP_BINDINGS_PATH=".." -G"Visual Studio 17 2022" .
           cmake --build . --verbose --config Release
