Exemple #1
0
        static ILExpression DivideBySize(ILExpression expr, TypeReference type)
        {
            expr = UnwrapIntPtrCast(expr);

            ILExpression sizeOfExpression;

            switch (TypeAnalysis.GetInformationAmount(type))
            {
            case 1:
            case 8:
                sizeOfExpression = new ILExpression(ILCode.Ldc_I4, 1);
                break;

            case 16:
                sizeOfExpression = new ILExpression(ILCode.Ldc_I4, 2);
                break;

            case 32:
                sizeOfExpression = new ILExpression(ILCode.Ldc_I4, 4);
                break;

            case 64:
                sizeOfExpression = new ILExpression(ILCode.Ldc_I4, 8);
                break;

            default:
                sizeOfExpression = new ILExpression(ILCode.Sizeof, type);
                break;
            }

            if (expr.Code == ILCode.Mul || expr.Code == ILCode.Mul_Ovf || expr.Code == ILCode.Mul_Ovf_Un)
            {
                ILExpression mulArg = expr.Arguments[1];
                if (mulArg.Code == sizeOfExpression.Code && sizeOfExpression.Operand.Equals(mulArg.Operand))
                {
                    return(UnwrapIntPtrCast(expr.Arguments[0]));
                }
            }

            if (expr.Code == sizeOfExpression.Code)
            {
                if (sizeOfExpression.Operand.Equals(expr.Operand))
                {
                    return(new ILExpression(ILCode.Ldc_I4, 1));
                }

                if (expr.Code == ILCode.Ldc_I4)
                {
                    int offsetInBytes    = (int)expr.Operand;
                    int elementSize      = (int)sizeOfExpression.Operand;
                    int offsetInElements = offsetInBytes / elementSize;

                    // ensure integer division
                    if (offsetInElements * elementSize == offsetInBytes)
                    {
                        expr.Operand = offsetInElements;
                        return(expr);
                    }
                }
            }

            return(new ILExpression(ILCode.Div_Un, null, expr, sizeOfExpression));
        }