Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Diff of /sml/trunk/src/cm/bootstrap/btcompile.sml
ViewVC logotype

Diff of /sml/trunk/src/cm/bootstrap/btcompile.sml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 357, Mon Jun 28 08:46:30 1999 UTC revision 518, Wed Jan 12 06:26:25 2000 UTC
# Line 7  Line 7 
7   * Author: Matthias Blume (blume@kurims.kyoto-u.ac.jp)   * Author: Matthias Blume (blume@kurims.kyoto-u.ac.jp)
8   *)   *)
9  functor BootstrapCompileFn (structure MachDepVC: MACHDEP_VC  functor BootstrapCompileFn (structure MachDepVC: MACHDEP_VC
10                              val os: SMLofNJ.SysInfo.os_kind) :> sig                              val os : SMLofNJ.SysInfo.os_kind
11                                val load_plugin : string -> bool) :> sig
12      val compile :      val make' : string option -> bool
13          { dirbase: string,      val make : unit -> bool
14            pcmodespec: string,      val deliver' : string option -> bool
15            initgspec: string,      val deliver : unit -> bool
16            maingspec: string,      val reset : unit -> unit
17            stabilize: bool }      val symval : string -> { get: unit -> int option, set: int option -> unit }
         -> bool  
   
18  end = struct  end = struct
19    
20      structure EM = GenericVC.ErrorMsg      structure EM = GenericVC.ErrorMsg
# Line 27  Line 25 
25      structure CoerceEnv = GenericVC.CoerceEnv      structure CoerceEnv = GenericVC.CoerceEnv
26      structure SSV = SpecificSymValFn (structure MachDepVC = MachDepVC      structure SSV = SpecificSymValFn (structure MachDepVC = MachDepVC
27                                        val os = os)                                        val os = os)
28        structure P = OS.Path
29      (* Since the bootstrap compiler never executes any of the code      structure F = OS.FileSys
30       * it produces, we don't need any dynamic values.  Therefore,      structure BF = MachDepVC.Binfile
      * we create RecompPersstate (but not FullPersstate!) and  
      * instantiate Recomp as well as RecompTraversal.  
      * Since RecompPersstate is not part of any surrounding FullPersstate,  
      * function "discard_value" simply does nothing. *)  
     structure RecompPersstate =  
         RecompPersstateFn (structure MachDepVC = MachDepVC  
                            val discard_code = true  
                            fun discard_value (i: SmlInfo.info) = ())  
     structure Recomp = RecompFn (structure PS = RecompPersstate)  
     structure RT = CompileGenericFn (structure CT = Recomp)  
   
     fun recomp gp g = isSome (RT.group gp g)  
   
     (* instantiate Stabilize... *)  
     structure Stabilize =  
         StabilizeFn (fun bn2statenv gp i = #1 (#stat (valOf (RT.bnode gp i)))  
                      val getPid = RecompPersstate.pid_fetch_sml  
                      fun warmup (i, p) = ()  
                      val recomp = recomp)  
     (* ... and Parse *)  
     structure Parse = ParseFn (structure Stabilize = Stabilize)  
   
     fun compile { dirbase, pcmodespec, initgspec, maingspec, stabilize } = let  
31    
32          val arch = MachDepVC.architecture          val arch = MachDepVC.architecture
33          val osname = FilenamePolicy.kind2name os          val osname = FilenamePolicy.kind2name os
34          val bindir = concat [dirbase, ".bin.", arch, "-", osname]      val archos = concat [arch, "-", osname]
         val bootdir = concat [dirbase, ".boot.", arch, "-", osname]  
35    
36          val keep_going = EnvConfig.getSet StdConfig.keep_going NONE      fun init_servers (GroupGraph.GROUP { grouppath, ... }) =
37            Servers.cmb { archos = archos,
38                          root = SrcPath.descr grouppath }
39    
40          val ctxt = SrcPath.cwdContext ()      structure Compile = CompileFn (structure MachDepVC = MachDepVC
41                                       val compile_there =
42                                           Servers.compile o SrcPath.descr)
43    
44          val pidfile = OS.Path.joinDirFile { dir = bootdir, file = "RTPID" }      structure BFC = BfcFn (structure MachDepVC = MachDepVC)
         val listfile = OS.Path.joinDirFile { dir = bootdir, file = "BINLIST" }  
