Inheritance: ISwitchCase
示例#1
0
 public override void TraverseChildren(IBlockStatement block) {
   base.TraverseChildren(block);
   Contract.Assume(block is BlockStatement);
   var decompiledBlock = (BlockStatement)block;
   var statements = decompiledBlock.Statements;
   for (int i = 0; i < statements.Count-1; i++) {
     var switchInstruction = statements[i] as SwitchInstruction;
     if (switchInstruction == null) continue;
     SwitchStatement result = new SwitchStatement();
     result.Expression = switchInstruction.switchExpression;
     statements[i] = result;
     for (int j = 0, n = switchInstruction.SwitchCases.Count; j < n; j++) {
       CompileTimeConstant caseLabel = new CompileTimeConstant() { Value = j, Type = this.host.PlatformType.SystemInt32 };
       var gotoCaseBody = switchInstruction.SwitchCases[j];
       Contract.Assume(gotoCaseBody != null);
       SwitchCase currentCase = new SwitchCase() { Expression = caseLabel };
       result.Cases.Add(currentCase);
       if (j < n-1) {
         Contract.Assume(switchInstruction.SwitchCases[j+1] != null);
         if (gotoCaseBody.TargetStatement == switchInstruction.SwitchCases[j+1].TargetStatement) continue;
       }
       currentCase.Body.Add(gotoCaseBody);
     }
     if (i == statements.Count-1) return;
     Contract.Assert(i+1 <= statements.Count);
     var gotoStatement = statements[i+1] as IGotoStatement;
     if (gotoStatement != null) {
       SwitchCase defaultCase = new SwitchCase() { }; // Default case is represented by a dummy Expression.
       defaultCase.Body.Add(statements[i + 1]);
       statements.RemoveAt(i + 1);
       result.Cases.Add(defaultCase);
     }
   }
 }
示例#2
0
 /// <summary>
 /// Get the mutable copy of a switch case. 
 /// </summary>
 /// <param name="swithCase"></param>
 /// <returns></returns>
 public virtual SwitchCase GetMutableCopy(ISwitchCase swithCase)
 {
     object cachedValue;
       if (this.cache.TryGetValue(swithCase, out cachedValue))
     return (SwitchCase)cachedValue;
       var result = new SwitchCase(swithCase);
       // Probably not necessary, no two switch cases are shared.
       this.cache.Add(swithCase, result);
       this.cache.Add(result, result);
       return result;
 }
示例#3
0
 /// <summary>
 /// Visits the specified switch case.
 /// </summary>
 /// <param name="switchCase">The switch case.</param>
 /// <returns></returns>
 protected virtual ISwitchCase DeepCopy(SwitchCase switchCase)
 {
     if (!switchCase.IsDefault)
     switchCase.Expression = (ICompileTimeConstant)Substitute(switchCase.Expression);
       switchCase.Body = this.Substitute(switchCase.Body);
       return switchCase;
 }
示例#4
0
 /// <summary>
 /// Build the state machine. 
 /// 
 /// We start from state 0. For each yield return, we assign a unique state, which we call continueing state. For a yield return 
 /// assigned with state x, we move the state machine from the previous state to x. Whenever we see a yield break, we transit
 /// the state to -1. 
 /// 
 /// When we return from state x, we jump to a label that is inserted right after the previous yield return (that is assigned with state x). 
 /// </summary>
 private BlockStatement BuildStateMachine(IteratorClosureInformation iteratorClosure, BlockStatement oldBody, Dictionary<int, ILabeledStatement> stateEntries) {
   // Switch on cases. StateEntries, which have been computed previously, map a state number (for initial and continuing states) to a label that has been inserted 
   // right after the associated yield return. 
   BlockStatement result = new BlockStatement();
   var returnFalse = new ReturnStatement() { Expression = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean } };
   var returnFalseLabel = new LabeledStatement() { Label = this.host.NameTable.GetNameFor("return false"), Statement = returnFalse };
   List<ISwitchCase> cases = new List<ISwitchCase>();
   foreach (int i in stateEntries.Keys) {
     SwitchCase c = new SwitchCase() {
       Expression = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt32, Value = i },
       Body = new List<IStatement>(),
     };
     c.Body.Add(new GotoStatement() { TargetStatement = stateEntries[i] });
     cases.Add(c);
   }
   // Default case.
   SwitchCase defaultCase = new SwitchCase();
   defaultCase.Body.Add(new GotoStatement() { TargetStatement = returnFalseLabel });
   cases.Add(defaultCase);
   SwitchStatement switchStatement = new SwitchStatement() {
     Cases = cases,
     Expression = new BoundExpression() { Type = this.host.PlatformType.SystemInt32, Instance = new ThisReference(), Definition = iteratorClosure.StateFieldReference }
   };
   result.Statements.Add(switchStatement);
   result.Statements.Add(oldBody);
   result.Statements.Add(returnFalseLabel);
   return result;
 }
示例#5
0
 private void DecompileSwitch(List<IStatement> statements, int i)
 {
     if (i >= statements.Count-1) return;
       SwitchInstruction/*?*/ switchInstruction = statements[i] as SwitchInstruction;
       if (switchInstruction == null) return;
       SwitchStatement result = new SwitchStatement();
       result.Expression = switchInstruction.switchExpression;
       statements[i] = result;
       for (int j = 0, n = switchInstruction.switchCases.Count; j < n; j++) {
     CompileTimeConstant caseLabel = new CompileTimeConstant() { Value = j, Type = this.platformType.SystemInt32 };
     var gotoCaseBody = switchInstruction.switchCases[j];
     SwitchCase currentCase = new SwitchCase() { Expression = caseLabel };
     result.Cases.Add(currentCase);
     if (j < n-1 && gotoCaseBody.TargetStatement == switchInstruction.switchCases[j+1].TargetStatement) continue;
     currentCase.Body.Add(gotoCaseBody);
       }
       if (i == statements.Count-1) return;
       var gotoStatement = statements[i+1] as IGotoStatement;
       if (gotoStatement != null) {
     SwitchCase defaultCase = new SwitchCase() { }; // Default case is represented by a dummy Expression.
     defaultCase.Body.Add(statements[i + 1]);
     statements.RemoveAt(i + 1);
     result.Cases.Add(defaultCase);
       }
 }
示例#6
0
 /// <summary>
 /// Rewrites the children of the given switch case.
 /// </summary>
 public virtual void RewriteChildren(SwitchCase switchCase)
 {
     if (!switchCase.IsDefault)
     switchCase.Expression = this.Rewrite((CompileTimeConstant)switchCase.Expression);
       switchCase.Body = this.Rewrite(switchCase.Body);
 }
示例#7
0
 /// <summary>
 /// Visits the specified switch case.
 /// </summary>
 /// <param name="switchCase">The switch case.</param>
 /// <returns></returns>
 public virtual ISwitchCase Visit(ISwitchCase switchCase)
 {
     SwitchCase mutableSwitchCase = switchCase as SwitchCase;
       if (!this.copyOnlyIfNotAlreadyMutable || mutableSwitchCase == null)
     mutableSwitchCase = new SwitchCase(switchCase);
       return Visit(mutableSwitchCase);
 }
示例#8
0
 /// <summary>
 /// Visits the specified switch case.
 /// </summary>
 /// <param name="switchCase">The switch case.</param>
 /// <returns></returns>
 public virtual ISwitchCase Visit(SwitchCase switchCase)
 {
     if (!switchCase.IsDefault)
     switchCase.Expression = Visit(switchCase.Expression);
       switchCase.Body = Visit(switchCase.Body);
       return switchCase;
 }