This project is read-only.

CodeModelToIL switch issue

Apr 16, 2011 at 4:08 AM


The following method of the CodeModelToILConverter (located at file Visitor.cs in the project CodeModelToIL) has an strange condition at the if:

    /// <summary>
    /// Generates IL for the specified switch statement.
    /// </summary>
    /// <param name="switchStatement">The switch statement.</param>
    public override void TraverseChildren(ISwitchStatement switchStatement) {
      uint numberOfCases;
      uint maxValue = GetMaxCaseExpressionValueAsUInt(switchStatement.Cases, out numberOfCases);
      if (numberOfCases == 0) { this.generator.Emit(OperationCode.Pop); return; }
      if (maxValue < uint.MaxValue && maxValue/2 < numberOfCases)
        this.GenerateSwitchInstruction(switchStatement.Cases, maxValue);
      //TODO: generate binary search
      //TemporaryVariable switchVar = new TemporaryVariable(switchStatement.Expression.Type);
      //List<ISwitchCase> switchCases = this.GetSortedListOfSwitchCases(switchStatement.Cases);
      //TODO: special handling for switch over strings
      this.lastStatementWasUnconditionalTransfer = false;

More precisly I'm refering to the line that contains the if:

      if (maxValue < uint.MaxValue && maxValue/2 < numberOfCases)
        this.GenerateSwitchInstruction(switchStatement.Cases, maxValue);

I dont understand the if condition. Why only the cases when maxValue/2 < numberOfCases are considred to generate the IL code? It's an strange thing because when this condition is false nothing is generated at all!!
Of course I ask this because I have an strange bug about some missing switches, but only happen in some cases.


Apr 16, 2011 at 4:12 AM

The current implementation of this method is just a quick and dirty implementation to get round tripping to work. Since the decompiler is not very smart, the logic here is probably adequate. However, this certainly needs an implementation and I hope to get to it sooner rather than later.

Apr 19, 2011 at 7:39 PM

Thanks, I saw that you comment that line in one of the latest commits. This way I don't need to link to a modified version.