Skip to content

Commit

Permalink
Add support for multidimensional arrays.
Browse files Browse the repository at this point in the history
  • Loading branch information
dgrunwald committed Feb 24, 2011
1 parent 680d7a4 commit 1607321
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
Expand Up @@ -273,7 +273,7 @@ AstNode TransformByteCode(ILExpression byteCode)
// Do branches first because TransformExpressionArguments does not work on arguments that are branches themselfs
// TODO: We should probably have virtual instructions for these and not abuse branch codes as expressions
switch(opCode) {
case ILCode.Br: return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name);
case ILCode.Br: return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name);
case ILCode.Brfalse:
case ILCode.Brtrue:
case ILCode.Beq:
Expand All @@ -293,7 +293,7 @@ AstNode TransformByteCode(ILExpression byteCode)
TrueStatement = new BlockStatement() {
new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name)
}
};
};
}

List<Ast.Expression> args = TransformExpressionArguments(byteCode);
Expand Down Expand Up @@ -361,14 +361,13 @@ AstNode TransformByteCode(ILExpression byteCode)
case Code.Stelem_R4:
case Code.Stelem_R8:
case Code.Stelem_Ref:
return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3);
case Code.Stelem_Any:
return InlineAssembly(byteCode, args);
return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3);
#endregion
#region Comparison
case Code.Ceq: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2);
case Code.Cgt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
case Code.Cgt_Un:
case Code.Cgt_Un:
// can also mean Inequality, when used with object references
{
TypeReference arg1Type = byteCode.Arguments[0].InferredType;
Expand Down Expand Up @@ -568,14 +567,18 @@ AstNode TransformByteCode(ILExpression byteCode)
case Code.Newobj:
{
Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType;
// TODO: Ensure that the corrent overloaded constructor is called

/*if (declaringType is ArrayType) { shouldn't this be newarr?
return new Ast.ArrayCreateExpression {
Type = AstBuilder.ConvertType((ArrayType)declaringType),
Arguments = args
};
}*/
if (declaringType is ArrayType) {
ComposedType ct = AstBuilder.ConvertType((ArrayType)declaringType) as ComposedType;
if (ct != null && ct.ArraySpecifiers.Count >= 1) {
var ace = new Ast.ArrayCreateExpression();
ct.ArraySpecifiers.First().Remove();
ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
ace.Type = ct;
ace.Arguments.AddRange(args);
return ace;
}
}
var oce = new Ast.ObjectCreateExpression();
oce.Type = AstBuilder.ConvertType(declaringType);
oce.Arguments.AddRange(args);
Expand Down Expand Up @@ -639,6 +642,12 @@ static AstNode TransformCall(bool isVirtual, object operand, MethodDefinition me
}
}

if (cecilMethod.Name == "Get" && cecilMethod.DeclaringType is ArrayType && methodArgs.Count > 1) {
return target.Indexer(methodArgs);
} else if (cecilMethod.Name == "Set" && cecilMethod.DeclaringType is ArrayType && methodArgs.Count > 2) {
return new AssignmentExpression(target.Indexer(methodArgs.GetRange(0, methodArgs.Count - 1)), methodArgs.Last());
}

// Resolve the method to figure out whether it is an accessor:
Cecil.MethodDefinition cecilMethodDef = cecilMethod.Resolve();
if (cecilMethodDef != null) {
Expand Down

0 comments on commit 1607321

Please sign in to comment.