Browse Source

Improve handling of pinned variables.

pull/100/head
Daniel Grunwald 15 years ago
parent
commit
a3c241dac6
  1. 8
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 2
      ICSharpCode.Decompiler/Ast/NameVariables.cs
  3. 10
      ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs
  4. 10
      ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs
  5. 4
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  6. 4
      ICSharpCode.Decompiler/ILAst/ILAstTypes.cs
  7. 2
      ICSharpCode.Decompiler/ILAst/ILCodes.cs
  8. 2
      ICSharpCode.Decompiler/ILAst/ILInlining.cs

8
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -292,8 +292,9 @@ namespace ICSharpCode.Decompiler.Ast @@ -292,8 +292,9 @@ namespace ICSharpCode.Decompiler.Ast
if (type is Mono.Cecil.ByReferenceType) {
typeIndex++;
// ignore by reference type (cannot be represented in C#)
return ConvertType((type as Mono.Cecil.ByReferenceType).ElementType, typeAttributes, ref typeIndex);
// by reference type cannot be represented in C#; so we'll represent it as a pointer instead
return ConvertType((type as Mono.Cecil.ByReferenceType).ElementType, typeAttributes, ref typeIndex)
.MakePointerType();
} else if (type is Mono.Cecil.PointerType) {
typeIndex++;
return ConvertType((type as Mono.Cecil.PointerType).ElementType, typeAttributes, ref typeIndex)
@ -799,6 +800,9 @@ namespace ICSharpCode.Decompiler.Ast @@ -799,6 +800,9 @@ namespace ICSharpCode.Decompiler.Ast
if (paramDef.ParameterType is ByReferenceType) {
astParam.ParameterModifier = (!paramDef.IsIn && paramDef.IsOut) ? ParameterModifier.Out : ParameterModifier.Ref;
ComposedType ct = astParam.Type as ComposedType;
if (ct != null && ct.PointerRank > 0)
ct.PointerRank--;
}
if (paramDef.HasCustomAttributes) {
foreach (CustomAttribute ca in paramDef.CustomAttributes) {

2
ICSharpCode.Decompiler/Ast/NameVariables.cs

@ -216,7 +216,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -216,7 +216,7 @@ namespace ICSharpCode.Decompiler.Ast
string name;
if (type.IsArray) {
name = "array";
} else if (type.IsPointer) {
} else if (type.IsPointer || type.IsByReference) {
name = "ptr";
} else if (!typeNameToVariableNameDict.TryGetValue(type.FullName, out name)) {
name = type.Name;

10
ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs

@ -118,7 +118,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -118,7 +118,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{
if (type is PinnedType) {
writer.Write("pinned ");
type.GetElementType().WriteTo(writer, onlyName, shortName);
((PinnedType)type).ElementType.WriteTo(writer, onlyName, shortName);
} else if (type is ArrayType) {
ArrayType at = (ArrayType)type;
at.ElementType.WriteTo(writer, onlyName, shortName);
@ -128,10 +128,10 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -128,10 +128,10 @@ namespace ICSharpCode.Decompiler.Disassembler
} else if (type is GenericParameter) {
writer.WriteReference(type.Name, type);
} else if (type is ByReferenceType) {
type.GetElementType().WriteTo(writer, onlyName, shortName);
((ByReferenceType)type).ElementType.WriteTo(writer, onlyName, shortName);
writer.Write('&');
} else if (type is PointerType) {
type.GetElementType().WriteTo(writer, onlyName, shortName);
((PointerType)type).ElementType.WriteTo(writer, onlyName, shortName);
writer.Write('*');
} else if (type is GenericInstanceType) {
type.GetElementType().WriteTo(writer, onlyName, shortName);
@ -147,12 +147,12 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -147,12 +147,12 @@ namespace ICSharpCode.Decompiler.Disassembler
writer.Write("modopt(");
((OptionalModifierType)type).ModifierType.WriteTo(writer, true, shortName);
writer.Write(") ");
type.GetElementType().WriteTo(writer, onlyName, shortName);
((OptionalModifierType)type).ElementType.WriteTo(writer, onlyName, shortName);
} else if (type is RequiredModifierType) {
writer.Write("modreq(");
((RequiredModifierType)type).ModifierType.WriteTo(writer, true, shortName);
writer.Write(") ");
type.GetElementType().WriteTo(writer, onlyName, shortName);
((RequiredModifierType)type).ElementType.WriteTo(writer, onlyName, shortName);
} else {
string name = PrimitiveTypeName(type);
if (name != null) {

10
ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

@ -479,15 +479,17 @@ namespace ICSharpCode.Decompiler.ILAst @@ -479,15 +479,17 @@ namespace ICSharpCode.Decompiler.ILAst
TypeReference varType = methodDef.Body.Variables[variableIndex].VariableType;
List<VariableInfo> newVars;
bool isPinned = methodDef.Body.Variables[variableIndex].IsPinned;
// If the variable is pinned, use single variable.
// If any of the loads is from "all", use single variable
// If any of the loads is ldloca, fallback to single variable as well
if (loads.Any(b => b.VariablesBefore[variableIndex].StoredByAll || b.Code == ILCode.Ldloca)) {
if (isPinned || loads.Any(b => b.VariablesBefore[variableIndex].StoredByAll || b.Code == ILCode.Ldloca)) {
newVars = new List<VariableInfo>(1) { new VariableInfo() {
Variable = new ILVariable() {
Name = "var_" + variableIndex,
Type = varType,
OriginalVariable = methodDef.Body.Variables[variableIndex]
Type = isPinned ? ((PinnedType)varType).ElementType : varType,
OriginalVariable = methodDef.Body.Variables[variableIndex]
},
Stores = stores,
Loads = loads

4
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -699,8 +699,10 @@ namespace ICSharpCode.Decompiler.ILAst @@ -699,8 +699,10 @@ namespace ICSharpCode.Decompiler.ILAst
{
switch(expr.Code) {
case ILCode.Call:
case ILCode.Calli:
case ILCode.Callvirt:
// property getters can't be expression statements, but all other method calls can be
MethodReference mr = (MethodReference)expr.Operand;
return !mr.Name.StartsWith("get_", StringComparison.Ordinal);
case ILCode.Newobj:
case ILCode.Newarr:
return true;

4
ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

@ -202,6 +202,10 @@ namespace ICSharpCode.Decompiler.ILAst @@ -202,6 +202,10 @@ namespace ICSharpCode.Decompiler.ILAst
public VariableDefinition OriginalVariable;
public ParameterDefinition OriginalParameter;
public bool IsPinned {
get { return OriginalVariable != null && OriginalVariable.IsPinned; }
}
public bool IsParameter {
get { return OriginalParameter != null; }
}

2
ICSharpCode.Decompiler/ILAst/ILCodes.cs

@ -433,6 +433,8 @@ namespace ICSharpCode.Decompiler.ILAst @@ -433,6 +433,8 @@ namespace ICSharpCode.Decompiler.ILAst
case ILCode.__Stind_I2: code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Int16; break;
case ILCode.__Stind_I4: code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Int32; break;
case ILCode.__Stind_I8: code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Int64; break;
case ILCode.__Stind_R4: code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Single; break;
case ILCode.__Stind_R8: code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Double; break;
}
}

2
ICSharpCode.Decompiler/ILAst/ILInlining.cs

@ -113,7 +113,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -113,7 +113,7 @@ namespace ICSharpCode.Decompiler.ILAst
{
ILVariable v;
ILExpression inlinedExpression;
if (block.Body[pos].Match(ILCode.Stloc, out v, out inlinedExpression)) {
if (block.Body[pos].Match(ILCode.Stloc, out v, out inlinedExpression) && !v.IsPinned) {
if (InlineIfPossible(v, inlinedExpression, block.Body.ElementAtOrDefault(pos+1), aggressive)) {
// Assign the ranges of the stloc instruction:
inlinedExpression.ILRanges.AddRange(((ILExpression)block.Body[pos]).ILRanges);

Loading…
Cancel
Save