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

Legend:
Removed from v.335  
changed lines
  Added in v.434

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