private void EmitOptimizedPower(FleeILGenerator ilg, bool emitOverflow, bool unsigned) { Int32LiteralElement right = (Int32LiteralElement)MyRightChild; if (right.Value == 0) { ilg.Emit(OpCodes.Pop); IntegralLiteralElement.EmitLoad(1, ilg); ImplicitConverter.EmitImplicitNumericConvert(typeof(Int32), MyLeftChild.ResultType, ilg); return; } if (right.Value == 1) { return; } // Start at 1 since left operand has already been emited once for (int i = 1; i <= right.Value - 1; i++) { ilg.Emit(OpCodes.Dup); } for (int i = 1; i <= right.Value - 1; i++) { this.EmitMultiply(ilg, emitOverflow, unsigned); } }
protected override System.Type GetResultType(System.Type leftType, System.Type rightType) { // Right argument (shift count) must be convertible to int32 if (ImplicitConverter.EmitImplicitNumericConvert(rightType, typeof(Int32), null) == false) { return(null); } // Left argument must be an integer type if (Utility.IsIntegralType(leftType) == false) { return(null); } TypeCode tc = Type.GetTypeCode(leftType); switch (tc) { case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: return(typeof(Int32)); case TypeCode.UInt32: return(typeof(UInt32)); case TypeCode.Int64: return(typeof(Int64)); case TypeCode.UInt64: return(typeof(UInt64)); default: Debug.Assert(false, "unknown left shift operand"); return(null); } }