public void EmitArrayAddress(ArrayContainer ac) { if (ac.Rank > 1) { if (IsAnonymousStoreyMutateRequired) { ac = (ArrayContainer)ac.Mutate(CurrentAnonymousMethod.Storey.Mutator); } ig.Emit(OpCodes.Call, ac.GetAddressMethod()); } else { var type = IsAnonymousStoreyMutateRequired ? CurrentAnonymousMethod.Storey.Mutator.Mutate(ac.Element) : ac.Element; ig.Emit(OpCodes.Ldelema, type.GetMetaInfo()); } }
public void EmitArrayNew(ArrayContainer ac) { if (ac.Rank == 1) { var type = IsAnonymousStoreyMutateRequired ? CurrentAnonymousMethod.Storey.Mutator.Mutate(ac.Element) : ac.Element; ig.Emit(OpCodes.Newarr, type.GetMetaInfo()); } else { if (IsAnonymousStoreyMutateRequired) { ac = (ArrayContainer)ac.Mutate(CurrentAnonymousMethod.Storey.Mutator); } ig.Emit(OpCodes.Newobj, ac.GetConstructor()); } }
// // Emits the right opcode to store to an array // public void EmitArrayStore (ArrayContainer ac) { if (ac.Rank > 1) { if (IsAnonymousStoreyMutateRequired) ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator); ig.Emit (OpCodes.Call, ac.GetSetMethod ()); return; } var type = ac.Element; if (type.Kind == MemberKind.Enum) type = EnumSpec.GetUnderlyingType (type); switch (type.BuiltinType) { case BuiltinTypeSpec.Type.Byte: case BuiltinTypeSpec.Type.SByte: case BuiltinTypeSpec.Type.Bool: Emit (OpCodes.Stelem_I1); return; case BuiltinTypeSpec.Type.Short: case BuiltinTypeSpec.Type.UShort: case BuiltinTypeSpec.Type.Char: Emit (OpCodes.Stelem_I2); return; case BuiltinTypeSpec.Type.Int: case BuiltinTypeSpec.Type.UInt: Emit (OpCodes.Stelem_I4); return; case BuiltinTypeSpec.Type.Long: case BuiltinTypeSpec.Type.ULong: Emit (OpCodes.Stelem_I8); return; case BuiltinTypeSpec.Type.Float: Emit (OpCodes.Stelem_R4); return; case BuiltinTypeSpec.Type.Double: Emit (OpCodes.Stelem_R8); return; } switch (type.Kind) { case MemberKind.Struct: Emit (OpCodes.Stobj, type); break; case MemberKind.TypeParameter: Emit (OpCodes.Stelem, type); break; case MemberKind.PointerType: Emit (OpCodes.Stelem_I); break; default: Emit (OpCodes.Stelem_Ref); 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 (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; } }
public void EmitArrayAddress (ArrayContainer ac) { if (ac.Rank > 1) { if (IsAnonymousStoreyMutateRequired) ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator); ig.Emit (OpCodes.Call, ac.GetAddressMethod ()); } else { var type = IsAnonymousStoreyMutateRequired ? CurrentAnonymousMethod.Storey.Mutator.Mutate (ac.Element) : ac.Element; ig.Emit (OpCodes.Ldelema, type.GetMetaInfo ()); } }
public void EmitArrayNew (ArrayContainer ac) { if (ac.Rank == 1) { var type = IsAnonymousStoreyMutateRequired ? CurrentAnonymousMethod.Storey.Mutator.Mutate (ac.Element) : ac.Element; ig.Emit (OpCodes.Newarr, type.GetMetaInfo ()); } else { if (IsAnonymousStoreyMutateRequired) ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator); ig.Emit (OpCodes.Newobj, ac.GetConstructor ()); } }
// // Emits the right opcode to store to an array // public void EmitArrayStore (ArrayContainer ac) { if (ac.Rank > 1) { if (IsAnonymousStoreyMutateRequired) ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator); ig.Emit (OpCodes.Call, ac.GetSetMethod ()); return; } var type = ac.Element; if (type.IsEnum) type = EnumSpec.GetUnderlyingType (type); if (type == TypeManager.byte_type || type == TypeManager.sbyte_type || type == TypeManager.bool_type) Emit (OpCodes.Stelem_I1); else if (type == TypeManager.short_type || type == TypeManager.ushort_type || type == TypeManager.char_type) Emit (OpCodes.Stelem_I2); else if (type == TypeManager.int32_type || type == TypeManager.uint32_type) Emit (OpCodes.Stelem_I4); else if (type == TypeManager.int64_type || type == TypeManager.uint64_type) Emit (OpCodes.Stelem_I8); else if (type == TypeManager.float_type) Emit (OpCodes.Stelem_R4); else if (type == TypeManager.double_type) Emit (OpCodes.Stelem_R8); else if (type == TypeManager.intptr_type) Emit (OpCodes.Stobj, type); else if (TypeManager.IsStruct (type)) Emit (OpCodes.Stobj, type); else if (type.IsGenericParameter) Emit (OpCodes.Stelem, type); else if (type.IsPointer) Emit (OpCodes.Stelem_I); else Emit (OpCodes.Stelem_Ref); }
public void EmitArrayAddress (ArrayContainer ac) { if (ac.Element.IsGenericParameter) ig.Emit (OpCodes.Readonly); if (ac.Rank > 1) { if (IsAnonymousStoreyMutateRequired) ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator); ig.Emit (OpCodes.Call, ac.GetAddressMethod ()); } else { Emit (OpCodes.Ldelema, ac.Element); } }
// // Emits the right opcode to store to an array // public void EmitArrayStore(ArrayContainer ac) { if (ac.Rank > 1) { if (IsAnonymousStoreyMutateRequired) { ac = (ArrayContainer)ac.Mutate(CurrentAnonymousMethod.Storey.Mutator); } ig.Emit(OpCodes.Call, ac.GetSetMethod()); return; } var type = ac.Element; if (type.Kind == MemberKind.Enum) { type = EnumSpec.GetUnderlyingType(type); } switch (type.BuiltinType) { case BuiltinTypeSpec.Type.Byte: case BuiltinTypeSpec.Type.SByte: case BuiltinTypeSpec.Type.Bool: Emit(OpCodes.Stelem_I1); return; case BuiltinTypeSpec.Type.Short: case BuiltinTypeSpec.Type.UShort: case BuiltinTypeSpec.Type.Char: Emit(OpCodes.Stelem_I2); return; case BuiltinTypeSpec.Type.Int: case BuiltinTypeSpec.Type.UInt: Emit(OpCodes.Stelem_I4); return; case BuiltinTypeSpec.Type.Long: case BuiltinTypeSpec.Type.ULong: Emit(OpCodes.Stelem_I8); return; case BuiltinTypeSpec.Type.Float: Emit(OpCodes.Stelem_R4); return; case BuiltinTypeSpec.Type.Double: Emit(OpCodes.Stelem_R8); return; } switch (type.Kind) { case MemberKind.Struct: Emit(OpCodes.Stobj, type); break; case MemberKind.TypeParameter: Emit(OpCodes.Stelem, type); break; case MemberKind.PointerType: Emit(OpCodes.Stelem_I); break; default: Emit(OpCodes.Stelem_Ref); 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 (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; } }
// // 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: // // Workaround MSIL limitation. Load bool element as single bit, // bool array can actually store any byte value // ig.Emit (OpCodes.Ldelem_U1); ig.Emit (OpCodes.Ldc_I4_0); ig.Emit (OpCodes.Cgt_Un); break; 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; } }
// // 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 ()); if (TrackStackTypes) { SetStackType (ac.Element); } 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; } if (TrackStackTypes) { SetStackType (type); } }
public void EmitArrayAddress (ArrayContainer ac) { if (ac.Rank > 1) { if (IsAnonymousStoreyMutateRequired) ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator); ig.Emit (OpCodes.Call, ac.GetAddressMethod ()); if (TrackStackTypes) { SetStackType (ReferenceContainer.MakeType (Module, ac.Element)); } } else { var type = IsAnonymousStoreyMutateRequired ? CurrentAnonymousMethod.Storey.Mutator.Mutate (ac.Element) : ac.Element; ig.Emit (OpCodes.Ldelema, type.GetMetaInfo ()); if (TrackStackTypes) { SetStackType (ReferenceContainer.MakeType (Module, type)); } } }