From 00fb5b228a0c7011381943eaa909b908336c8ff5 Mon Sep 17 00:00:00 2001 From: Vitor Sousa Date: Fri, 15 Dec 2017 22:15:00 -0200 Subject: [PATCH] eolian_mono: fix handling of regular ptr() types --- src/bin/eolian_mono/eolian/mono/helpers.hh | 25 +++++++- .../eolian_mono/eolian/mono/marshall_type_impl.hh | 15 +++-- src/bin/eolian_mono/eolian/mono/parameter.hh | 70 +++++++++++++++++++--- .../eolian_mono/eolian/mono/struct_definition.hh | 14 +++++ src/bin/eolian_mono/eolian/mono/type.hh | 4 +- src/bin/eolian_mono/eolian/mono/type_impl.hh | 2 + src/bindings/mono/eina_mono/eina_common.cs | 30 ++++++++++ .../mono/eina_mono/eina_container_common.cs | 15 +---- 8 files changed, 147 insertions(+), 28 deletions(-) diff --git a/src/bin/eolian_mono/eolian/mono/helpers.hh b/src/bin/eolian_mono/eolian/mono/helpers.hh index 28b54a5..7d013bd 100644 --- a/src/bin/eolian_mono/eolian/mono/helpers.hh +++ b/src/bin/eolian_mono/eolian/mono/helpers.hh @@ -33,7 +33,6 @@ inline std::string struct_full_name(attributes::struct_def const& struct_) inline bool is_struct_blacklisted(std::string const& full_name) { return full_name == "Efl.Event.Description" - // || full_name == "Eina.File" || full_name == "Eina.Binbuf" || full_name == "Eina.Slice" || full_name == "Eina.Rw_Slice"; @@ -54,6 +53,30 @@ inline bool need_struct_conversion(attributes::regular_type_def const* regular) return regular && regular->is_struct() && !is_struct_blacklisted(*regular); } +inline bool need_pointer_conversion(attributes::regular_type_def const* regular) +{ + if (!regular) + return false; + + if (regular->is_enum() + || (regular->is_struct() && type_full_name(*regular) != "Eina.Binbuf") + ) + return true; + + std::set const types { + "bool", "char" + , "byte" , "short" , "int" , "long" , "llong" , "int8" , "int16" , "int32" , "int64" , "ssize" + , "ubyte", "ushort", "uint", "ulong", "ullong", "uint8", "uint16", "uint32", "uint64", "size" + , "ptrdiff" + , "float", "double" + }; + if (types.find(regular->base_type) != types.end()) + return true; + + return false; +} + + } #endif diff --git a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh index 7950b31..89efc7f 100644 --- a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh +++ b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh @@ -149,7 +149,7 @@ struct marshall_type_visitor_generate }} }; - if (regular.is_struct() && !is_struct_blacklisted(regular)) + if (!is_ptr && regular.is_struct() && !is_struct_blacklisted(regular)) { return as_generator(*(lower_case[string] << ".") << string << "_StructInternal") .generate(sink, std::make_tuple(eolian_mono::escape_namespace(regular.namespaces), regular.base_type), *context); @@ -169,14 +169,21 @@ struct marshall_type_visitor_generate { return *b; } + else if (is_ptr && need_pointer_conversion(®ular)) + { + regular_type_def r = regular; + r.base_type = " System.IntPtr"; + r.namespaces.clear(); + return visitor_generate{sink, context, c_type, is_out, is_return, is_ptr}(r); + } else { - return visitor_generate{sink, context, c_type, is_out, is_return}(regular); + return visitor_generate{sink, context, c_type, is_out, is_return, is_ptr}(regular); } } bool operator()(attributes::klass_name klass_name) const { - return visitor_generate{sink, context, c_type, is_out, is_return}(klass_name); + return visitor_generate{sink, context, c_type, is_out, is_return, is_ptr}(klass_name); // return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context); } bool operator()(attributes::complex_type_def const& complex) const @@ -259,7 +266,7 @@ struct marshall_type_visitor_generate } //return default_match(complex); - return visitor_generate{sink, context, c_type, is_out, is_return}(complex); + return visitor_generate{sink, context, c_type, is_out, is_return, is_ptr}(complex); // return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context); } }; diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh index 0e3fa32..834ca12 100644 --- a/src/bin/eolian_mono/eolian/mono/parameter.hh +++ b/src/bin/eolian_mono/eolian/mono/parameter.hh @@ -269,6 +269,9 @@ inline bool param_should_use_out_var(attributes::parameter_def const& param, boo if (need_struct_conversion(regular)) return true; + if (param.type.is_ptr && need_pointer_conversion(regular)) + return true; + return false; } @@ -314,6 +317,9 @@ inline bool param_should_use_in_var(attributes::parameter_def const& param, bool if (need_struct_conversion(regular)) return true; + if (param.type.is_ptr && need_pointer_conversion(regular)) + return true; + return false; } @@ -501,7 +507,13 @@ struct native_convert_in_variable_generator return true; auto regular = efl::eina::get(¶m.type.original_type); - if (need_struct_conversion(regular)) + if (param.type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + "var " << string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(" << escape_keyword(param.param_name) << ");\n" + ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context); + } + else if (need_struct_conversion(regular)) { return as_generator( "var " << string << " = " << type << "_StructConvertion.ToExternal(" << escape_keyword(param.param_name) << ");\n" @@ -563,7 +575,13 @@ struct convert_in_variable_generator return true; auto regular = efl::eina::get(¶m.type.original_type); - if (need_struct_conversion(regular)) + if (param.type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + "var " << string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(" << escape_keyword(param.param_name) << ");\n" + ).generate(sink, in_variable_name(param.param_name), context); + } + else if (need_struct_conversion(regular)) { return as_generator( "var " << string << " = " << type << "_StructConvertion.ToInternal(" << escape_keyword(param.param_name) << ");\n" @@ -651,7 +669,13 @@ struct convert_out_variable_generator return true; auto regular = efl::eina::get(¶m.type.original_type); - if (need_struct_conversion(regular)) + if (param.type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + "System.IntPtr " << string << " = System.IntPtr.Zero;\n" + ).generate(sink, out_variable_name(param.param_name), context); + } + else if (need_struct_conversion(regular)) { return as_generator( "var " << string << " = new " << marshall_type << "();\n" @@ -718,7 +742,13 @@ struct native_convert_out_variable_generator return true; auto regular = efl::eina::get(¶m.type.original_type); - if (need_struct_conversion(regular) + if (param.type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + type << " " << string << " = default(" << type << ");\n" + ).generate(sink, std::make_tuple(param, out_variable_name(param.param_name), param), context); + } + else if (need_struct_conversion(regular) || param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT) || param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT)) { @@ -798,7 +828,13 @@ struct convert_out_assign_generator return true; auto regular = efl::eina::get(¶m.type.original_type); - if (need_struct_conversion(regular)) + if (param.type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(" << out_variable_name(param.param_name) << ");\n" + ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context); + } + else if (need_struct_conversion(regular)) { return as_generator( string << " = " << type << "_StructConvertion.ToExternal(" << out_variable_name(param.param_name) << ");\n" @@ -894,7 +930,13 @@ struct convert_return_generator bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const { auto regular = efl::eina::get(&ret_type.original_type); - if (need_struct_conversion(regular)) + if (ret_type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + "return eina.PrimitiveConversion.PointerToManaged<" << type << ">(_ret_var);\n" + ).generate(sink, ret_type, context); + } + else if (need_struct_conversion(regular)) { return as_generator( "return " << type << "_StructConvertion.ToExternal(_ret_var);\n" @@ -956,7 +998,13 @@ struct native_convert_out_assign_generator return true; auto regular = efl::eina::get(¶m.type.original_type); - if (need_struct_conversion(regular)) + if (param.type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(" << string << ");\n" + ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context); + } + else if (need_struct_conversion(regular)) { return as_generator( string << " = " << type << "_StructConvertion.ToInternal(" << string << ");\n" @@ -1083,7 +1131,13 @@ struct native_convert_return_generator bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const { auto regular = efl::eina::get(&ret_type.original_type); - if (need_struct_conversion(regular)) + if (ret_type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + "return eina.PrimitiveConversion.ManagedToPointerAlloc(_ret_var);\n" + ).generate(sink, attributes::unused, context); + } + else if (need_struct_conversion(regular)) { return as_generator( "return " << type << "_StructConvertion.ToInternal(_ret_var);\n" diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh index 6299235..85cc14c 100644 --- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh @@ -156,6 +156,13 @@ struct to_internal_field_convert_generator .generate(sink, std::make_tuple(field_name, field_name), context)) return false; } + else if (field.type.is_ptr && need_pointer_conversion(regular)) + { + if (!as_generator( + scope_tab << scope_tab << "_internal_struct." << string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(_external_struct." << string << ");\n") + .generate(sink, std::make_tuple(field_name, field_name), context)) + return false; + } else if (need_struct_conversion(regular)) { if (!as_generator( @@ -259,6 +266,13 @@ struct to_external_field_convert_generator .generate(sink, std::make_tuple(field_name, field.type, field_name), context)) return false; } + else if (field.type.is_ptr && need_pointer_conversion(regular)) + { + if (!as_generator( + scope_tab << scope_tab << "_external_struct." << string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(_internal_struct." << string << ");\n") + .generate(sink, std::make_tuple(field_name, field.type, field_name), context)) + return false; + } else if (need_struct_conversion(regular)) { if (!as_generator( diff --git a/src/bin/eolian_mono/eolian/mono/type.hh b/src/bin/eolian_mono/eolian/mono/type.hh index b0e1451..b968d9e 100644 --- a/src/bin/eolian_mono/eolian/mono/type.hh +++ b/src/bin/eolian_mono/eolian/mono/type.hh @@ -20,13 +20,13 @@ struct type_generator template bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const { - return type.original_type.visit(visitor_generate{sink, &context, type.c_type, false, is_return}); + return type.original_type.visit(visitor_generate{sink, &context, type.c_type, false, is_return, type.is_ptr}); } template bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const { return param.type.original_type.visit(visitor_generate{sink, &context, param.type.c_type - , param.direction != attributes::parameter_direction::in, false}); + , param.direction != attributes::parameter_direction::in, false, param.type.is_ptr}); } bool is_return; diff --git a/src/bin/eolian_mono/eolian/mono/type_impl.hh b/src/bin/eolian_mono/eolian/mono/type_impl.hh index 3d3950c..9b56805 100644 --- a/src/bin/eolian_mono/eolian/mono/type_impl.hh +++ b/src/bin/eolian_mono/eolian/mono/type_impl.hh @@ -62,6 +62,7 @@ struct visitor_generate std::string c_type; bool is_out; bool is_return; + bool is_ptr; typedef visitor_generate visitor_type; typedef bool result_type; @@ -102,6 +103,7 @@ struct visitor_generate , {"ptrdiff", nullptr, [&] { return replace_base_integer(regular); }} , {"intptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }} + , {"uintptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }} , {"void_ptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }} , {"void", nullptr, [&] { diff --git a/src/bindings/mono/eina_mono/eina_common.cs b/src/bindings/mono/eina_mono/eina_common.cs index 05a5625..fe4e3ec 100644 --- a/src/bindings/mono/eina_mono/eina_common.cs +++ b/src/bindings/mono/eina_mono/eina_common.cs @@ -86,6 +86,36 @@ public static class MemoryNative { } } +[StructLayout(LayoutKind.Sequential)] +public struct ConvertWrapper +{ + public T val; +} + +public static class PrimitiveConversion +{ + public static T PointerToManaged(IntPtr nat) + { + if (nat == IntPtr.Zero) + { + eina.Log.Error("Null pointer for primitive type."); + return default(T); + } + + var w = Marshal.PtrToStructure >(nat); + return w.val; + } + + public static IntPtr ManagedToPointerAlloc(T man) + { + GCHandle pinnedData = GCHandle.Alloc(man, GCHandleType.Pinned); + IntPtr ptr = pinnedData.AddrOfPinnedObject(); + IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf()); + pinnedData.Free(); + return nat; + } +} + public static class StringConversion { public static IntPtr ManagedStringToNativeUtf8Alloc(string managedString) diff --git a/src/bindings/mono/eina_mono/eina_container_common.cs b/src/bindings/mono/eina_mono/eina_container_common.cs index 6cdafdc..a264ed7 100644 --- a/src/bindings/mono/eina_mono/eina_container_common.cs +++ b/src/bindings/mono/eina_mono/eina_container_common.cs @@ -19,12 +19,6 @@ public static class ContainerCommonData } [StructLayout(LayoutKind.Sequential)] -public struct ConvertWrapper -{ - public T Val {get;set;} -} - -[StructLayout(LayoutKind.Sequential)] public struct InlistMem { public IntPtr next {get;set;} @@ -339,11 +333,7 @@ public abstract class PrimitiveElementTraits public IntPtr ManagedToNativeAlloc(T man) { - GCHandle pinnedData = GCHandle.Alloc(man, GCHandleType.Pinned); - IntPtr ptr = pinnedData.AddrOfPinnedObject(); - IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf()); - pinnedData.Free(); - return nat; + return PrimitiveConversion.ManagedToPointerAlloc(man); } public IntPtr ManagedToNativeAllocInlistNode(T man) @@ -394,8 +384,7 @@ public abstract class PrimitiveElementTraits eina.Log.Error("Null pointer on primitive/struct container."); return default(T); } - var w = Marshal.PtrToStructure >(nat); - return w.Val; + return PrimitiveConversion.PointerToManaged(nat); } public T NativeToManagedRef(IntPtr nat) -- 2.7.4