45    
46          val pcmode = let      (* instantiate Stabilize... *)
47              fun work s = let      structure Stabilize =
48                  fun loop l = let          StabilizeFn (fun destroy_state _ i = Compile.evict i
49                      val line = TextIO.inputLine s                       structure MachDepVC = MachDepVC
50                         fun recomp gp g = let
51                             val { store, get } = BFC.new ()
52                             val _ = init_servers g
53                             val { group, ... } =
54                                 Compile.newTraversal (fn _ => fn _ => (),
55                                                       store, g)
56                  in                  in
57                      if line = "" then PathConfig.hardwire l                           case Servers.withServers (fn () => group gp) of
58                      else case String.tokens Char.isSpace line of                               NONE => NONE
59                          [a, s] => loop ((a, s) :: l)                             | SOME _ => SOME get
60                        | _ => (Say.say [pcmodespec,                       end
61                                         ": malformed line (ignored)\n"];                       val getII = Compile.getII)
62                                loop l)  
63        (* ... and Parse *)
64        structure Parse = ParseFn (structure Stabilize = Stabilize
65                                   fun pending () = SymbolMap.empty)
66    
67        (* copying an input file to an output file safely... *)
68        fun copyFile (oi, ci, oo, co, inp, outp, eof) (inf, outf) = let
69            fun workIn is = let
70                fun workOut os = let
71                    val N = 4096
72                    fun loop () =
73                        if eof is then () else (outp (os, inp (is, N)); loop ())
74                in
75                    loop ()
76                end
77            in
78                SafeIO.perform { openIt = fn () => oo outf,
79                                 closeIt = co,
80                                 work = workOut,
81                                 cleanup = fn _ =>
82                                     (F.remove outf handle _ => ()) }
83                  end                  end
84              in              in
85                  loop []          SafeIO.perform { openIt = fn () => oi inf,
86                             closeIt = ci,
87                             work = workIn,
88                             cleanup = fn _ => () }
89        end
90    
91        val copyTextFile =
92            copyFile (TextIO.openIn, TextIO.closeIn,
93                      AutoDir.openTextOut, TextIO.closeOut,
94                      TextIO.inputN, TextIO.output, TextIO.endOfStream)
95    
96        val copyBinFile =
97            copyFile (BinIO.openIn, BinIO.closeIn,
98                      AutoDir.openBinOut, BinIO.closeOut,
99                      BinIO.inputN, BinIO.output, BinIO.endOfStream)
100    
101        fun mk_compile deliver root dbopt = let
102    
103            val dirbase = getOpt (dbopt, BtNames.dirbaseDefault)
104            val pcmodespec = BtNames.pcmodespec
105            val initgspec = BtNames.initgspec
106            val maingspec = BtNames.maingspec
107    
108            val bindir = concat [dirbase, ".bin.", archos]
109            val bootdir = concat [dirbase, ".boot.", archos]
110    
111            fun listName (p, copy) =
112                case P.fromString p of
113                    { vol = "", isAbs = false, arcs = arc0 :: arc1 :: arcn } => let
114                        fun win32name () =
115                            concat (arc1 ::
116                                    foldr (fn (a, r) => "\\" :: a :: r) [] arcn)
117                        fun doCopy () = let
118                            val bootpath =
119                                P.toString { isAbs = false, vol = "",
120                                             arcs = bootdir :: arc1 :: arcn }
121                        in
122                            copyBinFile (p, bootpath)
123              end              end
124          in          in
125              SafeIO.perform { openIt = fn () => TextIO.openIn pcmodespec,                      if copy andalso arc0 = bindir then doCopy () else ();
126                               closeIt = TextIO.closeIn,                      case os of
127                               work = work,                          SMLofNJ.SysInfo.WIN32 => win32name ()
128                               cleanup = fn () => () }                        | _ => P.toString { isAbs = false, vol = "",
129                                              arcs = arc1 :: arcn }
130          end          end
131                  | _ => raise Fail "BootstrapCompile:listName: bad name"
132    
133            val keep_going = #get StdConfig.keep_going ()
134    
135            val ctxt = SrcPath.cwdContext ()
136    
137            val pidfile = P.joinDirFile { dir = bootdir, file = "RTPID" }
138            val listfile = P.joinDirFile { dir = bootdir, file = "BOOTLIST" }
139    
140            val pcmode = PathConfig.new ()
141            val _ = PathConfig.processSpecFile (pcmode, pcmodespec)
142    
143          fun stdpath s = SrcPath.standard pcmode { context = ctxt, spec = s }          fun stdpath s = SrcPath.standard pcmode { context = ctxt, spec = s }
144    
145          val initgspec = stdpath initgspec          val initgspec = stdpath initgspec
146          val maingspec = stdpath maingspec          val maingspec =
147                case root of
148                    NONE => stdpath maingspec
149                  | SOME r => SrcPath.fromDescr pcmode r
150    
151          val initfnpolicy =          val cmifile = valOf (SrcPath.reAnchoredName (initgspec, bootdir))
152              FilenamePolicy.separate { bindir = bootdir, bootdir = bootdir }              handle Option => raise Fail "BootstrapCompile: cmifile"
                 { arch = arch, os = os }  
