private VTableEntry GetOrMakeVTableEntry(string name) { VTableEntry ret; if (vtable.TryGetValue(name, out ret)) return ret; ret = new VTableEntry(name, vtable.Count); vtable[name] = ret; return ret; }
private void CreateVTableSetterOverride(MethodInfo mi, VTableEntry methField) { CodeGen cg = tg.DefineMethodOverride(mi); Slot callTarget = EmitBaseClassCallCheckForProperties(cg, mi, methField); callTarget.EmitGet(cg); cg.EmitThis(); cg.EmitArgGet(0); cg.EmitConvertToObject(mi.GetParameters()[0].ParameterType); cg.EmitSymbolId(methField.name); cg.EmitCall(typeof(UserType), "SetPropertyHelper"); cg.EmitReturn(); cg.Finish(); }
private void CreateVTableEventOverride(EventInfo ei, MethodInfo mi, VTableEntry methField) { // override the add/remove method CodeGen cg = tg.DefineMethodOverride(mi); Slot callTarget = EmitBaseClassCallCheckForProperties(cg, mi, methField); callTarget.EmitGet(cg); cg.EmitThis(); typeField.EmitGet(cg); cg.EmitArgGet(0); cg.EmitConvertToObject(mi.GetParameters()[0].ParameterType); cg.EmitSymbolId(methField.name); cg.EmitCall(typeof(UserType), "AddRemoveEventHelper"); cg.EmitReturn(); cg.Finish(); }
private void CreateVTableMethodOverride(MethodInfo mi, VTableEntry methField) { CodeGen cg = tg.DefineMethodOverride(mi); Label instanceCall = cg.DefineLabel(); Slot callTarget = cg.GetLocalTmp(typeof(object)); typeField.EmitGet(cg); cg.EmitThis(); dictField.EmitGet(cg); cg.EmitSymbolId(methField.name); cg.EmitInt(methField.index); callTarget.EmitGetAddr(cg); // out param populated w/ bound method on success cg.EmitCall(typeof(UserType), "TryGetNonInheritedMethodHelper"); cg.Emit(OpCodes.Brtrue, instanceCall); EmitBaseMethodDispatch(mi, cg); cg.MarkLabel(instanceCall); int argStart = 0; Ast.FunctionAttributes attrs = Ast.FunctionAttributes.None; ParameterInfo[] pis = mi.GetParameters(); if (pis.Length > 0) { if (pis[0].ParameterType == typeof(ICallerContext)) argStart = 1; if (pis[pis.Length - 1].IsDefined(typeof(ParamArrayAttribute), false)) { attrs |= Ast.FunctionAttributes.ArgumentList; } } EmitCallFromClrToPython(cg, callTarget, argStart, attrs); cg.Finish(); }
/// <summary> /// Emits code to check if the class has overriden this specific /// function. For example: /// /// MyDerivedType.SomeVirtualFunction = ... /// or /// /// class MyDerivedType(MyBaseType): /// def SomeVirtualFunction(self, ...): /// /// </summary> internal Slot EmitBaseClassCallCheckForProperties(CodeGen cg, MethodInfo baseMethod, VTableEntry methField) { Label instanceCall = cg.DefineLabel(); Slot callTarget = cg.GetLocalTmp(typeof(object)); typeField.EmitGet(cg); cg.EmitInt(methField.index); callTarget.EmitGetAddr(cg); cg.EmitCall(typeof(UserType), "TryGetNonInheritedValueHelper"); cg.Emit(OpCodes.Brtrue, instanceCall); EmitBaseMethodDispatch(baseMethod, cg); cg.MarkLabel(instanceCall); return callTarget; }