Allow rendering of multiple files side by side
This commit is contained in:
parent
4583ad6a92
commit
caac87e70a
4 changed files with 111 additions and 58 deletions
|
@ -51,7 +51,13 @@ let add_line_boxes render_data dwarf_lines =
|
||||||
let box_end = Z.to_int @@ reg_ahead.Dwarf.lnr_address in
|
let box_end = Z.to_int @@ reg_ahead.Dwarf.lnr_address in
|
||||||
Format.eprintf "Add box %x -- %x@." box_start box_end ;
|
Format.eprintf "Add box %x -- %x@." box_start box_end ;
|
||||||
let n_render_data, _ = Renderer.add_box_excl
|
let n_render_data, _ = Renderer.add_box_excl
|
||||||
cur_render_data (box_start, box_end) in
|
cur_render_data (box_start, box_end)
|
||||||
|
Renderer.(Some {
|
||||||
|
box_file = Z.to_int cur_reg.lnr_file;
|
||||||
|
box_line = Z.to_int cur_reg.lnr_line;
|
||||||
|
box_col = Z.to_int cur_reg.lnr_column;
|
||||||
|
})
|
||||||
|
in
|
||||||
n_render_data)
|
n_render_data)
|
||||||
cur_render_data reg_list)
|
cur_render_data reg_list)
|
||||||
render_data
|
render_data
|
||||||
|
@ -80,10 +86,12 @@ let _ =
|
||||||
line_info ;
|
line_info ;
|
||||||
) elf_handles ;
|
) elf_handles ;
|
||||||
|
|
||||||
List.iter (fun (ElfHandle(_, _, static_info, asm)) ->
|
let multi_render_data = List.map (fun (ElfHandle(_, _, static_info, asm)) ->
|
||||||
let render_data = Renderer.init_render_data asm in
|
let render_data = Renderer.init_render_data asm in
|
||||||
let line_info = static_info.ds_evaluated_line_info in
|
let line_info = static_info.ds_evaluated_line_info in
|
||||||
let boxed_render_data = add_line_boxes render_data line_info in
|
let boxed_render_data = add_line_boxes render_data line_info in
|
||||||
|
boxed_render_data
|
||||||
|
) elf_handles in
|
||||||
|
|
||||||
Format.printf "%s@."
|
Format.printf "%s@."
|
||||||
(Renderer.to_string Html_renderer.render boxed_render_data)
|
(Renderer.to_string Html_renderer.render multi_render_data)
|
||||||
) elf_handles;
|
|
||||||
|
|
|
@ -18,14 +18,17 @@ let render_prog_box annotated_prog = Jingoo.Jg_types.(Renderer.AnnotAsm.(
|
||||||
));
|
));
|
||||||
("instr_asm", box_string row.instr_asm);
|
("instr_asm", box_string row.instr_asm);
|
||||||
("instr_events", (List.map (fun event ->
|
("instr_events", (List.map (fun event ->
|
||||||
let typ, id, bound = Renderer.(match event with
|
let typ, id, bound, data = Renderer.(match event with
|
||||||
| BoxStart(id, bound) -> "start", id, bound
|
| BoxStart(id, bound, data) -> "start", id, bound, data
|
||||||
| BoxEnd(id, bound) -> "end", id, bound
|
| BoxEnd(id, bound, data) -> "end", id, bound, data
|
||||||
) in
|
) in
|
||||||
[
|
[
|
||||||
("typ", box_string typ);
|
("typ", box_string typ);
|
||||||
("id", box_int id);
|
("id", box_int id);
|
||||||
("bound", box_string @@ render_addr bound);
|
("bound", box_string @@ render_addr bound);
|
||||||
|
("data", box_string @@ Format.sprintf "File %d, %d:%d"
|
||||||
|
data.box_file data.box_line data.box_col);
|
||||||
|
|
||||||
] |> box_obj)
|
] |> box_obj)
|
||||||
row.instr_annot.Renderer.events)
|
row.instr_annot.Renderer.events)
|
||||||
|> box_list);
|
|> box_list);
|
||||||
|
@ -36,11 +39,16 @@ let render_prog_box annotated_prog = Jingoo.Jg_types.(Renderer.AnnotAsm.(
|
||||||
|> box_list
|
|> box_list
|
||||||
))
|
))
|
||||||
|
|
||||||
(** [render render_data] renders the given [render_data] to a string. *)
|
let render_progs_box annotated_progs =
|
||||||
let render render_data = Jingoo.(
|
List.map render_prog_box annotated_progs
|
||||||
let annotated_prog = Renderer.render_data_to_annotated_asm render_data in
|
|> Jingoo.Jg_types.box_list
|
||||||
|
|
||||||
|
(** [render multi_render_data] renders the given [render_data] to a string. *)
|
||||||
|
let render multi_render_data = Jingoo.(
|
||||||
|
let annotated_progs = List.map (fun render_data ->
|
||||||
|
Renderer.render_data_to_annotated_asm render_data) multi_render_data in
|
||||||
let models = [
|
let models = [
|
||||||
("subroutines", render_prog_box annotated_prog);
|
("progs", render_progs_box annotated_progs);
|
||||||
] in
|
] in
|
||||||
Jg_template.from_file "src/render_html.jingoo" ~models:models
|
Jg_template.from_file "src/render_html.jingoo" ~models:models
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,6 +6,18 @@
|
||||||
body {
|
body {
|
||||||
font-family: "mono";
|
font-family: "mono";
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
background-color: #f7f6fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prog_container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prog {
|
||||||
|
background-color: white;
|
||||||
|
padding: 15px;
|
||||||
|
border: 1px solid #9584ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subroutine {
|
.subroutine {
|
||||||
|
@ -35,6 +47,9 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div class="prog_container">
|
||||||
|
{% for subroutines in progs %}
|
||||||
|
<div class="prog">
|
||||||
{% for subroutine in subroutines %}
|
{% for subroutine in subroutines %}
|
||||||
<div class="subroutine">
|
<div class="subroutine">
|
||||||
<div class="sub_headline">
|
<div class="sub_headline">
|
||||||
|
@ -46,7 +61,9 @@
|
||||||
{% for row in subroutine.sub_asm %}
|
{% for row in subroutine.sub_asm %}
|
||||||
{% for event in row.instr_events %}
|
{% for event in row.instr_events %}
|
||||||
{% if event.typ == "start" %}
|
{% if event.typ == "start" %}
|
||||||
<div class="instr_box" id="instr_box_{{ event.id }}">
|
<div class="instr_box" id="instr_box_{{ event.id }}"
|
||||||
|
title="{{ event.data }}"
|
||||||
|
>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<div class="sub_instr">
|
<div class="sub_instr">
|
||||||
|
@ -63,5 +80,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -7,8 +7,14 @@
|
||||||
module RawAsm = Asm_info.NoAnnot
|
module RawAsm = Asm_info.NoAnnot
|
||||||
|
|
||||||
type addr_range_t = RawAsm.addr_t * RawAsm.addr_t
|
type addr_range_t = RawAsm.addr_t * RawAsm.addr_t
|
||||||
|
type box_data_t = {
|
||||||
|
box_file : int;
|
||||||
|
box_line : int;
|
||||||
|
box_col : int;
|
||||||
|
}
|
||||||
type addr_range_tag_t = int
|
type addr_range_tag_t = int
|
||||||
type tag_addr_range_t = TaggedRange of addr_range_tag_t * addr_range_t
|
type tag_addr_range_t = TaggedRange of addr_range_tag_t * addr_range_t *
|
||||||
|
box_data_t
|
||||||
|
|
||||||
type render_data_t = {
|
type render_data_t = {
|
||||||
render_prog : RawAsm.asm_info_t ;
|
render_prog : RawAsm.asm_info_t ;
|
||||||
|
@ -16,9 +22,11 @@ type render_data_t = {
|
||||||
render_prev_address : RawAsm.addr_t RawAsm.AddrMap.t
|
render_prev_address : RawAsm.addr_t RawAsm.AddrMap.t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type multi_render_data_t = render_data_t list
|
||||||
|
|
||||||
type render_box_event_t =
|
type render_box_event_t =
|
||||||
BoxStart of addr_range_tag_t * RawAsm.addr_t
|
BoxStart of addr_range_tag_t * RawAsm.addr_t * box_data_t
|
||||||
| BoxEnd of addr_range_tag_t * RawAsm.addr_t
|
| BoxEnd of addr_range_tag_t * RawAsm.addr_t * box_data_t
|
||||||
|
|
||||||
type asm_annot_type = {
|
type asm_annot_type = {
|
||||||
events : render_box_event_t list
|
events : render_box_event_t list
|
||||||
|
@ -52,24 +60,33 @@ let init_render_data prog =
|
||||||
(** [add_box render_data range] adds a box around an address range, inclusive
|
(** [add_box render_data range] adds a box around an address range, inclusive
|
||||||
of both bounds, in [render_data] and returns the new render data and the
|
of both bounds, in [render_data] and returns the new render data and the
|
||||||
newly inserted element's id *)
|
newly inserted element's id *)
|
||||||
let add_box render_data range : render_data_t * int =
|
let add_box render_data range opt_data : render_data_t * int =
|
||||||
let elt_id = (match render_data.render_boxes with
|
let elt_id = (match render_data.render_boxes with
|
||||||
| [] -> 0
|
| [] -> 0
|
||||||
| TaggedRange(prev_id, _)::_ -> prev_id + 1) in
|
| TaggedRange(prev_id, _, _)::_ -> prev_id + 1) in
|
||||||
|
|
||||||
|
let data = (match opt_data with
|
||||||
|
| Some data -> data
|
||||||
|
| None -> {
|
||||||
|
box_file = 0;
|
||||||
|
box_line = 0;
|
||||||
|
box_col = 0
|
||||||
|
})
|
||||||
|
in
|
||||||
{
|
{
|
||||||
render_data with
|
render_data with
|
||||||
render_boxes = (TaggedRange(elt_id, range)) :: render_data.render_boxes
|
render_boxes =
|
||||||
|
(TaggedRange(elt_id, range, data)) :: render_data.render_boxes
|
||||||
}, elt_id
|
}, elt_id
|
||||||
|
|
||||||
|
|
||||||
(** Same as [add_box], with an included start, excluded end for range. *)
|
(** Same as [add_box], with an included start, excluded end for range. *)
|
||||||
let add_box_excl render_data (addr_beg, addr_end) =
|
let add_box_excl render_data (addr_beg, addr_end) opt_data =
|
||||||
(match RawAsm.AddrMap.find_opt addr_end render_data.render_prev_address with
|
(match RawAsm.AddrMap.find_opt addr_end render_data.render_prev_address with
|
||||||
| None -> Format.eprintf "Box end address %x not found, ignoring box."
|
| None -> Format.eprintf "Box end address %x not found, ignoring box."
|
||||||
addr_end ;
|
addr_end ;
|
||||||
raise Not_found
|
raise Not_found
|
||||||
| Some end_bound -> add_box render_data (addr_beg, end_bound)
|
| Some end_bound -> add_box render_data (addr_beg, end_bound) opt_data
|
||||||
)
|
)
|
||||||
|
|
||||||
(** [to_file renderer render_data path] renders the given [render_data] to a
|
(** [to_file renderer render_data path] renders the given [render_data] to a
|
||||||
|
@ -81,17 +98,17 @@ let to_file renderer render_data path =
|
||||||
|> output_string handle ;
|
|> output_string handle ;
|
||||||
close_out handle
|
close_out handle
|
||||||
|
|
||||||
(** [to_string renderer render_data] renders the given [render_data] to a
|
(** [to_string renderer multi_render_data] renders the given
|
||||||
returned string using the provided specific renderer.
|
[multi_render_data] to a returned string using the provided specific
|
||||||
This function is provided for unification and clarity, but is an alias for
|
renderer. This function is provided for unification and clarity, but is an
|
||||||
[renderer].
|
alias for [renderer].
|
||||||
*)
|
*)
|
||||||
let to_string renderer render_data =
|
let to_string renderer multi_render_data =
|
||||||
renderer render_data
|
renderer multi_render_data
|
||||||
|
|
||||||
let extract_event_addr box_event = match box_event with
|
let extract_event_addr box_event = match box_event with
|
||||||
| BoxStart(_, addr) -> addr
|
| BoxStart(_, addr, _) -> addr
|
||||||
| BoxEnd(_, addr) -> addr
|
| BoxEnd(_, addr, _) -> addr
|
||||||
|
|
||||||
(** [boxes_to_events render_data] converts the list of boxes of `render_data`
|
(** [boxes_to_events render_data] converts the list of boxes of `render_data`
|
||||||
to a list of events, that is, an address-ordered list of
|
to a list of events, that is, an address-ordered list of
|
||||||
|
@ -103,16 +120,16 @@ let boxes_to_events render_data =
|
||||||
| 0 -> (match e1, e2 with
|
| 0 -> (match e1, e2 with
|
||||||
| BoxEnd(_), BoxStart(_) -> -1
|
| BoxEnd(_), BoxStart(_) -> -1
|
||||||
| BoxStart(_), BoxEnd(_) -> 1
|
| BoxStart(_), BoxEnd(_) -> 1
|
||||||
| BoxStart(id1, _), BoxStart(id2, _) -> compare id1 id2
|
| BoxStart(id1, _, _), BoxStart(id2, _, _) -> compare id1 id2
|
||||||
| BoxEnd(id1, _), BoxEnd(id2, _) -> compare id1 id2
|
| BoxEnd(id1, _, _), BoxEnd(id2, _, _) -> compare id1 id2
|
||||||
)
|
)
|
||||||
| n -> n
|
| n -> n
|
||||||
in
|
in
|
||||||
|
|
||||||
let unordered_events = List.fold_left
|
let unordered_events = List.fold_left
|
||||||
(fun accu (TaggedRange(elt_id, (range_beg, range_end))) ->
|
(fun accu (TaggedRange(elt_id, (range_beg, range_end), data)) ->
|
||||||
(BoxStart(elt_id, range_beg))
|
(BoxStart(elt_id, range_beg, data))
|
||||||
:: (BoxEnd(elt_id, range_end))
|
:: (BoxEnd(elt_id, range_end, data))
|
||||||
:: accu
|
:: accu
|
||||||
)
|
)
|
||||||
[]
|
[]
|
||||||
|
|
Loading…
Reference in a new issue