Skip to content

On shutdown from Python release all slot holders #1720

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Modernise syntax in ClassDerived
  • Loading branch information
filmor committed Mar 31, 2022
commit 01f473fb18e58e7f7952ebde02253c12ab1bb089
236 changes: 115 additions & 121 deletions src/runtime/Types/ClassDerived.cs
Original file line number Diff line number Diff line change
Expand Up @@ -472,100 +472,100 @@ private static void AddPythonMethod(string methodName, PyObject func, TypeBuilde
methodName = pyMethodName.As<string>() ?? throw new ArgumentNullException(methodNameAttribute);
}

using (PyObject pyReturnType = func.GetAttr("_clr_return_type_"))
using (var pyArgTypes = PyIter.GetIter(func.GetAttr("_clr_arg_types_")))
using var pyReturnType = func.GetAttr("_clr_return_type_");
using var pyArgTypes = func.GetAttr("_clr_arg_types_");
using var pyArgTypesIter = PyIter.GetIter(pyArgTypes);
var returnType = pyReturnType.AsManagedObject(typeof(Type)) as Type;
if (returnType == null)
{
var returnType = pyReturnType.AsManagedObject(typeof(Type)) as Type;
if (returnType == null)
{
returnType = typeof(void);
}
returnType = typeof(void);
}

var argTypes = new List<Type>();
foreach (PyObject pyArgType in pyArgTypes)
var argTypes = new List<Type>();
foreach (PyObject pyArgType in pyArgTypesIter)
{
var argType = pyArgType.AsManagedObject(typeof(Type)) as Type;
if (argType == null)
{
var argType = pyArgType.AsManagedObject(typeof(Type)) as Type;
if (argType == null)
{
throw new ArgumentException("_clr_arg_types_ must be a list or tuple of CLR types");
}
argTypes.Add(argType);
throw new ArgumentException("_clr_arg_types_ must be a list or tuple of CLR types");
}
argTypes.Add(argType);
pyArgType.Dispose();
}

// add the method to call back into python
MethodAttributes methodAttribs = MethodAttributes.Public |
MethodAttributes.Virtual |
MethodAttributes.ReuseSlot |
MethodAttributes.HideBySig;
// add the method to call back into python
MethodAttributes methodAttribs = MethodAttributes.Public |
MethodAttributes.Virtual |
MethodAttributes.ReuseSlot |
MethodAttributes.HideBySig;

MethodBuilder methodBuilder = typeBuilder.DefineMethod(methodName,
methodAttribs,
returnType,
argTypes.ToArray());
MethodBuilder methodBuilder = typeBuilder.DefineMethod(methodName,
methodAttribs,
returnType,
argTypes.ToArray());

ILGenerator il = methodBuilder.GetILGenerator();
ILGenerator il = methodBuilder.GetILGenerator();

il.DeclareLocal(typeof(object[]));
il.DeclareLocal(typeof(RuntimeMethodHandle));
il.DeclareLocal(typeof(object[]));
il.DeclareLocal(typeof(RuntimeMethodHandle));

// this
il.Emit(OpCodes.Ldarg_0);
// this
il.Emit(OpCodes.Ldarg_0);

// Python method to call
il.Emit(OpCodes.Ldstr, methodName);
// Python method to call
il.Emit(OpCodes.Ldstr, methodName);

// original method name
il.Emit(OpCodes.Ldnull); // don't fall back to the base type's method
// original method name
il.Emit(OpCodes.Ldnull); // don't fall back to the base type's method

// create args array
il.Emit(OpCodes.Ldc_I4, argTypes.Count);
il.Emit(OpCodes.Newarr, typeof(object));
il.Emit(OpCodes.Stloc_0);
// create args array
il.Emit(OpCodes.Ldc_I4, argTypes.Count);
il.Emit(OpCodes.Newarr, typeof(object));
il.Emit(OpCodes.Stloc_0);

// fill args array
for (var i = 0; i < argTypes.Count; ++i)
// fill args array
for (var i = 0; i < argTypes.Count; ++i)
{
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldc_I4, i);
il.Emit(OpCodes.Ldarg, i + 1);
var type = argTypes[i];
if (type.IsByRef)
{
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldc_I4, i);
il.Emit(OpCodes.Ldarg, i + 1);
var type = argTypes[i];
if (type.IsByRef)
{
type = type.GetElementType();
il.Emit(OpCodes.Ldobj, type);
}
if (type.IsValueType)
{
il.Emit(OpCodes.Box, type);
}
il.Emit(OpCodes.Stelem, typeof(object));
type = type.GetElementType();
il.Emit(OpCodes.Ldobj, type);
}
if (type.IsValueType)
{
il.Emit(OpCodes.Box, type);
}
il.Emit(OpCodes.Stelem, typeof(object));
}

// args array
il.Emit(OpCodes.Ldloc_0);
// args array
il.Emit(OpCodes.Ldloc_0);

