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

Stop using ELEMENT_TYPE_INTERNAL for generic instantiations #42

Open
SeeminglyScience opened this issue Oct 14, 2020 · 1 comment
Open
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@SeeminglyScience
Copy link
Owner

$longToBytes = il { [byte[]]([long]) } {
    .locals init {
        [Span[byte]] $span
    }

    ldarga.s 0
    sizeof { [long] }
    call { [Span[byte]] [Runtime.InteropServices.MemoryMarshal]::CreateSpan([g[byte]], [ref] [byte], [int]) }
    stloc.auto $span
    ldloca.auto $span
    call { [byte[]] [Span[byte]].ToArray() }
    ret
}

$longToBytes.Invoke(20l)
Get-Error
Exception             :
    Type           : System.Management.Automation.MethodInvocationException
    ErrorRecord    :
        Exception             :
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : Exception calling "Invoke" with "1" argument(s): "Could not load type 'Microsoft.CodeAnalysis.EmbeddedAttribute'
from assembly 'ILAssembler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' due to value type mismatch."
            HResult : -2146233087
        CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
        FullyQualifiedErrorId : TypeLoadException
        InvocationInfo        :
            ScriptLineNumber : 1
            OffsetInLine     : 1
            HistoryId        : -1
            Line             : $longToBytes.Invoke(20l)
            PositionMessage  : At line:1 char:1
                               + $longToBytes.Invoke(20l)
                               + ~~~~~~~~~~~~~~~~~~~~~~~~
            CommandOrigin    : Internal
        ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
    TargetSite     :
        Name          : ConvertToMethodInvocationException
        DeclaringType : System.Management.Automation.ExceptionHandlingOps, System.Management.Automation, Version=7.1.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35
        MemberType    : Method
        Module        : System.Management.Automation.dll
    StackTrace     :
   at System.Management.Automation.ExceptionHandlingOps.ConvertToMethodInvocationException(Exception exception, Type typeToThrow, String
methodName, Int32 numArgs, MemberInfo memberInfo)
   at CallSite.Target(Closure , CallSite , Object , Int64 )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
   at System.Management.Automation.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
    Message        : Exception calling "Invoke" with "1" argument(s): "Could not load type 'Microsoft.CodeAnalysis.EmbeddedAttribute' from
assembly 'ILAssembler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' due to value type mismatch."
    Data           : System.Collections.ListDictionaryInternal
    InnerException :
        Type       : System.TypeLoadException
        Message    : Could not load type 'Microsoft.CodeAnalysis.EmbeddedAttribute' from assembly 'ILAssembler, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null' due to value type mismatch.
        TypeName   : Microsoft.CodeAnalysis.EmbeddedAttribute
        TargetSite : Byte[] Invoke(Int64)
        StackTrace :
   at Invoke(Int64 )
   at CallSite.Target(Closure , CallSite , Object , Int64 )
        Source     : ILAssembler
        HResult    : -2146233054
    Source         : System.Management.Automation
    HResult        : -2146233087
CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : TypeLoadException
InvocationInfo        :
    ScriptLineNumber : 1
    OffsetInLine     : 1
    HistoryId        : -1
    Line             : $longToBytes.Invoke(20l)
    PositionMessage  : At line:1 char:1
                       + $longToBytes.Invoke(20l)
                       + ~~~~~~~~~~~~~~~~~~~~~~~~
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
@SeeminglyScience SeeminglyScience self-assigned this Oct 14, 2020
@SeeminglyScience SeeminglyScience added the bug Something isn't working label Oct 14, 2020
@SeeminglyScience SeeminglyScience added this to the v1.0.0 milestone Oct 14, 2020
@SeeminglyScience SeeminglyScience changed the title EmbeddedAttribute value type mismatch Declaring a Span<> local throws EmbeddedAttribute value type mismatch on Invoke Oct 17, 2020
@SeeminglyScience SeeminglyScience pinned this issue Oct 17, 2020
@SeeminglyScience SeeminglyScience modified the milestones: v1.0.0, Future Oct 17, 2020
@SeeminglyScience
Copy link
Owner Author

Turns out it's any generic instantiation. There doesn't appear to be anything wrong with the signature that I'm encoding, so I am leaning towards it being a bug with DynamicILInfo. I'll need to do more research and possibly open an issue on dotnet/runtime.

Until then, I've worked around the issue by using the unsupported element type ELEMENT_TYPE_INTERNAL to embed the type handle directly into the signature.

// The supported way of declaring a generic instantiation isn't
// working correctly in a locals sig. Unsure if it's something
// we're doing wrong or if it's a problem with the DynamicILInfo
// API. As a workaround, we're depending on an implementation
// detail used by the runtime to embed a type handle directly
// as a pointer.
//
// The proper implementation is commented below this.
//
// https://github.com/SeeminglyScience/ILAssembler/issues/42
const byte ELEMENT_TYPE_INTERNAL = 0x21;
encoder.Builder.WriteByte(ELEMENT_TYPE_INTERNAL);
IntPtr rawHandle = type.TypeHandle.Value;
unsafe
{
encoder.Builder.WriteBytes(
(byte*)&rawHandle,
sizeof(IntPtr));
}

@SeeminglyScience SeeminglyScience changed the title Declaring a Span<> local throws EmbeddedAttribute value type mismatch on Invoke Stop using ELEMENT_TYPE_INTERNAL for generic instantiations Oct 17, 2020
@SeeminglyScience SeeminglyScience added enhancement New feature or request and removed bug Something isn't working labels Oct 17, 2020
@SeeminglyScience SeeminglyScience unpinned this issue Oct 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant