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

SCM Repository

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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 433 - (view) (download)

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

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