diff --git a/Src/IronPython.Modules/_ctypes/CFuncPtr.cs b/Src/IronPython.Modules/_ctypes/CFuncPtr.cs index 47d7eda03..63e1ccfd5 100644 --- a/Src/IronPython.Modules/_ctypes/CFuncPtr.cs +++ b/Src/IronPython.Modules/_ctypes/CFuncPtr.cs @@ -4,24 +4,22 @@ #if FEATURE_CTYPES -using System.Linq.Expressions; -using System.Numerics; - using System; using System.Collections.Generic; -using System.Dynamic; using System.Diagnostics; +using System.Dynamic; +using System.Linq; +using System.Linq.Expressions; +using System.Numerics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; -using Microsoft.Scripting; using Microsoft.Scripting.Ast; using Microsoft.Scripting.Generation; using Microsoft.Scripting.Runtime; -using Microsoft.Scripting.Utils; using IronPython.Runtime; using IronPython.Runtime.Binding; @@ -388,7 +386,7 @@ private Expression AddReturnChecks(CodeContext context, DynamicMetaObject[] args typeof(PythonOps).GetMethod(nameof(PythonOps.MakeTuple)), Expression.NewArrayInit( typeof(object), - ArrayUtils.ConvertAll(args, x => Utils.Convert(x.Expression, typeof(object))) + Microsoft.Scripting.Utils.ArrayUtils.ConvertAll(args, x => Utils.Convert(x.Expression, typeof(object))) ) ) ); @@ -609,7 +607,7 @@ private INativeType GetNativeReturnType() { #endif method.Emit(OpCodes.Ldarg_0); - method.Emit(OpCodes.Calli, GetCalliSignature(convention, sig, calliRetType)); + method.EmitCalli(OpCodes.Calli, convention, calliRetType, sig.Select(x => x.NativeType).ToArray()); // if we have a return value we need to store it and marshal to Python // before we run any cleanup code. @@ -960,5 +958,19 @@ public string __repr__(CodeContext context) { } } } + +#if NETSTANDARD2_0 +#nullable enable + internal static class ILGeneratorExtensions { + private static MethodInfo? EmitCalliMethodInfo = typeof(ILGenerator).GetMethod("EmitCalli", new Type[] { typeof(OpCode), typeof(CallingConvention), typeof(Type), typeof(Type[]) }); + + public static void EmitCalli(this ILGenerator ilgen, OpCode opcode, CallingConvention unmanagedCallConv, Type? returnType, Type[]? parameterTypes) { + // should exist in runtimes of interest, but just in case, let it throw if the method doesn't exist... + EmitCalliMethodInfo!.Invoke(ilgen, new object[] { opcode, unmanagedCallConv, returnType!, parameterTypes! }); + } + } +#nullable restore +#endif } + #endif diff --git a/Src/IronPython/Lib/iptest/test_env.py b/Src/IronPython/Lib/iptest/test_env.py index 56ac5de28..9b8610b21 100644 --- a/Src/IronPython/Lib/iptest/test_env.py +++ b/Src/IronPython/Lib/iptest/test_env.py @@ -28,6 +28,7 @@ is_netcoreapp21 = clr.FrameworkDescription.startswith(".NET Core 2.x") is_netcoreapp31 = clr.FrameworkDescription.startswith(".NET Core 3.1") is_net50 = clr.FrameworkDescription.startswith(".NET 5.0") + is_net60 = clr.FrameworkDescription.startswith(".NET 6.0") if is_netcoreapp: clr.AddReference("System.Runtime.Extensions") is_posix = sys.platform == 'posix' or System.Environment.OSVersion.Platform == System.PlatformID.Unix is_osx = os.path.exists('/System/Library/CoreServices/SystemVersion.plist') diff --git a/Src/IronPython/Runtime/Binding/PythonBinder.cs b/Src/IronPython/Runtime/Binding/PythonBinder.cs index 91a06fc3c..9fbdce44a 100644 --- a/Src/IronPython/Runtime/Binding/PythonBinder.cs +++ b/Src/IronPython/Runtime/Binding/PythonBinder.cs @@ -378,6 +378,8 @@ internal IList GetExtensionTypesInternal(Type t) { } public override bool IncludeExtensionMember(MemberInfo member) { + // exclude static virtual members on interfaces + if (member.DeclaringType.IsInterface && member.IsStaticVirtual()) return false; return !member.DeclaringType.IsDefined(typeof(PythonHiddenBaseClassAttribute), false); } diff --git a/Src/IronPython/Runtime/Types/PythonTypeInfo.cs b/Src/IronPython/Runtime/Types/PythonTypeInfo.cs index e2b0150fc..2d5d40c9d 100644 --- a/Src/IronPython/Runtime/Types/PythonTypeInfo.cs +++ b/Src/IronPython/Runtime/Types/PythonTypeInfo.cs @@ -1371,6 +1371,11 @@ public ScriptDomainManager/*!*/ DomainManager { IEnumerable foundMembers = type.GetMember(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | flags); + if (type.IsInterface) { + // exclude static virtual members on interfaces + foundMembers = foundMembers.Where(mi => !mi.IsStaticVirtual()); + } + if (!Binder.DomainManager.Configuration.PrivateBinding) { foundMembers = CompilerHelpers.FilterNonVisibleMembers(type, foundMembers); } @@ -2071,6 +2076,22 @@ private static MethodInfo[] GetMethodSet(string name, int expected) { return filtered; } + private static bool IsStaticVirtual(this MethodInfo member) + => member.IsStatic && member.IsVirtual; + + internal static bool IsStaticVirtual(this MemberInfo member) { + switch (member) { + case MethodInfo mi: + return mi.IsStaticVirtual(); + case PropertyInfo pi: + if (pi.GetMethod?.IsStaticVirtual() == true) return true; + if (pi.SetMethod?.IsStaticVirtual() == true) return true; + break; + } + return false; + } + + #endregion } }