Skip to content

Commit fe7e48c

Browse files
committed
---
yaml --- r: 868 b: refs/heads/master c: 1e22a55 h: refs/heads/master v: v3
1 parent dcd6bd7 commit fe7e48c

File tree

5 files changed

+245
-1
lines changed

5 files changed

+245
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 7abf6eb7c67dfb43540fdcafd6f1e69bdd2a6849
2+
refs/heads/master: 1e22a55ff25612753665a76eb3b83628379334a0

trunk/src/boot/driver/lib.ml

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
open Common;;
2+
open Fmt;;
23

34
let log (sess:Session.sess) =
45
Session.log "lib"
@@ -12,6 +13,224 @@ let iflog (sess:Session.sess) (thunk:(unit -> unit)) : unit =
1213
else ()
1314
;;
1415

16+
(*
17+
* Stuff associated with 'crate interfaces'.
18+
*
19+
* The interface of a crate used to be defined by the accompanying DWARF
20+
* structure in the object file. This was an experiment -- we talked to
21+
* DWARF hackers before hand and they thought it worth trying -- which did
22+
* work, and had the advantage of economy of metadata-emitting, but several
23+
* downsides:
24+
*
25+
* - The reader -- which we want a copy of at runtime in the linker -- has
26+
* to know how to read DWARF. It's not the simplest format.
27+
*
28+
* - The complexity of the encoding meant we didn't always keep pace with
29+
* the AST, and maintaining any degree of inter-change compatibility was
30+
* going ot be a serious challenge.
31+
*
32+
* - Diagnostic tools are atrocious, as is the definition of
33+
* well-formedness. It's largely trial and error when talking to gdb,
34+
* say.
35+
*
36+
* - Because it was doing double-duty as *driving linkage*, we were never
37+
* going to get to the linkage efficiency of native symbols (hash
38+
* lookup) anyway. Runtime linkage -- even when lazy -- really ought to
39+
* be fast.
40+
*
41+
* - LLVM, our "main" backend (in rustc) does not really want to make
42+
* promises about preserving dwarf.
43+
*
44+
* - LLVM also *is* going to emit native symbols; complete with relocs and
45+
* such. We'd actually have to do *extra work* to inhibit that.
46+
*
47+
* - Most tools are set up to think of DWARF as "debug", meaning
48+
* "optional", and may well strip it or otherwise mangle it.
49+
*
50+
* - Many tools want native symbols anyways, and don't know how to look at
51+
* DWARF.
52+
*
53+
* - All the tooling arguments go double on win32. Pretty much only
54+
* objdump and gdb understand DWARF-in-PE. Everything else is just blank
55+
* stares.
56+
*
57+
* For all these reasons we're moving to a self-made format for describing
58+
* our interfaces. This will be stored in the .note.rust section as we
59+
* presently store the meta tags. The encoding is ASCII-compatible (the set
60+
* of "numbers" to encode is small enough, especially compared to dwarf,
61+
* that we can just use a text form) and is very easy to read with a simple
62+
* byte-at-a-time parser.
63+
*
64+
*)
65+
66+
(*
67+
* Encoding goals:
68+
*
69+
* - Simple. Minimal state or read-ambiguity in reader.
70+
*
71+
* - Compact. Shouldn't add a lot to the size of the binary to glue this
72+
* on to it.
73+
*
74+
* - Front-end-y. Doesn't need to contain much beyond parse-level of the
75+
* crate's exported items; it'll be fed into the front-end of the
76+
* pipeline anyway. No need to have all types or names resolved.
77+
*
78+
* - Testable. Human-legible and easy to identify/fix/test errors in.
79+
*
80+
* - Very fast to read the 'identifying' prefix (version, meta tags, hash)
81+
*
82+
* - Tolerably fast to read in its entirety.
83+
*
84+
* - Safe from version-drift (or at least able to notice it and abort).
85+
*
86+
* Anti-goals:
87+
*
88+
* - Random access.
89+
*
90+
* - Generality to other languages.
91+
*
92+
* Structure:
93+
*
94+
* - Line oriented.
95+
*
96+
* - Whitespace-separated and whitespace-agnostic. Indent for legibility.
97+
*
98+
* - Each line is a record. A record is either a full item, an item bracket,
99+
* a comment, or metadata.
100+
*
101+
* - First byte describes type of record, unless first byte is +, in which
102+
* case it's oh-no-we-ran-out-of-tags and it's followed by 2 type-bytes.
103+
* (Continue to +++ if you happen to run out *there* as well. You
104+
* won't.)
105+
*
106+
* - Metadata type is !
107+
*
108+
* - Comment type is #
109+
*
110+
* - Full item types are: y for type, c for const, f for fn, i for iter,
111+
* g for tag constructor.
112+
*
113+
* - Item brackets are those that open/close a scope of
114+
* sub-records. These would be obj (o), mod (m), tag (t) to open. The
115+
* closer is always '.'. So a mod looks like:
116+
*
117+
* m foo
118+
* c bar
119+
* .
120+
*
121+
* - After first byte of openers and full items is whitespace, then an
122+
* ident.
123+
*
124+
* - After that, if it's a ty, fn, iter, obj or tag, there may be [, a
125+
* list of comma-separated ty param names, and ].
126+
*
127+
* - After that, if it's a fn, iter, obj or tag constructor, there is a (,
128+
* a list of comma-separated type-encoded slot/ident pairs, and a ).
129+
*
130+
* - After that, if it's a fn or iter, there's a '->' and a type-encoded
131+
* output.
132+
*
133+
* - After that, a newline '\n'.
134+
*
135+
* - Type encoding is a longer issue! We'll get to that.
136+
*)
137+
138+
let fmt_iface (ff:Format.formatter) (crate:Ast.crate) : unit =
139+
let fmt_ty_param ff (p:Ast.ty_param identified) : unit =
140+
fmt ff "%s" (fst p.node)
141+
in
142+
let rec fmt_ty ff (t:Ast.ty) : unit =
143+
match t with
144+
Ast.TY_any -> fmt ff "a"
145+
| Ast.TY_nil -> fmt ff "n"
146+
| Ast.TY_bool -> fmt ff "b"
147+
| Ast.TY_mach tm -> fmt ff "%s" (string_of_ty_mach tm)
148+
| Ast.TY_int -> fmt ff "i"
149+
| Ast.TY_uint -> fmt ff "u"
150+
| Ast.TY_char -> fmt ff "c"
151+
| Ast.TY_str -> fmt ff "s"
152+
153+
| Ast.TY_tup ttup ->
154+
fmt_bracketed_arr_sep "(" ")" ","
155+
fmt_ty ff ttup
156+
| Ast.TY_vec ty ->
157+
fmt ff "v["; fmt_ty ff ty; fmt ff "]"
158+
| Ast.TY_chan ty ->
159+
fmt ff "C["; fmt_ty ff ty; fmt ff "]"
160+
161+
| Ast.TY_port ty ->
162+
fmt ff "P["; fmt_ty ff ty; fmt ff "]"
163+
164+
| Ast.TY_task ->
165+
fmt ff "T"
166+
167+
| Ast.TY_named n -> fmt ff ":"; fmt_name ff n
168+
| Ast.TY_type -> fmt ff "Y"
169+
170+
| Ast.TY_box t -> fmt ff "@@"; fmt_ty ff t
171+
| Ast.TY_mutable t -> fmt ff "~"; fmt_ty ff t
172+
173+
(* FIXME: finish this. *)
174+
| Ast.TY_rec _
175+
| Ast.TY_tag _
176+
| Ast.TY_fn _
177+
| Ast.TY_obj _
178+
| Ast.TY_native _
179+
| Ast.TY_param _
180+
| Ast.TY_constrained _ -> fmt ff "Z"
181+
182+
and fmt_name ff n =
183+
match n with
184+
Ast.NAME_base (Ast.BASE_ident id) -> fmt ff "%s" id
185+
| Ast.NAME_base (Ast.BASE_temp _) -> failwith "temp in fmt_name"
186+
| Ast.NAME_base (Ast.BASE_app (id, tys)) ->
187+
fmt ff "%s" id;
188+
fmt_bracketed_arr_sep "[" "]" ","
189+
fmt_ty ff tys;
190+
| Ast.NAME_ext (n, Ast.COMP_ident id) ->
191+
fmt_name ff n;
192+
fmt ff ".%s" id
193+
| Ast.NAME_ext (n, Ast.COMP_app (id, tys)) ->
194+
fmt_name ff n;
195+
fmt ff ".%s" id;
196+
fmt_bracketed_arr_sep "[" "]" ","
197+
fmt_ty ff tys;
198+
| Ast.NAME_ext (n, Ast.COMP_idx i) ->
199+
fmt_name ff n;
200+
fmt ff "._%d" i
201+
in
202+
let rec fmt_mod_item (id:Ast.ident) (mi:Ast.mod_item) : unit =
203+
let i c = fmt ff "@\n%c %s" c id in
204+
205+
let o c = fmt ff "@\n"; fmt_obox ff; fmt ff "%c %s" c id in
206+
let p _ =
207+
if (Array.length mi.node.Ast.decl_params) <> 0
208+
then
209+
fmt_bracketed_arr_sep "[" "]" ","
210+
fmt_ty_param ff mi.node.Ast.decl_params
211+
in
212+
let c _ = fmt_cbox ff; fmt ff "@\n." in
213+
match mi.node.Ast.decl_item with
214+
Ast.MOD_ITEM_type _ -> i 'y'; p()
215+
| Ast.MOD_ITEM_tag _ -> i 'g'; p()
216+
| Ast.MOD_ITEM_fn _ -> i 'f'; p();
217+
| Ast.MOD_ITEM_const _ -> i 'c'
218+
| Ast.MOD_ITEM_obj _ ->
219+
o 'o'; p();
220+
c ()
221+
| Ast.MOD_ITEM_mod (_, items) ->
222+
o 'm';
223+
fmt_mod_items items;
224+
c ()
225+
and fmt_mod_items items =
226+
sorted_htab_iter fmt_mod_item items
227+
in
228+
let (_,items) = crate.node.Ast.crate_items in
229+
fmt_mod_items items
230+
;;
231+
232+
(* Mechanisms for scanning libraries. *)
233+
15234
(* FIXME (issue #67): move these to sess. *)
16235
let ar_cache = Hashtbl.create 0 ;;
17236
let sects_cache = Hashtbl.create 0;;

trunk/src/boot/driver/main.ml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ let (sess:Session.sess) =
3333
Session.sess_log_lex = false;
3434
Session.sess_log_parse = false;
3535
Session.sess_log_ast = false;
36+
Session.sess_log_sig = false;
3637
Session.sess_log_passes = false;
3738
Session.sess_log_resolve = false;
3839
Session.sess_log_type = false;
@@ -116,6 +117,7 @@ let dump_sig (filename:filename) : unit =
116117
exit 0
117118
;;
118119

120+
119121
let dump_meta (filename:filename) : unit =
120122
begin
121123
match Lib.get_meta sess filename with
@@ -168,6 +170,8 @@ let argspecs =
168170
"-lparse" "log parsing");
169171
(flag (fun _ -> sess.Session.sess_log_ast <- true)
170172
"-last" "log AST");
173+
(flag (fun _ -> sess.Session.sess_log_sig <- true)
174+
"-lsig" "log signature");
171175
(flag (fun _ -> sess.Session.sess_log_passes <- true)
172176
"-lpasses" "log passes at high-level");
173177
(flag (fun _ -> sess.Session.sess_log_resolve <- true)
@@ -358,6 +362,17 @@ then
358362
Format.set_margin 80;
359363
Printf.fprintf stdout "%s\n" (Fmt.fmt_to_str Ast.fmt_crate crate)
360364
end
365+
;;
366+
367+
if sess.Session.sess_log_sig
368+
then
369+
begin
370+
Printf.fprintf stdout "Post-parse signature:\n";
371+
Format.set_margin 80;
372+
Printf.fprintf stdout "%s\n" (Fmt.fmt_to_str Lib.fmt_iface crate);
373+
end
374+
;;
375+
361376

362377
let list_to_seq ls = Asm.SEQ (Array.of_list ls);;
363378
let select_insns (quads:Il.quads) : Asm.frag =

trunk/src/boot/driver/session.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type sess =
1919
mutable sess_log_lex: bool;
2020
mutable sess_log_parse: bool;
2121
mutable sess_log_ast: bool;
22+
mutable sess_log_sig: bool;
2223
mutable sess_log_passes: bool;
2324
mutable sess_log_resolve: bool;
2425
mutable sess_log_type: bool;

trunk/src/boot/util/common.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,15 @@ let sorted_htab_keys (tab:('a, 'b) Hashtbl.t) : 'a array =
218218
keys
219219
;;
220220

221+
let sorted_htab_iter
222+
(f:'a -> 'b -> unit)
223+
(tab:('a, 'b) Hashtbl.t)
224+
: unit =
225+
Array.iter
226+
(fun k -> f k (Hashtbl.find tab k))
227+
(sorted_htab_keys tab)
228+
;;
229+
221230
let htab_vals (htab:('a,'b) Hashtbl.t) : ('b list) =
222231
Hashtbl.fold (fun _ v accum -> v :: accum) htab []
223232
;;

0 commit comments

Comments
 (0)