Browse Source

add AlwaysGenerateExceptionVariableForCatchBlocks setting to avoid Catch clauses without a variable; disable C#'s query expression translation

pull/254/head
Siegfried Pammer 15 years ago
parent
commit
f4d29b2f2b
  1. 2
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 15
      ICSharpCode.Decompiler/DecompilerSettings.cs
  3. 16
      ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs
  4. 2
      ICSharpCode.Decompiler/ILAst/YieldReturnDecompiler.cs
  5. 2
      ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs
  6. 4
      ILSpy/Languages/ILAstLanguage.cs
  7. 2
      ILSpy/VB/VBLanguage.cs

2
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -95,7 +95,7 @@ namespace ICSharpCode.Decompiler.Ast
context.CancellationToken.ThrowIfCancellationRequested(); context.CancellationToken.ThrowIfCancellationRequested();
ILBlock ilMethod = new ILBlock(); ILBlock ilMethod = new ILBlock();
ILAstBuilder astBuilder = new ILAstBuilder(); ILAstBuilder astBuilder = new ILAstBuilder();
ilMethod.Body = astBuilder.Build(methodDef, true); ilMethod.Body = astBuilder.Build(methodDef, true, context);
context.CancellationToken.ThrowIfCancellationRequested(); context.CancellationToken.ThrowIfCancellationRequested();
ILAstOptimizer bodyGraph = new ILAstOptimizer(); ILAstOptimizer bodyGraph = new ILAstOptimizer();

15
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -239,6 +239,21 @@ namespace ICSharpCode.Decompiler
} }
} }
} }
bool alwaysGenerateExceptionVariableForCatchBlocks = false;
/// <summary>
/// Gets/Sets whether to always generate exception variables in catch blocks
/// </summary>
public bool AlwaysGenerateExceptionVariableForCatchBlocks {
get { return alwaysGenerateExceptionVariableForCatchBlocks; }
set {
if (alwaysGenerateExceptionVariableForCatchBlocks != value) {
alwaysGenerateExceptionVariableForCatchBlocks = value;
OnPropertyChanged("AlwaysGenerateExceptionVariableForCatchBlocks");
}
}
}
#endregion #endregion
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;

16
ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

