public override void EmitSet(CodeGen cg) { if (instance.Type.IsAssignableFrom(type)) { cg.Emit(OpCodes.Castclass, instance.Type); } instance.EmitSet(cg); }
public override void EmitSet(CodeGen cg) { Slot val = cg.GetLocalTmp(Type); val.EmitSet(cg); EmitSet(cg, val); cg.FreeLocalTmp(val); }
/// <summary> /// Generates a static entry point for stand-alone EXEs. We just new up our module dstructure /// and then call into Ops to get running. /// </summary> internal static CodeGen GenerateModuleEntryPoint(TypeGen tg, CodeGen init, string moduleName, IList <string> referencedAssemblies) { CodeGen main = tg.DefineMethod(MethodAttributes.Static | MethodAttributes.Public, "Main", typeof(int), Type.EmptyTypes, new string[] { }); main.SetCustomAttribute(new CustomAttributeBuilder(typeof(STAThreadAttribute).GetConstructor(Type.EmptyTypes), new object[0])); // Create instance of the module Slot instance = main.GetLocalTmp(tg.myType); main.EmitNew(tg.DefaultConstructor); instance.EmitSet(main); // Emit instance for the ExecuteCompiled call instance.EmitGet(main); // Emit the delegate to the init method main.EmitDelegate(init, typeof(InitializeModule), instance); main.EmitString(moduleName); // 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 ExecuteCompiled main.EmitCall(typeof(IronPython.Hosting.PythonEngine), "ExecuteCompiled", new Type[] { typeof(CustomFieldIdDict), typeof(InitializeModule), typeof(string), typeof(string[]) }); main.EmitReturn(); return(main); }
public override void EmitSet(CodeGen cg, Slot val) { val.EmitGet(cg); cg.EmitCastToObject(Type); val = cg.GetLocalTmp(typeof(object)); val.EmitSet(cg); instance.EmitGet(cg); cg.EmitInt(index); val.EmitGet(cg); cg.Emit(OpCodes.Stelem_Ref); }
private void EmitGeneratorBody(CodeGen cg, CodeGen ocg) { // Create the GenerateNext function CodeGen ncg = cg.DefineMethod(name.GetString() + "$g" + counter++, typeof(bool), new Type[] { typeof(Generator), typeof(object).MakeByRefType() }, new String[] { "$gen", "$ret" }); PromoteLocalsToEnvironment(); // Namespace without er factory - all locals must exist ahead of time ncg.Names = new Namespace(null); Slot generator = ncg.GetArgumentSlot(0); ncg.StaticLinkSlot = new FieldSlot(generator, typeof(Generator).GetField("staticLink")); if (HasEnvironment) { cg.EnvironmentSlot = CreateEnvironment(cg); EnvironmentFactory ef = this.environmentFactory; Slot envSlotCast = new CastSlot( new FieldSlot(generator, typeof(Generator).GetField("environment")), ef.EnvironmentType ); Slot envSlot = ncg.GetLocalTmp(ef.EnvironmentType); // setup the environment and static link slots ncg.EnvironmentSlot = envSlot; ncg.ContextSlot = envSlot; // pull the environment into typed local variable envSlot.EmitSet(ncg, envSlotCast); InheritEnvironment(ncg); CreateGeneratorTemps(ef, ncg); } else { ncg.ContextSlot = ncg.StaticLinkSlot; } ncg.ModuleSlot = new PropertySlot(ncg.ContextSlot, typeof(ICallerContext).GetProperty("Module")); CreateClosureSlots(ncg); CreateGlobalSlots(ncg, ocg); // Emit the generator body using the typed er EmitGenerator(ncg); // Initialize the generator EmitTupleParams(cg); // Create instance of the generator cg.EmitStaticLinkOrNull(); cg.EmitEnvironmentOrNull(); cg.EmitDelegate(ncg, typeof(Generator.NextTarget), null); cg.EmitNew(typeof(Generator), new Type[] { typeof(FunctionEnvironmentDictionary), typeof(FunctionEnvironmentDictionary), typeof(Generator.NextTarget) }); cg.EmitReturn(); }
// This override assumes that the IL stack already holds the value to be assigned from. public virtual void EmitSet(CodeGen cg) { // localTmpVal = <top of IL stack> Slot localTmpVal = cg.GetLocalTmp(typeof(object)); localTmpVal.EmitSet(cg); // <slot> = localTmpVal EmitSet(cg, localTmpVal); cg.FreeLocalTmp(localTmpVal); }
public override void EmitSet(CodeGen cg) { Slot val = cg.GetLocalTmp(Type); val.EmitSet(cg); base.EmitGet(cg); val.EmitGet(cg); cg.EmitCall(typeof(BuiltinWrapper), "set_CurrentValue"); cg.FreeLocalTmp(val); }
//!!! code review protected void FinishCompare(CodeGen cg) { BinaryExpr bright = (BinaryExpr)right; Slot valTmp = cg.GetLocalTmp(typeof(object)); Slot retTmp = cg.GetLocalTmp(typeof(object)); bright.left.Emit(cg); cg.Emit(OpCodes.Dup); valTmp.EmitSet(cg); cg.EmitCall(op.target.Method); cg.Emit(OpCodes.Dup); retTmp.EmitSet(cg); cg.EmitTestTrue(); Label end = cg.DefineLabel(); cg.Emit(OpCodes.Brfalse, end); valTmp.EmitGet(cg); if (IsComparision(bright.right)) { bright.FinishCompare(cg); } else { bright.right.Emit(cg); cg.EmitCall(bright.op.target.Method); } retTmp.EmitSet(cg); cg.MarkLabel(end); retTmp.EmitGet(cg); }
public override void Emit(CodeGen cg) { cg.EmitPosition(start, end); cg.EmitModuleInstance(); cg.EmitString(root.MakeString()); if (names == Star) { cg.EmitCall(typeof(Ops), "ImportStar"); //!!! this is tricky } else { Slot fromObj = cg.GetLocalTmp(typeof(object)); cg.EmitStringArray(Name.ToStrings(names)); if (asNames != null) { cg.EmitStringArray(Name.ToStrings(asNames)); cg.EmitCall(typeof(Ops), "ImportFromAs"); } else { cg.EmitCall(typeof(Ops), "ImportFrom"); } fromObj.EmitSet(cg); for (int i = 0; i < names.Length; i++) { cg.EmitCallerContext(); fromObj.EmitGet(cg); cg.EmitString(names[i].GetString()); cg.EmitCall(typeof(Ops), "ImportOneFrom"); Name asName; if (i < asNames.Length && asNames[i] != null) { asName = asNames[i]; } else { asName = names[i]; } cg.EmitSet(asName); } } }
private void MakeRawKeysMethod() { Slot rawKeysCache = tg.AddStaticField(typeof(SymbolId[]), "ExtraKeysCache"); CodeGen init = tg.GetOrMakeInitializer(); SymbolId[] nameArray = new SymbolId[names.Slots.Count]; init.EmitSymbolIdArray(new List <Name>(names.Slots.Keys)); rawKeysCache.EmitSet(init); CodeGen cg = tg.DefineMethodOverride(typeof(CustomFieldIdDict).GetMethod("GetExtraKeys")); rawKeysCache.EmitGet(cg); cg.EmitReturn(); cg.Finish(); }
public void EmitIndirectedSymbol(CodeGen cg, SymbolId id) { Slot value; if (!indirectSymbolIds.TryGetValue(id, out value)) { // create field, emit fix-up... value = AddStaticField(typeof(int), "symbol_" + SymbolTable.IdToString(id)); CodeGen init = GetOrMakeInitializer(); Slot localTmp = init.GetLocalTmp(typeof(SymbolId)); init.EmitString((string)SymbolTable.IdToString(id)); init.EmitCall(typeof(SymbolTable), "StringToId"); localTmp.EmitSet(init); localTmp.EmitGetAddr(init); init.EmitFieldGet(typeof(SymbolId), "Id"); value.EmitSet(init); cg.FreeLocalTmp(localTmp); indirectSymbolIds[id] = value; } value.EmitGet(cg); }
public override void EmitSet(CodeGen cg) { // Disallow "[] = l", "[], a = l, l", "[[]] = [l]", etc if (items.Length == 0) { cg.Context.AddError("can't assign to " + EmptySequenceString, this); return; } // int leftCount = items.Length; Slot leftCount = cg.GetLocalTmp(typeof(int)); cg.EmitInt(items.Length); leftCount.EmitSet(cg); // object[] values = new object[leftCount]; Slot values = cg.GetLocalTmp(typeof(object[])); leftCount.EmitGet(cg); cg.Emit(OpCodes.Newarr, typeof(object)); values.EmitSet(cg); // ie = Ops.GetEnumerator(<value on stack>) Slot ie = cg.GetLocalTmp(typeof(IEnumerator)); cg.EmitCall(typeof(Ops), "GetEnumerator"); ie.EmitSet(cg); // int rightCount = Ops.GetEnumeratorValues(ie, ref values); Slot rightCount = cg.GetLocalTmp(typeof(int)); ie.EmitGet(cg); values.EmitGetAddr(cg); cg.EmitCall(typeof(Ops), "GetEnumeratorValues"); rightCount.EmitSet(cg); // if (leftCount != rightCount) // throw Ops.ValueErrorForUnpackMismatch(leftCount, rightCount); Label equalSizes = cg.DefineLabel(); leftCount.EmitGet(cg); rightCount.EmitGet(cg); cg.Emit(OpCodes.Ceq); cg.Emit(OpCodes.Brtrue_S, equalSizes); leftCount.EmitGet(cg); rightCount.EmitGet(cg); cg.EmitCall(typeof(Ops).GetMethod("ValueErrorForUnpackMismatch")); cg.Emit(OpCodes.Throw); cg.MarkLabel(equalSizes); // for (int i = 0; i < leftCount; i++) // items[i].Assign(values[i], env); int i = 0; foreach (Expr expr in items) { values.EmitGet(cg); cg.EmitInt(i++); cg.Emit(OpCodes.Ldelem_Ref); expr.EmitSet(cg); } cg.FreeLocalTmp(leftCount); cg.FreeLocalTmp(rightCount); cg.FreeLocalTmp(values); cg.FreeLocalTmp(ie); }
public 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 (ListCompIter iter in iters) { if (iter is ListCompFor) { 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 (ListCompIter iter in iters) { if (iter is ListCompFor) { ListCompFor cfor = iter as ListCompFor; cfor.list.Emit(cg); cg.EmitCall(typeof(Ops), "GetEnumerator"); 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.lhs.EmitSet(cg); iFors++; } else if (iter is ListCompIf) { ListCompIf cif = iter as ListCompIf; 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) { ListCompIter iter = iters[jIters]; if (iter is ListCompFor) { cg.Emit(OpCodes.Br, continueTargets[iFors]); cg.FreeLocalTmp(enumerators[iFors]); iFors--; } cg.MarkLabel(exitTargets[jIters]); jIters--; } list.EmitGet(cg); cg.FreeLocalTmp(list); }
//!!! need to evaluate break/continue through a try block public override void Emit(CodeGen cg) { Slot choiceVar = null; cg.EmitPosition(start, header); if (yieldTargets.Count > 0) { Label startOfBlock = cg.DefineLabel(); choiceVar = cg.GetLocalTmp(typeof(int)); cg.EmitInt(-1); choiceVar.EmitSet(cg); cg.Emit(OpCodes.Br, startOfBlock); int index = 0; foreach (YieldTarget yt in yieldTargets) { cg.MarkLabel(yt.topBranchTarget); cg.EmitInt(index++); choiceVar.EmitSet(cg); cg.Emit(OpCodes.Br, startOfBlock); } cg.MarkLabel(startOfBlock); } Label afterCatch = new Label(); Label afterElse = cg.DefineLabel(); cg.PushTryBlock(); cg.BeginExceptionBlock(); if (yieldTargets.Count > 0) { int index = 0; foreach (YieldTarget yt in yieldTargets) { choiceVar.EmitGet(cg); cg.EmitInt(index); cg.Emit(OpCodes.Beq, yt.tryBranchTarget); index++; } cg.FreeLocalTmp(choiceVar); } body.Emit(cg); if (yieldInExcept) { afterCatch = cg.DefineLabel(); cg.Emit(OpCodes.Leave, afterCatch); } cg.BeginCatchBlock(typeof(Exception)); // Extract state from the carrier exception cg.EmitCallerContext(); cg.EmitCall(typeof(Ops), "ExtractException"); Slot pyExc = cg.GetLocalTmp(typeof(object)); Slot tmpExc = cg.GetLocalTmp(typeof(object)); pyExc.EmitSet(cg); if (yieldInExcept) { cg.EndExceptionBlock(); cg.PopTargets(); } foreach (TryStmtHandler handler in handlers) { cg.EmitPosition(handler.start, handler.header); Label next = cg.DefineLabel(); if (handler.test != null) { pyExc.EmitGet(cg); handler.test.Emit(cg); cg.EmitCall(typeof(Ops), "CheckException"); if (handler.target != null) { tmpExc.EmitSet(cg); tmpExc.EmitGet(cg); } cg.EmitPythonNone(); cg.Emit(OpCodes.Ceq); cg.Emit(OpCodes.Brtrue, next); } if (handler.target != null) { tmpExc.EmitGet(cg); handler.target.EmitSet(cg); } cg.PushExceptionBlock(Targets.TargetBlockType.Catch, null); handler.body.Emit(cg); cg.EmitCallerContext(); cg.EmitCall(typeof(Ops), "ClearException"); cg.PopTargets(); if (yieldInExcept) { cg.Emit(OpCodes.Br, afterElse); } else { cg.Emit(OpCodes.Leave, afterElse); } cg.MarkLabel(next); } cg.FreeLocalTmp(tmpExc); if (yieldInExcept) { pyExc.EmitGet(cg); cg.Emit(OpCodes.Throw); cg.MarkLabel(afterCatch); } else { cg.Emit(OpCodes.Rethrow); cg.EndExceptionBlock(); cg.PopTargets(); } if (elseStmt != null) { elseStmt.Emit(cg); } cg.MarkLabel(afterElse); cg.FreeLocalTmp(pyExc); yieldTargets.Clear(); }
public override void EmitSet(CodeGen cg) { attribute.EmitSet(cg); }
public override void Emit(CodeGen cg) { cg.EmitPosition(start, header); Slot choiceVar = null; Slot returnVar = null; Label endOfTry = new Label(); if (yieldTargets.Count > 0) { Label startOfBlock = cg.DefineLabel(); choiceVar = cg.GetLocalTmp(typeof(int)); returnVar = cg.GetLocalTmp(typeof(bool)); cg.EmitInt(0); returnVar.EmitSet(cg); cg.EmitInt(-1); choiceVar.EmitSet(cg); cg.Emit(OpCodes.Br, startOfBlock); int index = 0; foreach (YieldTarget yt in yieldTargets) { cg.MarkLabel(yt.topBranchTarget); cg.EmitInt(index++); choiceVar.EmitSet(cg); cg.Emit(OpCodes.Br, startOfBlock); } cg.MarkLabel(startOfBlock); } cg.PushTryBlock(); cg.BeginExceptionBlock(); if (yieldTargets.Count > 0) { int index = 0; endOfTry = cg.DefineLabel(); foreach (YieldTarget yt in yieldTargets) { choiceVar.EmitGet(cg); cg.EmitInt(index++); cg.Emit(OpCodes.Beq, endOfTry); } } body.Emit(cg); if (yieldTargets.Count > 0) { cg.MarkLabel(endOfTry); } cg.PopTargets(); cg.PushFinallyBlock(returnVar); cg.BeginFinallyBlock(); if (yieldTargets.Count > 0) { int index = 0; foreach (YieldTarget yt in yieldTargets) { choiceVar.EmitGet(cg); cg.EmitInt(index++); cg.Emit(OpCodes.Beq, yt.tryBranchTarget); } } finallyStmt.Emit(cg); cg.EndExceptionBlock(); cg.PopTargets(); if (yieldTargets.Count > 0) { Label noReturn = cg.DefineLabel(); returnVar.EmitGet(cg); cg.Emit(OpCodes.Brfalse_S, noReturn); cg.Emit(OpCodes.Ldc_I4_1); cg.EmitReturn(); cg.MarkLabel(noReturn); } yieldTargets.Clear(); }
protected Slot CreateEnvironment(CodeGen cg) { // Get the environment size int size = CalculateEnvironmentSize(); // Create the array for the names Slot namesSlot = cg.GetLocalTmp(typeof(SymbolId[])); cg.EmitInt(size - tempsCount); cg.Emit(System.Reflection.Emit.OpCodes.Newarr, typeof(SymbolId)); namesSlot.EmitSet(cg); // Find the right environment type ConstructorInfo ctor; EnvironmentFactory esf; Type envType = GetEnvironmentType(size, cg, out ctor, out esf); // Emit the static link for the environment constructor cg.EmitStaticLinkOrNull(); cg.EmitCallerContext(); // Emit the names array for the environment constructor namesSlot.EmitGet(cg); cg.EmitNew(ctor); // Store the environment reference in the local Slot environmentSlot = cg.GetFrameSlot(envType); environmentSlot.EmitSet(cg); // Remember the environment factory for parent access environmentFactory = esf; // Create environment references environment = new Dictionary <Name, EnvironmentReference>(); foreach (KeyValuePair <Name, Binding> kv in names) { if (!kv.Value.IsEnvironment) { continue; } Name name = kv.Key; EnvironmentReference er = esf.MakeEnvironmentReference(name); Slot slot = er.CreateSlot(environmentSlot); Slot current; if (cg.Names.Slots.TryGetValue(name, out current)) { slot.EmitSet(cg, current); } else { slot.EmitSetUninitialized(cg, name); } // Set the name into the array namesSlot.EmitGet(cg); cg.EmitInt(er.Index); cg.Emit(OpCodes.Ldelema, typeof(SymbolId)); cg.EmitSymbolIdInt(name.GetString()); cg.Emit(OpCodes.Call, typeof(SymbolId).GetConstructor(new Type[] { typeof(int) })); // The full slot goes to the codegen's namespace cg.Names.SetSlot(name, slot); // Environment reference goes to the environment environment[name] = er; } return(environmentSlot); }