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

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

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