Skip to content

Commit

Permalink
Modernise syntax in ClassDerived
Browse files Browse the repository at this point in the history
  • Loading branch information
filmor committed May 4, 2022
1 parent d899083 commit aa5b54b
Showing 1 changed file with 115 additions and 121 deletions.
236 changes: 115 additions & 121 deletions src/runtime/Types/ClassDerived.cs
Original file line number Diff line number Diff line change
Expand Up @@ -469,100 +469,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 @@ -581,68 +581,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

0 comments on commit aa5b54b

Please sign in to comment.