private void TranslateToILForNoOverloadCase(ILGenerator il, Type rtype) { Type lhtype = Convert.ToType(this.operand1.InferType(null)); Type operand2type = Convert.ToType(this.operand2.InferType(null)); Type bbrType = BitwiseBinary.ResultType(lhtype, operand2type, this.operatorTok); this.operand1.TranslateToILPreSetPlusGet(il); Convert.Emit(this, il, lhtype, bbrType, true); this.operand2.TranslateToIL(il, operand2type); Convert.Emit(this, il, operand2type, BitwiseBinary.Operand2Type(this.operatorTok, bbrType), true); switch (this.operatorTok) { case JSToken.BitwiseAnd: il.Emit(OpCodes.And); break; case JSToken.BitwiseOr: il.Emit(OpCodes.Or); break; case JSToken.BitwiseXor: il.Emit(OpCodes.Xor); break; case JSToken.LeftShift: BitwiseBinary.TranslateToBitCountMask(il, bbrType, this.operand2); il.Emit(OpCodes.Shl); break; case JSToken.RightShift: BitwiseBinary.TranslateToBitCountMask(il, bbrType, this.operand2); il.Emit(OpCodes.Shr); break; case JSToken.UnsignedRightShift: BitwiseBinary.TranslateToBitCountMask(il, bbrType, this.operand2); il.Emit(OpCodes.Shr_Un); break; default: throw new JScriptException(JSError.InternalError, this.context); } if (rtype != Typeob.Void) { LocalBuilder result = il.DeclareLocal(bbrType); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stloc, result); Convert.Emit(this, il, bbrType, lhtype); this.operand1.TranslateToILSet(il); il.Emit(OpCodes.Ldloc, result); Convert.Emit(this, il, bbrType, rtype); } else { Convert.Emit(this, il, bbrType, lhtype); this.operand1.TranslateToILSet(il); } }
private void TranslateToILForNoOverloadCase(ILGenerator il, Type rtype) { Type type = Microsoft.JScript.Convert.ToType(base.operand1.InferType(null)); Type type2 = Microsoft.JScript.Convert.ToType(base.operand2.InferType(null)); Type type3 = BitwiseBinary.ResultType(type, type2, base.operatorTok); base.operand1.TranslateToILPreSetPlusGet(il); Microsoft.JScript.Convert.Emit(this, il, type, type3, true); base.operand2.TranslateToIL(il, type2); Microsoft.JScript.Convert.Emit(this, il, type2, BitwiseBinary.Operand2Type(base.operatorTok, type3), true); switch (base.operatorTok) { case JSToken.BitwiseOr: il.Emit(OpCodes.Or); break; case JSToken.BitwiseXor: il.Emit(OpCodes.Xor); break; case JSToken.BitwiseAnd: il.Emit(OpCodes.And); break; case JSToken.LeftShift: BitwiseBinary.TranslateToBitCountMask(il, type3, base.operand2); il.Emit(OpCodes.Shl); break; case JSToken.RightShift: BitwiseBinary.TranslateToBitCountMask(il, type3, base.operand2); il.Emit(OpCodes.Shr); break; case JSToken.UnsignedRightShift: BitwiseBinary.TranslateToBitCountMask(il, type3, base.operand2); il.Emit(OpCodes.Shr_Un); break; default: throw new JScriptException(JSError.InternalError, base.context); } if (rtype != Typeob.Void) { LocalBuilder local = il.DeclareLocal(type3); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stloc, local); Microsoft.JScript.Convert.Emit(this, il, type3, type); base.operand1.TranslateToILSet(il); il.Emit(OpCodes.Ldloc, local); Microsoft.JScript.Convert.Emit(this, il, type3, rtype); } else { Microsoft.JScript.Convert.Emit(this, il, type3, type); base.operand1.TranslateToILSet(il); } }
internal override IReflect InferType(JSField inference_target) { MethodInfo oper; if (this.type1 == null || inference_target != null) { oper = this.GetOperator(this.operand1.InferType(inference_target), this.operand2.InferType(inference_target)); } else { oper = this.GetOperator(this.type1, this.type2); } if (oper != null) { this.metaData = oper; return(oper.ReturnType); } return(BitwiseBinary.ResultType(this.type1, this.type2, this.operatorTok)); }
internal override void TranslateToIL(ILGenerator il, Type rtype) { if (this.metaData == null) { Type bbrType = BitwiseBinary.ResultType(this.type1, this.type2, this.operatorTok); if (Convert.IsPrimitiveNumericType(this.type1)) { this.operand1.TranslateToIL(il, this.type1); Convert.Emit(this, il, this.type1, bbrType, true); } else { this.operand1.TranslateToIL(il, Typeob.Double); Convert.Emit(this, il, Typeob.Double, bbrType, true); } Type op2type = BitwiseBinary.Operand2Type(this.operatorTok, bbrType); if (Convert.IsPrimitiveNumericType(this.type2)) { this.operand2.TranslateToIL(il, this.type2); Convert.Emit(this, il, this.type2, op2type, true); } else { this.operand2.TranslateToIL(il, Typeob.Double); Convert.Emit(this, il, Typeob.Double, op2type, true); } switch (this.operatorTok) { case JSToken.BitwiseAnd: il.Emit(OpCodes.And); break; case JSToken.BitwiseOr: il.Emit(OpCodes.Or); break; case JSToken.BitwiseXor: il.Emit(OpCodes.Xor); break; case JSToken.LeftShift: BitwiseBinary.TranslateToBitCountMask(il, bbrType, this.operand2); il.Emit(OpCodes.Shl); break; case JSToken.RightShift: BitwiseBinary.TranslateToBitCountMask(il, bbrType, this.operand2); il.Emit(OpCodes.Shr); break; case JSToken.UnsignedRightShift: BitwiseBinary.TranslateToBitCountMask(il, bbrType, this.operand2); il.Emit(OpCodes.Shr_Un); break; default: throw new JScriptException(JSError.InternalError, this.context); } Convert.Emit(this, il, bbrType, rtype); return; } if (this.metaData is MethodInfo) { MethodInfo oper = (MethodInfo)this.metaData; ParameterInfo[] pars = oper.GetParameters(); this.operand1.TranslateToIL(il, pars[0].ParameterType); this.operand2.TranslateToIL(il, pars[1].ParameterType); il.Emit(OpCodes.Call, oper); Convert.Emit(this, il, oper.ReturnType, rtype); return; } //Getting here is just too bad. We do not know until the code runs whether or not to call an overloaded operator method. //Compile operands to objects and devolve the decision making to run time thunks il.Emit(OpCodes.Ldloc, (LocalBuilder)this.metaData); this.operand1.TranslateToIL(il, Typeob.Object); this.operand2.TranslateToIL(il, Typeob.Object); il.Emit(OpCodes.Call, CompilerGlobals.evaluateBitwiseBinaryMethod); Convert.Emit(this, il, Typeob.Object, rtype); }