Browse Source

Add support for conv and ldobj opcodes

pull/728/head
Daniel Grunwald 11 years ago
parent
commit
79475a79c5
  1. 60
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 32
      ICSharpCode.Decompiler/IL/NRTypeExtensions.cs

60
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Diagnostics;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.Semantics;
@ -89,16 +90,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -89,16 +90,12 @@ namespace ICSharpCode.Decompiler.CSharp
public Expression Convert(ILInstruction inst)
{
var expr = inst.AcceptVisitor(this).Expression;
expr.AddAnnotation(inst);
return expr;
return ConvertArgument(inst).Expression;
}
public Expression Convert(ILInstruction inst, IType expectedType)
{
var expr = inst.AcceptVisitor(this);
expr.Expression.AddAnnotation(inst);
return expr.ConvertTo(expectedType, this);
return ConvertArgument(inst).ConvertTo(expectedType, this);
}
public AstType ConvertType(Mono.Cecil.TypeReference type)
@ -118,6 +115,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -118,6 +115,7 @@ namespace ICSharpCode.Decompiler.CSharp
ConvertedExpression ConvertArgument(ILInstruction inst)
{
var cexpr = inst.AcceptVisitor(this);
Debug.Assert(cexpr.Type.GetStackType() == inst.ResultType || cexpr.Type.Kind == TypeKind.Unknown || inst.ResultType == StackType.Void);
cexpr.Expression.AddAnnotation(inst);
return cexpr;
}
@ -272,11 +270,36 @@ namespace ICSharpCode.Decompiler.CSharp @@ -272,11 +270,36 @@ namespace ICSharpCode.Decompiler.CSharp
return HandleBinaryNumeric(inst, BinaryOperatorType.Subtract);
}
protected internal override ConvertedExpression VisitMul(Mul inst)
{
return HandleBinaryNumeric(inst, BinaryOperatorType.Multiply);
}
protected internal override ConvertedExpression VisitDiv(Div inst)
{
return HandleBinaryNumeric(inst, BinaryOperatorType.Divide);
}
protected internal override ConvertedExpression VisitRem(Rem inst)
{
return HandleBinaryNumeric(inst, BinaryOperatorType.Modulus);
}
protected internal override ConvertedExpression VisitBitXor(BitXor inst)
{
return HandleBinaryNumeric(inst, BinaryOperatorType.ExclusiveOr);
}
protected internal override ConvertedExpression VisitBitAnd(BitAnd inst)
{
return HandleBinaryNumeric(inst, BinaryOperatorType.BitwiseAnd);
}
protected internal override ConvertedExpression VisitBitOr(BitOr inst)
{
return HandleBinaryNumeric(inst, BinaryOperatorType.BitwiseOr);
}
protected internal override ConvertedExpression VisitShl(Shl inst)
{
return HandleBinaryNumeric(inst, BinaryOperatorType.ShiftLeft);
@ -314,6 +337,21 @@ namespace ICSharpCode.Decompiler.CSharp @@ -314,6 +337,21 @@ namespace ICSharpCode.Decompiler.CSharp
return sign == Sign.None || type.GetSign() == sign;
}
protected internal override ConvertedExpression VisitConv(Conv inst)
{
var arg = ConvertArgument(inst.Argument);
Expression input = arg.Expression;
if (arg.Type.GetSign() != inst.Sign) {
// we need to cast the input to a type of appropriate sign
var inputType = inst.Argument.ResultType.ToKnownTypeCode(inst.Sign);
input = arg.ConvertTo(compilation.FindType(inputType), this);
}
var targetType = compilation.FindType(inst.TargetType.ToKnownTypeCode());
return new ConvertedExpression(
new CastExpression(astBuilder.ConvertType(targetType), input),
targetType);
}
protected internal override ConvertedExpression VisitCall(Call inst)
{
return HandleCallInstruction(inst);
@ -346,6 +384,16 @@ namespace ICSharpCode.Decompiler.CSharp @@ -346,6 +384,16 @@ namespace ICSharpCode.Decompiler.CSharp
}
return new ConvertedExpression(invocation, cecilMapper.GetType(inst.Method.ReturnType));
}
protected internal override ConvertedExpression VisitLdObj(LdObj inst)
{
var target = ConvertArgument(inst.Target);
var pointerType = new PointerType(cecilMapper.GetType(inst.Type));
return new ConvertedExpression(
new UnaryOperatorExpression(
UnaryOperatorType.Dereference, target.ConvertTo(pointerType, this)),
pointerType.ElementType);
}
protected override ConvertedExpression Default(ILInstruction inst)
{

32
ICSharpCode.Decompiler/IL/NRTypeExtensions.cs

@ -95,6 +95,38 @@ namespace ICSharpCode.Decompiler.IL @@ -95,6 +95,38 @@ namespace ICSharpCode.Decompiler.IL
}
}
public static KnownTypeCode ToKnownTypeCode(this PrimitiveType primitiveType)
{
switch (primitiveType) {
case PrimitiveType.I1:
return KnownTypeCode.SByte;
case PrimitiveType.I2:
return KnownTypeCode.Int16;
case PrimitiveType.I4:
return KnownTypeCode.Int32;
case PrimitiveType.I8:
return KnownTypeCode.Int64;
case PrimitiveType.R4:
return KnownTypeCode.Single;
case PrimitiveType.R8:
return KnownTypeCode.Double;
case PrimitiveType.U1:
return KnownTypeCode.Byte;
case PrimitiveType.U2:
return KnownTypeCode.UInt16;
case PrimitiveType.U4:
return KnownTypeCode.UInt32;
case PrimitiveType.U8:
return KnownTypeCode.UInt64;
case PrimitiveType.I:
return KnownTypeCode.IntPtr;
case PrimitiveType.U:
return KnownTypeCode.UIntPtr;
default:
return KnownTypeCode.None;
}
}
public static KnownTypeCode ToKnownTypeCode(this StackType stackType, Sign sign = Sign.None)
{
switch (stackType) {

Loading…
Cancel
Save