bool IntroduceFixedStatements(List <ILNode> body, int i)
        {
            ILExpression initValue;
            ILVariable   pinnedVar;
            int          initEndPos;

            if (!MatchFixedInitializer(body, i, out pinnedVar, out initValue, out initEndPos))
            {
                return(false);
            }

            ILFixedStatement fixedStmt = body.ElementAtOrDefault(initEndPos) as ILFixedStatement;

            if (fixedStmt != null)
            {
                ILExpression expr = fixedStmt.BodyBlock.Body.LastOrDefault() as ILExpression;
                if (expr != null && expr.Code == ILCode.Stloc && expr.Operand == pinnedVar && IsNullOrZero(expr.Arguments[0]))
                {
                    // we found a second initializer for the existing fixed statement
                    fixedStmt.Initializers.Insert(0, initValue);
                    body.RemoveRange(i, initEndPos - i);
                    fixedStmt.BodyBlock.Body.RemoveAt(fixedStmt.BodyBlock.Body.Count - 1);
                    if (pinnedVar.Type.IsByReference)
                    {
                        pinnedVar.Type = new PointerType(((ByReferenceType)pinnedVar.Type).ElementType);
                    }
                    return(true);
                }
            }

            // find where pinnedVar is reset to 0:
            int j;

            for (j = initEndPos; j < body.Count; j++)
            {
                ILVariable   v2;
                ILExpression storedVal;
                // stloc(pinned_Var, conv.u(ldc.i4(0)))
                if (body[j].Match(ILCode.Stloc, out v2, out storedVal) && v2 == pinnedVar)
                {
                    if (IsNullOrZero(storedVal))
                    {
                        break;
                    }
                }
            }
            // Create fixed statement from i to j
            fixedStmt = new ILFixedStatement();
            fixedStmt.Initializers.Add(initValue);
            fixedStmt.BodyBlock = new ILBlock(body.GetRange(initEndPos, j - initEndPos)); // from initEndPos to j-1 (inclusive)
            body.RemoveRange(i + 1, Math.Min(j, body.Count - 1) - i);                     // from i+1 to j (inclusive)
            body[i] = fixedStmt;
            if (pinnedVar.Type.IsByReference)
            {
                pinnedVar.Type = new PointerType(((ByReferenceType)pinnedVar.Type).ElementType);
            }

            return(true);
        }
