Skip to content

Commit e6628b1

Browse files
authored
Fix Memory<> marshalling expression when building in VS (#467)
1 parent bf474ba commit e6628b1

File tree

1 file changed

+37
-3
lines changed

1 file changed

+37
-3
lines changed

src/NodeApi.DotNetHost/JSMarshaller.cs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2153,9 +2153,16 @@ private LambdaExpression BuildConvertFromJSValueExpression(Type toType)
21532153
Type[]? genericArguments = toType.IsGenericType ?
21542154
toType.GetGenericArguments() : null;
21552155

2156+
#if NETFRAMEWORK || NETSTANDARD
2157+
if (genericTypeDefinition?.FullName == typeof(Memory<>).FullName ||
2158+
genericTypeDefinition?.FullName == typeof(ReadOnlyMemory<>).FullName)
2159+
{
2160+
#else
21562161
if (genericTypeDefinition == typeof(Memory<>) ||
21572162
genericTypeDefinition == typeof(ReadOnlyMemory<>))
21582163
{
2164+
Expression valueExpression = valueParameter;
2165+
#endif
21592166
Type elementType = toType.GenericTypeArguments[0];
21602167
if (!IsTypedArrayType(elementType))
21612168
{
@@ -2166,10 +2173,21 @@ private LambdaExpression BuildConvertFromJSValueExpression(Type toType)
21662173
Type typedArrayType = typeof(JSTypedArray<>).MakeGenericType(elementType);
21672174
MethodInfo asTypedArray = typedArrayType.GetExplicitConversion(
21682175
typeof(JSValue), typedArrayType);
2169-
PropertyInfo memory = typedArrayType.GetInstanceProperty("Memory");
2176+
PropertyInfo memoryProperty = typedArrayType.GetInstanceProperty("Memory");
2177+
Expression memoryExpression = Expression.Property(
2178+
Expression.Call(asTypedArray, valueParameter), memoryProperty);
2179+
2180+
#if NETFRAMEWORK || NETSTANDARD
2181+
// The .NET Framework Memory<> type is different. Convert to object first to avoid
2182+
// type validation errors when constructing the Expression when building in VS.
2183+
// (It will be the exact same type at runtime.)
2184+
memoryExpression = Expression.Convert(
2185+
Expression.Convert(memoryExpression, typeof(object)), toType);
2186+
#endif
2187+
21702188
statements = new[]
21712189
{
2172-
Expression.Property(Expression.Call(asTypedArray, valueParameter), memory),
2190+
memoryExpression,
21732191
};
21742192
}
21752193
else if (genericTypeDefinition == typeof(KeyValuePair<,>))
@@ -2478,9 +2496,25 @@ private LambdaExpression BuildConvertToJSValueExpression(Type fromType)
24782496
Type[]? genericArguments = fromType.IsGenericType ?
24792497
fromType.GetGenericArguments() : null;
24802498

2499+
#if NETFRAMEWORK || NETSTANDARD
2500+
if (genericTypeDefinition?.FullName == typeof(Memory<>).FullName ||
2501+
genericTypeDefinition?.FullName == typeof(ReadOnlyMemory<>).FullName)
2502+
{
2503+
// The .NET Framework Memory<> type is different. Convert to object first to avoid
2504+
// type validation errors when constructing the Expression when building in VS.
2505+
// (It will be the exact same type at runtime.)
2506+
genericTypeDefinition =
2507+
genericTypeDefinition.FullName == typeof(Memory<>).FullName ?
2508+
typeof(Memory<>) : typeof(ReadOnlyMemory<>);
2509+
fromType = genericTypeDefinition.MakeGenericType(
2510+
fromType.GenericTypeArguments);
2511+
valueExpression = Expression.Convert(
2512+
Expression.Convert(valueExpression, typeof(object)), fromType);
2513+
#else
24812514
if (genericTypeDefinition == typeof(Memory<>) ||
24822515
genericTypeDefinition == typeof(ReadOnlyMemory<>))
24832516
{
2517+
#endif
24842518
Type elementType = fromType.GenericTypeArguments[0];
24852519
if (!IsTypedArrayType(elementType))
24862520
{
@@ -2494,7 +2528,7 @@ private LambdaExpression BuildConvertToJSValueExpression(Type fromType)
24942528
typedArrayType, typeof(JSValue));
24952529
statements = new[]
24962530
{
2497-
Expression.Call(asJSValue, Expression.New(constructor, valueParameter)),
2531+
Expression.Call(asJSValue, Expression.New(constructor, valueExpression)),
24982532
};
24992533
}
25002534
else if (genericTypeDefinition == typeof(KeyValuePair<,>))

0 commit comments

Comments
 (0)