SeeminglyScience / ILAssembler

ILAsm-like DSL for PowerShell
MIT License
16 stars 1 forks source link

Stop using `ELEMENT_TYPE_INTERNAL` for generic instantiations #42

Open SeeminglyScience opened 4 years ago

SeeminglyScience commented 4 years ago
$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 ```python 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 , : 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 , : line 1 ```
SeeminglyScience commented 4 years ago

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.

https://github.com/SeeminglyScience/ILAssembler/blob/7e1a7cedb07ee2bf450dd949920d47f523dd647e/src/ILAssembler/EncoderExtensions.cs#L48-L66