PreviousUpNext

15.4.733  src/lib/core/internal/make-mythryld-executable.pkg

##  make-mythryld-executable.pkg 

# Compiled by:
#     src/lib/core/internal/interactive-system.lib

# Here we handle generation of a new compiler "executable"
# heap image, and also start-of-execution of that image, since our
# image generation primitive (lib7::fork_to_disk f) is like fork()
# in that it returns one value in the dumping process and another
# value in the dumped process.
#
# At image generation time (aka "link time") this code builds the boot
# dictionaries, sets default signal handlers, and then dumps a heap.
# When the heap image restarts, the system goes interactive.

# (We do not want to go interactive before dumping the heap because it
# would mean that dictionaries get loaded unnecessarily.)
#
# This code refers directly to package compiler, because by the time it
# gets compiled, Makelib's conditional compilation facility has already
# made sure that package compiler refers to the visible compiler
# for the current architecture. 



###            "If I had to do it over again?
###             Hmmm...
###             I guess I'd spell 'creat()' with an 'e'."
###
###                               -- Ken Thompson


                                                                                        # mythryl_compiler_compiler_configuration       is from   src/app/makelib/mythryl-compiler-compiler/mythryl-compiler-compiler-configuration.pkg
stipulate
    package at  =  run_at__premicrothread;                                              # run_at__premicrothread                        is from   src/lib/std/src/nj/run-at--premicrothread.pkg
    package bc  =  basic_control;                                                       # basic_control                                 is from   src/lib/compiler/front/basics/main/basic-control.pkg
    package ci  =  global_control_index;                                                # global_control_index                          is from   src/lib/global-controls/global-control-index.pkg
    package cst =  compile_statistics;                                                  # compile_statistics                            is from   src/lib/compiler/front/basics/stats/compile-statistics.pkg
    package ctl =  global_controls;                                                     # global_controls                               is from   src/lib/compiler/toplevel/main/global-controls.pkg
    package fil =  file__premicrothread;                                                # file__premicrothread                          is from   src/lib/std/src/posix/file--premicrothread.pkg
    package iox =  io_exceptions;                                                       # io_exceptions                                 is from   src/lib/std/src/io/io-exceptions.pkg
    package is  =  interprocess_signals;                                                # interprocess_signals                          is from   src/lib/std/src/nj/interprocess-signals.pkg
    package lms =  list_mergesort;                                                      # list_mergesort                                is from   src/lib/src/list-mergesort.pkg
    package mcb =  mythryl_compiler;                                                    # mythryl_compiler                              is from   src/lib/core/compiler/set-mythryl_compiler-to-mythryl_compiler_for_intel32_posix.pkg
    package mcc =  makelib_internal::mythryl_compiler_compiler_configuration;           # makelib_internal                              is from   src/lib/core/internal/makelib-internal.pkg
    package mce =  make_mythryl_compiler_etc;                                           # make_mythryl_compiler_etc                     is from   src/lib/core/internal/make-mythryl-compiler-etc.pkg
    package mcv =  mythryl_compiler_version;                                            # mythryl_compiler_version                      is from   src/lib/core/internal/mythryl-compiler-version.pkg
    package ri  =  runtime_internals;                                                   # runtime_internals                             is from   src/lib/std/src/nj/runtime-internals.pkg
    package wnx =  winix__premicrothread;                                               # winix__premicrothread                         is from   src/lib/std/winix--premicrothread.pkg
    package xns =  exceptions;                                                          # exceptions                                    is from   src/lib/std/exceptions.pkg
