Browse Source

implement decompilation of typeof() (LdTypeToken and LdMemberToken)

pull/728/head
Siegfried Pammer 11 years ago
parent
commit
c4ba350015
  1. 7
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 9
      ICSharpCode.Decompiler/IL/ILReader.cs
  3. 46
      ICSharpCode.Decompiler/IL/Instructions.cs
  4. 14
      ICSharpCode.Decompiler/IL/Instructions.tt

7
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -168,6 +168,13 @@ namespace ICSharpCode.Decompiler.CSharp @@ -168,6 +168,13 @@ namespace ICSharpCode.Decompiler.CSharp
.WithRR(new ConstantResolveResult(SpecialType.NullType, null));
}
protected internal override TranslatedExpression VisitLdTypeToken(LdTypeToken inst)
{
return new TypeOfExpression(ConvertType(inst.Type))
.WithILInstruction(inst)
.WithRR(new TypeResolveResult(compilation.FindType(typeof(Type))));
}
protected internal override TranslatedExpression VisitLogicNot(LogicNot inst)
{
return LogicNot(TranslateCondition(inst.Argument)).WithILInstruction(inst);

9
ICSharpCode.Decompiler/IL/ILReader.cs

@ -632,7 +632,14 @@ namespace ICSharpCode.Decompiler.IL @@ -632,7 +632,14 @@ namespace ICSharpCode.Decompiler.IL
case ILOpCode.Stsfld:
return new Void(new StsFld(Pop(), ReadAndDecodeFieldReference()));
case ILOpCode.Ldtoken:
return new LdToken((MemberReference)ReadAndDecodeMetadataToken());
var memberReference = ReadAndDecodeMetadataToken() as MemberReference;
if (memberReference is TypeReference)
return new LdTypeToken(typeSystem.Resolve((TypeReference)memberReference));
if (memberReference is FieldReference)
return new LdMemberToken(typeSystem.Resolve((FieldReference)memberReference));
if (memberReference is MethodReference)
return new LdMemberToken(typeSystem.Resolve((MethodReference)memberReference));
throw new NotImplementedException();
case ILOpCode.Ldvirtftn:
return new LdVirtFtn(Pop(), ReadAndDecodeMethodReference());
case ILOpCode.Mkrefany:

46
ICSharpCode.Decompiler/IL/Instructions.cs

@ -119,7 +119,9 @@ namespace ICSharpCode.Decompiler.IL @@ -119,7 +119,9 @@ namespace ICSharpCode.Decompiler.IL
/// <summary>Load method pointer</summary>
LdVirtFtn,
/// <summary>Loads runtime representation of metadata token</summary>
LdToken,
LdTypeToken,
/// <summary>Loads runtime representation of metadata token</summary>
LdMemberToken,
/// <summary>Allocates space in the stack frame</summary>
LocAlloc,
/// <summary>Returns from the current method or lambda.</summary>
@ -1074,15 +1076,38 @@ namespace ICSharpCode.Decompiler.IL @@ -1074,15 +1076,38 @@ namespace ICSharpCode.Decompiler.IL
}
/// <summary>Loads runtime representation of metadata token</summary>
public sealed partial class LdToken : SimpleInstruction
public sealed partial class LdTypeToken : SimpleInstruction
{
public LdTypeToken(IType type) : base(OpCode.LdTypeToken)
{
this.type = type;
}
readonly IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public override StackType ResultType { get { return StackType.O; } }
public override void WriteTo(ITextOutput output)
{
output.Write(OpCode);
output.Write(' ');
Disassembler.DisassemblerHelpers.WriteOperand(output, type);
}
public override T AcceptVisitor<T>(ILVisitor<T> visitor)
{
return visitor.VisitLdTypeToken(this);
}
}
/// <summary>Loads runtime representation of metadata token</summary>
public sealed partial class LdMemberToken : SimpleInstruction
{
public LdToken(Mono.Cecil.MemberReference member) : base(OpCode.LdToken)
public LdMemberToken(IMember member) : base(OpCode.LdMemberToken)
{
this.member = member;
}
readonly Mono.Cecil.MemberReference member;
readonly IMember member;
/// <summary>Returns the token operand.</summary>
public Mono.Cecil.MemberReference Member { get { return member; } }
public IMember Member { get { return member; } }
public override StackType ResultType { get { return StackType.O; } }
public override void WriteTo(ITextOutput output)
{
@ -1092,7 +1117,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1092,7 +1117,7 @@ namespace ICSharpCode.Decompiler.IL
}
public override T AcceptVisitor<T>(ILVisitor<T> visitor)
{
return visitor.VisitLdToken(this);
return visitor.VisitLdMemberToken(this);
}
}
@ -2200,7 +2225,11 @@ namespace ICSharpCode.Decompiler.IL @@ -2200,7 +2225,11 @@ namespace ICSharpCode.Decompiler.IL
{
return Default(inst);
}
protected internal virtual T VisitLdToken(LdToken inst)
protected internal virtual T VisitLdTypeToken(LdTypeToken inst)
{
return Default(inst);
}
protected internal virtual T VisitLdMemberToken(LdMemberToken inst)
{
return Default(inst);
}
@ -2406,7 +2435,8 @@ namespace ICSharpCode.Decompiler.IL @@ -2406,7 +2435,8 @@ namespace ICSharpCode.Decompiler.IL
"ldnull",
"ldftn",
"ldvirtftn",
"ldtoken",
"ldtypetoken",
"ldmembertoken",
"localloc",
"ret",
"shl",

