예제 #1
0
        public override void Generate(ILGenerator gen)
        {
            switch (argNum)
            {
            case 0:
                gen.Emit(OpCodes.Ldarg_0);
                break;

            case 1:
                gen.Emit(OpCodes.Ldarg_1);
                break;

            case 2:
                gen.Emit(OpCodes.Ldarg_2);
                break;

            case 3:
                gen.Emit(OpCodes.Ldarg_3);
                break;

            default:
                gen.Emit(OpCodes.Ldarg, argNum);
                break;
            }
            if (type.IsByRef)
            {
                CodeGenerationHelper.LoadFromPtr(gen, type.GetElementType());
            }
        }
예제 #2
0
        public override void Generate(ILGenerator gen)
        {
            array.Generate(gen);
            index.Generate(gen);

            Type t = array.GetResultType().GetElementType();

            if (t.IsEnum && t != typeof(Enum))
            {
                t = t.UnderlyingSystemType;
            }

            switch (Type.GetTypeCode(t))
            {
            case TypeCode.Byte:
                gen.Emit(OpCodes.Ldelem_U1);
                break;

            case TypeCode.Double:
                gen.Emit(OpCodes.Ldelem_R8);
                break;

            case TypeCode.Int16:
                gen.Emit(OpCodes.Ldelem_I2);
                break;

            case TypeCode.UInt32:
                gen.Emit(OpCodes.Ldelem_U4);
                break;

            case TypeCode.Int32:
                gen.Emit(OpCodes.Ldelem_I4);
                break;

            case TypeCode.UInt64:
            case TypeCode.Int64:
                gen.Emit(OpCodes.Ldelem_I8);
                break;

            case TypeCode.SByte:
                gen.Emit(OpCodes.Ldelem_I1);
                break;

            case TypeCode.Single:
                gen.Emit(OpCodes.Ldelem_R4);
                break;

            case TypeCode.UInt16:
                gen.Emit(OpCodes.Ldelem_U2);
                break;

            default:
                if (t.IsValueType)
                {
                    gen.Emit(OpCodes.Ldelema, t);
                    CodeGenerationHelper.LoadFromPtr(gen, t);
                }
                else
                {
                    gen.Emit(OpCodes.Ldelem_Ref);
                }
                break;
            }
        }
예제 #3
0
        public override void Generate(ILGenerator gen)
        {
            exp.Generate(gen);

            Type typeObj = exp.GetResultType();

            if (type.IsAssignableFrom(typeObj))
            {
                if (typeObj.IsValueType)
                {
                    gen.Emit(OpCodes.Box, typeObj);
                }
                return;
            }
            else if (type.IsValueType && typeObj == typeof(object))
            {
                // Unbox
                gen.Emit(OpCodes.Unbox, type);
                CodeGenerationHelper.LoadFromPtr(gen, type);
                return;
            }
            else if (typeObj.IsAssignableFrom(type))
            {
                // Sub s = (Sub)base
                gen.Emit(OpCodes.Castclass, type);
                return;
            }
            else if (CodeGenerationHelper.IsNumber(type) && CodeGenerationHelper.IsNumber(typeObj))
            {
                switch (Type.GetTypeCode(type))
                {
                case TypeCode.Byte:
                    gen.Emit(OpCodes.Conv_U1);
                    return;

                case TypeCode.Double:
                    gen.Emit(OpCodes.Conv_R8);
                    return;

                case TypeCode.Int16:
                    gen.Emit(OpCodes.Conv_I2);
                    return;

                case TypeCode.Int32:
                    gen.Emit(OpCodes.Conv_I4);
                    return;

                case TypeCode.Int64:
                    gen.Emit(OpCodes.Conv_I8);
                    return;

                case TypeCode.SByte:
                    gen.Emit(OpCodes.Conv_I1);
                    return;

                case TypeCode.Single:
                    gen.Emit(OpCodes.Conv_R4);
                    return;

                case TypeCode.UInt16:
                    gen.Emit(OpCodes.Conv_U2);
                    return;

                case TypeCode.UInt32:
                    gen.Emit(OpCodes.Conv_U4);
                    return;

                case TypeCode.UInt64:
                    gen.Emit(OpCodes.Conv_U8);
                    return;
                }
            }

            MethodInfo imp = type.GetMethod("op_Implicit", new Type[] { typeObj });

            if (imp != null)
            {
                gen.Emit(OpCodes.Call, imp);
                return;
            }

            foreach (MethodInfo m in typeObj.GetMember("op_Explicit"))
            {
                if (m.ReturnType == type)
                {
                    gen.Emit(OpCodes.Call, m);
                    return;
                }
            }

            throw new InvalidOperationException("Can't cast from " + typeObj + " to " + type);
        }