Beispiel #2
0
 protected virtual ILFixedStatement VisitFixedStatement(ILFixedStatement fixedStatement)
 {
     foreach (var child in fixedStatement.GetChildren())
     {
         Visit(child);
     }
     return(fixedStatement);
 }
        bool MatchFixedInitializer(List <ILNode> body, int i, out ILVariable pinnedVar, out ILExpression initValue, out int nextPos)
        {
            if (body[i].Match(ILCode.Stloc, out pinnedVar, out initValue) && pinnedVar.IsPinned && !IsNullOrZero(initValue))
            {
                initValue = (ILExpression)body[i];
                nextPos   = i + 1;
                HandleStringFixing(pinnedVar, body, ref nextPos, ref initValue);
                return(true);
            }
            ILCondition  ifStmt = body[i] as ILCondition;
            ILExpression arrayLoadingExpr;

            if (ifStmt != null && MatchFixedArrayInitializerCondition(ifStmt.Condition, out arrayLoadingExpr))
            {
                ILVariable   arrayVariable = (ILVariable)arrayLoadingExpr.Operand;
                ILExpression trueValue;
                if (ifStmt.TrueBlock != null && ifStmt.TrueBlock.Body.Count == 1 &&
                    ifStmt.TrueBlock.Body[0].Match(ILCode.Stloc, out pinnedVar, out trueValue) &&
                    pinnedVar.IsPinned && IsNullOrZero(trueValue))
                {
                    if (ifStmt.FalseBlock != null && ifStmt.FalseBlock.Body.Count == 1 && ifStmt.FalseBlock.Body[0] is ILFixedStatement)
                    {
                        ILFixedStatement fixedStmt = (ILFixedStatement)ifStmt.FalseBlock.Body[0];
                        ILVariable       stlocVar;
                        ILExpression     falseValue;
                        if (fixedStmt.Initializers.Count == 1 && fixedStmt.BodyBlock.Body.Count == 0 &&
                            fixedStmt.Initializers[0].Match(ILCode.Stloc, out stlocVar, out falseValue) && stlocVar == pinnedVar)
                        {
                            ILVariable loadedVariable;
                            if (falseValue.Code == ILCode.Ldelema &&
                                falseValue.Arguments[0].Match(ILCode.Ldloc, out loadedVariable) && loadedVariable == arrayVariable &&
                                IsNullOrZero(falseValue.Arguments[1]))
                            {
                                // OK, we detected the pattern for fixing an array.
                                // Now check whether the loading expression was a store ot a temp. var
                                // that can be eliminated.
                                if (arrayLoadingExpr.Code == ILCode.Stloc)
                                {
                                    ILInlining inlining = new ILInlining(method);
                                    if (inlining.numLdloc.GetOrDefault(arrayVariable) == 2 &&
                                        inlining.numStloc.GetOrDefault(arrayVariable) == 1 && inlining.numLdloca.GetOrDefault(arrayVariable) == 0)
                                    {
                                        arrayLoadingExpr = arrayLoadingExpr.Arguments[0];
                                    }
                                }
                                initValue = new ILExpression(ILCode.Stloc, pinnedVar, arrayLoadingExpr);
                                nextPos   = i + 1;
                                return(true);
                            }
                        }
                    }
                }
            }
            initValue = null;
            nextPos   = -1;
            return(false);
        }
		bool IntroduceFixedStatements(List<ILNode> body, int i)
		{
			ILExpression initValue;
			ILVariable pinnedVar;
			int initEndPos;
			if (!MatchFixedInitializer(body, i, out pinnedVar, out initValue, out initEndPos))
				return false;
			
			ILFixedStatement fixedStmt = body.ElementAtOrDefault(initEndPos) as ILFixedStatement;
			if (fixedStmt != null) {
				ILExpression expr = fixedStmt.BodyBlock.Body.LastOrDefault() as ILExpression;
				if (expr != null && expr.Code == ILCode.Stloc && expr.Operand == pinnedVar && IsNullOrZero(expr.Arguments[0])) {
					// we found a second initializer for the existing fixed statement
					fixedStmt.Initializers.Insert(0, initValue);
					body.RemoveRange(i, initEndPos - i);
					fixedStmt.BodyBlock.Body.RemoveAt(fixedStmt.BodyBlock.Body.Count - 1);
					if (pinnedVar.Type.IsByReference)
						pinnedVar.Type = new PointerType(((ByReferenceType)pinnedVar.Type).ElementType);
					return true;
				}
			}
			
			// find where pinnedVar is reset to 0:
			int j;
			for (j = initEndPos; j < body.Count; j++) {
				ILVariable v2;
				ILExpression storedVal;
				// stloc(pinned_Var, conv.u(ldc.i4(0)))
				if (body[j].Match(ILCode.Stloc, out v2, out storedVal) && v2 == pinnedVar) {
					if (IsNullOrZero(storedVal)) {
						break;
					}
				}
			}
			// Create fixed statement from i to j
			fixedStmt = new ILFixedStatement();
			fixedStmt.Initializers.Add(initValue);
			fixedStmt.BodyBlock = new ILBlock(body.GetRange(initEndPos, j - initEndPos)); // from initEndPos to j-1 (inclusive)
			body.RemoveRange(i + 1, Math.Min(j, body.Count - 1) - i); // from i+1 to j (inclusive)
			body[i] = fixedStmt;
			if (pinnedVar.Type.IsByReference)
				pinnedVar.Type = new PointerType(((ByReferenceType)pinnedVar.Type).ElementType);
			
			return true;
		}
Beispiel #5
0
 public JSExpression TranslateNode(ILFixedStatement fxd)
 {
     throw new AbortTranslation("Fixed statements not implemented");
 }
