Skip to content

Commit

Permalink
add AlwaysGenerateExceptionVariableForCatchBlocks setting to avoid Ca…
Browse files Browse the repository at this point in the history
…tch clauses without a variable; disable C#'s query expression translation
  • Loading branch information
siegfriedpammer committed Jul 15, 2011
1 parent 7542cc7 commit f4d29b2
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 10 deletions.
2 changes: 1 addition & 1 deletion ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public BlockStatement CreateMethodBody(IEnumerable<ParameterDeclaration> paramet
context.CancellationToken.ThrowIfCancellationRequested();
ILBlock ilMethod = new ILBlock();
ILAstBuilder astBuilder = new ILAstBuilder();
ilMethod.Body = astBuilder.Build(methodDef, true);
ilMethod.Body = astBuilder.Build(methodDef, true, context);

context.CancellationToken.ThrowIfCancellationRequested();
ILAstOptimizer bodyGraph = new ILAstOptimizer();
Expand Down
15 changes: 15 additions & 0 deletions ICSharpCode.Decompiler/DecompilerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,21 @@ public bool IntroduceIncrementAndDecrement {
}
}
}

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

public event PropertyChangedEventHandler PropertyChanged;
Expand Down
16 changes: 11 additions & 5 deletions ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static List<StackSlot> CloneStack(List<StackSlot> stack, int? popCount)

/// <summary> Immutable </summary>
class VariableSlot
{
{
public readonly ByteCode[] StoredBy; // One of those
public readonly bool StoredByAll; // Overestimate which is useful for exceptional control flow.

Expand Down Expand Up @@ -224,10 +224,13 @@ public override string ToString()
// Virtual instructions to load exception on stack
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.optimize = optimize;
this.context = context;

if (methodDef.Body.Instructions.Count == 0) return new List<ILNode>();

Expand Down Expand Up @@ -351,7 +354,7 @@ List<ByteCode> StackAnalysis(MethodDefinition methodDef)
if (!byteCode.Code.IsUnconditionalControlFlow()) {
if (exceptionHandlerStarts.Contains(byteCode.Next)) {
// 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 {
branchTargets.Add(byteCode.Next);
}
Expand Down Expand Up @@ -711,7 +714,10 @@ List<ILNode> ConvertToAst(List<ByteCode> body, HashSet<ExceptionHandler> ehs)
first.Arguments[0].Operand == ldexception.StoreTo[0])
{
// 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);
} else {
catchBlock.ExceptionVariable = ldexception.StoreTo[0];
Expand Down Expand Up @@ -778,7 +784,7 @@ List<ILNode> ConvertToAst(List<ByteCode> body)
StackSlot slot = byteCode.StackBefore[i];
expr.Arguments.Add(new ILExpression(ILCode.Ldloc, slot.LoadFrom));
}

// Store the result to temporary variable(s) if needed
if (byteCode.StoreTo == null || byteCode.StoreTo.Count == 0) {
ast.Add(expr);
Expand Down
2 changes: 1 addition & 1 deletion ICSharpCode.Decompiler/ILAst/YieldReturnDecompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ ILBlock CreateILAst(MethodDefinition method)

ILBlock ilMethod = new ILBlock();
ILAstBuilder astBuilder = new ILAstBuilder();
ilMethod.Body = astBuilder.Build(method, true);
ilMethod.Body = astBuilder.Build(method, true, context);
ILAstOptimizer optimizer = new ILAstOptimizer();
optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.YieldReturn);
return ilMethod;
Expand Down
2 changes: 1 addition & 1 deletion ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ public Dictionary<int, EventRegistration[]> DecompileEventMappings(string fullTy
// decompile method and optimize the switch
ILBlock ilMethod = new ILBlock();
ILAstBuilder astBuilder = new ILAstBuilder();
ilMethod.Body = astBuilder.Build(def, true);
ILAstOptimizer optimizer = new ILAstOptimizer();
var context = new DecompilerContext(type.Module) { CurrentMethod = def, CurrentType = type };
ilMethod.Body = astBuilder.Build(def, true, context);
optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.RemoveRedundantCode3);

ILSwitch ilSwitch = ilMethod.Body.OfType<ILSwitch>().FirstOrDefault();
Expand Down
4 changes: 2 additions & 2 deletions ILSpy/Languages/ILAstLanguage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ public override void DecompileMethod(MethodDefinition method, ITextOutput output

ILAstBuilder astBuilder = new ILAstBuilder();
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) {
DecompilerContext context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType, CurrentMethod = method };
new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
}

Expand Down
2 changes: 2 additions & 0 deletions ILSpy/VB/VBLanguage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ AstBuilder CreateAstBuilder(DecompilationOptions options, ModuleDefinition curre
if (isSingleMember)
settings.UsingDeclarations = false;
settings.IntroduceIncrementAndDecrement = false;
settings.QueryExpressions = false;
settings.AlwaysGenerateExceptionVariableForCatchBlocks = true;
return new AstBuilder(
new DecompilerContext(currentModule) {
CancellationToken = options.CancellationToken,
Expand Down

0 comments on commit f4d29b2

Please sign in to comment.