Beispiel #1
0
        //
        // Emits the right opcode to load from an array
        //
        public void EmitArrayLoad(ArrayContainer ac)
        {
            if (ac.Rank > 1)
            {
                if (IsAnonymousStoreyMutateRequired)
                {
                    ac = (ArrayContainer)ac.Mutate(CurrentAnonymousMethod.Storey.Mutator);
                }

                ig.Emit(OpCodes.Call, ac.GetGetMethod());
                return;
            }


            var type = ac.Element;

            if (type.Kind == MemberKind.Enum)
            {
                type = EnumSpec.GetUnderlyingType(type);
            }

            switch (type.BuiltinType)
            {
            case BuiltinTypeSpec.Type.Bool:
            //
            // bool array can actually store any byte value in underlying byte slot
            // and C# spec does not specify any normalization rule, except the result
            // is undefined
            //
            case BuiltinTypeSpec.Type.Byte:
                ig.Emit(OpCodes.Ldelem_U1);
                break;

            case BuiltinTypeSpec.Type.SByte:
                ig.Emit(OpCodes.Ldelem_I1);
                break;

            case BuiltinTypeSpec.Type.Short:
                ig.Emit(OpCodes.Ldelem_I2);
                break;

            case BuiltinTypeSpec.Type.UShort:
            case BuiltinTypeSpec.Type.Char:
                ig.Emit(OpCodes.Ldelem_U2);
                break;

            case BuiltinTypeSpec.Type.Int:
                ig.Emit(OpCodes.Ldelem_I4);
                break;

            case BuiltinTypeSpec.Type.UInt:
                ig.Emit(OpCodes.Ldelem_U4);
                break;

            case BuiltinTypeSpec.Type.ULong:
            case BuiltinTypeSpec.Type.Long:
                ig.Emit(OpCodes.Ldelem_I8);
                break;

            case BuiltinTypeSpec.Type.Float:
                ig.Emit(OpCodes.Ldelem_R4);
                break;

            case BuiltinTypeSpec.Type.Double:
                ig.Emit(OpCodes.Ldelem_R8);
                break;

            case BuiltinTypeSpec.Type.IntPtr:
                ig.Emit(OpCodes.Ldelem_I);
                break;

            default:
                switch (type.Kind)
                {
                case MemberKind.Struct:
                    if (IsAnonymousStoreyMutateRequired)
                    {
                        type = CurrentAnonymousMethod.Storey.Mutator.Mutate(type);
                    }

                    ig.Emit(OpCodes.Ldelema, type.GetMetaInfo());
                    ig.Emit(OpCodes.Ldobj, type.GetMetaInfo());
                    break;

                case MemberKind.TypeParameter:
                    if (IsAnonymousStoreyMutateRequired)
                    {
                        type = CurrentAnonymousMethod.Storey.Mutator.Mutate(type);
                    }

                    ig.Emit(OpCodes.Ldelem, type.GetMetaInfo());
                    break;

                case MemberKind.PointerType:
                    ig.Emit(OpCodes.Ldelem_I);
                    break;

                default:
                    ig.Emit(OpCodes.Ldelem_Ref);
                    break;
                }
                break;
            }
        }