herein

    package make_mythryld_executable: (weak)   api { }   {                              # No return value -- our 'return value' is the 'mythryld' compiler executable heap image file we generate.




                                                                                        # file__premicrothread                          is from   src/lib/std/src/posix/file--premicrothread.pkg

        my _ = {                                                                        # A little trick forcing all our code to execute immediately upon this module being loaded.
             
            my  { the_do_all_requested_compiles }                                       # This is ultimately the return value from
                =                                                                       #        fun read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries'
                mce::make_mythryl_compiler_etc                                          # in    src/app/makelib/main/makelib-g.pkg       
                  {
                    root_dir_of_mythryl_source_distro
                        =>
                        wnx::file::current_directory ()
                  }
# Can't we move this exception busywork down into mce:: ?
                except
                    e as iox::IO { op, name, cause }
                        =>
                        {   fil::write (fil::stderr,
                                           cat ["IO exception: file = ", name,
                                                   ", op = ", op,
                                                   ", cause: ",
                                                   xns::exception_message cause,
                                                   "\n"]);
                            raise exception e;
                        };

                   e
                       =>
                       {   fil::write (fil::stderr,
                                               cat ["exception raised during init phase: ",
                                                       xns::exception_message e, "\n"]);
                           raise exception e;
                       };
                end;

            do_all_requested_compiles
                =
# Can't we move this busywork down into mce:: ?
                case the_do_all_requested_compiles              # Ultimately, this is the return value from   fun read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries'     in    src/app/makelib/main/makelib-g.pkg
                    THE  do_all_requested_compiles              # Defined by "fun do_all_requested_compiles () ..."                                                                             in    src/app/makelib/main/makelib-g.pkg
                        =>
                        do_all_requested_compiles;
                        #
                        # Above does NOT RETURN!        

                    NULL =>
                        raise exception DIE "make-mythryld-executable.pkg: the_do_all_requested_compiles was NULL?!\n";
                esac;


            # Establish default signal handlers:
            #
            fun handle_sigint  _
                =
                *unsafe::sigint_fate;                                   # unsafe                        is from   src/lib/std/src/unsafe/unsafe.pkg

            #
            fun handle_term _
                =
                wnx::process::exit_x  wnx::process::failure;

            #
                                                                                                my _ =
            {   is::override_signal_handler  (is::SIGINT,  is::HANDLER handle_sigint    );
                is::override_signal_handler  (is::SIGTERM, is::HANDLER handle_term      );
                is::override_signal_handler  (is::SIGQUIT, is::HANDLER handle_term      );
            };


            # Install "read_eval_print_hook" functionality:
            /* */                                                                               my _ =
            read_eval_print_hook::read_eval_print_hook
                :=
                mcb::rpl::read_eval_print_from_file;


            # Put lowhalf controls into the main hierarchy of controls:
            /* */                                                                               my _ =
            bc::note_subindex
              (
                ctl::lowhalf::prefix,
                ctl::lowhalf::registry,
                ctl::lowhalf::menu_slot
              );



                                                                                        my _ =
            {
                # Initialize controls.  In particular, this will
                # (for example) initialize control cm::foo
                # from the Unix environment variable CM_FOO,
                # if it exists:
                #
                ci::set_up_controls_from_posix_environment
                    #
                    bc::top_index;


                # Populate toplevel scripting enviroment with
                # various handy things, in particular
                #
                #     makelib::scripting_globals                                                                # See "package scripting_globals" def in    src/app/makelib/main/makelib-g.pkg
                #
                stipulate

                    fun eval_string  code_string
                        =
                        safely::do {    # This should be a supported, exported 'eval' function.
                          #
                          open_it  =>   {. fil::open_string  code_string; },
                          close_it =>   fil::close_input,
                          cleanup  =>   \\ _  =  ()
                        }
                        mcb::rpl::read_eval_print_from_stream;

                herein
                    # Empty the contents of the 'makelib' package
                    # into the toplevel environment, so we can
                    # interactively type
                    #     help ()
                    # instead of the more verbose
                    #     makelib::help ()
                    # and ditto for   show_apis()   etc.
                                                                my _ =
                    { eval_string "include package   makelib;;";                print "\n\n"; };


                    # Ditto for the 'math' package:
                                                                my _ =
                    { eval_string "include package   math;;";           print "\n\n"; };


                    # Ditto for the 'file' package:
                                                                my _ =
                    { eval_string "include package   file__premicrothread;;";           print "\n\n"; };

                                                                my _ =
                    { eval_string "include package   makelib::scripting_globals;;";             print "\n\n"; };
                end;


                {   ctl::print::say ("            make-mythryld-executable.pkg:   Startup/shutdown code-hooks schedule is:\n\n");
                    #
                    # Here we whip up a listing looking something like:
                    #
                    #     ([ STARTUP_PHASE_4_MAKE_STDIN_STDOUT_AND_STDERR                   ],   winix-text-file-for-os-g--premicrothread.pkg: Make stdin/stdout/stderr
                    #     ([ STARTUP_PHASE_5_CLOSE_STALE_OUTPUT_STREAMS                     ],   io-startup-and-shutdown--premicrothread.pkg: .init streams
                    #     ([ STARTUP_PHASE_7_RESET_POSIX_INTERPROCESS_SIGNAL_HANDLER_TABLE  ],   interprocess-signals.pkg: reset_posix_interprocess_signal_handler_table
                    #     ([ STARTUP_PHASE_8_RESET_COMPILER_STATISTICS                      ],   compile-statistics.pkg:  reset
                    #     ([ STARTUP_PHASE_9_RESET_CPU_AND_WALLCLOCK_TIMERS                 ],   runtime-internals: reset cpu and wallclock timers
                    #     ([ STARTUP_PHASE_11_START_SUPPORT_HOSTTHREADS                     ],   microthread-preemptive-scheduler.pkg: start support hostthreads
                    #     ([ STARTUP_PHASE_16_OF_HEAP_MADE_BY_SPAWN_TO_DISK                 ],   interprocess-signals.pkg: initialize_posix_interprocess_signal_handler_table
                    #     ([ SHUTDOWN_PHASE_4_STOP_SUPPORT_HOSTTHREADS                      ],   microthread-preemptive-scheduler.pkg: stop  support hostthreads
                    #     ([ SHUTDOWN_PHASE_5_ZERO_COMPILE_STATISTICS                       ],   compile-statistics.pkg:  last := zeros
                    #     ([ SHUTDOWN_PHASE_6_CLOSE_OPEN_FILES                              ],   io-startup-and-shutdown--premicrothread.pkg: .close streams
                    #     ([ SHUTDOWN_PHASE_6_FLUSH_OPEN_FILES                              ],   io-startup-and-shutdown--premicrothread.pkg: .flush streams
                    #     ([ SHUTDOWN_PHASE_7_CLEAR_POSIX_INTERPROCESS_SIGNAL_HANDLER_TABLE ],   interprocess-signals.pkg: clear_posix_interprocess_signal_handler_table
                    #
                    fun compare_schedule_entries ((_, (when1 ! _)), (_, (when2 ! _))) =>  at::when_gt (when1, when2);
                        compare_schedule_entries _                                    =>  TRUE;                         # Cannot happen.
                    end;

                    schedule =  at::get_schedule();
                    schedule =  lms::sort_list  compare_schedule_entries  schedule;

                    apply'  schedule  (\\ (label, whens) =  printf "                ([ %-66s ],\t %s\n"  (string::join ", " (map at::when_to_string whens))  label);
                };


                ctl::print::say ("\n\n            make-mythryld-executable.pkg:   Generating heap image '" + mcc::mythryld_executable_filename_to_create + "'...\n");

                # Now we do our 'fork-to-disk' call.
                #
                #
                case (lib7::fork_to_disk  mcc::mythryld_executable_filename_to_create)                  # fork_to_disk                          is from   src/lib/std/src/nj/save-heap-to-disk.pkg
                    #
                    lib7::AM_CHILD
                        =>
                        {   # We are the dumped executable (heap image)                                 # Note that at this point fork_to_disk will already have done
                            # just starting execution after                                             #
                            # being invoked as an application,                                          #    at::run_functions_scheduled_to_run   at::STARTUP_PHASE_[1-7]...
                            # and we need to go do our stuff:                                           # 
                            #
                            mythryld_app::main  do_all_requested_compiles;                              # Does not return.
                        };

                    lib7::AM_PARENT
                        =>
                        {   # We are the 'parent' process generating
                            # the executable, and we're done:
                            #   
                            print "            make-mythryld-executable.pkg:   Wrote executable for ";
                            print mcv::mythryl_interactive_banner;
                            print "\n";
                            print "            make-mythryld-executable.pkg:   Done, doing exit (0);\n";
                            wnx::process::exit_x   wnx::process::success;
                        };
                esac;
                                                                                                        # read_eval_print_loops_g               is from   src/lib/compiler/toplevel/interact/read-eval-print-loops-g.pkg
                                                                                                        # read_eval_print_loop_g                is from   src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg
                                                                                                        # translate_raw_syntax_to_execode_g     is from   src/lib/compiler/toplevel/main/translate-raw-syntax-to-execode-g.pkg
            };
        };                                                                                              # my _ = 
    };                                                                                                  # package make_mythryld_executable
end;                                                                                                    # stipulate


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext