Browse Source

[switch] Add StringToInt instruction

pull/887/head
Siegfried Pammer 8 years ago
parent
commit
d40ecb5e0c
  1. 2
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  2. 96
      ICSharpCode.Decompiler/IL/Instructions.cs
  3. 2
      ICSharpCode.Decompiler/IL/Instructions.tt
  4. 32
      ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs
  5. 45
      ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs
  6. 53
      ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs

2
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -271,6 +271,8 @@
<Compile Include="DotNetCore\DotNetCorePathFinder.cs" /> <Compile Include="DotNetCore\DotNetCorePathFinder.cs" />
<Compile Include="DotNetCore\DotNetCorePathFinderExtensions.cs" /> <Compile Include="DotNetCore\DotNetCorePathFinderExtensions.cs" />
<Compile Include="DotNetCore\UnresolvedAssemblyNameReference.cs" /> <Compile Include="DotNetCore\UnresolvedAssemblyNameReference.cs" />
<Compile Include="IL\Instructions\StringToInt.cs" />
<Compile Include="IL\Instructions\UsingInstruction.cs" />
<Compile Include="IL\Transforms\UsingTransform.cs" /> <Compile Include="IL\Transforms\UsingTransform.cs" />
<Compile Include="IL\ControlFlow\AsyncAwaitDecompiler.cs" /> <Compile Include="IL\ControlFlow\AsyncAwaitDecompiler.cs" />
<Compile Include="IL\ControlFlow\ControlFlowGraph.cs" /> <Compile Include="IL\ControlFlow\ControlFlowGraph.cs" />

96
ICSharpCode.Decompiler/IL/Instructions.cs