Beispiel #2
0
        //
        // Emits the right opcode to load from an array
        //
        public void EmitArrayLoad(ArrayContainer ac)
        {
            if (ac.Rank > 1)
            {
                if (IsAnonymousStoreyMutateRequired)
                {
                    ac = (ArrayContainer)ac.Mutate(CurrentAnonymousMethod.Storey.Mutator);
                }

                ig.Emit(OpCodes.Call, ac.GetGetMethod());
                return;
            }


            var type = ac.Element;

            if (type.Kind == MemberKind.Enum)
            {
                type = EnumSpec.GetUnderlyingType(type);
            }

            switch (type.BuiltinType)
            {
            case BuiltinTypeSpec.Type.Byte:
            case BuiltinTypeSpec.Type.Bool:
                ig.Emit(OpCodes.Ldelem_U1);
                break;

            case BuiltinTypeSpec.Type.SByte:
                ig.Emit(OpCodes.Ldelem_I1);
                break;

            case BuiltinTypeSpec.Type.Short:
                ig.Emit(OpCodes.Ldelem_I2);
                break;

            case BuiltinTypeSpec.Type.UShort:
            case BuiltinTypeSpec.Type.Char:
                ig.Emit(OpCodes.Ldelem_U2);
                break;

            case BuiltinTypeSpec.Type.Int:
                ig.Emit(OpCodes.Ldelem_I4);
                break;

            case BuiltinTypeSpec.Type.UInt:
                ig.Emit(OpCodes.Ldelem_U4);
                break;

            case BuiltinTypeSpec.Type.ULong:
            case BuiltinTypeSpec.Type.Long:
                ig.Emit(OpCodes.Ldelem_I8);
                break;

            case BuiltinTypeSpec.Type.Float:
                ig.Emit(OpCodes.Ldelem_R4);
                break;

            case BuiltinTypeSpec.Type.Double:
                ig.Emit(OpCodes.Ldelem_R8);
                break;

            case BuiltinTypeSpec.Type.IntPtr:
                ig.Emit(OpCodes.Ldelem_I);
                break;

            default:
                switch (type.Kind)
                {
                case MemberKind.Struct:
                    if (IsAnonymousStoreyMutateRequired)
                    {
                        type = CurrentAnonymousMethod.Storey.Mutator.Mutate(type);
                    }

                    ig.Emit(OpCodes.Ldelema, type.GetMetaInfo());
                    ig.Emit(OpCodes.Ldobj, type.GetMetaInfo());
                    break;

                case MemberKind.TypeParameter:
                    if (IsAnonymousStoreyMutateRequired)
                    {
                        type = CurrentAnonymousMethod.Storey.Mutator.Mutate(type);
                    }

                    ig.Emit(OpCodes.Ldelem, type.GetMetaInfo());
                    break;

                case MemberKind.PointerType:
                    ig.Emit(OpCodes.Ldelem_I);
                    break;

                default:
                    ig.Emit(OpCodes.Ldelem_Ref);
                    break;
                }
                break;
            }
        }
        //
        // Emits the right opcode to load from an array
        //
        public void EmitArrayLoad(ArrayContainer ac)
        {
            if (ac.Rank > 1)
            {
                if (IsAnonymousStoreyMutateRequired)
                {
                    ac = (ArrayContainer)ac.Mutate(CurrentAnonymousMethod.Storey.Mutator);
                }

                ig.Emit(OpCodes.Call, ac.GetGetMethod());
                return;
            }

            var type = ac.Element;

            if (TypeManager.IsEnumType(type))
            {
                type = EnumSpec.GetUnderlyingType(type);
            }

            if (type == TypeManager.byte_type || type == TypeManager.bool_type)
            {
                Emit(OpCodes.Ldelem_U1);
            }
            else if (type == TypeManager.sbyte_type)
            {
                Emit(OpCodes.Ldelem_I1);
            }
            else if (type == TypeManager.short_type)
            {
                Emit(OpCodes.Ldelem_I2);
            }
            else if (type == TypeManager.ushort_type || type == TypeManager.char_type)
            {
                Emit(OpCodes.Ldelem_U2);
            }
            else if (type == TypeManager.int32_type)
            {
                Emit(OpCodes.Ldelem_I4);
            }
            else if (type == TypeManager.uint32_type)
            {
                Emit(OpCodes.Ldelem_U4);
            }
            else if (type == TypeManager.uint64_type)
            {
                Emit(OpCodes.Ldelem_I8);
            }
            else if (type == TypeManager.int64_type)
            {
                Emit(OpCodes.Ldelem_I8);
            }
            else if (type == TypeManager.float_type)
            {
                Emit(OpCodes.Ldelem_R4);
            }
            else if (type == TypeManager.double_type)
            {
                Emit(OpCodes.Ldelem_R8);
            }
            else if (type == TypeManager.intptr_type)
            {
                Emit(OpCodes.Ldelem_I);
            }
            else if (TypeManager.IsStruct(type))
            {
                Emit(OpCodes.Ldelema, type);
                Emit(OpCodes.Ldobj, type);
            }
            else if (type.IsGenericParameter)
            {
                Emit(OpCodes.Ldelem, type);
            }
            else if (type.IsPointer)
            {
                Emit(OpCodes.Ldelem_I);
            }
            else
            {
                Emit(OpCodes.Ldelem_Ref);
            }
        }