protected override void TranslateToILWithDupOfThisOb(ILGenerator il) { IReflect ir = this.rootObject.InferType(null); Type tempType = Convert.ToType(ir); this.rootObject.TranslateToIL(il, tempType); if (ir == Typeob.Object || ir == Typeob.String || ir is TypedArray || (ir == tempType && Typeob.Array.IsAssignableFrom(tempType))) { tempType = Typeob.Object; this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.toObjectMethod); } il.Emit(OpCodes.Dup); this.temp = il.DeclareLocal(tempType); il.Emit(OpCodes.Stloc, temp); Convert.Emit(this, il, tempType, Typeob.Object); this.TranslateToIL(il, Typeob.Object); }
internal override void TranslateToIL(ILGenerator il, Type rtype) { //This assumes that rtype == Void.class Label loop_start = il.DefineLabel(); Label loop_end = il.DefineLabel(); Label body = il.DefineLabel(); compilerGlobals.BreakLabelStack.Push(loop_end); compilerGlobals.ContinueLabelStack.Push(loop_start); if (this.initializer != null) { this.initializer.TranslateToIL(il, Typeob.Void); } this.inExpressionContext.EmitLineInfo(il); this.collection.TranslateToIL(il, Typeob.Object); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.toForInObjectMethod); il.Emit(OpCodes.Call, CompilerGlobals.jScriptGetEnumeratorMethod); LocalBuilder enumerator = il.DeclareLocal(Typeob.IEnumerator); il.Emit(OpCodes.Stloc, enumerator); il.Emit(OpCodes.Br, loop_start); il.MarkLabel(body); this.body.TranslateToIL(il, Typeob.Void); il.MarkLabel(loop_start); this.context.EmitLineInfo(il); il.Emit(OpCodes.Ldloc, enumerator); il.Emit(OpCodes.Callvirt, CompilerGlobals.moveNextMethod); il.Emit(OpCodes.Brfalse, loop_end); il.Emit(OpCodes.Ldloc, enumerator); il.Emit(OpCodes.Callvirt, CompilerGlobals.getCurrentMethod); Type vt = Convert.ToType(this.var.InferType(null)); LocalBuilder val = il.DeclareLocal(vt); Convert.Emit(this, il, Typeob.Object, vt); il.Emit(OpCodes.Stloc, val); this.var.TranslateToILPreSet(il); il.Emit(OpCodes.Ldloc, val); this.var.TranslateToILSet(il); il.Emit(OpCodes.Br, body); il.MarkLabel(loop_end); compilerGlobals.BreakLabelStack.Pop(); compilerGlobals.ContinueLabelStack.Pop(); }
private IReflect[] ArgIRs() { int n = this.args.count; IReflect[] argIRs = new IReflect[n]; for (int i = 0; i < n; i++) { AST arg = this.args[i]; IReflect ir = argIRs[i] = arg.InferType(null); if (arg is AddressOf) { if (ir is ClassScope) { ir = ((ClassScope)ir).GetBakedSuperType(); //this should change if ever JS can declare out params } argIRs[i] = Convert.ToType("&", Convert.ToType(ir)); } } return(argIRs); }
public override String ToString() { Type elemType = this.elementType as Type; if (elemType != null) { return(elemType.FullName + TypedArray.ToRankString(this.rank)); } ClassScope csc = this.elementType as ClassScope; if (csc != null) { return(csc.GetFullName() + TypedArray.ToRankString(this.rank)); } TypedArray tarr = this.elementType as TypedArray; if (tarr != null) { return(tarr.ToString() + TypedArray.ToRankString(this.rank)); } return(Convert.ToType(this.elementType).FullName + TypedArray.ToRankString(this.rank)); }
internal override void TranslateToIL(ILGenerator il, Type rtype) { Type lhtype = Convert.ToType(this.lhside.InferType(null)); this.lhside.TranslateToILPreSet(il); if (rtype != Typeob.Void) { Type rhtype = Convert.ToType(this.rhside.InferType(null)); this.rhside.TranslateToIL(il, rhtype); LocalBuilder result = il.DeclareLocal(rhtype); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stloc, result); Convert.Emit(this, il, rhtype, lhtype); this.lhside.TranslateToILSet(il); il.Emit(OpCodes.Ldloc, result); Convert.Emit(this, il, rhtype, rtype); } else { this.lhside.TranslateToILSet(il, rhside); } }
internal override void TranslateToILCall(ILGenerator il, Type rtype, ASTList argList, bool construct, bool brackets) { if (this.defaultMember != null && construct && brackets) { base.TranslateToILCall(il, rtype, argList, construct, brackets); return; } JSGlobalField gf = this.member as JSGlobalField; if (gf != null && gf.IsLiteral && argList.count == 1) { Type t = Convert.ToType((IReflect)gf.value); argList[0].TranslateToIL(il, t); Convert.Emit(this, il, t, rtype); return; } this.TranslateToILWithDupOfThisOb(il); argList.TranslateToIL(il, typeof(Object[])); if (construct) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } if (brackets) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.callValueMethod); Convert.Emit(this, il, Typeob.Object, rtype); }
protected override void TranslateToILObject(ILGenerator il, Type obType, bool noValue) { if (noValue && obType.IsValueType && obType != Typeob.Enum) { if (this.temp == null) { this.rootObject.TranslateToILReference(il, obType); } else { Type tempType = Convert.ToType(this.rootObject.InferType(null)); if (tempType == obType) { il.Emit(OpCodes.Ldloca, this.temp); } else { il.Emit(OpCodes.Ldloc, this.temp); Convert.Emit(this, il, tempType, obType); Convert.EmitLdloca(il, obType); } } } else { if (this.temp == null || this.rootObject is ThisLiteral) { this.rootObject.TranslateToIL(il, obType); } else { il.Emit(OpCodes.Ldloc, this.temp); Type tempType = Convert.ToType(this.rootObject.InferType(null)); Convert.Emit(this, il, tempType, obType); } } }
internal override void TranslateToIL(ILGenerator il, Type rtype) { Type type = Convert.ToType(this.InferType(null)); if (this.metaData == null) { Type rt = Typeob.Object; if (rtype == Typeob.Double) { rt = rtype; } else if (this.type1 == Typeob.Char && this.type2 == Typeob.Char) { rt = Typeob.String; } else if (Convert.IsPrimitiveNumericType(rtype) && Convert.IsPromotableTo(this.type1, rtype) && Convert.IsPromotableTo(this.type2, rtype)) { rt = rtype; } else if (this.type1 != Typeob.String && this.type2 != Typeob.String) //Both will be converted to numbers { rt = Typeob.Double; //Won't get here unless InferType returned Typeob.Double. } else { rt = Typeob.String; } if (rt == Typeob.SByte || rt == Typeob.Int16) { rt = Typeob.Int32; } else if (rt == Typeob.Byte || rt == Typeob.UInt16 || rt == Typeob.Char) { rt = Typeob.UInt32; } if (rt == Typeob.String) { if (this.operand1 is Plus && this.type1 == rt) { Plus op1 = (Plus)this.operand1; if (op1.operand1 is Plus && op1.type1 == rt) { Plus op11 = (Plus)op1.operand1; if (op11.operand1 is Plus && op11.type1 == rt) { int len = op1.TranslateToILArrayOfStrings(il, 1); il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, len - 1); this.operand2.TranslateToIL(il, rt); il.Emit(OpCodes.Stelem_Ref); il.Emit(OpCodes.Call, CompilerGlobals.stringConcatArrMethod); Convert.Emit(this, il, rt, rtype); return; } Plus.TranslateToStringWithSpecialCaseForNull(il, op11.operand1); Plus.TranslateToStringWithSpecialCaseForNull(il, op11.operand2); Plus.TranslateToStringWithSpecialCaseForNull(il, op1.operand2); Plus.TranslateToStringWithSpecialCaseForNull(il, this.operand2); il.Emit(OpCodes.Call, CompilerGlobals.stringConcat4Method); Convert.Emit(this, il, rt, rtype); return; } Plus.TranslateToStringWithSpecialCaseForNull(il, op1.operand1); Plus.TranslateToStringWithSpecialCaseForNull(il, op1.operand2); Plus.TranslateToStringWithSpecialCaseForNull(il, this.operand2); il.Emit(OpCodes.Call, CompilerGlobals.stringConcat3Method); Convert.Emit(this, il, rt, rtype); return; } Plus.TranslateToStringWithSpecialCaseForNull(il, this.operand1); Plus.TranslateToStringWithSpecialCaseForNull(il, this.operand2); il.Emit(OpCodes.Call, CompilerGlobals.stringConcat2Method); Convert.Emit(this, il, rt, rtype); return; } this.operand1.TranslateToIL(il, rt); this.operand2.TranslateToIL(il, rt); if (rt == Typeob.Object) { il.Emit(OpCodes.Call, CompilerGlobals.plusDoOpMethod); } else if (rt == Typeob.Double || rt == Typeob.Single) { il.Emit(OpCodes.Add); } else if (rt == Typeob.Int32 || rt == Typeob.Int64) { il.Emit(OpCodes.Add_Ovf); } else { il.Emit(OpCodes.Add_Ovf_Un); } if (type == Typeob.Char) { Convert.Emit(this, il, rt, Typeob.Char); Convert.Emit(this, il, Typeob.Char, rtype); } else { Convert.Emit(this, il, rt, 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 //Also get here when dealing with Int64 and UInt64. These cannot always be converted to doubles. The late-bound code checks for this. il.Emit(OpCodes.Ldloc, (LocalBuilder)this.metaData); this.operand1.TranslateToIL(il, Typeob.Object); this.operand2.TranslateToIL(il, Typeob.Object); il.Emit(OpCodes.Callvirt, CompilerGlobals.evaluatePlusMethod); Convert.Emit(this, il, Typeob.Object, rtype); }
internal void TranslateToConditionalBranch(ILGenerator il, Type etype, bool branchIfTrue, Label label, bool shortForm) { Debug.PreCondition(this.case_value != null); Type t1 = etype; Type t2 = Convert.ToType(this.case_value.InferType(null)); if (t1 != t2 && t1.IsPrimitive && t2.IsPrimitive) { if (t1 == Typeob.Single && t2 == Typeob.Double) { t2 = Typeob.Single; } else if (Convert.IsPromotableTo(t2, t1)) { t2 = t1; } else if (Convert.IsPromotableTo(t1, t2)) { t1 = t2; } } bool nonPrimitive = true; if (t1 == t2 && t1 != Typeob.Object) { Convert.Emit(this, il, etype, t1); if (!t1.IsPrimitive && t1.IsValueType) { il.Emit(OpCodes.Box, t1); } this.case_value.context.EmitLineInfo(il); this.case_value.TranslateToIL(il, t1); if (t1 == Typeob.String) { il.Emit(OpCodes.Call, CompilerGlobals.stringEqualsMethod); } else if (!t1.IsPrimitive) { if (t1.IsValueType) { il.Emit(OpCodes.Box, t1); } il.Emit(OpCodes.Callvirt, CompilerGlobals.equalsMethod); } else { nonPrimitive = false; } } else { Convert.Emit(this, il, etype, Typeob.Object); this.case_value.context.EmitLineInfo(il); this.case_value.TranslateToIL(il, Typeob.Object); il.Emit(OpCodes.Call, CompilerGlobals.jScriptStrictEqualsMethod); } if (branchIfTrue) { if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brtrue_S : OpCodes.Brtrue, label); } else { il.Emit(shortForm ? OpCodes.Beq_S : OpCodes.Beq, label); } } else { if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brfalse_S : OpCodes.Brfalse, label); } else { il.Emit(shortForm ? OpCodes.Bne_Un_S : OpCodes.Bne_Un, label); } } }
private void TranslateToIL(ILGenerator il, Object val, Type rtype) { IConvertible ic = Convert.GetIConvertible(val); switch (Convert.GetTypeCode(val, ic)) { case TypeCode.Empty: il.Emit(OpCodes.Ldnull); if (rtype.IsValueType) { Convert.Emit(this, il, Typeob.Object, rtype); } return; case TypeCode.Object: break; case TypeCode.DBNull: il.Emit(OpCodes.Ldsfld, typeof(DBNull).GetField("Value")); Convert.Emit(this, il, Typeob.Null, rtype); return; case TypeCode.Boolean: ConstantWrapper.TranslateToILInt(il, ic.ToInt32(null)); Convert.Emit(this, il, Typeob.Boolean, rtype); return; case TypeCode.Char: case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: ConstantWrapper.TranslateToILInt(il, ic.ToInt32(null)); if (rtype.IsEnum) { return; } if (val is EnumWrapper) { Convert.Emit(this, il, ((EnumWrapper)val).type.GetTypeBuilderOrEnumBuilder(), rtype); } else { Convert.Emit(this, il, val.GetType(), rtype); } return; case TypeCode.UInt32: ConstantWrapper.TranslateToILInt(il, (int)ic.ToUInt32(null)); if (rtype.IsEnum) { return; } if (val is EnumWrapper) { Convert.Emit(this, il, ((EnumWrapper)val).type.GetTypeBuilderOrEnumBuilder(), rtype); } else { Convert.Emit(this, il, Typeob.UInt32, rtype); } return; case TypeCode.Int64: long l = ic.ToInt64(null); if (Int32.MinValue <= l && l <= Int32.MaxValue) { ConstantWrapper.TranslateToILInt(il, (int)l); il.Emit(OpCodes.Conv_I8); } else { il.Emit(OpCodes.Ldc_I8, l); } if (rtype.IsEnum) { return; } if (val is EnumWrapper) { Convert.Emit(this, il, ((EnumWrapper)val).type.GetTypeBuilderOrEnumBuilder(), rtype); } else { Convert.Emit(this, il, Typeob.Int64, rtype); } return; case TypeCode.UInt64: ulong ul = ic.ToUInt64(null); if (ul <= Int32.MaxValue) { ConstantWrapper.TranslateToILInt(il, (int)ul); il.Emit(OpCodes.Conv_I8); } else { il.Emit(OpCodes.Ldc_I8, (long)ul); } if (rtype.IsEnum) { return; } if (val is EnumWrapper) { Convert.Emit(this, il, ((EnumWrapper)val).type.GetTypeBuilderOrEnumBuilder(), rtype); } else { Convert.Emit(this, il, Typeob.UInt64, rtype); } return; case TypeCode.Single: float f = ic.ToSingle(null); if (f == f && (f != 0 || !Single.IsNegativeInfinity(1 / f))) { int i = (int)f; if (-128 <= i && i <= 127 && f == (float)i) { ConstantWrapper.TranslateToILInt(il, i); il.Emit(OpCodes.Conv_R4); } else { il.Emit(OpCodes.Ldc_R4, f); } } else { il.Emit(OpCodes.Ldc_R4, f); } Convert.Emit(this, il, Typeob.Single, rtype); return; case TypeCode.Double: double d = ic.ToDouble(null); if (d == d && (d != 0 || !Double.IsNegativeInfinity(1 / d))) { int i = (int)d; if (-128 <= i && i <= 127 && d == (double)i) { ConstantWrapper.TranslateToILInt(il, i); il.Emit(OpCodes.Conv_R8); } else { il.Emit(OpCodes.Ldc_R8, d); } } else { il.Emit(OpCodes.Ldc_R8, d); } Convert.Emit(this, il, Typeob.Double, rtype); return; case TypeCode.Decimal: int[] bits = Decimal.GetBits(ic.ToDecimal(null)); ConstantWrapper.TranslateToILInt(il, bits[0]); ConstantWrapper.TranslateToILInt(il, bits[1]); ConstantWrapper.TranslateToILInt(il, bits[2]); il.Emit(bits[3] < 0 ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); //bool isNegative ConstantWrapper.TranslateToILInt(il, (bits[3] & 0x7FFFFFFF) >> 16); il.Emit(OpCodes.Newobj, CompilerGlobals.decimalConstructor); Convert.Emit(this, il, Typeob.Decimal, rtype); return; case TypeCode.DateTime: l = ic.ToDateTime(null).Ticks; il.Emit(OpCodes.Ldc_I8, l); Convert.Emit(this, il, Typeob.Int64, rtype); return; case TypeCode.String: String str = ic.ToString(null); if (rtype == Typeob.Char && str.Length == 1) { ConstantWrapper.TranslateToILInt(il, (int)str[0]); return; } il.Emit(OpCodes.Ldstr, str); Convert.Emit(this, il, Typeob.String, rtype); return; } if (val is Enum) { if (rtype == Typeob.String) { this.TranslateToIL(il, val.ToString(), rtype); } else if (rtype.IsPrimitive) { this.TranslateToIL(il, System.Convert.ChangeType(val, Enum.GetUnderlyingType(val.GetType())), rtype); } else { Type et = val.GetType(); Type ut = Enum.GetUnderlyingType(et); this.TranslateToIL(il, System.Convert.ChangeType(val, ut), ut); il.Emit(OpCodes.Box, et); Convert.Emit(this, il, Typeob.Object, rtype); } return; } if (val is EnumWrapper) { if (rtype == Typeob.String) { this.TranslateToIL(il, val.ToString(), rtype); } else if (rtype.IsPrimitive) { this.TranslateToIL(il, ((EnumWrapper)val).ToNumericValue(), rtype); } else { Type et = ((EnumWrapper)val).type.owner.GetTypeBuilderOrEnumBuilder(); Type ut = ((EnumWrapper)val).value.GetType(); this.TranslateToIL(il, ((EnumWrapper)val).value, ut); il.Emit(OpCodes.Box, et); Convert.Emit(this, il, Typeob.Object, rtype); } return; } if (val is Type) { il.Emit(OpCodes.Ldtoken, (Type)val); il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod); Convert.Emit(this, il, Typeob.Type, rtype); } else if (val is Namespace) { il.Emit(OpCodes.Ldstr, ((Namespace)val).Name); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.getNamespaceMethod); Convert.Emit(this, il, typeof(Namespace), rtype); } else if (val is ClassScope) { il.Emit(OpCodes.Ldtoken, ((ClassScope)val).GetTypeBuilderOrEnumBuilder()); il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod); Convert.Emit(this, il, Typeob.Type, rtype); } else if (val is TypedArray) { il.Emit(OpCodes.Ldtoken, Convert.ToType((TypedArray)val)); il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod); Convert.Emit(this, il, Typeob.Type, rtype); } else if (val is NumberObject) { this.TranslateToIL(il, ((NumberObject)val).value, Typeob.Object); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.toObjectMethod); Convert.Emit(this, il, Typeob.NumberObject, rtype); } else if (val is StringObject) { il.Emit(OpCodes.Ldstr, ((StringObject)val).value); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.toObjectMethod); Convert.Emit(this, il, Typeob.StringObject, rtype); } else if (val is BooleanObject) { il.Emit(((BooleanObject)val).value ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); il.Emit(OpCodes.Box, Typeob.Boolean); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.toObjectMethod); Convert.Emit(this, il, Typeob.BooleanObject, rtype); } else if (val is ActiveXObjectConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("ActiveXObject").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is ArrayConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Array").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is BooleanConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Boolean").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is DateConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Date").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is EnumeratorConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Enumerator").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is ErrorConstructor) { ErrorConstructor error = (ErrorConstructor)val; if (error == ErrorConstructor.evalOb) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("EvalError").GetGetMethod()); } else if (error == ErrorConstructor.rangeOb) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("RangeError").GetGetMethod()); } else if (error == ErrorConstructor.referenceOb) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("ReferenceError").GetGetMethod()); } else if (error == ErrorConstructor.syntaxOb) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("SyntaxError").GetGetMethod()); } else if (error == ErrorConstructor.typeOb) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("TypeError").GetGetMethod()); } else if (error == ErrorConstructor.uriOb) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("URIError").GetGetMethod()); } else { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Error").GetGetMethod()); } Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is FunctionConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Function").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is MathObject) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Math").GetGetMethod()); Convert.Emit(this, il, Typeob.JSObject, rtype); } else if (val is NumberConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Number").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is ObjectConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Object").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is RegExpConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("RegExp").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is StringConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("String").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is VBArrayConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("VBArray").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is IntPtr) { il.Emit(OpCodes.Ldc_I8, (long)(IntPtr)val); il.Emit(OpCodes.Conv_I); Convert.Emit(this, il, typeof(IntPtr), rtype); } else if (val is UIntPtr) { il.Emit(OpCodes.Ldc_I8, (long)(UIntPtr)val); il.Emit(OpCodes.Conv_U); Convert.Emit(this, il, typeof(UIntPtr), rtype); } else if (val is Missing) { il.Emit(OpCodes.Ldsfld, CompilerGlobals.missingField); Convert.Emit(this, il, Typeob.Object, rtype); } else if (val is System.Reflection.Missing) { if (rtype.IsPrimitive) { this.TranslateToIL(il, Double.NaN, rtype); } else if (rtype != Typeob.Object && !rtype.IsValueType) { il.Emit(OpCodes.Ldnull); } else { il.Emit(OpCodes.Ldsfld, CompilerGlobals.systemReflectionMissingField); Convert.Emit(this, il, Typeob.Object, rtype); } } else if (val != this.value) //Value was coerced to some type we have no compile time knowlegde of { this.TranslateToIL(il, this.value, rtype); } else { throw new JScriptException(JSError.InternalError, this.context); //It should not be possible to wrap any other kind of object } }
internal Type ToType() { Type elemType = Convert.ToType(this.elementType); return(Convert.ToType(TypedArray.ToRankString(this.rank), elemType)); }
internal override void TranslateToIL(ILGenerator il, Type rtype) { if (this.metaData == null) { TranslateToILForNoOverloadCase(il, rtype); return; } if (this.metaData is MethodInfo) { Object result = null; Type type = Convert.ToType(this.operand.InferType(null)); this.operand.TranslateToILPreSetPlusGet(il); if (rtype != Typeob.Void) { result = il.DeclareLocal(rtype); if (this.operatorTok == PostOrPrefix.PostfixDecrement || this.operatorTok == PostOrPrefix.PostfixIncrement) { il.Emit(OpCodes.Dup); Convert.Emit(this, il, type, rtype); il.Emit(OpCodes.Stloc, (LocalBuilder)result); } } MethodInfo oper = (MethodInfo)this.metaData; ParameterInfo[] pars = oper.GetParameters(); Convert.Emit(this, il, type, pars[0].ParameterType); il.Emit(OpCodes.Call, oper); if (rtype != Typeob.Void) { if (this.operatorTok == PostOrPrefix.PrefixDecrement || this.operatorTok == PostOrPrefix.PrefixIncrement) { il.Emit(OpCodes.Dup); Convert.Emit(this, il, type, rtype); il.Emit(OpCodes.Stloc, (LocalBuilder)result); } } Convert.Emit(this, il, oper.ReturnType, type); this.operand.TranslateToILSet(il); if (rtype != Typeob.Void) { il.Emit(OpCodes.Ldloc, (LocalBuilder)result); } } else { //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 Type type = Convert.ToType(this.operand.InferType(null)); LocalBuilder result = il.DeclareLocal(Typeob.Object); this.operand.TranslateToILPreSetPlusGet(il); Convert.Emit(this, il, type, Typeob.Object); il.Emit(OpCodes.Stloc, result); il.Emit(OpCodes.Ldloc, (LocalBuilder)this.metaData); il.Emit(OpCodes.Ldloca, result); il.Emit(OpCodes.Call, CompilerGlobals.evaluatePostOrPrefixOperatorMethod); if (rtype != Typeob.Void) { if (this.operatorTok == PostOrPrefix.PrefixDecrement || this.operatorTok == PostOrPrefix.PrefixIncrement) { il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stloc, result); } } Convert.Emit(this, il, Typeob.Object, type); this.operand.TranslateToILSet(il); if (rtype != Typeob.Void) { il.Emit(OpCodes.Ldloc, result); Convert.Emit(this, il, Typeob.Object, rtype); } } }
internal void TranslateToILSet(ILGenerator il, bool doBoth, AST rhvalue) { if (this.isFullyResolved) { base.TranslateToILSet(il, rhvalue); return; } if (rhvalue != null) { rhvalue.TranslateToIL(il, Typeob.Object); } if (this.fieldLoc == null) { //There is a callable value plus parameters on the stack il.Emit(OpCodes.Call, CompilerGlobals.setIndexedPropertyValueStaticMethod); return; } LocalBuilder temp = il.DeclareLocal(Typeob.Object); if (doBoth) { //save copy of rh value il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stloc, temp); //store it in early bound location this.isFullyResolved = true; Convert.Emit(this, il, Typeob.Object, Convert.ToType(this.InferType(null))); base.TranslateToILSet(il, null); } //See if there is a late bound field Label earlyBound = il.DefineLabel(); il.Emit(OpCodes.Ldloc, this.fieldLoc); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Beq_S, earlyBound); //No late bound field //store it in the late bound field Label done = il.DefineLabel(); if (!doBoth) { il.Emit(OpCodes.Stloc, temp); if (this.thereIsAnObjectOnTheStack) { il.Emit(OpCodes.Pop); } } il.Emit(OpCodes.Ldloc, this.fieldLoc); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ldloc, temp); il.Emit(OpCodes.Callvirt, CompilerGlobals.setFieldValueMethod); il.Emit(OpCodes.Br_S, done); //Alternative store it in the early bound location il.MarkLabel(earlyBound); if (!doBoth) { this.isFullyResolved = true; Convert.Emit(this, il, Typeob.Object, Convert.ToType(this.InferType(null))); base.TranslateToILSet(il, null); } il.MarkLabel(done); }
internal override void TranslateToConditionalBranch(ILGenerator il, bool branchIfTrue, Label label, bool shortForm) { Type t1 = Convert.ToType(this.operand1.InferType(null)); Type t2 = Convert.ToType(this.operand2.InferType(null)); if (this.operand1 is ConstantWrapper) { if (this.operand1.Evaluate() == null) { t1 = Typeob.Empty; } } if (this.operand2 is ConstantWrapper) { if (this.operand2.Evaluate() == null) { t2 = Typeob.Empty; } } if (t1 != t2 && t1.IsPrimitive && t2.IsPrimitive) { if (t1 == Typeob.Single) { t2 = t1; } else if (t2 == Typeob.Single) { t1 = t2; } else if (Convert.IsPromotableTo(t2, t1)) { t2 = t1; } else if (Convert.IsPromotableTo(t1, t2)) { t1 = t2; } } bool nonPrimitive = true; if (t1 == t2 && t1 != Typeob.Object) { // Operand types are equal and not Object - need to compare values only. Primitive // values get compared with IL instructions; other values including value types // get compared with Object.Equals. String is special cased for perf. Type t = t1; if (!t1.IsPrimitive) { t = Typeob.Object; } this.operand1.TranslateToIL(il, t); this.operand2.TranslateToIL(il, t); if (t1 == Typeob.String) { il.Emit(OpCodes.Call, CompilerGlobals.stringEqualsMethod); } else if (!t1.IsPrimitive) { il.Emit(OpCodes.Callvirt, CompilerGlobals.equalsMethod); } else { nonPrimitive = false; } } else if (t1 == Typeob.Empty) { this.operand2.TranslateToIL(il, Typeob.Object); branchIfTrue = !branchIfTrue; } else if (t2 == Typeob.Empty) { this.operand1.TranslateToIL(il, Typeob.Object); branchIfTrue = !branchIfTrue; } else { this.operand1.TranslateToIL(il, Typeob.Object); this.operand2.TranslateToIL(il, Typeob.Object); il.Emit(OpCodes.Call, CompilerGlobals.jScriptStrictEqualsMethod); } if (branchIfTrue) { if (this.operatorTok == JSToken.StrictEqual) { if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brtrue_S : OpCodes.Brtrue, label); } else { il.Emit(shortForm ? OpCodes.Beq_S : OpCodes.Beq, label); } } else if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brfalse_S : OpCodes.Brfalse, label); } else { il.Emit(shortForm ? OpCodes.Bne_Un_S : OpCodes.Bne_Un, label); } } else { if (this.operatorTok == JSToken.StrictEqual) { if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brfalse_S : OpCodes.Brfalse, label); } else { il.Emit(shortForm ? OpCodes.Bne_Un_S : OpCodes.Bne_Un, label); } } else if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brtrue_S : OpCodes.Brtrue, label); } else { il.Emit(shortForm ? OpCodes.Beq_S : OpCodes.Beq, label); } } return; }
private void TranslateToILForNoOverloadCase(ILGenerator il, Type rtype) { Type lhtype = Convert.ToType(this.operand1.InferType(null)); Type rhtype = Convert.ToType(this.operand2.InferType(null)); Type rt = Typeob.Double; if (this.operatorTok != JSToken.Divide && (rtype == Typeob.Void || rtype == lhtype || Convert.IsPrimitiveNumericType(lhtype)) && (Convert.IsPromotableTo(rhtype, lhtype) || ((this.operand2 is ConstantWrapper) && ((ConstantWrapper)this.operand2).IsAssignableTo(lhtype)))) { rt = lhtype; } if (rt == Typeob.SByte || rt == Typeob.Int16) { rt = Typeob.Int32; } else if (rt == Typeob.Byte || rt == Typeob.UInt16 || rt == Typeob.Char) { rt = Typeob.UInt32; } // If we have "unsigned -= signed" or "signed -= unsigned" then generating the // correct code gets quite complicated. Just go late-bound for this edge case. if (this.operand2 is ConstantWrapper) { if (!((ConstantWrapper)this.operand2).IsAssignableTo(rt)) { // eg: "var u : byte = 123; u -= -100;" should go late bound because // of signed/unsigned mismatch but "u -= 1" should not. rt = Typeob.Object; } } else { if ((Convert.IsPrimitiveSignedNumericType(rhtype) && Convert.IsPrimitiveUnsignedIntegerType(lhtype)) || (Convert.IsPrimitiveUnsignedIntegerType(rhtype) && Convert.IsPrimitiveSignedIntegerType(lhtype))) { rt = Typeob.Object; } } this.operand1.TranslateToILPreSetPlusGet(il); Convert.Emit(this, il, lhtype, rt); this.operand2.TranslateToIL(il, rt); if (rt == Typeob.Object) { il.Emit(OpCodes.Ldc_I4, (int)this.operatorTok); il.Emit(OpCodes.Call, CompilerGlobals.numericbinaryDoOpMethod); } else if (rt == Typeob.Double || rt == Typeob.Single) { switch (this.operatorTok) { case JSToken.Divide: il.Emit(OpCodes.Div); break; case JSToken.Minus: il.Emit(OpCodes.Sub); break; case JSToken.Modulo: il.Emit(OpCodes.Rem); break; case JSToken.Multiply: il.Emit(OpCodes.Mul); break; default: throw new JScriptException(JSError.InternalError, this.context); } } else if (rt == Typeob.Int32 || rt == Typeob.Int64 || rt == Typeob.Int16 || rt == Typeob.SByte) { switch (this.operatorTok) { case JSToken.Divide: il.Emit(OpCodes.Div); break; case JSToken.Minus: il.Emit(OpCodes.Sub_Ovf); break; case JSToken.Modulo: il.Emit(OpCodes.Rem); break; case JSToken.Multiply: il.Emit(OpCodes.Mul_Ovf); break; default: throw new JScriptException(JSError.InternalError, this.context); } } else { switch (this.operatorTok) { case JSToken.Divide: il.Emit(OpCodes.Div); break; case JSToken.Minus: il.Emit(OpCodes.Sub_Ovf_Un); break; case JSToken.Modulo: il.Emit(OpCodes.Rem); break; case JSToken.Multiply: il.Emit(OpCodes.Mul_Ovf_Un); break; default: throw new JScriptException(JSError.InternalError, this.context); } } if (rtype != Typeob.Void) { LocalBuilder result = il.DeclareLocal(rt); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stloc, result); Convert.Emit(this, il, rt, lhtype); this.operand1.TranslateToILSet(il); il.Emit(OpCodes.Ldloc, result); Convert.Emit(this, il, rt, rtype); } else { Convert.Emit(this, il, rt, lhtype); this.operand1.TranslateToILSet(il); } }
internal override void TranslateToConditionalBranch(ILGenerator il, bool branchIfTrue, Label label, bool shortForm) { Type t1 = Convert.ToType(this.operand1.InferType(null)); Type t2 = Convert.ToType(this.operand2.InferType(null)); if (this.operand1 is ConstantWrapper) { if (this.operand1.Evaluate() == null) { t1 = Typeob.Empty; } } if (this.operand2 is ConstantWrapper) { if (this.operand2.Evaluate() == null) { t2 = Typeob.Empty; } } if (t1 != t2 && t1.IsPrimitive && t2.IsPrimitive) { if (t1 == Typeob.Single) { t2 = t1; } else if (t2 == Typeob.Single) { t1 = t2; } else if (Convert.IsPromotableTo(t2, t1)) { t2 = t1; } else if (Convert.IsPromotableTo(t1, t2)) { t1 = t2; } } bool nonPrimitive = true; if (t1 == t2 && t1 != Typeob.Object) { this.operand1.TranslateToIL(il, t1); if (!t1.IsPrimitive && t1.IsValueType) { Convert.EmitLdloca(il, t1); } this.operand2.TranslateToIL(il, t1); if (t1 == Typeob.String) { il.Emit(OpCodes.Call, CompilerGlobals.stringEqualsMethod); } else if (!t1.IsPrimitive) { il.Emit(OpCodes.Callvirt, CompilerGlobals.equalsMethod); } else { nonPrimitive = false; } } else if (t1 == Typeob.Empty) { this.operand2.TranslateToIL(il, Typeob.Object); branchIfTrue = !branchIfTrue; } else if (t2 == Typeob.Empty) { this.operand1.TranslateToIL(il, Typeob.Object); branchIfTrue = !branchIfTrue; } else { this.operand1.TranslateToIL(il, Typeob.Object); this.operand2.TranslateToIL(il, Typeob.Object); il.Emit(OpCodes.Call, CompilerGlobals.jScriptStrictEqualsMethod); } if (branchIfTrue) { if (this.operatorTok == JSToken.StrictEqual) { if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brtrue_S : OpCodes.Brtrue, label); } else { il.Emit(shortForm ? OpCodes.Beq_S : OpCodes.Beq, label); } } else if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brfalse_S : OpCodes.Brfalse, label); } else { il.Emit(shortForm ? OpCodes.Bne_Un_S : OpCodes.Bne_Un, label); } } else { if (this.operatorTok == JSToken.StrictEqual) { if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brfalse_S : OpCodes.Brfalse, label); } else { il.Emit(shortForm ? OpCodes.Bne_Un_S : OpCodes.Bne_Un, label); } } else if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brtrue_S : OpCodes.Brtrue, label); } else { il.Emit(shortForm ? OpCodes.Beq_S : OpCodes.Beq, label); } } return; }
internal override void TranslateToIL(ILGenerator il, Type rtype) { if (this.metaData == null) { Type rt = Typeob.Double; if (Convert.IsPrimitiveNumericType(rtype) && Convert.IsPromotableTo(this.type1, rtype) && Convert.IsPromotableTo(this.type2, rtype)) { rt = rtype; } if (this.operatorTok == JSToken.Divide) { rt = Typeob.Double; } else if (rt == Typeob.SByte || rt == Typeob.Int16) { rt = Typeob.Int32; } else if (rt == Typeob.Byte || rt == Typeob.UInt16 || rt == Typeob.Char) { rt = Typeob.UInt32; } this.operand1.TranslateToIL(il, rt); this.operand2.TranslateToIL(il, rt); if (rt == Typeob.Double || rt == Typeob.Single) { switch (this.operatorTok) { case JSToken.Divide: il.Emit(OpCodes.Div); break; case JSToken.Minus: il.Emit(OpCodes.Sub); break; case JSToken.Modulo: il.Emit(OpCodes.Rem); break; case JSToken.Multiply: il.Emit(OpCodes.Mul); break; default: throw new JScriptException(JSError.InternalError, this.context); } } else if (rt == Typeob.Int32 || rt == Typeob.Int64) { switch (this.operatorTok) { case JSToken.Divide: il.Emit(OpCodes.Div); break; case JSToken.Minus: il.Emit(OpCodes.Sub_Ovf); break; case JSToken.Modulo: il.Emit(OpCodes.Rem); break; case JSToken.Multiply: il.Emit(OpCodes.Mul_Ovf); break; default: throw new JScriptException(JSError.InternalError, this.context); } } else { switch (this.operatorTok) { case JSToken.Divide: il.Emit(OpCodes.Div); break; case JSToken.Minus: il.Emit(OpCodes.Sub_Ovf_Un); break; case JSToken.Modulo: il.Emit(OpCodes.Rem); break; case JSToken.Multiply: il.Emit(OpCodes.Mul_Ovf_Un); break; default: throw new JScriptException(JSError.InternalError, this.context); } } if (Convert.ToType(this.InferType(null)) == Typeob.Char) { Convert.Emit(this, il, rt, Typeob.Char); Convert.Emit(this, il, Typeob.Char, rtype); } else { Convert.Emit(this, il, rt, 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.evaluateNumericBinaryMethod); Convert.Emit(this, il, Typeob.Object, rtype); }
private void TranslateToILForNoOverloadCase(ILGenerator il, Type rtype) { Type lhtype = Convert.ToType(this.operand1.InferType(null)); Type rhtype = Convert.ToType(this.operand2.InferType(null)); Type rt = Typeob.Object; if (lhtype == Typeob.String || rhtype == Typeob.String) { rt = Typeob.String; } else if (rtype == Typeob.Void || rtype == lhtype || Convert.IsPrimitiveNumericType(lhtype) && (Convert.IsPromotableTo(rhtype, lhtype) || ((this.operand2 is ConstantWrapper) && ((ConstantWrapper)this.operand2).IsAssignableTo(lhtype)))) { rt = lhtype; } if (rt == Typeob.SByte || rt == Typeob.Int16) { rt = Typeob.Int32; } else if (rt == Typeob.Byte || rt == Typeob.UInt16) { rt = Typeob.UInt32; } // If we have "unsigned += signed" or "signed += unsigned" then generating the // correct code gets quite complicated. Just go late-bound for this edge case. if (this.operand2 is ConstantWrapper) { if (!((ConstantWrapper)this.operand2).IsAssignableTo(rt)) { // eg: "var u : byte = 123; u += -100;" should go late bound because // of signed/unsigned mismatch but "u += 1" should not. rt = Typeob.Object; } } else { if ((Convert.IsPrimitiveSignedNumericType(rhtype) && Convert.IsPrimitiveUnsignedIntegerType(lhtype)) || (Convert.IsPrimitiveUnsignedIntegerType(rhtype) && Convert.IsPrimitiveSignedIntegerType(lhtype))) { rt = Typeob.Object; } } this.operand1.TranslateToILPreSetPlusGet(il); Convert.Emit(this, il, lhtype, rt); this.operand2.TranslateToIL(il, rt); if (rt == Typeob.Object || rt == Typeob.String) { il.Emit(OpCodes.Call, CompilerGlobals.plusDoOpMethod); rt = Typeob.Object; } else if (rt == Typeob.Double || rt == Typeob.Single) { il.Emit(OpCodes.Add); } else if (rt == Typeob.Int32 || rt == Typeob.Int64 || rt == Typeob.Int16 || rt == Typeob.SByte) { il.Emit(OpCodes.Add_Ovf); } else { il.Emit(OpCodes.Add_Ovf_Un); } if (rtype != Typeob.Void) { LocalBuilder result = il.DeclareLocal(rt); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stloc, result); Convert.Emit(this, il, rt, lhtype); this.operand1.TranslateToILSet(il); il.Emit(OpCodes.Ldloc, result); Convert.Emit(this, il, rt, rtype); } else { Convert.Emit(this, il, rt, lhtype); this.operand1.TranslateToILSet(il); } }
private void TranslateToILForNoOverloadCase(ILGenerator il, Type rtype) { Type type = Convert.ToType(this.operand.InferType(null)); this.operand.TranslateToILPreSetPlusGet(il); if (rtype == Typeob.Void) { Type rt = Typeob.Double; if (Convert.IsPrimitiveNumericType(type)) { if (type == Typeob.SByte || type == Typeob.Int16) { rt = Typeob.Int32; } else if (type == Typeob.Byte || type == Typeob.UInt16 || type == Typeob.Char) { rt = Typeob.UInt32; } else { rt = type; } } Convert.Emit(this, il, type, rt); il.Emit(OpCodes.Ldc_I4_1); Convert.Emit(this, il, Typeob.Int32, rt); if (rt == Typeob.Double || rt == Typeob.Single) { if (this.operatorTok == PostOrPrefix.PostfixDecrement || this.operatorTok == PostOrPrefix.PrefixDecrement) { il.Emit(OpCodes.Sub); } else { il.Emit(OpCodes.Add); } } else if (rt == Typeob.Int32 || rt == Typeob.Int64) { if (this.operatorTok == PostOrPrefix.PostfixDecrement || this.operatorTok == PostOrPrefix.PrefixDecrement) { il.Emit(OpCodes.Sub_Ovf); } else { il.Emit(OpCodes.Add_Ovf); } } else { if (this.operatorTok == PostOrPrefix.PostfixDecrement || this.operatorTok == PostOrPrefix.PrefixDecrement) { il.Emit(OpCodes.Sub_Ovf_Un); } else { il.Emit(OpCodes.Add_Ovf_Un); } } Convert.Emit(this, il, rt, type); this.operand.TranslateToILSet(il); } else { //set rt to be the smallest type that is precise enough for the result and the variable Type rt = Typeob.Double; if (Convert.IsPrimitiveNumericType(rtype) && Convert.IsPromotableTo(type, rtype)) { rt = rtype; } else if (Convert.IsPrimitiveNumericType(type) && Convert.IsPromotableTo(rtype, type)) { rt = type; } if (rt == Typeob.SByte || rt == Typeob.Int16) { rt = Typeob.Int32; } else if (rt == Typeob.Byte || rt == Typeob.UInt16 || rt == Typeob.Char) { rt = Typeob.UInt32; } LocalBuilder result = il.DeclareLocal(rtype); Convert.Emit(this, il, type, rt); if (this.operatorTok == PostOrPrefix.PostfixDecrement) { il.Emit(OpCodes.Dup); if (type == Typeob.Char) { Convert.Emit(this, il, rt, Typeob.Char); Convert.Emit(this, il, Typeob.Char, rtype); } else { Convert.Emit(this, il, rt, rtype); } il.Emit(OpCodes.Stloc, result); il.Emit(OpCodes.Ldc_I4_1); Convert.Emit(this, il, Typeob.Int32, rt); if (rt == Typeob.Double || rt == Typeob.Single) { il.Emit(OpCodes.Sub); } else if (rt == Typeob.Int32 || rt == Typeob.Int64) { il.Emit(OpCodes.Sub_Ovf); } else { il.Emit(OpCodes.Sub_Ovf_Un); } } else if (this.operatorTok == PostOrPrefix.PostfixIncrement) { il.Emit(OpCodes.Dup); if (type == Typeob.Char) { Convert.Emit(this, il, rt, Typeob.Char); Convert.Emit(this, il, Typeob.Char, rtype); } else { Convert.Emit(this, il, rt, rtype); } il.Emit(OpCodes.Stloc, result); il.Emit(OpCodes.Ldc_I4_1); Convert.Emit(this, il, Typeob.Int32, rt); if (rt == Typeob.Double || rt == Typeob.Single) { il.Emit(OpCodes.Add); } else if (rt == Typeob.Int32 || rt == Typeob.Int64) { il.Emit(OpCodes.Add_Ovf); } else { il.Emit(OpCodes.Add_Ovf_Un); } } else if (this.operatorTok == PostOrPrefix.PrefixDecrement) { il.Emit(OpCodes.Ldc_I4_1); Convert.Emit(this, il, Typeob.Int32, rt); if (rt == Typeob.Double || rt == Typeob.Single) { il.Emit(OpCodes.Sub); } else if (rt == Typeob.Int32 || rt == Typeob.Int64) { il.Emit(OpCodes.Sub_Ovf); } else { il.Emit(OpCodes.Sub_Ovf_Un); } il.Emit(OpCodes.Dup); if (type == Typeob.Char) { Convert.Emit(this, il, rt, Typeob.Char); Convert.Emit(this, il, Typeob.Char, rtype); } else { Convert.Emit(this, il, rt, rtype); } il.Emit(OpCodes.Stloc, result); } else //if (this.operatorTok == PostOrPrefix.PrefixIncrement) { il.Emit(OpCodes.Ldc_I4_1); Convert.Emit(this, il, Typeob.Int32, rt); if (rt == Typeob.Double || rt == Typeob.Single) { il.Emit(OpCodes.Add); } else if (rt == Typeob.Int32 || rt == Typeob.Int64) { il.Emit(OpCodes.Add_Ovf); } else { il.Emit(OpCodes.Add_Ovf_Un); } il.Emit(OpCodes.Dup); if (type == Typeob.Char) { Convert.Emit(this, il, rt, Typeob.Char); Convert.Emit(this, il, Typeob.Char, rtype); } else { Convert.Emit(this, il, rt, rtype); } il.Emit(OpCodes.Stloc, result); } Convert.Emit(this, il, rt, type); this.operand.TranslateToILSet(il); il.Emit(OpCodes.Ldloc, result); } }