@ -158,6 +158,8 @@ namespace ICSharpCode.Decompiler.IL
/// <summary>Converts an array pointer (O) to a reference to the first element, or to a null reference if the array is null or empty. /// <summary>Converts an array pointer (O) to a reference to the first element, or to a null reference if the array is null or empty.
/// Also used to convert a string to a reference to the first character.</summary> /// Also used to convert a string to a reference to the first character.</summary>
ArrayToPointer, ArrayToPointer,
/// <summary>Maps a string value to an integer. This is used in switch(string).</summary>
StringToInt,
/// <summary>Push a typed reference of type class onto the stack.</summary> /// <summary>Push a typed reference of type class onto the stack.</summary>
MakeRefAny, MakeRefAny,
/// <summary>Push the type token stored in a typed reference.</summary> /// <summary>Push the type token stored in a typed reference.</summary>
@ -4021,6 +4023,87 @@ namespace ICSharpCode.Decompiler.IL
} }
} }
namespace ICSharpCode.Decompiler.IL namespace ICSharpCode.Decompiler.IL
{
/// <summary>Maps a string value to an integer. This is used in switch(string).</summary>
public sealed partial class StringToInt : ILInstruction
{
public static readonly SlotInfo ArgumentSlot = new SlotInfo("Argument", canInlineInto: true);
ILInstruction argument;
public ILInstruction Argument {
get { return this.argument; }
set {
ValidateChild(value);
SetChildInstruction(ref this.argument, value, 0);
}
}
protected sealed override int GetChildCount()
{
return 1;
}
protected sealed override ILInstruction GetChild(int index)
{
switch (index) {
case 0:
return this.argument;
default:
throw new IndexOutOfRangeException();
}
}
protected sealed override void SetChild(int index, ILInstruction value)
{
switch (index) {
case 0:
this.Argument = value;
break;
default:
throw new IndexOutOfRangeException();
}
}
protected sealed override SlotInfo GetChildSlot(int index)
{
switch (index) {
case 0:
return ArgumentSlot;
default:
throw new IndexOutOfRangeException();
}
}
public sealed override ILInstruction Clone()
{
var clone = (StringToInt)ShallowClone();
clone.Argument = this.argument.Clone();
return clone;
}
public override StackType ResultType { get { return StackType.I4; } }
protected override InstructionFlags ComputeFlags()
{
return argument.Flags;
}
public override InstructionFlags DirectFlags {
get {
return InstructionFlags.None;
}
}
public override void AcceptVisitor(ILVisitor visitor)
{
visitor.VisitStringToInt(this);
}
public override T AcceptVisitor<T>(ILVisitor<T> visitor)
{
return visitor.VisitStringToInt(this);
}
public override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)
{
return visitor.VisitStringToInt(this, context);
}
protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match)
{
var o = other as StringToInt;
return o != null && this.argument.PerformMatch(o.argument, ref match);
}
}
}
namespace ICSharpCode.Decompiler.IL
{ {
/// <summary>Push a typed reference of type class onto the stack.</summary> /// <summary>Push a typed reference of type class onto the stack.</summary>
public sealed partial class MakeRefAny : UnaryInstruction public sealed partial class MakeRefAny : UnaryInstruction
@ -4633,6 +4716,10 @@ namespace ICSharpCode.Decompiler.IL
{ {
Default(inst); Default(inst);
} }
protected internal virtual void VisitStringToInt(StringToInt inst)
{
Default(inst);
}
protected internal virtual void VisitMakeRefAny(MakeRefAny inst) protected internal virtual void VisitMakeRefAny(MakeRefAny inst)
{ {
Default(inst); Default(inst);
@ -4919,6 +5006,10 @@ namespace ICSharpCode.Decompiler.IL
{ {
return Default(inst); return Default(inst);
} }
protected internal virtual T VisitStringToInt(StringToInt inst)
{
return Default(inst);
}
protected internal virtual T VisitMakeRefAny(MakeRefAny inst) protected internal virtual T VisitMakeRefAny(MakeRefAny inst)
{ {
return Default(inst); return Default(inst);
@ -5205,6 +5296,10 @@ namespace ICSharpCode.Decompiler.IL
{ {
return Default(inst, context); return Default(inst, context);
} }
protected internal virtual T VisitStringToInt(StringToInt inst, C context)
{
return Default(inst, context);
}
protected internal virtual T VisitMakeRefAny(MakeRefAny inst, C context) protected internal virtual T VisitMakeRefAny(MakeRefAny inst, C context)
{ {
return Default(inst, context); return Default(inst, context);
@ -5294,6 +5389,7 @@ namespace ICSharpCode.Decompiler.IL
"ldlen", "ldlen",
"ldelema", "ldelema",
"array.to.pointer", "array.to.pointer",
"string.to.int",
"mkrefany", "mkrefany",
"refanytype", "refanytype",
"refanyval", "refanyval",

2
ICSharpCode.Decompiler/IL/Instructions.tt

@ -220,6 +220,8 @@
new OpCode("array.to.pointer", "Converts an array pointer (O) to a reference to the first element, or to a null reference if the array is null or empty." + Environment.NewLine new OpCode("array.to.pointer", "Converts an array pointer (O) to a reference to the first element, or to a null reference if the array is null or empty." + Environment.NewLine
+ "Also used to convert a string to a reference to the first character.", + "Also used to convert a string to a reference to the first character.",
CustomArguments("array"), ResultType("Ref")), CustomArguments("array"), ResultType("Ref")),
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("mkrefany", "Push a typed reference of type class onto the stack.", new OpCode("mkrefany", "Push a typed reference of type class onto the stack.",
CustomClassName("MakeRefAny"), Unary, HasTypeOperand, ResultType("O")), CustomClassName("MakeRefAny"), Unary, HasTypeOperand, ResultType("O")),

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

@ -38,36 +38,4 @@ namespace ICSharpCode.Decompiler.IL
output.Write("}"); output.Write("}");
} }
} }
/// <summary>
/// IL using instruction.
/// Equivalent to:
/// <code>
/// stloc v(resourceExpression)
/// try {
/// body
/// } finally {
/// v?.Dispose();
/// }
/// </code>
/// </summary>
/// <remarks>
/// The value of v is undefined after the end of the body block.
/// </remarks>
partial class UsingInstruction
{
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
output.Write("using (");
Variable.WriteTo(output);
output.Write(" = ");
ResourceExpression.WriteTo(output, options);
output.WriteLine(") {");
output.Indent();
Body.WriteTo(output, options);
output.Unindent();
output.WriteLine();
output.Write("}");
}
}
} }

45
ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs

@ -0,0 +1,45 @@
// Copyright (c) 2017 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
namespace ICSharpCode.Decompiler.IL
{
partial class StringToInt
{
public string[] Map { get; }
public StringToInt(ILInstruction argument, string[] map)
: base(OpCode.StringToInt)
{
this.Argument = argument;
this.Map = map;
}
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
output.Write("string.to.int (");
Argument.WriteTo(output, options);
output.Write(", { ");
for (int i = 0; i < Map.Length; i++) {
if (i > 0) output.Write(", ");
output.Write($"[{i}] = \"{Map[i]}\"");
}
output.Write(" })");
}
}
}

53
ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs

@ -0,0 +1,53 @@
// Copyright (c) 2017 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
namespace ICSharpCode.Decompiler.IL
{
/// <summary>
/// IL using instruction.
/// Equivalent to:
/// <code>
/// stloc v(resourceExpression)
/// try {
/// body
/// } finally {
/// v?.Dispose();
/// }
/// </code>
/// </summary>
/// <remarks>
/// The value of v is undefined after the end of the body block.
/// </remarks>
partial class UsingInstruction
{
public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
{
output.Write("using (");
Variable.WriteTo(output);
output.Write(" = ");
ResourceExpression.WriteTo(output, options);
output.WriteLine(") {");
output.Indent();
Body.WriteTo(output, options);
output.Unindent();
output.WriteLine();
output.Write("}");
}
}
}
Loading…
Cancel
Save