@ -62,7 +62,7 @@ namespace ICSharpCode.Decompiler.ILAst
/// <summary> Immutable </summary> /// <summary> Immutable </summary>
class VariableSlot class VariableSlot
{ {
public readonly ByteCode[] StoredBy; // One of those public readonly ByteCode[] StoredBy; // One of those
public readonly bool StoredByAll; // Overestimate which is useful for exceptional control flow. public readonly bool StoredByAll; // Overestimate which is useful for exceptional control flow.
@ -224,10 +224,13 @@ namespace ICSharpCode.Decompiler.ILAst
// Virtual instructions to load exception on stack // Virtual instructions to load exception on stack
Dictionary<ExceptionHandler, ByteCode> ldexceptions = new Dictionary<ExceptionHandler, ILAstBuilder.ByteCode>(); Dictionary<ExceptionHandler, ByteCode> ldexceptions = new Dictionary<ExceptionHandler, ILAstBuilder.ByteCode>();
public List<ILNode> Build(MethodDefinition methodDef, bool optimize) DecompilerContext context;
public List<ILNode> Build(MethodDefinition methodDef, bool optimize, DecompilerContext context)
{ {
this.methodDef = methodDef; this.methodDef = methodDef;
this.optimize = optimize; this.optimize = optimize;
this.context = context;
if (methodDef.Body.Instructions.Count == 0) return new List<ILNode>(); if (methodDef.Body.Instructions.Count == 0) return new List<ILNode>();
@ -351,7 +354,7 @@ namespace ICSharpCode.Decompiler.ILAst
if (!byteCode.Code.IsUnconditionalControlFlow()) { if (!byteCode.Code.IsUnconditionalControlFlow()) {
if (exceptionHandlerStarts.Contains(byteCode.Next)) { if (exceptionHandlerStarts.Contains(byteCode.Next)) {
// Do not fall though down to exception handler // Do not fall though down to exception handler
// It is invalid IL as per ECMA-335 §12.4.2.8.1, but some obfuscators produce it // It is invalid IL as per ECMA-335 §12.4.2.8.1, but some obfuscators produce it
} else { } else {
branchTargets.Add(byteCode.Next); branchTargets.Add(byteCode.Next);
} }
@ -711,7 +714,10 @@ namespace ICSharpCode.Decompiler.ILAst
first.Arguments[0].Operand == ldexception.StoreTo[0]) first.Arguments[0].Operand == ldexception.StoreTo[0])
{ {
// The exception is just poped - optimize it all away; // The exception is just poped - optimize it all away;
catchBlock.ExceptionVariable = null; if (context.Settings.AlwaysGenerateExceptionVariableForCatchBlocks)
catchBlock.ExceptionVariable = new ILVariable() { Name = "ex_" + eh.HandlerStart.Offset.ToString("X2"), IsGenerated = true };
else
catchBlock.ExceptionVariable = null;
catchBlock.Body.RemoveAt(0); catchBlock.Body.RemoveAt(0);
} else { } else {
catchBlock.ExceptionVariable = ldexception.StoreTo[0]; catchBlock.ExceptionVariable = ldexception.StoreTo[0];
@ -778,7 +784,7 @@ namespace ICSharpCode.Decompiler.ILAst
StackSlot slot = byteCode.StackBefore[i]; StackSlot slot = byteCode.StackBefore[i];
expr.Arguments.Add(new ILExpression(ILCode.Ldloc, slot.LoadFrom)); expr.Arguments.Add(new ILExpression(ILCode.Ldloc, slot.LoadFrom));
} }
// Store the result to temporary variable(s) if needed // Store the result to temporary variable(s) if needed
if (byteCode.StoreTo == null || byteCode.StoreTo.Count == 0) { if (byteCode.StoreTo == null || byteCode.StoreTo.Count == 0) {
ast.Add(expr); ast.Add(expr);

2
ICSharpCode.Decompiler/ILAst/YieldReturnDecompiler.cs

@ -224,7 +224,7 @@ namespace ICSharpCode.Decompiler.ILAst
ILBlock ilMethod = new ILBlock(); ILBlock ilMethod = new ILBlock();
ILAstBuilder astBuilder = new ILAstBuilder(); ILAstBuilder astBuilder = new ILAstBuilder();
ilMethod.Body = astBuilder.Build(method, true); ilMethod.Body = astBuilder.Build(method, true, context);
ILAstOptimizer optimizer = new ILAstOptimizer(); ILAstOptimizer optimizer = new ILAstOptimizer();
optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.YieldReturn); optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.YieldReturn);
return ilMethod; return ilMethod;

2
ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs

@ -56,9 +56,9 @@ namespace ILSpy.BamlDecompiler
// decompile method and optimize the switch // decompile method and optimize the switch
ILBlock ilMethod = new ILBlock(); ILBlock ilMethod = new ILBlock();
ILAstBuilder astBuilder = new ILAstBuilder(); ILAstBuilder astBuilder = new ILAstBuilder();
ilMethod.Body = astBuilder.Build(def, true);
ILAstOptimizer optimizer = new ILAstOptimizer(); ILAstOptimizer optimizer = new ILAstOptimizer();
var context = new DecompilerContext(type.Module) { CurrentMethod = def, CurrentType = type }; var context = new DecompilerContext(type.Module) { CurrentMethod = def, CurrentType = type };
ilMethod.Body = astBuilder.Build(def, true, context);
optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.RemoveRedundantCode3); optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.RemoveRedundantCode3);
ILSwitch ilSwitch = ilMethod.Body.OfType<ILSwitch>().FirstOrDefault(); ILSwitch ilSwitch = ilMethod.Body.OfType<ILSwitch>().FirstOrDefault();

4
ILSpy/Languages/ILAstLanguage.cs

@ -53,10 +53,10 @@ namespace ICSharpCode.ILSpy
ILAstBuilder astBuilder = new ILAstBuilder(); ILAstBuilder astBuilder = new ILAstBuilder();
ILBlock ilMethod = new ILBlock(); ILBlock ilMethod = new ILBlock();
ilMethod.Body = astBuilder.Build(method, inlineVariables); DecompilerContext context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType, CurrentMethod = method };
ilMethod.Body = astBuilder.Build(method, inlineVariables, context);
if (abortBeforeStep != null) { if (abortBeforeStep != null) {
DecompilerContext context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType, CurrentMethod = method };
new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value); new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
} }

2
ILSpy/VB/VBLanguage.cs

@ -126,6 +126,8 @@ namespace ICSharpCode.ILSpy.VB
if (isSingleMember) if (isSingleMember)
settings.UsingDeclarations = false; settings.UsingDeclarations = false;
settings.IntroduceIncrementAndDecrement = false; settings.IntroduceIncrementAndDecrement = false;
settings.QueryExpressions = false;
settings.AlwaysGenerateExceptionVariableForCatchBlocks = true;
return new AstBuilder( return new AstBuilder(
new DecompilerContext(currentModule) { new DecompilerContext(currentModule) {
CancellationToken = options.CancellationToken, CancellationToken = options.CancellationToken,

Loading…
Cancel
Save