Beispiel #6
0
		bool IntroduceFixedStatements(ILBlockBase block, List<ILNode> body, int i)
		{
			ILExpression initValue;
			ILVariable pinnedVar;
			int initEndPos;
			if (!MatchFixedInitializer(body, i, out pinnedVar, out initValue, out initEndPos))
				return false;
			
			ILFixedStatement fixedStmt = body.ElementAtOrDefault(initEndPos) as ILFixedStatement;
			if (fixedStmt != null) {
				ILExpression expr = fixedStmt.BodyBlock.Body.LastOrDefault() as ILExpression;
				if (expr != null && expr.Code == ILCode.Stloc && expr.Operand == pinnedVar && IsNullOrZero(expr.Arguments[0])) {
					// we found a second initializer for the existing fixed statement
					fixedStmt.Initializers.Insert(0, initValue);
					if (context.CalculateILRanges) {
						for (int k = i; k < initEndPos; k++)
							initValue.ILRanges.AddRange(body[k].GetSelfAndChildrenRecursiveILRanges().ToArray());
					}
					body.RemoveRange(i, initEndPos - i);
					if (context.CalculateILRanges)
						Utils.AddILRanges(fixedStmt.BodyBlock, fixedStmt.BodyBlock.Body, fixedStmt.BodyBlock.Body.Count - 1);
					fixedStmt.BodyBlock.Body.RemoveAt(fixedStmt.BodyBlock.Body.Count - 1);
					if (pinnedVar.Type is ByRefSig)
						pinnedVar.Type = new PtrSig(((ByRefSig)pinnedVar.Type).Next);
					return true;
				}
			}
			
			// find where pinnedVar is reset to 0:
			int j;
			for (j = initEndPos; j < body.Count; j++) {
				ILVariable v2;
				ILExpression storedVal;
				// stloc(pinned_Var, conv.u(ldc.i4(0)))
				if (body[j].Match(ILCode.Stloc, out v2, out storedVal) && v2 == pinnedVar) {
					if (IsNullOrZero(storedVal)) {
						break;
					}
				}
			}
			// Create fixed statement from i to j
			fixedStmt = new ILFixedStatement();
			fixedStmt.Initializers.Add(initValue);
			fixedStmt.BodyBlock = new ILBlock(body.GetRange(initEndPos, j - initEndPos)); // from initEndPos to j-1 (inclusive)
			if (context.CalculateILRanges) {
				for (int k = i; k < initEndPos; k++)
					initValue.ILRanges.AddRange(body[k].GetSelfAndChildrenRecursiveILRanges().ToArray());
			}
			body.RemoveRange(i + 1, Math.Min(j, body.Count - 1) - i); // from i+1 to j (inclusive)
			body[i] = fixedStmt;
			if (pinnedVar.Type is ByRefSig)
				pinnedVar.Type = new PtrSig(((ByRefSig)pinnedVar.Type).Next);
			
			return true;
		}
Beispiel #7
0
 protected virtual ILFixedStatement VisitFixedStatement(ILFixedStatement fixedStatement)
 {
     foreach (var child in fixedStatement.GetChildren())
         Visit(child);
     return fixedStatement;
 }
