public void AddModuleField(Type moduleType) { FieldBuilder moduleField = this.myType.DefineField(CompiledModule.ModuleFieldName, moduleType, FieldAttributes.Public | FieldAttributes.Static); moduleField.SetCustomAttribute(new CustomAttributeBuilder(typeof(PythonHiddenFieldAttribute).GetConstructor(new Type[0]), Runtime.Operations.Ops.EMPTY)); this.moduleSlot = new StaticFieldSlot(moduleField); }
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(); }
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(); }
private void EmitTopYieldTargetLabels(List<YieldTarget> yieldTargets, Slot choiceVar, CodeGen cg) { if (IsBlockYieldable(yieldTargets)) { Label label = cg.DefineLabel(); cg.EmitInt(-1); choiceVar.EmitSet(cg); cg.Emit(OpCodes.Br, label); int index = 0; foreach (YieldTarget yt in yieldTargets) { cg.MarkLabel(yt.TopBranchTarget); cg.EmitInt(index++); choiceVar.EmitSet(cg); cg.Emit(OpCodes.Br, label); } cg.MarkLabel(label); } }
public SignatureInfo(Type[] paramTypes, SymbolId[] paramNames, bool hasContext, Slot contextSlot) { ParamTypes = paramTypes; ParamNames = paramNames; HasContext = hasContext; ContextSlot = contextSlot; }
public Delegate MakeCallTarget(bool needsContext) { if (!CanMakeCallTarget()) return null; if (IsDirectTarget(needsContext)) { Delegate ret = FastCallable.MakeDelegate((MethodInfo)method.Method); if (ret != null) return ret; } if (IronPython.Compiler.Options.EngineDebug) { PerfTrack.NoteEvent(PerfTrack.Categories.Compiler, "CT:" + this.ToString()); } int contextOffset = needsContext ? 1 : 0; Type[] paramTypes = new Type[parameters.Count + contextOffset]; if (needsContext) paramTypes[0] = typeof(ICallerContext); for (int i = 0; i < parameters.Count; i++) { paramTypes[i + contextOffset] = typeof(object); } CodeGen cg = OutputGenerator.Snippets.DefineDynamicMethod(method.Name, typeof(object), paramTypes); Slot contextSlot = needsContext ? cg.argumentSlots[0] : null; Slot[] argSlots = new Slot[parameters.Count]; for (int i = 0; i < argSlots.Length; i++) { argSlots[i] = cg.argumentSlots[i + contextOffset]; } if (!method.IsStatic) { if (method.DeclaringType.IsValueType) { SimpleArgBuilder sb = instanceBuilder as SimpleArgBuilder; argSlots[sb.index].EmitGet(cg); cg.Emit(OpCodes.Unbox, method.DeclaringType); } else { instanceBuilder.Generate(cg, contextSlot, argSlots); } } for (int i = 0; i < argBuilders.Count; i++) { argBuilders[i].Generate(cg, contextSlot, argSlots); } Type returnType = GenerateCall(cg); //!!! add support for reference arg remapping returnBuilder.Generate(cg, contextSlot, argSlots); cg.Finish(); return cg.CreateDelegate(FastCallable.GetTargetType(needsContext, parameters.Count)); }
public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots) { contextSlot.EmitGet(cg); }
public abstract void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots);
public static void EmitCallFromClrToPython(CodeGen cg, Slot callTarget, int firstArg) { EmitCallFromClrToPython(cg, callTarget, firstArg, IronPython.Compiler.Ast.FunctionAttributes.None); }
public void SetSlot(SymbolId name, Slot slot) { slots[name] = slot; }
public void AddTempSlot(Slot slot) { temps.Add(slot); }
public IndexSlotFactory(Slot instance) { this.instance = instance; }
public FieldSlotFactory(TypeGen typeGen, Slot instance) { this.typeGen = typeGen; this.instance = instance; }
public LocalFrameSlotFactory(Slot frame) { this.frame = frame; }
public static Slot MakeParentSlot(Slot instance) { return new FieldSlot(instance, typeof(FunctionEnvironmentDictionary).GetField("parent")); }
public virtual void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots) { cg.EmitConvertToObject(returnType); cg.EmitReturn(); }
public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots) { argSlots[index].EmitGet(cg); cg.EmitConvertFromObject(parameter.Type); }
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(); }
public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots) { throw new NotImplementedException(); }
public ReturnFixer(Slot refSlot, Slot argSlot) { Debug.Assert(refSlot.Type.IsGenericType && refSlot.Type.GetGenericTypeDefinition() == typeof(ClrModule.Reference<>)); Debug.Assert(argSlot.Type.IsByRef); this.refSlot = refSlot; this.argSlot = argSlot; }
public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots) { if (argumentType.IsByRef) { Type baseType = argumentType.GetElementType(); Slot tmp = cg.GetLocalTmp(baseType); // Emit the default value as the base type EmitDefaultValue(cg, defaultValue, baseType); tmp.EmitSet(cg); // And pass the reference to the callee tmp.EmitGetAddr(cg); } else { // Emit the default value directly as the argument type EmitDefaultValue(cg, defaultValue, argumentType); } }
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 void CreateClosureSlots(Slot staticLink, Namespace nspace) { foreach (KeyValuePair<SymbolId, Binding> kv in names) { if (!kv.Value.IsFree) continue; // Find the slot Slot instance = staticLink; ScopeStatement current = parent; for (; ; ) { instance = new CastSlot(instance, current.environmentFactory.EnvironmentType); Debug.Assert(current != null, "cannot resolve closure", kv.Key.GetString()); if (current.environment != null) { EnvironmentReference er; // Is the slot in this environment? if (current.TryGetEnvironmentReference(kv.Key, out er)) { nspace.SetSlot(kv.Key, er.CreateSlot(instance)); break; } } instance = EnvironmentFactory.MakeParentSlot(instance); current = current.parent; } } }
private void GetOrDefineClass() { FieldInfo baseTypeField = baseType.GetField("__class__"); if (baseTypeField == null) { typeField = tg.AddField(typeof(UserType), "__class__"); } else { Debug.Assert(baseTypeField.FieldType == typeof(UserType)); typeField = new FieldSlot(new ThisSlot(tg.myType), baseTypeField); hasBaseTypeField = true; } }
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); } }
internal override void Emit(CodeGen cg) { Slot list = cg.GetLocalTmp(typeof(List)); cg.EmitCall(typeof(Ops), "MakeList", Type.EmptyTypes); list.EmitSet(cg); // first loop: how many For; initialize labels/slots int iFors = 0; foreach (ListComprehensionIterator iter in iters) { if (iter is ListComprehensionFor) iFors++; } Label[] continueTargets = new Label[iFors]; Slot[] enumerators = new Slot[iFors]; int jIters = iters.Length; Label[] exitTargets = new Label[jIters]; for (int i = 0; i < iFors; i++) { continueTargets[i] = cg.DefineLabel(); enumerators[i] = cg.GetLocalTmp(typeof(IEnumerator)); } for (int i = 0; i < jIters; i++) { exitTargets[i] = cg.DefineLabel(); } // second loop: before emiting item iFors = jIters = 0; foreach (ListComprehensionIterator iter in iters) { if (iter is ListComprehensionFor) { ListComprehensionFor cfor = iter as ListComprehensionFor; cfor.List.Emit(cg); cg.EmitCall(typeof(Ops), "GetEnumeratorForIteration"); enumerators[iFors].EmitSet(cg); cg.MarkLabel(continueTargets[iFors]); enumerators[iFors].EmitGet(cg); cg.EmitCall(typeof(IEnumerator), "MoveNext", Type.EmptyTypes); cg.Emit(OpCodes.Brfalse, exitTargets[jIters]); enumerators[iFors].EmitGet(cg); cg.EmitCall(typeof(IEnumerator).GetProperty("Current").GetGetMethod()); cfor.Left.EmitSet(cg); iFors++; } else if (iter is ListComprehensionIf) { ListComprehensionIf cif = iter as ListComprehensionIf; cg.EmitTestTrue(cif.Test); cg.Emit(OpCodes.Brfalse, exitTargets[jIters]); } jIters++; } // append the item list.EmitGet(cg); this.item.Emit(cg); cg.EmitCall(typeof(List), "Append"); // third loop: in reverse order iFors = continueTargets.Length - 1; jIters = iters.Length - 1; while (jIters >= 0) { ListComprehensionIterator iter = iters[jIters]; if (iter is ListComprehensionFor) { cg.Emit(OpCodes.Br, continueTargets[iFors]); cg.FreeLocalTmp(enumerators[iFors]); iFors--; } cg.MarkLabel(exitTargets[jIters]); jIters--; } list.EmitGet(cg); cg.FreeLocalTmp(list); }
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++; } } }
public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots) { cg.EmitRawConstant(null); }
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 }
public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots) { cg.EmitInt(count); cg.Emit(OpCodes.Newarr, parameter.Type); for (int i = 0; i < count; i++) { cg.Emit(OpCodes.Dup); cg.EmitInt(i); argSlots[start + i].EmitGet(cg); cg.EmitConvertFromObject(parameter.Type); cg.EmitStelem(parameter.Type); } }