14
ICSharpCode.Decompiler/IL/Instructions.tt

@ -122,8 +122,10 @@ @@ -122,8 +122,10 @@
CustomClassName("LdFtn"), NoArguments, HasMethodOperand, ResultType("I")),
new OpCode("ldvirtftn", "Load method pointer",
CustomClassName("LdVirtFtn"), Unary, HasMethodOperand, MayThrow, ResultType("I")),
new OpCode("ldtoken", "Loads runtime representation of metadata token",
CustomClassName("LdToken"), NoArguments, HasTokenOperand, ResultType("O")),
new OpCode("ldtypetoken", "Loads runtime representation of metadata token",
CustomClassName("LdTypeToken"), NoArguments, HasTypeOperand, ResultType("O")),
new OpCode("ldmembertoken", "Loads runtime representation of metadata token",
CustomClassName("LdMemberToken"), NoArguments, HasMemberOperand, ResultType("O")),
new OpCode("localloc", "Allocates space in the stack frame",
CustomClassName("LocAlloc"), Unary, ResultType("I"), MayThrow),
new OpCode("ret", "Returns from the current method or lambda.",
@ -684,12 +686,12 @@ namespace ICSharpCode.Decompiler.IL @@ -684,12 +686,12 @@ namespace ICSharpCode.Decompiler.IL
opCode.WriteOperand.Add("Disassembler.DisassemblerHelpers.WriteOperand(output, method);");
};
static Action<OpCode> HasTokenOperand = opCode => {
opCode.ConstructorParameters.Add("Mono.Cecil.MemberReference member");
opCode.Members.Add("readonly Mono.Cecil.MemberReference member;");
static Action<OpCode> HasMemberOperand = opCode => {
opCode.ConstructorParameters.Add("IMember member");
opCode.Members.Add("readonly IMember member;");
opCode.ConstructorBody.Add("this.member = member;");
opCode.Members.Add("/// <summary>Returns the token operand.</summary>" + Environment.NewLine
+ "public Mono.Cecil.MemberReference Member { get { return member; } }");
+ "public IMember Member { get { return member; } }");
opCode.GenerateWriteTo = true;
opCode.WriteOperand.Add("output.Write(' ');");
opCode.WriteOperand.Add("Disassembler.DisassemblerHelpers.WriteOperand(output, member);");

Loading…
Cancel
Save