Browse Source

Add UsingInstruction to ILAst.

pull/870/merge
Siegfried Pammer 8 years ago
parent
commit
dea81a685d
  1. 140
      ICSharpCode.Decompiler/IL/Instructions.cs
  2. 7
      ICSharpCode.Decompiler/IL/Instructions.tt
  3. 30
      ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs

140
ICSharpCode.Decompiler/IL/Instructions.cs

@ -73,6 +73,8 @@ namespace ICSharpCode.Decompiler.IL
TryFault, TryFault,
/// <summary>Lock statement</summary> /// <summary>Lock statement</summary>
LockInstruction, LockInstruction,
/// <summary>Using statement</summary>
UsingInstruction,
/// <summary>Breakpoint instruction</summary> /// <summary>Breakpoint instruction</summary>
DebugBreak, DebugBreak,
/// <summary>Comparison. The inputs must be both integers; or both floats; or both object references. Object references can only be compared for equality or inequality. Floating-point comparisons evaluate to 0 (false) when an input is NaN, except for 'NaN != NaN' which evaluates to 1 (true).</summary> /// <summary>Comparison. The inputs must be both integers; or both floats; or both object references. Object references can only be compared for equality or inequality. Floating-point comparisons evaluate to 0 (false) when an input is NaN, except for 'NaN != NaN' which evaluates to 1 (true).</summary>
@ -1667,6 +1669,16 @@ namespace ICSharpCode.Decompiler.IL
clone.Body = this.body.Clone(); clone.Body = this.body.Clone();
return clone; return clone;
} }
public override StackType ResultType { get { return StackType.Void; } }
protected override InstructionFlags ComputeFlags()
{
return onExpression.Flags | body.Flags | InstructionFlags.ControlFlow | InstructionFlags.SideEffect;
}
public override InstructionFlags DirectFlags {
get {
return InstructionFlags.ControlFlow | InstructionFlags.SideEffect;
}
}
public override void AcceptVisitor(ILVisitor visitor) public override void AcceptVisitor(ILVisitor visitor)
{ {
visitor.VisitLockInstruction(this); visitor.VisitLockInstruction(this);
@ -1687,6 +1699,109 @@ namespace ICSharpCode.Decompiler.IL
} }
} }
namespace ICSharpCode.Decompiler.IL namespace ICSharpCode.Decompiler.IL
{
/// <summary>Using statement</summary>
public sealed partial class UsingInstruction : ILInstruction
{
public UsingInstruction(ILInstruction resourceExpression, ILInstruction body) : base(OpCode.UsingInstruction)
{
this.ResourceExpression = resourceExpression;
this.Body = body;
}
public static readonly SlotInfo ResourceExpressionSlot = new SlotInfo("ResourceExpression", canInlineInto: true);
ILInstruction resourceExpression;
public ILInstruction ResourceExpression {
get { return this.resourceExpression; }
set {
ValidateChild(value);
SetChildInstruction(ref this.resourceExpression, value, 0);
}
}
public static readonly SlotInfo BodySlot = new SlotInfo("Body");
ILInstruction body;
public ILInstruction Body {
get { return this.body; }
set {
ValidateChild(value);
SetChildInstruction(ref this.body, value, 1);
}
}
protected sealed override int GetChildCount()
{
return 2;
}
protected sealed override ILInstruction GetChild(int index)
{
switch (index) {
case 0:
return this.resourceExpression;
case 1:
return this.body;
default:
throw new IndexOutOfRangeException();
}
}
protected sealed override void SetChild(int index, ILInstruction value)
{
switch (index) {
case 0:
this.ResourceExpression = value;
break;
case 1:
this.Body = value;
break;
default:
throw new IndexOutOfRangeException();
}
}
protected sealed override SlotInfo GetChildSlot(int index)
{
switch (index) {
case 0:
return ResourceExpressionSlot;
case 1:
return BodySlot;
default:
throw new IndexOutOfRangeException();
}
}
public sealed override ILInstruction Clone()
{
var clone = (UsingInstruction)ShallowClone();
clone.ResourceExpression = this.resourceExpression.Clone();
clone.Body = this.body.Clone();
return clone;
}
public override StackType ResultType { get { return StackType.Void; } }
protected override InstructionFlags ComputeFlags()
{
return resourceExpression.Flags | body.Flags | InstructionFlags.ControlFlow | InstructionFlags.SideEffect;
}
public override InstructionFlags DirectFlags {
get {
return InstructionFlags.ControlFlow | InstructionFlags.SideEffect;
}
}
public override void AcceptVisitor(ILVisitor visitor)
{
visitor.VisitUsingInstruction(this);
}
public override T AcceptVisitor<T>(ILVisitor<T> visitor)
{
return visitor.VisitUsingInstruction(this);
}
public override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)
{
return visitor.VisitUsingInstruction(this, context);
}
protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match)
{
var o = other as UsingInstruction;
return o != null && this.resourceExpression.PerformMatch(o.resourceExpression, ref match) && this.body.PerformMatch(o.body, ref match);
}
}
}
namespace ICSharpCode.Decompiler.IL
{ {
/// <summary>Breakpoint instruction</summary> /// <summary>Breakpoint instruction</summary>
public sealed partial class DebugBreak : SimpleInstruction public sealed partial class DebugBreak : SimpleInstruction
@ -4310,6 +4425,10 @@ namespace ICSharpCode.Decompiler.IL
{ {
Default(inst); Default(inst);
} }
protected internal virtual void VisitUsingInstruction(UsingInstruction inst)
{
Default(inst);
}
protected internal virtual void VisitDebugBreak(DebugBreak inst) protected internal virtual void VisitDebugBreak(DebugBreak inst)
{ {
Default(inst); Default(inst);
@ -4592,6 +4711,10 @@ namespace ICSharpCode.Decompiler.IL
{ {
return Default(inst); return Default(inst);
} }
protected internal virtual T VisitUsingInstruction(UsingInstruction inst)
{
return Default(inst);
}
protected internal virtual T VisitDebugBreak(DebugBreak inst) protected internal virtual T VisitDebugBreak(DebugBreak inst)
{ {
return Default(inst); return Default(inst);
@ -4874,6 +4997,10 @@ namespace ICSharpCode.Decompiler.IL
{ {
return Default(inst, context); return Default(inst, context);
} }
protected internal virtual T VisitUsingInstruction(UsingInstruction inst, C context)
{
return Default(inst, context);
}
protected internal virtual T VisitDebugBreak(DebugBreak inst, C context) protected internal virtual T VisitDebugBreak(DebugBreak inst, C context)
{ {
return Default(inst, context); return Default(inst, context);
@ -5085,6 +5212,7 @@ namespace ICSharpCode.Decompiler.IL
"try.finally", "try.finally",
"try.fault", "try.fault",
"lock", "lock",
"using",
"debug.break", "debug.break",
"comp", "comp",
"call", "call",
@ -5209,6 +5337,18 @@ namespace ICSharpCode.Decompiler.IL
body = default(ILInstruction); body = default(ILInstruction);
return false; return false;
} }
public bool MatchUsingInstruction(out ILInstruction resourceExpression, out ILInstruction body)
{
var inst = this as UsingInstruction;
if (inst != null) {
resourceExpression = inst.ResourceExpression;
body = inst.Body;
return true;
}
resourceExpression = default(ILInstruction);
body = default(ILInstruction);
return false;
}
public bool MatchDebugBreak() public bool MatchDebugBreak()
{ {
var inst = this as DebugBreak; var inst = this as DebugBreak;

7
ICSharpCode.Decompiler/IL/Instructions.tt

@ -118,7 +118,12 @@
CustomChildren(new [] { CustomChildren(new [] {
new ArgumentInfo("onExpression"), new ArgumentInfo("onExpression"),
new ChildInfo("body") new ChildInfo("body")
}), CustomWriteTo, CustomComputeFlags), }), CustomWriteTo, ControlFlow, SideEffect, ResultType("Void")),
new OpCode("using", "Using statement", CustomClassName("UsingInstruction"),
CustomChildren(new [] {
new ArgumentInfo("resourceExpression"),
new ChildInfo("body")
}), CustomWriteTo, ControlFlow, SideEffect, ResultType("Void")),
new OpCode("debug.break", "Breakpoint instruction", new OpCode("debug.break", "Breakpoint instruction",
NoArguments, VoidResult, SideEffect), NoArguments, VoidResult, SideEffect),
new OpCode("comp", "Comparison. The inputs must be both integers; or both floats; or both object references. " new OpCode("comp", "Comparison. The inputs must be both integers; or both floats; or both object references. "

30
ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs

@ -8,21 +8,31 @@ namespace ICSharpCode.Decompiler.IL
{ {
partial class LockInstruction partial class LockInstruction
{ {
protected override InstructionFlags ComputeFlags() public override void WriteTo(ITextOutput output)
{ {
return Body.Flags | OnExpression.Flags | InstructionFlags.ControlFlow | InstructionFlags.SideEffect; output.Write("lock (");
OnExpression.WriteTo(output);
output.WriteLine(") {");
output.Indent();
Body.WriteTo(output);
output.Unindent();
output.WriteLine();
output.Write("}");
} }
}
public override InstructionFlags DirectFlags => InstructionFlags.ControlFlow | InstructionFlags.SideEffect; partial class UsingInstruction
{
public override StackType ResultType => StackType.Void;
public override void WriteTo(ITextOutput output, ILAstWritingOptions options) public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{ {
output.Write("lock ("); output.Write("using (");
OnExpression.WriteTo(output, options); ResourceExpression.WriteTo(output);
output.WriteLine(") "); output.WriteLine(") {");
Body.WriteTo(output, options); output.Indent();
Body.WriteTo(output);
output.Unindent();
output.WriteLine();
output.Write("}");
} }
} }
} }

Loading…
Cancel
Save