Skip to content

Commit

Permalink
Merge pull request #25080 from neikeq/mm-c
Browse files Browse the repository at this point in the history
C# Bindings Generator: Fix vararg methods with custom return type
  • Loading branch information
neikeq authored Jan 18, 2019
2 parents e8a1d4b + 8f26c54 commit ce36351
Showing 1 changed file with 24 additions and 3 deletions.
27 changes: 24 additions & 3 deletions modules/mono/editor/bindings_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
#define ICALL_GET_METHODBIND ICALL_PREFIX "Object_ClassDB_get_method"

#define C_LOCAL_RET "ret"
#define C_LOCAL_VARARG_RET "vararg_ret"
#define C_LOCAL_PTRCALL_ARGS "call_args"
#define C_MACRO_OBJECT_CONSTRUCT "GODOTSHARP_INSTANCE_OBJECT"

Expand All @@ -96,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(5)
#define BINDINGS_GENERATOR_VERSION UINT32_C(6)

const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN = "\t%0 %1_in = %1;\n";
Expand Down Expand Up @@ -1501,6 +1502,15 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
String ptrcall_return_type;
String initialization;

if (p_imethod.is_vararg && return_type->cname != name_cache.type_Variant) {
// VarArg methods always return Variant, but there are some cases in which MethodInfo provides
// a specific return type. We trust this information is valid. We need a temporary local to keep
// the Variant alive until the method returns. Otherwise, if the returned Variant holds a RefPtr,
// it could be deleted too early. This is the case with GDScript.new() which returns OBJECT.
// Alternatively, we could just return Variant, but that would result in a worse API.
p_output.push_back("\tVariant " C_LOCAL_VARARG_RET ";\n");
}

if (return_type->is_object_type) {
ptrcall_return_type = return_type->is_reference ? "Ref<Reference>" : return_type->c_type;
initialization = return_type->is_reference ? "" : " = NULL";
Expand Down Expand Up @@ -1558,12 +1568,23 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
if (p_imethod.is_vararg) {
p_output.push_back("\tVariant::CallError vcall_error;\n\t");

if (!ret_void)
p_output.push_back(C_LOCAL_RET " = ");
if (!ret_void) {
// See the comment on the C_LOCAL_VARARG_RET declaration
if (return_type->cname != name_cache.type_Variant) {
p_output.push_back(C_LOCAL_VARARG_RET " = ");
} else {
p_output.push_back(C_LOCAL_RET " = ");
}
}

p_output.push_back(CS_PARAM_METHODBIND "->call(" CS_PARAM_INSTANCE ", ");
p_output.push_back(p_imethod.arguments.size() ? "(const Variant**)" C_LOCAL_PTRCALL_ARGS ".ptr()" : "NULL");
p_output.push_back(", total_length, vcall_error);\n");

// See the comment on the C_LOCAL_VARARG_RET declaration
if (return_type->cname != name_cache.type_Variant) {
p_output.push_back("\t" C_LOCAL_RET " = " C_LOCAL_VARARG_RET ";\n");
}
} else {
p_output.push_back("\t" CS_PARAM_METHODBIND "->ptrcall(" CS_PARAM_INSTANCE ", ");
p_output.push_back(p_imethod.arguments.size() ? C_LOCAL_PTRCALL_ARGS ", " : "NULL, ");
Expand Down

0 comments on commit ce36351

Please sign in to comment.