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
.WithRR(new ConstantResolveResult(SpecialType.NullType, null)); .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) protected internal override TranslatedExpression VisitLogicNot(LogicNot inst)
{ {
return LogicNot(TranslateCondition(inst.Argument)).WithILInstruction(inst); return LogicNot(TranslateCondition(inst.Argument)).WithILInstruction(inst);

9
ICSharpCode.Decompiler/IL/ILReader.cs

@ -632,7 +632,14 @@ namespace ICSharpCode.Decompiler.IL
case ILOpCode.Stsfld: case ILOpCode.Stsfld:
return new Void(new StsFld(Pop(), ReadAndDecodeFieldReference())); return new Void(new StsFld(Pop(), ReadAndDecodeFieldReference()));
case ILOpCode.Ldtoken: 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: case ILOpCode.Ldvirtftn:
return new LdVirtFtn(Pop(), ReadAndDecodeMethodReference()); return new LdVirtFtn(Pop(), ReadAndDecodeMethodReference());
case ILOpCode.Mkrefany: case ILOpCode.Mkrefany:

46
ICSharpCode.Decompiler/IL/Instructions.cs

@ -119,7 +119,9 @@ namespace ICSharpCode.Decompiler.IL
/// <summary>Load method pointer</summary> /// <summary>Load method pointer</summary>
LdVirtFtn, LdVirtFtn,
/// <summary>Loads runtime representation of metadata token</summary> /// <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> /// <summary>Allocates space in the stack frame</summary>
LocAlloc, LocAlloc,
/// <summary>Returns from the current method or lambda.</summary> /// <summary>Returns from the current method or lambda.</summary>
@ -1074,15 +1076,38 @@ namespace ICSharpCode.Decompiler.IL
} }
/// <summary>Loads runtime representation of metadata token</summary> /// <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; this.member = member;
} }
readonly Mono.Cecil.MemberReference member; readonly IMember member;
/// <summary>Returns the token operand.</summary> /// <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 StackType ResultType { get { return StackType.O; } }
public override void WriteTo(ITextOutput output) public override void WriteTo(ITextOutput output)
{ {
@ -1092,7 +1117,7 @@ namespace ICSharpCode.Decompiler.IL
} }
public override T AcceptVisitor<T>(ILVisitor<T> visitor) public override T AcceptVisitor<T>(ILVisitor<T> visitor)
{ {
return visitor.VisitLdToken(this); return visitor.VisitLdMemberToken(this);
} }
} }
@ -2200,7 +2225,11 @@ namespace ICSharpCode.Decompiler.IL
{ {
return Default(inst); 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); return Default(inst);
} }
@ -2406,7 +2435,8 @@ namespace ICSharpCode.Decompiler.IL
"ldnull", "ldnull",
"ldftn", "ldftn",
"ldvirtftn", "ldvirtftn",
"ldtoken", "ldtypetoken",
"ldmembertoken",
"localloc", "localloc",
"ret", "ret",
"shl", "shl",

14
ICSharpCode.Decompiler/IL/Instructions.tt

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

Loading…
Cancel
Save