// method handle for the base method is null
il.Emit(OpCodes.Ldloca_S, 1);
il.Emit(OpCodes.Initobj, typeof(RuntimeMethodHandle));
il.Emit(OpCodes.Ldloc_1);
// method handle for the base method is null
il.Emit(OpCodes.Ldloca_S, 1);
il.Emit(OpCodes.Initobj, typeof(RuntimeMethodHandle));
il.Emit(OpCodes.Ldloc_1);
#pragma warning disable CS0618 // PythonDerivedType is for internal use only

// invoke the method
if (returnType == typeof(void))
{
il.Emit(OpCodes.Call, typeof(PythonDerivedType).GetMethod(nameof(InvokeMethodVoid)));
}
else
{
il.Emit(OpCodes.Call,
typeof(PythonDerivedType).GetMethod(nameof(InvokeMethod)).MakeGenericMethod(returnType));
}
// invoke the method
if (returnType == typeof(void))
{
il.Emit(OpCodes.Call, typeof(PythonDerivedType).GetMethod(nameof(InvokeMethodVoid)));
}
else
{
il.Emit(OpCodes.Call,
typeof(PythonDerivedType).GetMethod(nameof(InvokeMethod)).MakeGenericMethod(returnType));
}

CodeGenerator.GenerateMarshalByRefsBack(il, argTypes);
CodeGenerator.GenerateMarshalByRefsBack(il, argTypes);

#pragma warning restore CS0618 // PythonDerivedType is for internal use only
il.Emit(OpCodes.Ret);
}
il.Emit(OpCodes.Ret);
}

/// <summary>
Expand All @@ -584,68 +584,62 @@ private static void AddPythonProperty(string propertyName, PyObject func, TypeBu
MethodAttributes.HideBySig |
MethodAttributes.SpecialName;

using (PyObject pyPropertyType = func.GetAttr("_clr_property_type_"))
using var pyPropertyType = func.GetAttr("_clr_property_type_");
var propertyType = pyPropertyType.AsManagedObject(typeof(Type)) as Type;
if (propertyType == null)
{
var propertyType = pyPropertyType.AsManagedObject(typeof(Type)) as Type;
if (propertyType == null)
{
throw new ArgumentException("_clr_property_type must be a CLR type");
}
throw new ArgumentException("_clr_property_type must be a CLR type");
}

PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName,
PropertyAttributes.None,
propertyType,
null);
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName,
PropertyAttributes.None,
propertyType,
null);

if (func.HasAttr("fget"))
if (func.HasAttr("fget"))
{
using var pyfget = func.GetAttr("fget");
if (pyfget.IsTrue())
{
using (PyObject pyfget = func.GetAttr("fget"))
{
if (pyfget.IsTrue())
{
MethodBuilder methodBuilder = typeBuilder.DefineMethod("get_" + propertyName,
methodAttribs,
propertyType,
null);

ILGenerator il = methodBuilder.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldstr, propertyName);
MethodBuilder methodBuilder = typeBuilder.DefineMethod("get_" + propertyName,
methodAttribs,
propertyType,
null);

ILGenerator il = methodBuilder.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldstr, propertyName);
#pragma warning disable CS0618 // PythonDerivedType is for internal use only
il.Emit(OpCodes.Call,
typeof(PythonDerivedType).GetMethod("InvokeGetProperty").MakeGenericMethod(propertyType));
il.Emit(OpCodes.Call,
typeof(PythonDerivedType).GetMethod("InvokeGetProperty").MakeGenericMethod(propertyType));
#pragma warning restore CS0618 // PythonDerivedType is for internal use only
il.Emit(OpCodes.Ret);
il.Emit(OpCodes.Ret);

propertyBuilder.SetGetMethod(methodBuilder);
}
}
propertyBuilder.SetGetMethod(methodBuilder);
}
}

if (func.HasAttr("fset"))
if (func.HasAttr("fset"))
{
using var pyset = func.GetAttr("fset");
if (pyset.IsTrue())
{
using (PyObject pyset = func.GetAttr("fset"))
{
if (pyset.IsTrue())
{
MethodBuilder methodBuilder = typeBuilder.DefineMethod("set_" + propertyName,
methodAttribs,
null,
new[] { propertyType });

ILGenerator il = methodBuilder.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldstr, propertyName);
il.Emit(OpCodes.Ldarg_1);
MethodBuilder methodBuilder = typeBuilder.DefineMethod("set_" + propertyName,
methodAttribs,
null,
new[] { propertyType });

ILGenerator il = methodBuilder.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldstr, propertyName);
il.Emit(OpCodes.Ldarg_1);
#pragma warning disable CS0618 // PythonDerivedType is for internal use only
il.Emit(OpCodes.Call,
typeof(PythonDerivedType).GetMethod("InvokeSetProperty").MakeGenericMethod(propertyType));
il.Emit(OpCodes.Call,
typeof(PythonDerivedType).GetMethod("InvokeSetProperty").MakeGenericMethod(propertyType));
#pragma warning restore CS0618 // PythonDerivedType is for internal use only
il.Emit(OpCodes.Ret);
il.Emit(OpCodes.Ret);

propertyBuilder.SetSetMethod(methodBuilder);
}
}
propertyBuilder.SetSetMethod(methodBuilder);
}
}
}
Expand Down