Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ MethodDefinition GenerateWrapper (MarshalMethodEntry method, Dictionary<Assembly
MethodDefinition callback = method.NativeCallback;
AssemblyImports imports = assemblyImports [callback.Module.Assembly];
string wrapperName = $"{callback.Name}_mm_wrapper";
TypeReference retType = MapToBlittableTypeIfNecessary (callback.ReturnType, out bool returnTypeMapped);
TypeReference retType = MapToBlittableTypeIfNecessary (callback, callback.ReturnType, out bool returnTypeMapped);
bool hasReturnValue = String.Compare ("System.Void", callback.ReturnType.FullName, StringComparison.Ordinal) != 0;
var wrapperMethod = new MethodDefinition (wrapperName, callback.Attributes, retType);

Expand All @@ -222,7 +222,7 @@ MethodDefinition GenerateWrapper (MarshalMethodEntry method, Dictionary<Assembly
Instruction? inst = null;
uint nparam = 0;
foreach (ParameterDefinition pdef in callback.Parameters) {
TypeReference newType = MapToBlittableTypeIfNecessary (pdef.ParameterType, out _);
TypeReference newType = MapToBlittableTypeIfNecessary (callback, pdef.ParameterType, out _);
wrapperMethod.Parameters.Add (new ParameterDefinition (pdef.Name, pdef.Attributes, newType));

inst = GetLoadArgInstruction (nparam++, pdef);
Expand Down Expand Up @@ -313,6 +313,11 @@ void GenerateNonBlittableConversion (TypeReference sourceType, TypeReference tar
return;
}

if (IsCharConversion (sourceType, targetType)) {
// There isn't any special code we need to generate.
return;
}

ThrowUnsupportedType (sourceType);
}

Expand All @@ -330,6 +335,11 @@ void GenerateRetValCast (TypeReference sourceType, TypeReference targetType)
return;
}

if (IsCharConversion (sourceType, targetType)) {
// There isn't any special code we need to generate.
return;
}

ThrowUnsupportedType (sourceType);
}

Expand All @@ -346,9 +356,22 @@ bool IsBooleanConversion (TypeReference sourceType, TypeReference targetType)
return false;
}

bool IsCharConversion (TypeReference sourceType, TypeReference targetType)
{
if (String.Compare ("System.Char", sourceType.FullName, StringComparison.Ordinal) == 0) {
if (String.Compare ("System.UInt16", targetType.FullName, StringComparison.Ordinal) != 0) {
throw new InvalidOperationException ($"Unexpected conversion from '{sourceType.FullName}' to '{targetType.FullName}'");
}

return true;
}

return false;
}

void ThrowUnsupportedType (TypeReference type)
{
throw new InvalidOperationException ($"Unsupported non-blittable type '{type.FullName}'");
throw new InvalidOperationException ($"Unsupported non-blittable type '{type.FullName}' in method '{callback.FullName}'");
}
}

Expand Down Expand Up @@ -437,7 +460,7 @@ Instruction GetLoadArgInstruction (uint nparam, ParameterDefinition pdef)
return Instruction.Create (ldargOp, pdef);
}

TypeReference MapToBlittableTypeIfNecessary (TypeReference type, out bool typeMapped)
TypeReference MapToBlittableTypeIfNecessary (MethodDefinition method, TypeReference type, out bool typeMapped)
{
if (type.IsBlittable () || String.Compare ("System.Void", type.FullName, StringComparison.Ordinal) == 0) {
typeMapped = false;
Expand All @@ -450,7 +473,13 @@ TypeReference MapToBlittableTypeIfNecessary (TypeReference type, out bool typeMa
return ReturnValid (typeof(byte));
}

throw new NotSupportedException ($"Cannot map unsupported blittable type '{type.FullName}'");
if (String.Compare ("System.Char", type.FullName, StringComparison.Ordinal) == 0) {
// `char` is 16-bytes both in Java and in .NET
typeMapped = true;
return ReturnValid (typeof(ushort));
}

throw new NotSupportedException ($"Cannot map unsupported blittable type '{type.FullName}' in method '{method.FullName}'");

TypeReference ReturnValid (Type typeToLookUp)
{
Expand Down