internal static CodeGen CreateVirtualMethodHelper(TypeGen tg, MethodInfo mi) { ParameterInfo[] parms = mi.GetParameters(); Type[] types = CompilerHelpers.GetTypes(parms); string[] paramNames = new string[parms.Length]; Type miType = mi.DeclaringType; for (int i = 0; i < types.Length; i++) { paramNames[i] = parms[i].Name; if (types[i] == miType) { types[i] = tg.myType; } } CodeGen cg = tg.DefineMethod(MethodAttributes.Public | MethodAttributes.HideBySig, "#base#" + mi.Name, mi.ReturnType, types, paramNames); EmitBaseMethodDispatch(mi, cg); cg.Finish(); return cg; }
/// <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), Ops.EMPTY)); // leaves our module instance on the stack, we save it to create the delegate. Slot instance = new LocalSlot(main.DeclareLocal(tg.myType), main); // notify the PythonEngine of the module. EmitModuleConstruction(tg, main, moduleName, instance, referencedAssemblies); main.Emit(OpCodes.Pop); // we don't care about the PythonModule. // Emit the delegate to the init method (init) main.EmitDelegate(init, typeof(InitializeModule), instance); // Call ExecuteCompiled main.EmitCall(typeof(Ops), "ExecuteCompiled", ExecuteCompiledSignature); main.EmitReturn(); return main; }