Beispiel #8
0
        private void ProcessMethodDecencies(InterMethod method, ILNode node, List <InterGenericArgument> genericArgs)
        {
            if (node is ILBlock)
            {
                ILBlock block = node as ILBlock;

                foreach (ILNode n in block.Body)
                {
                    ProcessMethodDecencies(method, n, genericArgs);
                }
            }
            else if (node is ILBasicBlock)
            {
                ILBasicBlock block = node as ILBasicBlock;

                foreach (ILNode n in block.Body)
                {
                    ProcessMethodDecencies(method, n, genericArgs);
                }
            }
            else if (node is ILTryCatchBlock)
            {
                ILTryCatchBlock block = node as ILTryCatchBlock;

                foreach (ILNode n in block.TryBlock.Body)
                {
                    ProcessMethodDecencies(method, n, genericArgs);
                }
                if (block.FaultBlock != null)
                {
                    foreach (ILNode n in block.FaultBlock.Body)
                    {
                        ProcessMethodDecencies(method, n, genericArgs);
                    }
                }
                if (block.FinallyBlock != null)
                {
                    foreach (ILNode n in block.FinallyBlock.Body)
                    {
                        ProcessMethodDecencies(method, n, genericArgs);
                    }
                }
                foreach (var catchBlock in block.CatchBlocks)
                {
                    ((IResolver)this).Resolve(catchBlock.ExceptionType, genericArgs);
                    ProcessMethodDecencies(method, catchBlock, genericArgs);
                }
            }
            else if (node is ILExpression)
            {
                ILExpression e = node as ILExpression;

                foreach (var n in e.Arguments)
                {
                    ProcessMethodDecencies(method, n, genericArgs);
                }

                if ((e.Code == ILCode.Mkrefany) || (e.Code == ILCode.Refanyval))
                {
                    ((IResolver)this).Resolve(ClassNames.SystemTypedReference.ClassName);
                }

                if (e.Code == ILCode.Refanytype)
                {
                    ((IResolver)this).Resolve(ClassNames.SystemTypedReference.ClassName);
                    ((IResolver)this).Resolve(ClassNames.SystemRuntimeTypeHandle.ClassName);
                }

                if (e.Code == ILCode.Arglist)
                {
                    ((IResolver)this).Resolve(ClassNames.SystemRuntimeArgumentHandle.ClassName);
                }

                if (e.Code.IsExternalRealization())
                {
                    ((IResolver)this).Resolve(ClassNames.CIL2JavaVESInstructions.ClassName);
                }

                if (e.Code == ILCode.Ldc_Decimal)
                {
                    ((IResolver)this).Resolve(ClassNames.SystemDecimal.ClassNames);
                }

                if (e.Code == ILCode.Ldtoken)
                {
                    if (e.Operand is TypeReference)
                    {
                        ((IResolver)this).Resolve(ClassNames.SystemRuntimeTypeHandle.ClassName);
                    }
                    else if (e.Operand is FieldReference)
                    {
                        ((IResolver)this).Resolve(ClassNames.SystemRuntimeFieldHandle.ClassName);
                    }
                    else if (e.Operand is MethodReference)
                    {
                        ((IResolver)this).Resolve(ClassNames.SystemRuntimeMethodHandle.ClassName);
                    }
                }

                if (e.Operand is ILVariable)
                {
                    ((IResolver)this).Resolve(((ILVariable)e.Operand).Type, genericArgs);
                }
                if (e.Operand is TypeReference)
                {
                    ((IResolver)this).Resolve((TypeReference)e.Operand, genericArgs);
                }
                if (e.Operand is MethodReference)
                {
                    ((IResolver)this).Resolve((MethodReference)e.Operand, genericArgs);
                }
                if (e.Operand is FieldReference)
                {
                    InterField fld          = ((IResolver)this).Resolve((FieldReference)e.Operand, genericArgs);
                    bool       needAccessor = false;

                    if ((fld.IsPrivate) && (fld.DeclaringType != method.DeclaringType))
                    {
                        needAccessor = true;
                    }
                    else if ((fld.IsProtected) && (fld.DeclaringType != method.DeclaringType) &&
                             (!method.DeclaringType.IsSuper(fld.DeclaringType)))
                    {
                        needAccessor = true;
                    }

                    if (needAccessor)
                    {
                        switch (e.Code)
                        {
                        case ILCode.Ldflda:
                        case ILCode.Ldsflda:
                            if (fld.FieldType.IsValueType)
                            {
                                fld.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Getter, fld));
                            }
                            break;

                        case ILCode.Ldfld:
                        case ILCode.Ldsfld:
                            fld.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Getter, fld));
                            break;

                        case ILCode.Stfld:
                        case ILCode.Stsfld:
                            fld.DeclaringType.AddFieldAccessor(new FieldAccessor(FieldAccessorType.Setter, fld));
                            break;
                        }
                    }
                }

                InterType expected = null;
                InterType inferred = null;

                if (e.ExpectedType != null)
                {
                    expected = ((IResolver)this).Resolve(e.ExpectedType, genericArgs);
                }
                if (e.InferredType != null)
                {
                    inferred = ((IResolver)this).Resolve(e.InferredType, genericArgs);
                }

                if ((expected != null) && (expected.IsInterface) && (inferred != null) && (inferred.IsArray))
                {
                    ((IResolver)this).Resolve(ClassNames.ArraysInterfaceAdapterTypeName,
                                              new List <InterGenericArgument>()
                    {
                        new InterGenericArgument(GenericArgumentOwnerType.Type, 0, inferred.ElementType)
                    });
                }
            }
            else if (node is ILWhileLoop)
            {
                ILWhileLoop loop = node as ILWhileLoop;
                ProcessMethodDecencies(method, loop.Condition, genericArgs);
                ProcessMethodDecencies(method, loop.BodyBlock, genericArgs);
            }
            else if (node is ILCondition)
            {
                ILCondition cond = node as ILCondition;
                ProcessMethodDecencies(method, cond.Condition, genericArgs);
                ProcessMethodDecencies(method, cond.TrueBlock, genericArgs);
                ProcessMethodDecencies(method, cond.FalseBlock, genericArgs);
            }
            else if (node is ILSwitch)
            {
                ILSwitch sw = node as ILSwitch;
                ProcessMethodDecencies(method, sw.Condition, genericArgs);
                foreach (var c in sw.CaseBlocks)
                {
                    ProcessMethodDecencies(method, c, genericArgs);
                }
            }
            else if (node is ILFixedStatement)
            {
                ILFixedStatement fs = node as ILFixedStatement;
                foreach (var n in fs.Initializers)
                {
                    ProcessMethodDecencies(method, n, genericArgs);
                }
                ProcessMethodDecencies(method, fs.BodyBlock, genericArgs);
            }
        }