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); }
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; }
public JSExpression TranslateNode(ILFixedStatement fxd) { throw new AbortTranslation("Fixed statements not implemented"); }
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; }
protected virtual ILFixedStatement VisitFixedStatement(ILFixedStatement fixedStatement) { foreach (var child in fixedStatement.GetChildren()) Visit(child); return fixedStatement; }
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); } }