Browse Source

Add ExpressionTreeCast instruction

pull/988/head
Siegfried Pammer 8 years ago
parent
commit
21dfa43dab
  1. 7
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  3. 55
      ICSharpCode.Decompiler/IL/Instructions.cs
  4. 4
      ICSharpCode.Decompiler/IL/Instructions.tt
  5. 31
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTreeCast.cs

7
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1701,7 +1701,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1701,7 +1701,12 @@ namespace ICSharpCode.Decompiler.CSharp
{
return Translate(inst.Argument).ConvertTo(inst.Type, this);
}
protected internal override TranslatedExpression VisitExpressionTreeCast(ExpressionTreeCast inst, TranslationContext context)
{
return Translate(inst.Argument).ConvertTo(inst.Type, this, inst.IsChecked);
}
protected internal override TranslatedExpression VisitArglist(Arglist inst, TranslationContext context)
{
return new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.ArgListAccess }

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -283,6 +283,7 @@ @@ -283,6 +283,7 @@
<Compile Include="IL\Instructions\CallIndirect.cs" />
<Compile Include="IL\Instructions\DefaultValue.cs" />
<Compile Include="IL\Transforms\EarlyExpressionTransforms.cs" />
<Compile Include="IL\Transforms\ExpressionTreeCast.cs" />
<Compile Include="IL\Transforms\HighLevelLoopTransform.cs" />
<Compile Include="IL\Transforms\ProxyCallReplacer.cs" />
<Compile Include="IL\Instructions\StringToInt.cs" />

55
ICSharpCode.Decompiler/IL/Instructions.cs

@ -168,6 +168,8 @@ namespace ICSharpCode.Decompiler.IL @@ -168,6 +168,8 @@ namespace ICSharpCode.Decompiler.IL
ArrayToPointer,
/// <summary>Maps a string value to an integer. This is used in switch(string).</summary>
StringToInt,
/// <summary>ILAst representation of Expression.Convert.</summary>
ExpressionTreeCast,
/// <summary>Push a typed reference of type class onto the stack.</summary>
MakeRefAny,
/// <summary>Push the type token stored in a typed reference.</summary>
@ -4493,6 +4495,46 @@ namespace ICSharpCode.Decompiler.IL @@ -4493,6 +4495,46 @@ namespace ICSharpCode.Decompiler.IL
}
}
namespace ICSharpCode.Decompiler.IL
{
/// <summary>ILAst representation of Expression.Convert.</summary>
public sealed partial class ExpressionTreeCast : UnaryInstruction
{
IType type;
/// <summary>Returns the type operand.</summary>
public IType Type {
get { return type; }
set { type = value; InvalidateFlags(); }
}
public override StackType ResultType { get { return type.GetStackType(); } }
protected override InstructionFlags ComputeFlags()
{
return base.ComputeFlags() | InstructionFlags.MayThrow;
}
public override InstructionFlags DirectFlags {
get {
return base.DirectFlags | InstructionFlags.MayThrow;
}
}
public override void AcceptVisitor(ILVisitor visitor)
{
visitor.VisitExpressionTreeCast(this);
}
public override T AcceptVisitor<T>(ILVisitor<T> visitor)
{
return visitor.VisitExpressionTreeCast(this);
}
public override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)
{
return visitor.VisitExpressionTreeCast(this, context);
}
protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match)
{
var o = other as ExpressionTreeCast;
return o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type) && this.IsChecked == o.IsChecked;
}
}
}
namespace ICSharpCode.Decompiler.IL
{
/// <summary>Push a typed reference of type class onto the stack.</summary>
public sealed partial class MakeRefAny : UnaryInstruction
@ -5132,6 +5174,10 @@ namespace ICSharpCode.Decompiler.IL @@ -5132,6 +5174,10 @@ namespace ICSharpCode.Decompiler.IL
{
Default(inst);
}
protected internal virtual void VisitExpressionTreeCast(ExpressionTreeCast inst)
{
Default(inst);
}
protected internal virtual void VisitMakeRefAny(MakeRefAny inst)
{
Default(inst);
@ -5434,6 +5480,10 @@ namespace ICSharpCode.Decompiler.IL @@ -5434,6 +5480,10 @@ namespace ICSharpCode.Decompiler.IL
{
return Default(inst);
}
protected internal virtual T VisitExpressionTreeCast(ExpressionTreeCast inst)
{
return Default(inst);
}
protected internal virtual T VisitMakeRefAny(MakeRefAny inst)
{
return Default(inst);
@ -5736,6 +5786,10 @@ namespace ICSharpCode.Decompiler.IL @@ -5736,6 +5786,10 @@ namespace ICSharpCode.Decompiler.IL
{
return Default(inst, context);
}
protected internal virtual T VisitExpressionTreeCast(ExpressionTreeCast inst, C context)
{
return Default(inst, context);
}
protected internal virtual T VisitMakeRefAny(MakeRefAny inst, C context)
{
return Default(inst, context);
@ -5829,6 +5883,7 @@ namespace ICSharpCode.Decompiler.IL @@ -5829,6 +5883,7 @@ namespace ICSharpCode.Decompiler.IL
"ldelema",
"array.to.pointer",
"string.to.int",
"expression.tree.cast",
"mkrefany",
"refanytype",
"refanyval",

4
ICSharpCode.Decompiler/IL/Instructions.tt

@ -240,6 +240,10 @@ @@ -240,6 +240,10 @@
new OpCode("string.to.int", "Maps a string value to an integer. This is used in switch(string).",
CustomArguments("argument"), CustomConstructor, CustomWriteTo, ResultType("I4")),
new OpCode("expression.tree.cast", "ILAst representation of Expression.Convert.",
CustomClassName("ExpressionTreeCast"), Unary, HasTypeOperand, MayThrow, CustomConstructor, CustomWriteTo, ResultType("type.GetStackType()"),
MatchCondition("this.IsChecked == o.IsChecked")),
new OpCode("mkrefany", "Push a typed reference of type class onto the stack.",
CustomClassName("MakeRefAny"), Unary, HasTypeOperand, ResultType("O")),
new OpCode("refanytype", "Push the type token stored in a typed reference.",

31
ICSharpCode.Decompiler/IL/Transforms/ExpressionTreeCast.cs

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Text;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.IL
{
partial class ExpressionTreeCast
{
public bool IsChecked { get; set; }
public ExpressionTreeCast(IType type, ILInstruction argument, bool isChecked)
: base(OpCode.ExpressionTreeCast, argument)
{
this.Type = type;
this.IsChecked = isChecked;
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
ILRange.WriteTo(output, options);
output.Write(OpCode);
if (IsChecked) output.Write(".checked");
output.Write(' ');
type.WriteTo(output);
output.Write('(');
Argument.WriteTo(output, options);
output.Write(')');
}
}
}
Loading…
Cancel
Save