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 361 - (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 360 val compile : string option -> bool
12 : blume 357 end = struct
13 :    
14 : blume 327 structure EM = GenericVC.ErrorMsg
15 :     structure E = GenericVC.Environment
16 :     structure SE = GenericVC.CMStaticEnv
17 :     structure BE = GenericVC.BareEnvironment
18 :     structure PS = GenericVC.PersStamps
19 :     structure CoerceEnv = GenericVC.CoerceEnv
20 : blume 336 structure SSV = SpecificSymValFn (structure MachDepVC = MachDepVC
21 :     val os = os)
22 : blume 327
23 :     (* Since the bootstrap compiler never executes any of the code
24 :     * it produces, we don't need any dynamic values. Therefore,
25 :     * we create RecompPersstate (but not FullPersstate!) and
26 :     * instantiate Recomp as well as RecompTraversal.
27 :     * Since RecompPersstate is not part of any surrounding FullPersstate,
28 :     * function "discard_value" simply does nothing. *)
29 :     structure RecompPersstate =
30 :     RecompPersstateFn (structure MachDepVC = MachDepVC
31 :     val discard_code = true
32 : blume 360 fun new_smlinfo (i, popt) = ())
33 :    
34 : blume 327 structure Recomp = RecompFn (structure PS = RecompPersstate)
35 :     structure RT = CompileGenericFn (structure CT = Recomp)
36 :    
37 :     fun recomp gp g = isSome (RT.group gp g)
38 :    
39 :     (* instantiate Stabilize... *)
40 : blume 329 structure Stabilize =
41 :     StabilizeFn (fun bn2statenv gp i = #1 (#stat (valOf (RT.bnode gp i)))
42 : blume 357 val getPid = RecompPersstate.pid_fetch_sml
43 :     fun warmup (i, p) = ()
44 : blume 329 val recomp = recomp)
45 : blume 327 (* ... and Parse *)
46 :     structure Parse = ParseFn (structure Stabilize = Stabilize)
47 :    
48 : blume 358 fun listName p =
49 :     case OS.Path.fromString p of
50 :     { vol = "", isAbs = false, arcs = _ :: arc1 :: arcn } => let
51 :     fun win32name () =
52 :     concat (arc1 ::
53 :     foldr (fn (a, r) => "\\" :: a :: r) [] arcn)
54 :     in
55 :     case os of
56 :     SMLofNJ.SysInfo.WIN32 => win32name ()
57 :     | _ => OS.Path.toString { isAbs = false, vol = "",
58 :     arcs = arc1 :: arcn }
59 :     end
60 :     | _ => raise Fail "BootstrapCompile:listName: bad name"
61 : blume 327
62 : blume 360 fun compile dbopt = let
63 : blume 358
64 : blume 360 val dirbase = getOpt (dbopt, BtNames.dirbaseDefault)
65 :     val pcmodespec = BtNames.pcmodespec
66 :     val initgspec = BtNames.initgspec
67 :     val maingspec = BtNames.maingspec
68 :    
69 : blume 357 val arch = MachDepVC.architecture
70 :     val osname = FilenamePolicy.kind2name os
71 :     val bindir = concat [dirbase, ".bin.", arch, "-", osname]
72 :     val bootdir = concat [dirbase, ".boot.", arch, "-", osname]
73 :    
74 : blume 329 val keep_going = EnvConfig.getSet StdConfig.keep_going NONE
75 :    
76 : blume 354 val ctxt = SrcPath.cwdContext ()
77 : blume 329
78 : blume 357 val pidfile = OS.Path.joinDirFile { dir = bootdir, file = "RTPID" }
79 :     val listfile = OS.Path.joinDirFile { dir = bootdir, file = "BINLIST" }
80 : blume 329
81 : blume 361 val pcmode = PathConfig.new ()
82 :     val _ = PathConfig.processSpecFile (pcmode, pcmodespec)
83 : blume 329
84 : blume 354 fun stdpath s = SrcPath.standard pcmode { context = ctxt, spec = s }
85 : blume 352
86 :     val initgspec = stdpath initgspec
87 :     val maingspec = stdpath maingspec
88 :    
89 : blume 360 val cmifile = valOf (SrcPath.reAnchoredName (initgspec, bootdir))
90 :     handle Option => raise Fail "BootstrapCompile: cmifile"
91 :    
92 : blume 357 val initfnpolicy =
93 :     FilenamePolicy.separate { bindir = bootdir, bootdir = bootdir }
94 :     { arch = arch, os = os }
95 : blume 329
96 : blume 357 val mainfnpolicy =
97 :     FilenamePolicy.separate { bindir = bindir, bootdir = bootdir }
98 :     { arch = arch, os = os }
99 :    
100 :     fun mkParam { primconf, pervasive, pervcorepids, fnpolicy }
101 :     { corenv } =
102 : blume 349 { primconf = primconf,
103 :     fnpolicy = fnpolicy,
104 :     pcmode = pcmode,
105 :     symenv = SSV.env,
106 :     keep_going = keep_going,
107 :     pervasive = pervasive,
108 :     corenv = corenv,
109 :     pervcorepids = pervcorepids }
110 :    
111 : blume 327 val emptydyn = E.dynamicPart E.emptyEnv
112 :    
113 :     (* first, build an initial GeneralParam.info, so we can
114 :     * deal with the pervasive env and friends... *)
115 :    
116 : blume 360 val primconf = Primitive.primEnvConf
117 : blume 349 val mkInitParam = mkParam { primconf = primconf,
118 :     pervasive = E.emptyEnv,
119 : blume 357 pervcorepids = PidSet.empty,
120 :     fnpolicy = initfnpolicy }
121 : blume 327
122 : blume 349 val param_nocore = mkInitParam { corenv = BE.staticPart BE.emptyEnv }
123 :    
124 : blume 327 val groupreg = GroupReg.new ()
125 :     val errcons = EM.defaultConsumer ()
126 : blume 329 val ginfo_nocore = { param = param_nocore, groupreg = groupreg,
127 :     errcons = errcons }
128 : blume 327
129 :     fun main_compile arg = let
130 : blume 335 val { rts, core, pervasive, primitives, binpaths } = arg
131 : blume 327
132 : blume 329 val ovldR = GenericVC.Control.overloadKW
133 :     val savedOvld = !ovldR
134 :     val _ = ovldR := true
135 :    
136 : blume 327 (* here we build a new gp -- the one that uses the freshly
137 :     * brewed pervasive env, core env, and primitives *)
138 : blume 358 val core = valOf (RT.sbnode ginfo_nocore core)
139 : blume 329 val corenv = CoerceEnv.es2bs (#1 (#stat core))
140 : blume 356 val core_sym = #1 (#sym core)
141 : blume 329
142 :     (* The following is a bit of a hack (but corenv is a hack anyway):
143 :     * As soon as we have core available, we have to patch the
144 :     * ginfo to include the correct corenv (because virtually
145 :     * everybody else needs access to corenv). *)
146 : blume 349 val param_justcore = mkInitParam { corenv = corenv }
147 : blume 329 val ginfo_justcore = { param = param_justcore, groupreg = groupreg,
148 :     errcons = errcons }
149 :    
150 : blume 358 fun rt n = valOf (RT.sbnode ginfo_justcore n)
151 : blume 327 val rts = rt rts
152 :     val pervasive = rt pervasive
153 :    
154 :     fun sn2pspec (name, n) = let
155 :     val { stat = (s, sp), sym = (sy, syp), ctxt } = rt n
156 :     val env =
157 :     E.mkenv { static = s, symbolic = sy, dynamic = emptydyn }
158 :     val pidInfo = { statpid = sp, sympid = syp, ctxt = ctxt }
159 :     in
160 :     { name = name, env = env, pidInfo = pidInfo }
161 :     end
162 :    
163 :     val pspecs = map sn2pspec primitives
164 :    
165 : blume 329 val _ = ovldR := savedOvld
166 :    
167 : blume 356 (* This is a hack but must be done for both the symbolic
168 :     * and later the dynamic part of the core environment:
169 :     * we must include these parts in the pervasive env. *)
170 :     val perv_sym = E.layerSymbolic (#1 (#sym pervasive), core_sym)
171 :    
172 : blume 349 val param =
173 :     mkParam { primconf = Primitive.configuration pspecs,
174 : blume 327 pervasive = E.mkenv { static = #1 (#stat pervasive),
175 : blume 356 symbolic = perv_sym,
176 : blume 327 dynamic = emptydyn },
177 :     pervcorepids =
178 :     PidSet.addList (PidSet.empty,
179 :     [#2 (#stat pervasive),
180 :     #2 (#sym pervasive),
181 : blume 357 #2 (#stat core)]),
182 :     fnpolicy = mainfnpolicy }
183 : blume 349 { corenv = corenv }
184 : blume 327 in
185 : blume 358 case Parse.parse NONE param (SOME true) maingspec of
186 : blume 349 NONE => false
187 : blume 329 | SOME (g, gp) =>
188 : blume 349 if recomp gp g then let
189 :     val rtspid = PS.toHex (#2 (#stat rts))
190 :     val bootfiles =
191 :     map (fn x => (x, NONE)) binpaths @
192 :     MkBootList.group g
193 :     fun writeList s = let
194 :     fun offset NONE = ["\n"]
195 :     | offset (SOME i) = ["@", Int.toString i, "\n"]
196 :     fun showBootFile (p, off) =
197 : blume 358 TextIO.output (s, concat (listName p ::
198 :     offset off))
199 : blume 349 in
200 :     app showBootFile bootfiles
201 :     end
202 : blume 360 fun cpCMI (ins, outs) = let
203 :     val N = 4096
204 :     fun cp () =
205 :     if TextIO.endOfStream ins then ()
206 :     else (TextIO.output (outs,
207 :     TextIO.inputN (ins, N));
208 :     cp ())
209 :     in
210 :     cp ()
211 :     end
212 : blume 349 in
213 :     Say.say ["Runtime System PID is: ", rtspid, "\n"];
214 :     SafeIO.perform { openIt = fn () =>
215 : blume 354 AutoDir.openTextOut pidfile,
216 : blume 349 closeIt = TextIO.closeOut,
217 :     work = fn s =>
218 :     TextIO.output (s, rtspid ^ "\n"),
219 :     cleanup = fn () =>
220 : blume 354 OS.FileSys.remove pidfile
221 :     handle _ => () };
222 : blume 349 SafeIO.perform { openIt = fn () =>
223 : blume 354 AutoDir.openTextOut listfile,
224 : blume 349 closeIt = TextIO.closeOut,
225 :     work = writeList,
226 :     cleanup = fn () =>
227 : blume 354 OS.FileSys.remove listfile
228 :     handle _ => () };
229 : blume 360 SafeIO.perform { openIt = fn () =>
230 :     (SrcPath.openTextIn initgspec,
231 :     AutoDir.openTextOut cmifile),
232 :     closeIt = fn (ins, outs) =>
233 :     (TextIO.closeIn ins;
234 :     TextIO.closeOut outs),
235 :     work = cpCMI,
236 :     cleanup = fn () =>
237 :     OS.FileSys.remove cmifile
238 :     handle _ => () };
239 : blume 349 true
240 :     end
241 :     else false
242 : blume 351 end handle Option => (RT.reset (); false)
243 : blume 330 (* to catch valOf failures in "rt" *)
244 : blume 327 in
245 : blume 329 case BuildInitDG.build ginfo_nocore initgspec of
246 : blume 327 SOME x => main_compile x
247 : blume 349 | NONE => false
248 : blume 327 end
249 :     end

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