Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix support for constant arrays of function pointers #222

Open
PathogenDavid opened this issue Oct 21, 2021 · 1 comment
Open

Fix support for constant arrays of function pointers #222

PathogenDavid opened this issue Oct 21, 2021 · 1 comment
Labels
Bug Concept-OutputUsability Issues concerning whether or not the output from Biohazrd is actually usable EdgeCase Language-C# Issues specific to C# Workaround

Comments

@PathogenDavid
Copy link
Member

Right now arrays of function pointers are emitted as normal non-function pointer arrays, which emits the following invalid methods:

public Span<delegate* unmanaged[Cdecl]<mjModel*, mjData*, mjContact*, int, int, double, int>> AsSpan()
    => new Span<delegate* unmanaged[Cdecl]<mjModel*, mjData*, mjContact*, int, int, double, int>>(Element0Pointer, 8);

public ConstantArrayEnumerator<delegate* unmanaged[Cdecl]<mjModel*, mjData*, mjContact*, int, int, double, int>> GetEnumerator()
    => new ConstantArrayEnumerator<delegate* unmanaged[Cdecl]<mjModel*, mjData*, mjContact*, int, int, double, int>>(Element0Pointer, 8);

This isn't valid since function pointers cannot be used as a type argument. We can't use ConstantArrayOfPointersEnumerator either, so GetEnumerator will need to be special-cased similar to #221

@PathogenDavid PathogenDavid added Bug Language-C# Issues specific to C# Concept-OutputUsability Issues concerning whether or not the output from Biohazrd is actually usable EdgeCase labels Oct 21, 2021
@PathogenDavid
Copy link
Member Author

Workaround transformation to rewrite the constant arrays to byte*[] arrays:

using Biohazrd;
using Biohazrd.CSharp;
using Biohazrd.Transformation;

namespace Mochi.MuJoCo.Generator
{
    // This is a workaround for https://github.com/InfectedLibraries/Biohazrd/issues/221
    internal sealed class __WorkaroundBiohazrd221and222Transformation : CSharpTransformationBase
    {
        protected override TransformationResult TransformConstantArrayType(TransformationContext context, ConstantArrayTypeDeclaration declaration)
        {
            bool IsFunctionPointerOfAnyLevelOfIndirection(TypeReference type)
                => type switch
                {
                    FunctionPointerTypeReference => true,
                    PointerTypeReference pointerType => IsFunctionPointerOfAnyLevelOfIndirection(pointerType.Inner),
                    TranslatedTypeReference typeReference =>
                        typeReference.TryResolve(context.Library) is TranslatedTypedef typedef ? IsFunctionPointerOfAnyLevelOfIndirection(typedef.UnderlyingType) : false,
                    _ => false
                };

            if (declaration.Type == VoidTypeReference.PointerInstance || IsFunctionPointerOfAnyLevelOfIndirection(declaration.Type))
            {
                return declaration with { Type = new PointerTypeReference(CSharpBuiltinType.Byte) };
            }
            else
            { return declaration; }
        }
    }
}

(Doesn't match the level of indirection like it probablu should, but byte* is already pretty far from the truth as it is.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Concept-OutputUsability Issues concerning whether or not the output from Biohazrd is actually usable EdgeCase Language-C# Issues specific to C# Workaround
Projects
None yet
Development

No branches or pull requests

1 participant