vitorsousa pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=00fb5b228a0c7011381943eaa909b908336c8ff5

commit 00fb5b228a0c7011381943eaa909b908336c8ff5
Author: Vitor Sousa <[email protected]>
Date:   Fri Dec 15 22:15:00 2017 -0200

    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 28b54a5aef..7d013bd6f5 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<std::string> 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 7950b31213..89efc7f3e2 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(&regular))
+        {
+           regular_type_def r = regular;
+           r.base_type = " System.IntPtr";
+           r.namespaces.clear();
+           return visitor_generate<OutputIterator, Context>{sink, context, 
c_type, is_out, is_return, is_ptr}(r);
+        }
       else
         {
-          return visitor_generate<OutputIterator, Context>{sink, context, 
c_type, is_out, is_return}(regular);
+          return visitor_generate<OutputIterator, Context>{sink, context, 
c_type, is_out, is_return, is_ptr}(regular);
         }
    }
    bool operator()(attributes::klass_name klass_name) const
    {
-     return visitor_generate<OutputIterator, Context>{sink, context, c_type, 
is_out, is_return}(klass_name);
+     return visitor_generate<OutputIterator, Context>{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<OutputIterator, Context>{sink, context, c_type, 
is_out, is_return}(complex);
+     return visitor_generate<OutputIterator, Context>{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 0e3fa326d5..834ca1248d 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<attributes::regular_type_def>(&param.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<attributes::regular_type_def>(&param.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<attributes::regular_type_def>(&param.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<attributes::regular_type_def>(&param.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<attributes::regular_type_def>(&param.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<attributes::regular_type_def>(&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<attributes::regular_type_def>(&param.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<attributes::regular_type_def>(&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 62992357f2..85cc14cc0d 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 b0e14516ce..b968d9e0bc 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 <typename OutputIterator, typename Context>
    bool generate(OutputIterator sink, attributes::type_def const& type, 
Context const& context) const
    {
-      return type.original_type.visit(visitor_generate<OutputIterator, 
Context>{sink, &context, type.c_type, false, is_return});
+      return type.original_type.visit(visitor_generate<OutputIterator, 
Context>{sink, &context, type.c_type, false, is_return, type.is_ptr});
    }
    template <typename OutputIterator, typename Context>
    bool generate(OutputIterator sink, attributes::parameter_def const& param, 
Context const& context) const
    {
       return param.type.original_type.visit(visitor_generate<OutputIterator, 
Context>{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 3d3950c172..9b56805b99 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<OutputIterator, Context> visitor_type;
    typedef bool result_type;
@@ -102,6 +103,7 @@ struct visitor_generate
            
            , {"ptrdiff", nullptr, [&] { return 
replace_base_integer<ptrdiff_t>(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 05a562595c..fe4e3ecabb 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<T>
+{
+    public T val;
+}
+
+public static class PrimitiveConversion
+{
+   public static T PointerToManaged<T>(IntPtr nat)
+   {
+       if (nat == IntPtr.Zero)
+       {
+           eina.Log.Error("Null pointer for primitive type.");
+           return default(T);
+       }
+
+       var w = Marshal.PtrToStructure<eina.ConvertWrapper<T> >(nat);
+       return w.val;
+   }
+
+   public static IntPtr ManagedToPointerAlloc<T>(T man)
+   {
+       GCHandle pinnedData = GCHandle.Alloc(man, GCHandleType.Pinned);
+       IntPtr ptr = pinnedData.AddrOfPinnedObject();
+       IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<T>());
+       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 6cdafdc836..a264ed7577 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<T>
-{
-    public T Val {get;set;}
-}
-
-[StructLayout(LayoutKind.Sequential)]
 public struct InlistMem
 {
     public IntPtr next {get;set;}
@@ -339,11 +333,7 @@ public abstract class PrimitiveElementTraits<T>
 
     public IntPtr ManagedToNativeAlloc(T man)
     {
-        GCHandle pinnedData = GCHandle.Alloc(man, GCHandleType.Pinned);
-        IntPtr ptr = pinnedData.AddrOfPinnedObject();
-        IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<T>());
-        pinnedData.Free();
-        return nat;
+        return PrimitiveConversion.ManagedToPointerAlloc(man);
     }
 
     public IntPtr ManagedToNativeAllocInlistNode(T man)
@@ -394,8 +384,7 @@ public abstract class PrimitiveElementTraits<T>
             eina.Log.Error("Null pointer on primitive/struct container.");
             return default(T);
         }
-        var w = Marshal.PtrToStructure<eina.ConvertWrapper<T> >(nat);
-        return w.Val;
+        return PrimitiveConversion.PointerToManaged<T>(nat);
     }
 
     public T NativeToManagedRef(IntPtr nat)

-- 


Reply via email to