private void EmitWithFinallyBlock(CodeGen cg, Slot exc, Slot exit, Slot isTryYielded) { // we are certain that Finally will never yield cg.PushFinallyBlock(null, null); cg.BeginFinallyBlock(); //finally body Label endOfFinally = cg.DefineLabel(); // isTryYielded == True ? isTryYielded.EmitGet(cg); cg.EmitTestTrue(); cg.Emit(OpCodes.Brtrue, endOfFinally); // exc == False ? exc.EmitGet(cg); cg.EmitTestTrue(); cg.Emit(OpCodes.Brfalse, endOfFinally); //exit(None, None, None) cg.EmitCallerContext(); exit.EmitGet(cg); cg.Emit(OpCodes.Ldnull); cg.Emit(OpCodes.Ldnull); cg.Emit(OpCodes.Ldnull); cg.EmitCall(typeof(Ops), "CallWithContext", new Type[] { typeof(ICallerContext), typeof(object), typeof(object), typeof(object), typeof(object) }); cg.Emit(OpCodes.Pop); cg.MarkLabel(endOfFinally); cg.PopTargets(); // finally end }
private void EmitYieldDispatch(List<YieldTarget> yieldTargets, Slot isYielded, Slot choiceVar, CodeGen cg) { if (IsBlockYieldable(yieldTargets)) { cg.EmitFieldGet(typeof(Ops).GetField("FALSE")); isYielded.EmitSet(cg); int index = 0; foreach (YieldTarget yt in yieldTargets) { choiceVar.EmitGet(cg); cg.EmitInt(index); cg.Emit(OpCodes.Beq, yt.YieldContinuationTarget); index++; } } }
private void EmitWithCatchBlock(CodeGen cg, Slot exc, Slot exit) { cg.BeginCatchBlock(typeof(Exception)); // Extract state from the carrier exception cg.EmitCallerContext(); cg.EmitCall(typeof(Ops), "ExtractException", new Type[] { typeof(Exception), typeof(ICallerContext) }); cg.Emit(OpCodes.Pop); // except body cg.PushExceptionBlock(Targets.TargetBlockType.Catch, null, null); cg.EmitConstantBoxed(false); exc.EmitSet(cg); cg.EmitCallerContext(); exit.EmitGet(cg); cg.EmitObjectArray(new Expression[0]); cg.EmitCallerContext(); cg.EmitCall(typeof(Ops), "ExtractSysExcInfo"); cg.EmitCall(typeof(Ops), "CallWithArgsTupleAndContext", new Type[] { typeof(ICallerContext), typeof(object), typeof(object[]), typeof(object) }); Label afterRaise = cg.DefineLabel(); cg.EmitTestTrue(); cg.Emit(OpCodes.Brtrue, afterRaise); cg.EmitCall(typeof(Ops), "Raise", new Type[0]); //, new Type[] { typeof(object), typeof(SymbolId) }); cg.MarkLabel(afterRaise); cg.EmitCallerContext(); cg.EmitCall(typeof(Ops), "ClearException", new Type[] { typeof(ICallerContext) }); cg.PopTargets(); }
public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots) { contextSlot.EmitGet(cg); }
private void EmitOnYieldBranchToLabel(List<YieldTarget> yieldTargets, Slot isYielded, Label label, CodeGen cg) { if (IsBlockYieldable(yieldTargets)) { isYielded.EmitGet(cg); cg.EmitUnbox(typeof(bool)); cg.Emit(OpCodes.Brtrue, label); } }
public static void EmitCallFromClrToPython(CodeGen cg, Slot callTarget, int firstArg, Ast.FunctionAttributes functionAttributes) { callTarget.EmitGet(cg); List<ReturnFixer> fixers = new List<ReturnFixer>(0); Slot[] args = cg.argumentSlots; int nargs = args.Length - firstArg; if (nargs <= Ops.MaximumCallArgs && (functionAttributes & IronPython.Compiler.Ast.FunctionAttributes.ArgumentList) == 0) { for (int i = firstArg; i < args.Length; i++) { ReturnFixer rf = CompilerHelpers.EmitArgument(cg, args[i]); if (rf != null) fixers.Add(rf); } cg.EmitCall(typeof(Ops), "Call", CompilerHelpers.MakeRepeatedArray(typeof(object), nargs + 1)); } else if ((functionAttributes & IronPython.Compiler.Ast.FunctionAttributes.ArgumentList) == 0) { cg.EmitObjectArray(nargs, delegate(int index) { ReturnFixer rf = CompilerHelpers.EmitArgument(cg, args[index + firstArg]); if (rf != null) fixers.Add(rf); }); cg.EmitCall(typeof(Ops), "Call", new Type[] { typeof(object), typeof(object[]) }); } else { cg.EmitObjectArray(nargs - 1, delegate(int index) { ReturnFixer rf = CompilerHelpers.EmitArgument(cg, args[index + firstArg]); if (rf != null) fixers.Add(rf); }); args[args.Length - 1].EmitGet(cg); cg.EmitCall(typeof(Tuple), "Make"); cg.EmitCall(typeof(Ops), "CallWithArgsTuple"); } foreach (ReturnFixer rf in fixers) { rf.FixReturn(cg); } cg.EmitReturnFromObject(); }
private void CreateVirtualMethodOverride(MethodInfo mi, Slot methField) { CodeGen cg = tg.DefineMethodOverride(mi); Label baseCall = cg.DefineLabel(); methField.EmitGet(cg); cg.EmitCall(typeof(MethodWrapper), "IsBuiltinMethod"); cg.Emit(OpCodes.Brtrue, baseCall); methField.EmitGet(cg); cg.EmitThis(); for (int i = 0; i < mi.GetParameters().Length; i++) { cg.EmitArgGet(i); cg.EmitConvertToObject(mi.GetParameters()[i].ParameterType); } if (mi.GetParameters().Length > 3) { throw new NotImplementedException("OverrideBaseMethod: " + mi); } cg.EmitCall(typeof(MethodWrapper), "Invoke", CompilerHelpers.MakeRepeatedArray(typeof(object), 1 + mi.GetParameters().Length)); MethodInfo object_ToString = typeof(object).GetMethod("ToString"); if (mi.MethodHandle != object_ToString.MethodHandle) { cg.EmitReturnFromObject(); } else { cg.EmitCall(typeof(UserType), "ToStringReturnHelper"); cg.EmitReturn(); } cg.MarkLabel(baseCall); if (mi.MethodHandle == object_ToString.MethodHandle) { // object.ToString() displays the CLI type name. However, __class__ is the real type for Python type instances cg.EmitThis(); cg.EmitCall(typeof(UserType).GetMethod("ToStringHelper")); cg.EmitReturn(); } else if (mi.IsAbstract) { EmitBadCallThrow(cg, mi, "must override abstract method"); //@todo better exception } else { // Just forward to the base method implementation EmitBaseMethodDispatch(mi, cg); } cg.Finish(); }
private static CodeGen AddIDynamicObject(TypeGen newType, Slot dictSlot) { Slot classSlot = newType.AddStaticField(typeof(DynamicType), FieldAttributes.Private, "$class"); newType.myType.AddInterfaceImplementation(typeof(ISuperDynamicObject)); /* GetDynamicType */ CodeGen gdtCg = newType.DefineMethodOverride(typeof(IDynamicObject).GetMethod("GetDynamicType")); CodeGen cg = newType.DefineUserHiddenMethod(MethodAttributes.FamORAssem | MethodAttributes.Static, "$$GetOrMakeDynamicType", typeof(DynamicType), new Type[0]); DoLazyInitCheck(cg, classSlot, delegate() { // if not null, just return the value. classSlot.EmitGet(cg); cg.EmitReturn(); }, delegate() { // initialization code // CompiledType GetTypeForType(Type t) cg.EmitType(newType.myType); cg.EmitCall(typeof(CompiledType), "GetTypeForType"); cg.Emit(OpCodes.Dup); classSlot.EmitSet(cg); cg.EmitReturn(); }); cg.Finish(); CodeGen ret = cg; // just a call to the helper method gdtCg.EmitThis(); gdtCg.EmitCall(typeof(object), "GetType"); gdtCg.EmitType(newType.myType); Label differ = gdtCg.DefineLabel(); gdtCg.Emit(OpCodes.Bne_Un, differ); gdtCg.EmitCall(cg.MethodInfo); gdtCg.EmitReturn(); gdtCg.MarkLabel(differ); gdtCg.EmitThis(); gdtCg.EmitCall(typeof(object), "GetType"); gdtCg.EmitCall(typeof(Ops), "GetDynamicTypeFromType"); gdtCg.EmitReturn(); gdtCg.Finish(); /* GetDict */ cg = newType.DefineMethodOverride(typeof(ISuperDynamicObject).GetMethod("GetDict")); DoLazyInitCheck(cg, dictSlot, delegate() { // if not null, just return the value. dictSlot.EmitGet(cg); cg.EmitReturn(); }, delegate() { // initialization code - dictSlot = new CustomOldClassDict() cg.EmitNew(typeof(CustomOldClassDict).GetConstructor(new Type[0])); cg.Emit(OpCodes.Dup); dictSlot.EmitSet(cg); cg.EmitReturn(); }); cg.Finish(); /* SetDict */ cg = newType.DefineMethodOverride(typeof(ISuperDynamicObject).GetMethod("SetDict")); cg.EmitString("SetDict"); cg.EmitInt(0); cg.Emit(OpCodes.Newarr, typeof(object)); cg.EmitCall(typeof(Ops), "NotImplementedError"); cg.Emit(OpCodes.Throw); /* SetDynamicType */ cg = newType.DefineMethodOverride(typeof(ISuperDynamicObject).GetMethod("SetDynamicType")); cg.EmitString("SetDynamicType"); cg.EmitInt(0); cg.Emit(OpCodes.Newarr, typeof(object)); cg.EmitCall(typeof(Ops), "NotImplementedError"); cg.Emit(OpCodes.Throw); return ret; }
private static void DoLazyInitCheck(CodeGen cg, Slot val, LazyInitHelper ifNotNull, LazyInitHelper initCode) { Label initType = cg.DefineLabel(); val.EmitGet(cg); cg.Emit(OpCodes.Ldnull); cg.Emit(OpCodes.Beq, initType); ifNotNull(); cg.MarkLabel(initType); initCode(); }
// Must override at least one of these two methods or get infinite loop public virtual void EmitSet(CodeGen cg, Slot val) { val.EmitGet(cg); EmitSet(cg); }
/// <summary> /// Emits a call into the PythonModule to register this module, and then /// returns the resulting PythonModule /// </summary> public static void EmitModuleConstruction(TypeGen tg, CodeGen main, string moduleName, Slot initialize, IList<string> referencedAssemblies) { // calling PythonModule InitializeModule(CustomDict compiled, string fullName) main.EmitNew(tg.DefaultConstructor); // Emit instance for the InitializeModule call (compiled) initialize.EmitSet(main); initialize.EmitGet(main); main.EmitString(moduleName); // emit module name (fullName) // emit the references assemblies if (referencedAssemblies != null) { for (int i = 0; i < referencedAssemblies.Count; i++) { if (referencedAssemblies[i].ToLower().EndsWith("\\ironpython.dll")) { referencedAssemblies.RemoveAt(i); i--; } else { if (referencedAssemblies[i].IndexOf(Path.DirectorySeparatorChar) != -1) { referencedAssemblies[i] = referencedAssemblies[i].Substring(referencedAssemblies[i].LastIndexOf(Path.DirectorySeparatorChar) + 1); } if (referencedAssemblies[i].ToLower().EndsWith(".dll")) { referencedAssemblies[i] = referencedAssemblies[i].Substring(0, referencedAssemblies[i].Length - 4); } } } main.EmitStringArray(referencedAssemblies); } else main.Emit(OpCodes.Ldnull); // Call InitializeModule main.EmitCall(typeof(Ops), "InitializeModule"); }
public override void EmitSet(CodeGen cg, Slot val) { MethodInfo method = property.GetSetMethod(); Debug.Assert(method != null, "Cannot set property"); Debug.Assert(method.GetParameters().Length == 1, "Wrong number of parameters on the property setter"); // Emit instance if (!method.IsStatic) { Debug.Assert(instance != null, "need instance slot for instance property"); instance.EmitGet(cg); } // Emit value val.EmitGet(cg); // Emit call cg.EmitCall(method); }
public override void EmitSet(CodeGen cg, Slot val) { // // frame.SetGlobal(symbol_id, val) // frame.EmitGet(cg); cg.EmitSymbolId(name); val.EmitGet(cg); cg.EmitCall(typeof(IModuleScope), "SetGlobal"); }
public override void EmitSet(CodeGen cg, Slot val) { // Emit the following: // frame.SetLocal(symbol_id, val) frame.EmitGet(cg); cg.EmitSymbolId(name); val.EmitGet(cg); cg.EmitCall(typeof(ModuleScope), "SetLocal"); }
public override void EmitSet(CodeGen cg, Slot val) { val.EmitGet(cg); cg.EmitConvertToObject(Type); val = cg.GetLocalTmp(typeof(object)); val.EmitSet(cg); instance.EmitGet(cg); cg.EmitInt(index); val.EmitGet(cg); cg.Emit(OpCodes.Stelem_Ref); }
public override void EmitSet(CodeGen cg, Slot val) { instance.EmitGet(cg); val.EmitGet(cg); cg.Emit(OpCodes.Stfld, field); }