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

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