Esempio n. 1
0
 ILExpression MakeGoTo(LabelRangeMapping mapping, int state)
 {
     foreach (var pair in mapping)
     {
         if (pair.Value.Contains(state))
         {
             return(new ILExpression(ILCode.Br, pair.Key));
         }
     }
     throw new SymbolicAnalysisFailedException();
 }
		void CreateLabelRangeMapping(List<ILNode> body, int pos, int bodyLength, LabelRangeMapping result, bool onlyInitialLabels)
		{
			for (int i = pos; i < bodyLength; i++) {
				ILLabel label = body[i] as ILLabel;
				if (label != null) {
					result.Add(new KeyValuePair<ILLabel, StateRange>(label, ranges[label]));
				} else {
					ILTryCatchBlock tryCatchBlock = body[i] as ILTryCatchBlock;
					if (tryCatchBlock != null) {
						CreateLabelRangeMapping(tryCatchBlock.TryBlock.Body, 0, tryCatchBlock.TryBlock.Body.Count, result, true);
					} else if (onlyInitialLabels) {
						break;
					}
				}
			}
		}
Esempio n. 3
0
		List<ILNode> ConvertBody(List<ILNode> body, int startPos, int bodyLength, LabelRangeMapping mapping)
		{
			List<ILNode> newBody = new List<ILNode>();
			// Copy all instructions from the old body to newBody.
			for (int pos = startPos; pos < bodyLength; pos++) {
				ILTryCatchBlock tryCatchBlock = body[pos] as ILTryCatchBlock;
				ILExpression expr = body[pos] as ILExpression;
				if (expr != null && expr.Code == ILCode.Leave && expr.Operand == exitLabel) {
					ILVariable awaiterVar;
					FieldDef awaiterField;
					int targetStateID;
					HandleAwait(newBody, out awaiterVar, out awaiterField, out targetStateID);
					MarkAsGeneratedVariable(awaiterVar);
					newBody.Add(new ILExpression(ILCode.Await, null, new ILExpression(ILCode.Ldloca, awaiterVar)));
					newBody.Add(MakeGoTo(mapping, targetStateID));
				} else if (tryCatchBlock != null) {
					ILTryCatchBlock newTryCatchBlock = new ILTryCatchBlock();
					var tryBody = tryCatchBlock.TryBlock.Body;
					if (tryBody.Count == 0)
						throw new SymbolicAnalysisFailedException();
					StateRangeAnalysis rangeAnalysis = new StateRangeAnalysis(tryBody[0], StateRangeAnalysisMode.AsyncMoveNext, stateField, cachedStateVar);
					int tryBodyLength = tryBody.Count;
					int posInTryBody = rangeAnalysis.AssignStateRanges(tryBody, tryBodyLength);
					rangeAnalysis.EnsureLabelAtPos(tryBody, ref posInTryBody, ref tryBodyLength);
					
					var mappingInTryBlock = rangeAnalysis.CreateLabelRangeMapping(tryBody, posInTryBody, tryBodyLength);
					var newTryBody = ConvertBody(tryBody, posInTryBody, tryBodyLength, mappingInTryBlock);
					newTryBody.Insert(0, MakeGoTo(mappingInTryBlock, initialState));
					
					// If there's a label at the beginning of the state dispatcher, copy that
					if (posInTryBody > 0 && tryBody.FirstOrDefault() is ILLabel)
						newTryBody.Insert(0, tryBody.First());
					
					newTryCatchBlock.TryBlock = new ILBlock(newTryBody);
					newTryCatchBlock.CatchBlocks = new List<ILTryCatchBlock.CatchBlock>(tryCatchBlock.CatchBlocks);
					newTryCatchBlock.FaultBlock = tryCatchBlock.FaultBlock;
					if (tryCatchBlock.FinallyBlock != null)
						newTryCatchBlock.FinallyBlock = new ILBlock(ConvertFinally(tryCatchBlock.FinallyBlock.Body));
					
					newBody.Add(newTryCatchBlock);
				} else {
					newBody.Add(body[pos]);
				}
			}
			return newBody;
		}
Esempio n. 4
0
 ILExpression MakeGoTo(LabelRangeMapping mapping, int state)
 {
     foreach (var pair in mapping) {
         if (pair.Value.Contains(state))
             return new ILExpression(ILCode.Br, pair.Key);
     }
     throw new SymbolicAnalysisFailedException();
 }
Esempio n. 5
0
        List<ILNode> ConvertBody(List<ILNode> body, int startPos, int bodyLength, LabelRangeMapping mapping)
        {
            List<ILNode> newBody = new List<ILNode>();
            // Copy all instructions from the old body to newBody.
            for (int pos = startPos; pos < bodyLength; pos++) {
                ILTryCatchBlock tryCatchBlock = body[pos] as ILTryCatchBlock;
                ILExpression expr = body[pos] as ILExpression;
                if (expr != null && expr.Code == ILCode.Leave && expr.Operand == exitLabel) {
                    ILVariable awaiterVar;
                    FieldDef awaiterField;
                    int targetStateID;
                    HandleAwait(newBody, out awaiterVar, out awaiterField, out targetStateID);
                    MarkAsGeneratedVariable(awaiterVar);
                    newBody.Add(new ILExpression(ILCode.Await, null, new ILExpression(ILCode.Ldloca, awaiterVar)));
                    newBody.Add(MakeGoTo(mapping, targetStateID));
                } else if (tryCatchBlock != null) {
                    ILTryCatchBlock newTryCatchBlock = new ILTryCatchBlock();
                    var tryBody = tryCatchBlock.TryBlock.Body;
                    if (tryBody.Count == 0)
                        throw new SymbolicAnalysisFailedException();
                    StateRangeAnalysis rangeAnalysis = new StateRangeAnalysis(tryBody[0], StateRangeAnalysisMode.AsyncMoveNext, stateField, cachedStateVar);
                    int tryBodyLength = tryBody.Count;
                    int posInTryBody = rangeAnalysis.AssignStateRanges(tryBody, tryBodyLength);
                    rangeAnalysis.EnsureLabelAtPos(tryBody, ref posInTryBody, ref tryBodyLength);

                    var mappingInTryBlock = rangeAnalysis.CreateLabelRangeMapping(tryBody, posInTryBody, tryBodyLength);
                    var newTryBody = ConvertBody(tryBody, posInTryBody, tryBodyLength, mappingInTryBlock);
                    newTryBody.Insert(0, MakeGoTo(mappingInTryBlock, initialState));

                    // If there's a label at the beginning of the state dispatcher, copy that
                    if (posInTryBody > 0 && tryBody.FirstOrDefault() is ILLabel)
                        newTryBody.Insert(0, tryBody.First());

                    newTryCatchBlock.TryBlock = new ILBlock(newTryBody);
                    newTryCatchBlock.CatchBlocks = new List<ILTryCatchBlock.CatchBlock>(tryCatchBlock.CatchBlocks);
                    newTryCatchBlock.FaultBlock = tryCatchBlock.FaultBlock;
                    if (tryCatchBlock.FinallyBlock != null)
                        newTryCatchBlock.FinallyBlock = new ILBlock(ConvertFinally(tryCatchBlock.FinallyBlock.Body));

                    newBody.Add(newTryCatchBlock);
                } else {
                    newBody.Add(body[pos]);
                }
            }
            return newBody;
        }
		public LabelRangeMapping CreateLabelRangeMapping(List<ILNode> body, int pos, int bodyLength)
		{
			LabelRangeMapping result = new LabelRangeMapping();
			CreateLabelRangeMapping(body, pos, bodyLength, result, false);
			return result;
		}