// // Summary: // Visits the children of the System.Linq.Expressions.IndexExpression. // // Parameters: // node: // The expression to visit. // // Returns: // The modified expression, if it or any subexpression was modified; otherwise, // returns the original expression. protected override Expression VisitIndex(IndexExpression node) { Console.WriteLine("VisitIndex:"); Console.WriteLine('\t' + node.GetType().ToString()); Console.WriteLine('\t' + node.ToString()); return(base.VisitIndex(node)); }
public static void ToStringTest() { IndexExpression e1 = Expression.MakeIndex(Expression.Parameter(typeof(Vector1), "v"), typeof(Vector1).GetProperty("Item"), new[] { Expression.Parameter(typeof(int), "i") }); Assert.Equal("v.Item[i]", e1.ToString()); IndexExpression e2 = Expression.MakeIndex(Expression.Parameter(typeof(Vector2), "v"), typeof(Vector2).GetProperty("Item"), new[] { Expression.Parameter(typeof(int), "i"), Expression.Parameter(typeof(int), "j") }); Assert.Equal("v.Item[i, j]", e2.ToString()); IndexExpression e3 = Expression.ArrayAccess(Expression.Parameter(typeof(int[, ]), "xs"), Expression.Parameter(typeof(int), "i"), Expression.Parameter(typeof(int), "j")); Assert.Equal("xs[i, j]", e3.ToString()); }
public static void Base() { ParameterExpression a = Expression.Parameter(typeof(int), "a"); ParameterExpression b = Expression.Parameter(typeof(int), "b"); ParameterExpression i = Expression.Parameter(typeof(int), "i"); BinaryExpression add = Expression.Add(a, b); ConstantExpression s = Expression.Constant(1); BinaryExpression substract = Expression.Subtract(i, s); NewArrayExpression arrayint = Expression.NewArrayInit(typeof(int), a, b, add); IndexExpression arracc = Expression.ArrayAccess(arrayint, substract); Console.WriteLine(arracc.ToString()); }
public bool BackwalkInstruction(TInstr instr) { var ass = host.AsAssignment(instr); if (ass.Item1 != null) { var(assSrc, _) = ass.Item2 !.Accept(eval); var assDst = ass.Item1; var regSrc = RegisterOf(assSrc); if (assSrc is BinaryExpression binSrc) { if (RegisterOf(assDst) == Index || assDst == IndexExpression) { regSrc = RegisterOf(binSrc.Left); var immSrc = binSrc.Right as Constant; if (binSrc.Operator == Operator.IAdd || binSrc.Operator == Operator.ISub) { Index = HandleAddition(Index, Index, regSrc, immSrc !, binSrc.Operator == Operator.IAdd); return(true); } if (binSrc.Operator == Operator.And) { if (immSrc != null && Bits.IsEvenPowerOfTwo(immSrc.ToInt32() + 1)) { Operations.Add(new BackwalkOperation(BackwalkOperator.cmp, immSrc.ToInt32() + 1)); } else { Index = null; } return(false); } if (binSrc.Operator is IMulOperator && immSrc != null) { var m = immSrc.ToInt32(); Operations.Add(new BackwalkOperation(BackwalkOperator.mul, m)); Stride *= m; return(true); } if (binSrc.Operator is ShlOperator && immSrc != null) { var m = 1 << immSrc.ToInt32(); Operations.Add(new BackwalkOperation(BackwalkOperator.mul, m)); Stride *= m; return(true); } } if (Index != null && binSrc.Operator == Operator.Xor && binSrc.Left == assDst && binSrc.Right == assDst && RegisterOf(assDst) == host.GetSubregister(Index, new BitRange(8, 16))) { Operations.Add(new BackwalkOperation(BackwalkOperator.and, 0xFF)); Index = host.GetSubregister(Index, new BitRange(0, 8)); } } var cSrc = assSrc as Constant; if (Index != null && cSrc != null && cSrc.IsIntegerZero && RegisterOf(assDst) == host.GetSubregister(Index, new BitRange(8, 16))) { // mov bh,0 ;; xor bh,bh // jmp [bx...] Operations.Add(new BackwalkOperation(BackwalkOperator.and, 0xFF)); Index = host.GetSubregister(Index, new BitRange(0, 8)); return(true); } if (assSrc is ConditionOf cof && UsedFlagIdentifier != null) { var grfDef = (((Identifier)assDst).Storage as FlagGroupStorage) !.FlagGroupBits; var grfUse = (UsedFlagIdentifier.Storage as FlagGroupStorage) !.FlagGroupBits; if ((grfDef & grfUse) == 0) { return(true); } var binCmp = cof.Expression as BinaryExpression; binCmp = NegateRight(binCmp); if (binCmp != null && (binCmp.Operator is ISubOperator || binCmp.Operator is USubOperator)) { var idLeft = RegisterOf(binCmp.Left as Identifier); if (idLeft != null && (idLeft == Index || idLeft == host.GetSubregister(Index !, new BitRange(0, 8))) || (IndexExpression != null && IndexExpression.ToString() == idLeft !.ToString())) //$HACK: sleazy, but we don't appear to have an expression comparer { if (binCmp.Right is Constant immSrc) { // Found the bound of the table. Operations.Add(new BackwalkOperation(BackwalkOperator.cmp, immSrc.ToInt32())); return(false); } } } if (cof.Expression is Identifier idCof) { IndexExpression = idCof; Index = null; UsedFlagIdentifier = null; UsedAsFlag = idCof; return(true); } } //$BUG: this is rubbish, the simplifier should _just_ // perform simplification, no substitutions. var src = assSrc is InvalidConstant ? ass.Item2 : assSrc; var cvtSrc = src as Conversion; if (cvtSrc != null) { src = cvtSrc.Expression; } var regDst = RegisterOf(assDst); if (src is MemoryAccess memSrc && (regDst == Index || (Index != null && regDst != null && regDst.Name != "None" && regDst.IsSubRegisterOf(Index)))) { // R = Mem[xxx] var rIdx = Index; var rDst = RegisterOf(assDst); if ((rDst != host.GetSubregister(rIdx, new BitRange(0, 8)) && cvtSrc == null) && rDst != rIdx) { Index = RegisterStorage.None; IndexExpression = src; return(true); } if (!(memSrc.EffectiveAddress is BinaryExpression binEa)) { Index = RegisterStorage.None; IndexExpression = null; return(false); } var scale = GetMultiplier(binEa.Left); var baseReg = GetBaseRegister(binEa.Left); if (binEa.Right is Constant memOffset && binEa.Operator == Operator.IAdd) { var mOff = memOffset.ToInt32(); if (mOff > 0x200) { Operations.Add(new BackwalkDereference(memOffset.ToInt32(), scale)); Index = baseReg; return(true); } } // Some architectures have pc-relative addressing, which the rewriters // should convert to an _address_. var addr = binEa.Left as Address; baseReg = GetBaseRegister(binEa.Right); if (!(addr is null || VectorAddress is null)) { this.VectorAddress = addr; Index = baseReg; return(true); } Index = RegisterStorage.None; IndexExpression = ass.Item2; return(true); } if (regSrc != null && regDst == Index) { Index = regSrc; return(true); } UsedAsFlag = null; return(true); } var bra = host.AsBranch(instr); if (bra != null) { bool fallthrough = host.IsFallthrough(instr, startBlock !); return(VisitBranch(bra, fallthrough)); } Debug.WriteLine("Backwalking not supported: " + instr); return(true); }
/// <summary>访问子内容为: <see cref="T:System.Linq.Expressions.IndexExpression"></see>.</summary> /// <param name="node">被访问的表达式</param> /// <returns>The modified expression, if it or any subexpression was modified; otherwise, returns the original expression.</returns> protected override Expression VisitIndex(IndexExpression node) { Log(node.ToString()); throw new NotImplementedException(); }
public bool BackwalkInstruction(Instruction instr) { var ass = instr as Assignment; if (ass != null) { var assSrc = ass.Src.Accept(eval); var regSrc = RegisterOf(assSrc as Identifier); var binSrc = assSrc as BinaryExpression; if (binSrc != null) { if (RegisterOf(ass.Dst) == Index || ass.Dst == IndexExpression) { regSrc = RegisterOf(binSrc.Left); var immSrc = binSrc.Right as Constant; if (binSrc.Operator == Operator.IAdd || binSrc.Operator == Operator.ISub) { Index = HandleAddition(Index, Index, regSrc, immSrc, binSrc.Operator == Operator.IAdd); return(true); } if (binSrc.Operator == Operator.And) { if (immSrc != null && IsEvenPowerOfTwo(immSrc.ToInt32() + 1)) { Operations.Add(new BackwalkOperation(BackwalkOperator.cmp, immSrc.ToInt32() + 1)); } else { Index = null; } return(false); } if (binSrc.Operator is IMulOperator && immSrc != null) { var m = immSrc.ToInt32(); Operations.Add(new BackwalkOperation(BackwalkOperator.mul, m)); Stride *= m; return(true); } if (binSrc.Operator is ShlOperator && immSrc != null) { var m = 1 << immSrc.ToInt32(); Operations.Add(new BackwalkOperation(BackwalkOperator.mul, m)); Stride *= m; return(true); } } if (Index != null && binSrc.Operator == Operator.Xor && binSrc.Left == ass.Dst && binSrc.Right == ass.Dst && RegisterOf(ass.Dst) == host.GetSubregister(Index, 8, 8)) { Operations.Add(new BackwalkOperation(BackwalkOperator.and, 0xFF)); Index = host.GetSubregister(Index, 0, 8); } } var cSrc = assSrc as Constant; if (Index != null && cSrc != null && cSrc.IsIntegerZero && RegisterOf(ass.Dst) == host.GetSubregister(Index, 8, 8)) { // mov bh,0 ;; xor bh,bh // jmp [bx...] Operations.Add(new BackwalkOperation(BackwalkOperator.and, 0xFF)); Index = host.GetSubregister(Index, 0, 8); return(true); } var cof = assSrc as ConditionOf; if (cof != null && UsedFlagIdentifier != null) { var grfDef = (ass.Dst.Storage as FlagGroupStorage).FlagGroupBits; var grfUse = (UsedFlagIdentifier.Storage as FlagGroupStorage).FlagGroupBits; if ((grfDef & grfUse) == 0) { return(true); } var binCmp = cof.Expression as BinaryExpression; if (binCmp != null && (binCmp.Operator is ISubOperator || binCmp.Operator is USubOperator)) { var idLeft = RegisterOf(binCmp.Left as Identifier); if (idLeft != null && (idLeft == Index || idLeft == host.GetSubregister(Index, 0, 8)) || (IndexExpression != null && IndexExpression.ToString() == idLeft.ToString())) //$HACK: sleazy, but we don't appear to have an expression comparer { var immSrc = binCmp.Right as Constant; if (immSrc != null) { // Found the bound of the table. Operations.Add(new BackwalkOperation(BackwalkOperator.cmp, immSrc.ToInt32())); return(false); } } } var idCof = cof.Expression as Identifier; if (idCof != null) { IndexExpression = idCof; Index = null; UsedFlagIdentifier = null; UsedAsFlag = idCof; return(true); } } //$BUG: this is rubbish, the simplifier should _just_ // perform simplification, no substitutions. var src = assSrc == Constant.Invalid ? ass.Src : assSrc; var castSrc = src as Cast; if (castSrc != null) { src = castSrc.Expression; } var memSrc = src as MemoryAccess; var regDst = RegisterOf(ass.Dst); if (memSrc != null && (regDst == Index || (Index != null && regDst != null && regDst.Name != "None" && regDst.IsSubRegisterOf(Index)))) { // R = Mem[xxx] var rIdx = Index; var rDst = RegisterOf(ass.Dst); if ((rDst != host.GetSubregister(rIdx, 0, 8) && castSrc == null) && rDst != rIdx) { Index = RegisterStorage.None; IndexExpression = src; return(true); } var binEa = memSrc.EffectiveAddress as BinaryExpression; if (binEa == null) { Index = RegisterStorage.None; IndexExpression = null; return(false); } var memOffset = binEa.Right as Constant; var scale = GetMultiplier(binEa.Left); var baseReg = GetBaseRegister(binEa.Left); if (memOffset != null && binEa.Operator == Operator.IAdd) { var mOff = memOffset.ToInt32(); if (mOff > 0x200) { Operations.Add(new BackwalkDereference(memOffset.ToInt32(), scale)); Index = baseReg; return(true); } } // Some architectures have pc-relative addressing, which the rewriters // should convert to an _address_. var addr = binEa.Left as Address; baseReg = GetBaseRegister(binEa.Right); if (addr != null && VectorAddress == null) { this.VectorAddress = addr; Index = baseReg; return(true); } Index = RegisterStorage.None; IndexExpression = ass.Src; return(true); } if (regSrc != null && regDst == Index) { Index = regSrc; return(true); } UsedAsFlag = null; return(true); } var bra = instr as Branch; if (bra != null) { var cond = bra.Condition as TestCondition; if (cond != null) { if (cond.ConditionCode == ConditionCode.UGE || cond.ConditionCode == ConditionCode.UGT || cond.ConditionCode == ConditionCode.GT) { Operations.Add(new BackwalkBranch(cond.ConditionCode)); UsedFlagIdentifier = (Identifier)cond.Expression; } } return(true); } Debug.WriteLine("Backwalking not supported: " + instr); return(true); }
public bool BackwalkInstruction(Instruction instr) { var ass = instr as Assignment; if (ass != null) { var regSrc = RegisterOf(ass.Src as Identifier); var binSrc = ass.Src as BinaryExpression; if (binSrc != null) { if (RegisterOf(ass.Dst) == Index) { regSrc = RegisterOf(binSrc.Left as Identifier); var immSrc = binSrc.Right as Constant; if (binSrc.Operator == Operator.IAdd || binSrc.Operator == Operator.ISub) { Index = HandleAddition(Index, Index, regSrc, immSrc, binSrc.Operator == Operator.IAdd); return(true); } if (binSrc.Operator == Operator.And) { if (immSrc != null && IsEvenPowerOfTwo(immSrc.ToInt32() + 1)) { Operations.Add(new BackwalkOperation(BackwalkOperator.cmp, immSrc.ToInt32() + 1)); } else { Index = null; } return(false); } if (binSrc.Operator is IMulOperator && immSrc != null) { Operations.Add(new BackwalkOperation(BackwalkOperator.mul, immSrc.ToInt32())); return(true); } } if (Index != null && binSrc.Operator == Operator.Xor && binSrc.Left == ass.Dst && binSrc.Right == ass.Dst && RegisterOf(ass.Dst) == Index.GetSubregister(8, 8)) { Operations.Add(new BackwalkOperation(BackwalkOperator.and, 0xFF)); Index = Index.GetSubregister(0, 8); } } var cof = ass.Src as ConditionOf; if (cof != null && UsedFlagIdentifier != null) { var grfDef = (ass.Dst.Storage as FlagGroupStorage).FlagGroupBits; var grfUse = (UsedFlagIdentifier.Storage as FlagGroupStorage).FlagGroupBits; if ((grfDef & grfUse) == 0) { return(true); } var binCmp = cof.Expression as BinaryExpression; if (binCmp != null && (binCmp.Operator is ISubOperator || binCmp.Operator is USubOperator)) { var idLeft = RegisterOf(binCmp.Left as Identifier); if (idLeft != null && (idLeft == Index || idLeft == Index.GetPart(PrimitiveType.Byte)) || (IndexExpression != null && IndexExpression.ToString() == idLeft.ToString())) //$HACK: sleazy, but we don't appear to have an expression comparer { var immSrc = binCmp.Right as Constant; if (immSrc != null) { Operations.Add(new BackwalkOperation(BackwalkOperator.cmp, immSrc.ToInt32())); return(false); } } } } var src = ass.Src; var castSrc = src as Cast; if (castSrc != null) { src = castSrc.Expression; } var memSrc = src as MemoryAccess; var regDst = RegisterOf(ass.Dst); if (memSrc != null && (regDst == Index || regDst.IsSubRegisterOf(Index))) { // R = Mem[xxx] var rIdx = Index; var rDst = RegisterOf(ass.Dst); if (rDst != rIdx.GetSubregister(0, 8) && castSrc == null) { Index = RegisterStorage.None; IndexExpression = src; return(true); } var binEa = memSrc.EffectiveAddress as BinaryExpression; if (binEa == null) { return(false); } var memOffset = binEa.Right as Constant; var scale = GetMultiplier(binEa.Left); var baseReg = GetBaseRegister(binEa.Left); if (memOffset != null && binEa.Operator == Operator.IAdd) { var mOff = memOffset.ToInt32(); if (mOff > 0x200) { Operations.Add(new BackwalkDereference(memOffset.ToInt32(), scale)); Index = baseReg; return(true); } } return(false); } if (regSrc != null && regDst == Index) { Index = regSrc; return(true); } return(true); } var bra = instr as Branch; if (bra != null) { var cond = bra.Condition as TestCondition; if (cond != null && cond.ConditionCode == ConditionCode.UGT) { Operations.Add(new BackwalkBranch(ConditionCode.UGT)); UsedFlagIdentifier = (Identifier)cond.Expression; } return(true); } Debug.WriteLine("Backwalking not supported: " + instr); return(true); }