/// <inheritdoc /> public override IntrospectiveMethodInfo GeneratePassthroughDefinition(PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { if (!workUnit.Definition.ReturnType.GenericTypeArguments[0].IsValueType) { // Span<byte> is used because unbound generics are not allowed inside a nameof, and it still results as just 'Span' throw new NotSupportedException($"Method is not a {nameof(ValueType)} and cannot be marshaled as a {nameof(Span<byte>)}. Marshalling {nameof(Span<byte>)}" + $"requires the marshaled type T in {nameof(Span<byte>)}<T> to be a {nameof(ValueType)}"); } var definition = workUnit.Definition; Type newReturnType = definition.ReturnType.GenericTypeArguments[0].MakePointerType(); /* TODO? Add marshaling for Span<> params */ Type[] parametersTypes = definition.ParameterTypes.ToArray(); MethodBuilder passthroughMethod = TargetType.DefineMethod ( $"{workUnit.GetUniqueBaseMemberName()}_wrapped", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.Standard, newReturnType, parametersTypes ); passthroughMethod.ApplyCustomAttributesFrom(definition, newReturnType, parametersTypes); return(new IntrospectiveMethodInfo ( passthroughMethod, newReturnType, parametersTypes, definition.MetadataType, definition )); }
/// <inheritdoc /> public override IntrospectiveMethodInfo GeneratePassthroughDefinition(PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var returnType = workUnit.Definition.ReturnType; Type newReturnType; var definition = workUnit.Definition; if (IsSpanType(returnType)) { var genericType = returnType.GenericTypeArguments[0]; if (!genericType.IsUnmanaged()) { throw new NotSupportedException($"Method return type must be blittable."); } newReturnType = genericType.MakePointerType(); } else { newReturnType = returnType; } var parametersTypes = definition.ParameterTypes.ToArray(); for (int i = 0; i < parametersTypes.Length; ++i) { var paramType = parametersTypes[i]; if (IsSpanType(paramType)) { var genericParam = paramType.GenericTypeArguments[0]; if (genericParam.IsGenericType) { throw new NotSupportedException("Generic type found as Span generic argument"); } if (!genericParam.IsUnmanaged()) { throw new NotSupportedException("Reference or value type containing references found in Span<T> or ReadOnlySpan<T> generic parameter."); } parametersTypes[i] = genericParam.MakePointerType(); // genercParam.MakePointerType(); } } MethodBuilder passthroughMethod = TargetType.DefineMethod ( $"{workUnit.GetUniqueBaseMemberName()}_wrapped", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.Standard, newReturnType, parametersTypes ); passthroughMethod.ApplyCustomAttributesFrom(definition, newReturnType, parametersTypes); return(new IntrospectiveMethodInfo ( passthroughMethod, newReturnType, parametersTypes, definition.MetadataType, definition )); }