ToType() static private method

static private ToType ( IReflect ir ) : Type
ir IReflect
return System.Type
コード例 #1
0
ファイル: member.cs プロジェクト: ydunk/masters
        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);
        }
コード例 #2
0
        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();
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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));
        }
コード例 #5
0
        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);
            }
        }
コード例 #6
0
ファイル: callableexpression.cs プロジェクト: ydunk/masters
        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);
        }
コード例 #7
0
 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);
         }
     }
 }
コード例 #8
0
        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);
        }
コード例 #9
0
ファイル: switchcase.cs プロジェクト: SSCLI/sscli_20021101
        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);
                }
            }
        }
コード例 #10
0
        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
            }
        }
コード例 #11
0
        internal Type ToType()
        {
            Type elemType = Convert.ToType(this.elementType);

            return(Convert.ToType(TypedArray.ToRankString(this.rank), elemType));
        }
コード例 #12
0
ファイル: postorprefixoperator.cs プロジェクト: ydunk/masters
 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);
         }
     }
 }
コード例 #13
0
ファイル: lookup.cs プロジェクト: blancosj/dodonet-framework
        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);
        }
コード例 #14
0
        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;
        }
コード例 #15
0
        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);
            }
        }
コード例 #16
0
ファイル: strictequality.cs プロジェクト: ydunk/masters
        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;
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        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);
            }
        }
コード例 #19
0
ファイル: postorprefixoperator.cs プロジェクト: ydunk/masters
        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);
            }
        }