From 23ae64b15e14e868f3a152ca2745b2db764b12c2 Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Wed, 17 Oct 2018 21:37:57 +0200 Subject: C#: Optimize struct marshalling - We no longer box struct to return them from internal calls. - Use reinterpret_cast if the managed struct layout is the same as the native struct. --- modules/mono/editor/bindings_generator.cpp | 82 ++++++++++++++++-------------- modules/mono/editor/bindings_generator.h | 21 +++++--- 2 files changed, 58 insertions(+), 45 deletions(-) (limited to 'modules/mono/editor') diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index f4c3033d19..41666bc3e9 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -97,7 +97,7 @@ #define C_METHOD_MONOARRAY_TO(m_type) C_NS_MONOMARSHAL "::mono_array_to_" #m_type #define C_METHOD_MONOARRAY_FROM(m_type) C_NS_MONOMARSHAL "::" #m_type "_to_mono_array" -#define BINDINGS_GENERATOR_VERSION UINT32_C(3) +#define BINDINGS_GENERATOR_VERSION UINT32_C(4) const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN = "\t%0 %1_in = %1;\n"; @@ -1993,18 +1993,18 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { TypeInterface itype; -#define INSERT_STRUCT_TYPE(m_type, m_type_in) \ - { \ - itype = TypeInterface::create_value_type(String(#m_type)); \ - itype.c_in = "\tMARSHALLED_IN(" #m_type ", %1, %1_in);\n"; \ - itype.c_out = "\tMARSHALLED_OUT(" #m_type ", %1, ret_out)\n" \ - "\treturn mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(%2), ret_out);\n"; \ - itype.c_arg_in = "&%s_in"; \ - itype.c_type_in = m_type_in; \ - itype.cs_in = "ref %s"; \ - itype.cs_out = "return (%1)%0;"; \ - itype.im_type_out = "object"; \ - builtin_types.insert(itype.cname, itype); \ +#define INSERT_STRUCT_TYPE(m_type, m_type_in) \ + { \ + itype = TypeInterface::create_value_type(String(#m_type)); \ + itype.c_in = "\t%0 %1_in = MARSHALLED_IN(" #m_type ", %1);\n"; \ + itype.c_out = "\treturn MARSHALLED_OUT(" #m_type ", %1);\n"; \ + itype.c_arg_in = "&%s_in"; \ + itype.c_type_in = "GDMonoMarshal::M_" #m_type "*"; \ + itype.c_type_out = "GDMonoMarshal::M_" #m_type; \ + itype.cs_in = "ref %s"; \ + itype.cs_out = "return (%1)%0;"; \ + itype.im_type_out = itype.cs_type; \ + builtin_types.insert(itype.cname, itype); \ } INSERT_STRUCT_TYPE(Vector2, "real_t*") @@ -2022,26 +2022,31 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { // bool itype = TypeInterface::create_value_type(String("bool")); - itype.c_arg_in = "&%s_in"; - // /* MonoBoolean <---> bool - itype.c_in = "\t%0 %1_in = (%0)%1;\n"; - itype.c_out = "\treturn (%0)%1;\n"; - itype.c_type = "bool"; - // */ - itype.c_type_in = "MonoBoolean"; - itype.c_type_out = itype.c_type_in; + + { + // MonoBoolean <---> bool + itype.c_in = "\t%0 %1_in = (%0)%1;\n"; + itype.c_out = "\treturn (%0)%1;\n"; + itype.c_type = "bool"; + itype.c_type_in = "MonoBoolean"; + itype.c_type_out = itype.c_type_in; + itype.c_arg_in = "&%s_in"; + } itype.im_type_in = itype.name; itype.im_type_out = itype.name; builtin_types.insert(itype.cname, itype); // int + // C interface is the same as that of enums. Remember to apply any + // changes done here to TypeInterface::postsetup_enum_type as well itype = TypeInterface::create_value_type(String("int")); itype.c_arg_in = "&%s_in"; - // /* ptrcall only supports int64_t and uint64_t - itype.c_in = "\t%0 %1_in = (%0)%1;\n"; - itype.c_out = "\treturn (%0)%1;\n"; - itype.c_type = "int64_t"; - // */ + { + // The expected types for parameters and return value in ptrcall are 'int64_t' or 'uint64_t'. + itype.c_in = "\t%0 %1_in = (%0)%1;\n"; + itype.c_out = "\treturn (%0)%1;\n"; + itype.c_type = "int64_t"; + } itype.c_type_in = "int32_t"; itype.c_type_out = itype.c_type_in; itype.im_type_in = itype.name; @@ -2050,21 +2055,22 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { // real_t itype = TypeInterface(); + itype.name = "float"; // The name is always "float" in Variant, even with REAL_T_IS_DOUBLE. + itype.cname = itype.name; #ifdef REAL_T_IS_DOUBLE - itype.name = "double"; + itype.proxy_name = "double"; #else - itype.name = "float"; + itype.proxy_name = "float"; #endif - itype.cname = itype.name; - itype.proxy_name = itype.name; - itype.c_arg_in = "&%s_in"; - //* ptrcall only supports double - itype.c_in = "\t%0 %1_in = (%0)%1;\n"; - itype.c_out = "\treturn (%0)%1;\n"; - itype.c_type = "double"; - //*/ - itype.c_type_in = "real_t"; - itype.c_type_out = "real_t"; + { + // The expected type for parameters and return value in ptrcall is 'double'. + itype.c_in = "\t%0 %1_in = (%0)%1;\n"; + itype.c_out = "\treturn (%0)%1;\n"; + itype.c_type = "double"; + itype.c_type_in = "real_t"; + itype.c_type_out = "real_t"; + itype.c_arg_in = "&%s_in"; + } itype.cs_type = itype.proxy_name; itype.im_type_in = itype.proxy_name; itype.im_type_out = itype.proxy_name; diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index ad89255ba5..7ae52e180f 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -223,7 +223,7 @@ class BindingsGenerator { String c_in; /** - * Determines the name of the variable that will be passed as argument to a ptrcall. + * Determines the expression that will be passed as argument to ptrcall. * By default the value equals the name of the parameter, * this varies for types that require special manipulation via [c_in]. * Formatting elements: @@ -333,8 +333,6 @@ class BindingsGenerator { itype.proxy_name = itype.name; itype.c_type = itype.name; - itype.c_type_in = "void*"; - itype.c_type_out = "MonoObject*"; itype.cs_type = itype.proxy_name; itype.im_type_in = "ref " + itype.proxy_name; itype.im_type_out = itype.proxy_name; @@ -385,10 +383,19 @@ class BindingsGenerator { } static void postsetup_enum_type(TypeInterface &r_enum_itype) { - r_enum_itype.c_arg_in = "&%s"; - r_enum_itype.c_type = "int"; - r_enum_itype.c_type_in = "int"; - r_enum_itype.c_type_out = "int"; + // C interface is the same as that of 'int'. Remember to apply any + // changes done here to the 'int' type interface as well + + r_enum_itype.c_arg_in = "&%s_in"; + { + // The expected types for parameters and return value in ptrcall are 'int64_t' or 'uint64_t'. + r_enum_itype.c_in = "\t%0 %1_in = (%0)%1;\n"; + r_enum_itype.c_out = "\treturn (%0)%1;\n"; + r_enum_itype.c_type = "int64_t"; + } + r_enum_itype.c_type_in = "int32_t"; + r_enum_itype.c_type_out = r_enum_itype.c_type_in; + r_enum_itype.cs_type = r_enum_itype.proxy_name; r_enum_itype.cs_in = "(int)%s"; r_enum_itype.cs_out = "return (%1)%0;"; -- cgit v1.2.3