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;
        }