Skip to content

Commit

Permalink
Fix fillarray code gen - should not pass by ref (#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
Scottj1s authored Apr 22, 2020
1 parent ce2cedd commit 6c70f7e
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 29 deletions.
32 changes: 16 additions & 16 deletions UnitTest/TestComponent_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ public void Array_Bool()
bool[] a = new bool[] { true, false, true };
bool[] b = new bool[a.Length];
bool[] c;
bool[] d = Tests.Array1(a, ref b, out c);
bool[] d = Tests.Array1(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -270,7 +270,7 @@ public void Array_Byte()
byte[] a = new byte[] { 1, 2, 3 };
byte[] b = new byte[a.Length];
byte[] c;
byte[] d = Tests.Array2(a, ref b, out c);
byte[] d = Tests.Array2(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -280,7 +280,7 @@ public void Array_UInt16()
UInt16[] a = new UInt16[] { 1, 2, 3 };
UInt16[] b = new UInt16[a.Length];
UInt16[] c;
UInt16[] d = Tests.Array3(a, ref b, out c);
UInt16[] d = Tests.Array3(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -290,7 +290,7 @@ public void Array_UInt32()
UInt32[] a = new UInt32[] { 1, 2, 3 };
UInt32[] b = new UInt32[a.Length];
UInt32[] c;
UInt32[] d = Tests.Array4(a, ref b, out c);
UInt32[] d = Tests.Array4(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -300,7 +300,7 @@ public void Array_UInt64()
UInt64[] a = new UInt64[] { 1, 2, 3 };
UInt64[] b = new UInt64[a.Length];
UInt64[] c;
UInt64[] d = Tests.Array5(a, ref b, out c);
UInt64[] d = Tests.Array5(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -310,7 +310,7 @@ public void Array_Int16()
Int16[] a = new Int16[] { 1, 2, 3 };
Int16[] b = new Int16[a.Length];
Int16[] c;
Int16[] d = Tests.Array6(a, ref b, out c);
Int16[] d = Tests.Array6(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -320,7 +320,7 @@ public void Array_Int32()
Int32[] a = new Int32[] { 1, 2, 3 };
Int32[] b = new Int32[a.Length];
Int32[] c;
Int32[] d = Tests.Array7(a, ref b, out c);
Int32[] d = Tests.Array7(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -330,7 +330,7 @@ public void Array_Int64()
Int64[] a = new Int64[] { 1, 2, 3 };
Int64[] b = new Int64[a.Length];
Int64[] c;
Int64[] d = Tests.Array8(a, ref b, out c);
Int64[] d = Tests.Array8(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -340,7 +340,7 @@ public void Array_Float()
float[] a = new float[] { 1.0f, 2.0f, 3.0f };
float[] b = new float[a.Length];
float[] c;
float[] d = Tests.Array9(a, ref b, out c);
float[] d = Tests.Array9(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -350,7 +350,7 @@ public void Array_Double()
double[] a = new double[] { 1.0, 2.0, 3.0 };
double[] b = new double[a.Length];
double[] c;
double[] d = Tests.Array10(a, ref b, out c);
double[] d = Tests.Array10(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -360,7 +360,7 @@ public void Array_Char()
char[] a = new char[] { 'a', 'b', 'c' };
char[] b = new char[a.Length];
char[] c;
char[] d = Tests.Array11(a, ref b, out c);
char[] d = Tests.Array11(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -370,7 +370,7 @@ public void Array_String()
string[] a = new string[] { "apples", "oranges", "pears" };
string[] b = new string[a.Length];
string[] c;
string[] d = Tests.Array12(a, ref b, out c);
string[] d = Tests.Array12(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -383,7 +383,7 @@ public void Array_Blittable()
};
Blittable[] b = new Blittable[a.Length];
Blittable[] c;
Blittable[] d = Tests.Array13(a, ref b, out c);
Blittable[] d = Tests.Array13(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -397,7 +397,7 @@ public void Array_NonBlittable()
};
NonBlittable[] b = new NonBlittable[a.Length];
NonBlittable[] c;
NonBlittable[] d = Tests.Array14(a, ref b, out c);
NonBlittable[] d = Tests.Array14(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

Expand All @@ -417,11 +417,11 @@ public void Array_Nested()
};
Nested[] b = new Nested[a.Length];
Nested[] c;
Nested[] d = Tests.Array15(a, ref b, out c);
Nested[] d = Tests.Array15(a, b, out c);
Assert.True(AllEqual(a, b, c, d));
}

private T[] Array_Call<T>(T[] a, ref T[] b, out T[] c)
private T[] Array_Call<T>(T[] a, T[] b, out T[] c)
{
Assert.True(a.Length == b.Length);
a.CopyTo(b, 0);
Expand Down
27 changes: 15 additions & 12 deletions cswinrt/code_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,11 +303,6 @@ namespace cswinrt
switch (get_param_category(param))
{
case param_category::out:
w.write("out ");
break;
case param_category::fill_array:
w.write("ref ");
break;
case param_category::receive_array:
w.write("out ");
break;
Expand All @@ -330,10 +325,8 @@ namespace cswinrt
w.write("out %", bind<write_projection_type>(semantics));
break;
case param_category::pass_array:
w.write("%[]", bind<write_projection_type>(semantics));
break;
case param_category::fill_array:
w.write("ref %[]", bind<write_projection_type>(semantics));
w.write("%[]", bind<write_projection_type>(semantics));
break;
case param_category::receive_array:
w.write("out %[]", bind<write_projection_type>(semantics));
Expand Down Expand Up @@ -435,8 +428,6 @@ namespace cswinrt
w.write(", out % %", bind<write_abi_type>(semantics), param_name);
break;
case param_category::pass_array:
w.write(", int __%Size, IntPtr %", param_name, param_name);
break;
case param_category::fill_array:
w.write(", int __%Size, IntPtr %", param_name, param_name);
break;
Expand Down Expand Up @@ -1873,6 +1864,18 @@ event % %;)",
{
if (!is_ref() && (!is_out() || local_type.empty()))
return;
if (is_ref())
{
if (!starts_with(marshaler_type, "MarshalBlittable"))
{
w.write("%.CopyAbiArray(%, (__%_length, __%_data));\n",
marshaler_type,
bind<write_escaped_identifier>(param_name),
param_name,
param_name);
}
return;
}
is_return ?
w.write("return ") :
w.write("% = ", bind<write_escaped_identifier>(param_name));
Expand Down Expand Up @@ -2886,7 +2889,7 @@ remove => _%.Unsubscribe(value);
{
is_generic() ?
w.write("null") :
w.write("% __%", is_out() ? "out" : "ref", param_name);
w.write("% __%", is_out() ? "out" : "", param_name);
}
else if (marshaler_type.empty())
{
Expand Down Expand Up @@ -2924,7 +2927,7 @@ remove => _%.Unsubscribe(value);
if (!is_ref() && (!is_out() || local_type.empty()))
return;
auto param_local = get_param_local(w);
if (category == param_category::fill_array)
if (is_ref())
{
w.write("%.CopyManagedArray(%, %);\n",
marshaler_type,
Expand Down
25 changes: 24 additions & 1 deletion cswinrt/strings/WinRT_Marshal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public static bool ObjectEquals<T>(this T x, T y)

// TODO: minimize heap allocations for marshalers by eliminating explicit try/finally
// and adopting ref structs with non-IDisposable Dispose and 'using var ...' pattern,
// as well as passing marshalers to FromAbi by ref so they can be disposed.
// as well as passing marshalers to FromAbi by ref so they can be conditionally disposed.
class MarshalString
{
public unsafe struct HStringHeader // sizeof(HSTRING_HEADER)
Expand Down Expand Up @@ -177,6 +177,16 @@ public static unsafe string[] FromAbiArray(object box)
return array;
}

public static unsafe void CopyAbiArray(string[] array, object box)
{
var abi = ((int length, IntPtr data))box;
var data = (IntPtr*)abi.data.ToPointer();
for (int i = 0; i < abi.length; i++)
{
array[i] = MarshalString.FromAbi(data[i]);
}
}

public static unsafe (int length, IntPtr data) FromManagedArray(string[] array)
{
IntPtr data = IntPtr.Zero;
Expand Down Expand Up @@ -464,6 +474,19 @@ public static unsafe T[] FromAbiArray(object box)
return array;
}

public static unsafe void CopyAbiArray(T[] array, object box)
{
var abi = ((int length, IntPtr data))box;
var data = (byte*)abi.data.ToPointer();
var abi_element_size = Marshal.SizeOf(HelperType);
for (int i = 0; i < abi.length; i++)
{
var abi_element = Marshal.PtrToStructure((IntPtr)data, HelperType);
array[i] = Marshaler<T>.FromAbi(abi_element);
data += abi_element_size;
}
}

public static unsafe (int length, IntPtr data) FromManagedArray(T[] array)
{
IntPtr data = IntPtr.Zero;
Expand Down

0 comments on commit 6c70f7e

Please sign in to comment.