153    
154          val mainfnpolicy =          val fnpolicy =
155              FilenamePolicy.separate { bindir = bindir, bootdir = bootdir }              FilenamePolicy.separate { bindir = bindir, bootdir = bootdir }
156                  { arch = arch, os = os }                  { arch = arch, os = os }
157    
158          fun mkParam { primconf, pervasive, pervcorepids, fnpolicy }          fun mkParam { primconf, pervasive, pervcorepids }
159                      { corenv } =                      { corenv } =
160              { primconf = primconf,              { primconf = primconf,
161                fnpolicy = fnpolicy,                fnpolicy = fnpolicy,
162                pcmode = pcmode,                pcmode = pcmode,
163                symenv = SSV.env,                symval = SSV.symval,
164                keep_going = keep_going,                keep_going = keep_going,
165                pervasive = pervasive,                pervasive = pervasive,
166                corenv = corenv,                corenv = corenv,
# Line 116  Line 170 
170    
171          (* first, build an initial GeneralParam.info, so we can          (* first, build an initial GeneralParam.info, so we can
172           * deal with the pervasive env and friends... *)           * deal with the pervasive env and friends... *)
         local  
             (* We could actually go and calculate the actual pid of primEnv.  
              * But in reality it's pretty pointless to do so... *)  
             val bogusPid = PS.fromBytes (Byte.stringToBytes "0123456789abcdef")  
             val pspec = { name = "primitive",  
                           env = E.mkenv { static = E.primEnv,  
                                           symbolic = E.symbolicPart E.emptyEnv,  
                                           dynamic = emptydyn },  
                           pidInfo = { statpid = bogusPid,  
                                       sympid = bogusPid,  
                                       ctxt = SE.empty } }  
         in  
             val primconf = Primitive.configuration [pspec]  
         end  
173    
174            val primconf = Primitive.primEnvConf
175          val mkInitParam = mkParam { primconf = primconf,          val mkInitParam = mkParam { primconf = primconf,
176                                      pervasive = E.emptyEnv,                                      pervasive = E.emptyEnv,
177                                      pervcorepids = PidSet.empty,                                      pervcorepids = PidSet.empty }
                                     fnpolicy = initfnpolicy }  
178    
179          val param_nocore = mkInitParam { corenv = BE.staticPart BE.emptyEnv }          val param_nocore = mkInitParam { corenv = BE.staticPart BE.emptyEnv }
180    
# Line 143  Line 183 
183          val ginfo_nocore = { param = param_nocore, groupreg = groupreg,          val ginfo_nocore = { param = param_nocore, groupreg = groupreg,
184                               errcons = errcons }                               errcons = errcons }
185    
186          fun main_compile arg = let          fun mk_main_compile arg = let
187    
188              val { rts, core, pervasive, primitives, binpaths } = arg              val { rts, core, pervasive, primitives, binpaths } = arg
189    
190              val ovldR = GenericVC.Control.overloadKW              val ovldR = GenericVC.Control.overloadKW
191              val savedOvld = !ovldR              val savedOvld = !ovldR
192              val _ = ovldR := true              val _ = ovldR := true
193                val sbnode = Compile.newSbnodeTraversal ()
194    
195              (* here we build a new gp -- the one that uses the freshly              (* here we build a new gp -- the one that uses the freshly
196               * brewed pervasive env, core env, and primitives *)               * brewed pervasive env, core env, and primitives *)
197              val core = valOf (RT.snode ginfo_nocore core)              val core = valOf (sbnode ginfo_nocore core)
198              val corenv =  CoerceEnv.es2bs (#1 (#stat core))              val corenv =  CoerceEnv.es2bs (#env (#statenv core ()))
199              val core_sym = #1 (#sym core)              val core_sym = #symenv core ()
200    
201              (* The following is a bit of a hack (but corenv is a hack anyway):              (* The following is a bit of a hack (but corenv is a hack anyway):
202               * As soon as we have core available, we have to patch the               * As soon as we have core available, we have to patch the
# Line 164  Line 206 
206              val ginfo_justcore = { param = param_justcore, groupreg = groupreg,              val ginfo_justcore = { param = param_justcore, groupreg = groupreg,
207                                     errcons = errcons }                                     errcons = errcons }
208    
209              fun rt n = valOf (RT.snode ginfo_justcore n)              fun rt n = valOf (sbnode ginfo_justcore n)
210              val rts = rt rts              val rts = rt rts
211              val pervasive = rt pervasive              val pervasive = rt pervasive
212    
213              fun sn2pspec (name, n) = let              fun sn2pspec (name, n) = let
214                  val { stat = (s, sp), sym = (sy, syp), ctxt } = rt n                  val { statenv, symenv, statpid, sympid } = rt n
215                    val { env = static, ctxt } = statenv ()
216                  val env =                  val env =
217                      E.mkenv { static = s, symbolic = sy, dynamic = emptydyn }                      E.mkenv { static = static,
218                  val pidInfo = { statpid = sp, sympid = syp, ctxt = ctxt }                                symbolic = symenv (),
219                                  dynamic = emptydyn }
220                    val pidInfo =
221                        { statpid = statpid, sympid = sympid, ctxt = ctxt }
222              in              in
223                  { name = name, env = env, pidInfo = pidInfo }                  { name = name, env = env, pidInfo = pidInfo }
224              end              end
# Line 181  Line 227 
227    
228              val _ = ovldR := savedOvld              val _ = ovldR := savedOvld
229    
230              (* This is a hack but must be done for both the symbolic              (* The following is a hack but must be done for both the symbolic
231               * and later the dynamic part of the core environment:               * and later the dynamic part of the core environment:
232               * we must include these parts in the pervasive env. *)               * we must include these parts in the pervasive env. *)
233              val perv_sym = E.layerSymbolic (#1 (#sym pervasive), core_sym)              val perv_sym = E.layerSymbolic (#symenv pervasive (),
234                                                core_sym)
235    
236              val param =              val param =
237                  mkParam { primconf = Primitive.configuration pspecs,                  mkParam { primconf = Primitive.configuration pspecs,
238                            pervasive = E.mkenv { static = #1 (#stat pervasive),                            pervasive =
239                              E.mkenv { static = #env (#statenv pervasive ()),
240                                                  symbolic = perv_sym,                                                  symbolic = perv_sym,
241                                                  dynamic = emptydyn },                                                  dynamic = emptydyn },
242                            pervcorepids =                            pervcorepids =
243                              PidSet.addList (PidSet.empty,                              PidSet.addList (PidSet.empty,
244                                              [#2 (#stat pervasive),                                              [#statpid pervasive,
245                                               #2 (#sym pervasive),                                               #sympid pervasive,
246                                               #2 (#stat core)]),                                               #statpid core]) }
                           fnpolicy = mainfnpolicy }  
247                          { corenv = corenv }                          { corenv = corenv }
248              val stableflag = if stabilize then SOME true else NONE              val stab =
249                    if deliver then SOME true else NONE
250          in          in
251              case Parse.parse NONE param stableflag maingspec of              Servers.dirbase dirbase;
252                  NONE => false              case Parse.parse load_plugin NONE param stab maingspec of
253                | SOME (g, gp) =>                  NONE => NONE
254                      if recomp gp g then let                | SOME (g, gp) => let
255                          val rtspid = PS.toHex (#2 (#stat rts))                      fun thunk () = let
256                          val bootfiles =                          val _ = init_servers g
257                              map (fn x => (x, NONE)) binpaths @                          fun store _ = ()
258                              MkBootList.group g                          val { group = recomp, ... } =
259                                Compile.newTraversal (fn _ => fn _ => (), store, g)
260                            val res =
261                                Servers.withServers (fn () => recomp gp)
262                        in
263                            if isSome res then let
264                                val rtspid = PS.toHex (#statpid rts)
265                          fun writeList s = let                          fun writeList s = let
266                              fun offset NONE = ["\n"]                                  fun add ((p, flag), l) = let
267                                | offset (SOME i) = ["@", Int.toString i, "\n"]                                      val n = listName (p, true)
268                              fun showBootFile (p, off) =                                  in
269                                  TextIO.output (s, concat (p :: offset off))                                      if flag then n :: l else l
270                                    end
271                                    fun transcribe (p, NONE) = listName (p, true)
272                                      | transcribe (p, SOME (off, desc)) =
273                                        concat [listName (p, false),
274                                                "@", Int.toString off, ":", desc]
275                                    val bootstrings =
276                                        foldr add
277                                              (map transcribe (MkBootList.group g))
278                                              binpaths
279                                    fun show str =
280                                        (TextIO.output (s, str);
281                                         TextIO.output (s, "\n"))
282                          in                          in
283                              app showBootFile bootfiles                                  app show bootstrings
284                          end                          end
285                      in                      in
286                          Say.say ["Runtime System PID is: ", rtspid, "\n"];                              if deliver then
287                          SafeIO.perform { openIt = fn () =>                                  (SafeIO.perform
288                                     { openIt = fn () =>
289                                             AutoDir.openTextOut pidfile,                                             AutoDir.openTextOut pidfile,
290                                           closeIt = TextIO.closeOut,                                           closeIt = TextIO.closeOut,
291                                           work = fn s =>                                           work = fn s =>
292                                             TextIO.output (s, rtspid ^ "\n"),                                             TextIO.output (s, rtspid ^ "\n"),
293                                           cleanup = fn () =>                                     cleanup = fn _ =>
294                                             OS.FileSys.remove pidfile                                             OS.FileSys.remove pidfile
295                                             handle _ => () };                                             handle _ => () };
296                          SafeIO.perform { openIt = fn () =>                                   SafeIO.perform
297                                     { openIt = fn () =>
298                                             AutoDir.openTextOut listfile,                                             AutoDir.openTextOut listfile,
299                                           closeIt = TextIO.closeOut,                                           closeIt = TextIO.closeOut,
300                                           work = writeList,                                           work = writeList,
301                                           cleanup = fn () =>                                     cleanup = fn _ =>
302                                             OS.FileSys.remove listfile                                             OS.FileSys.remove listfile
303                                             handle _ => () };                                             handle _ => () };
304                                     copyTextFile (SrcPath.osstring initgspec,
305                                                   cmifile);
306                                     Say.say ["Runtime System PID is: ",
307                                              rtspid, "\n"])
308                                else ();
309                          true                          true
310                      end                      end
311                      else false                      else false
312          end handle Option => (RT.reset (); false)                      end
313                    in
314                        SOME ((g, gp, pcmode), thunk)
315                    end
316            end handle Option => (Compile.reset (); NONE)
317                     (* to catch valOf failures in "rt" *)                     (* to catch valOf failures in "rt" *)
318      in      in
319          case BuildInitDG.build ginfo_nocore initgspec of          case BuildInitDG.build ginfo_nocore initgspec of
320              SOME x => main_compile x              SOME x => mk_main_compile x
321            | NONE => false            | NONE => NONE
322        end
323    
324        fun compile deliver dbopt =
325            case mk_compile deliver NONE dbopt of
326                NONE => false
327              | SOME (_, thunk) => thunk ()
328    
329        local
330            fun slave (dirbase, root) =
331                case mk_compile false (SOME root) (SOME dirbase) of
332                    NONE => NONE
333                  | SOME ((g, gp, pcmode), _) => let
334                        val trav = Compile.newSbnodeTraversal () gp
335                        fun trav' sbn = isSome (trav sbn)
336                    in
337                        SOME (g, trav', pcmode)
338      end      end
339        in
340            val _ = CMBSlaveHook.init archos slave
341        end
342    
343        fun reset () =
344            (Compile.reset ();
345             Parse.reset ())
346    
347        val make' = compile false
348        fun make () = make' NONE
349        fun deliver' arg =
350            SafeIO.perform { openIt = fn () => (),
351                             closeIt = reset,
352                             work = fn () => compile true arg,
353                             cleanup = fn _ => () }
354        fun deliver () = deliver' NONE
355        val symval = SSV.symval
356  end  end

Legend:
Removed from v.357  
changed lines
  Added in v.518

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0