Skip to content
Open
Show file tree
Hide file tree
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
@@ -1,4 +1,3 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

Expand All @@ -19,7 +18,7 @@ public class NoArrayInitializers
public int[] LiteralArray()
{
int[] array = new int[3];
RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
RuntimeHelpers.InitializeArray(array, __ldtoken(_003CPrivateImplementationDetails_003E._4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D));
return array;
}

Expand Down
30 changes: 30 additions & 0 deletions ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5153,6 +5153,36 @@ protected internal override TranslatedExpression VisitLdVirtFtn(LdVirtFtn inst,
.WithILInstruction(inst);
}

protected internal override TranslatedExpression VisitLdMemberToken(LdMemberToken inst, TranslationContext context)
{
// C# does not have syntax for obtaining a member token; so we emit pseudo-syntax:
// fields: __ldtoken(DeclaringType.Member)
// methods: __ldtoken(DeclaringType.Member(parameter-types))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generic arguments?

var classType = astBuilder.ConvertType(inst.Member.DeclaringType);
var mre = new MemberReferenceExpression(
new TypeReferenceExpression(classType),
inst.Member.Name
);
Expression memberExpr = mre.WithRR(new MemberResolveResult(null, inst.Member));
if (inst.Member is IMethod method)
{
foreach (var t in method.TypeArguments)
{
mre.TypeArguments.Add(astBuilder.ConvertType(t));
}
var inv = new InvocationExpression(memberExpr);
foreach (var param in method.Parameters)
{
inv.Arguments.Add(new TypeReferenceExpression(astBuilder.ConvertType(param.Type)));
}
memberExpr = inv;
}
var tokenType = inst.Member is IField ? KnownTypeCode.RuntimeFieldHandle : KnownTypeCode.RuntimeMethodHandle;
return new InvocationExpression(new IdentifierExpression("__ldtoken"), memberExpr)
.WithRR(new ResolveResult(compilation.FindType(tokenType)))
.WithILInstruction(inst);
}

protected internal override TranslatedExpression VisitCallIndirect(CallIndirect inst, TranslationContext context)
{
if (inst.IsInstance)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,10 @@ public ITypeDefinition GetTypeDefinition(string name, int typeParameterCount)
// and using the main assembly can cause a stack overflow if there
// are internal assembly attributes.
}
anyTypeDef = typeDef;
// If there's multiple possible matches prefer the first one -- we most likely are
// in the context of the assembly being decompiled, which usually is the first in the list,
// so this increases the odds of picking the correct type.
anyTypeDef ??= typeDef;
}
}
return anyTypeDef;
Expand Down
Loading