Skip to content

Commit e816419

Browse files
authored
Update linker in prep for updating LLVM (#2760)
- Implement extended name section (https://github.com/WebAssembly/extended-name-section/blob/master/proposals/extended-name-section/Overview.md) - Handle `start` functions in the RTS module in linker These changes are needed to update to LLVM 12: #2542
1 parent 10d1a5d commit e816419

4 files changed

Lines changed: 74 additions & 42 deletions

File tree

src/codegen/compile.ml

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8205,13 +8205,10 @@ and conclude_module env start_fi_o =
82058205
let open Wasm_exts.CustomModule in
82068206
{ module_;
82078207
dylink = None;
8208-
name = {
8209-
module_ = None;
8210-
function_names =
8211-
List.mapi (fun i (f,n,_) -> Int32.(add ni' (of_int i), n)) funcs;
8212-
locals_names =
8213-
List.mapi (fun i (f,_,ln) -> Int32.(add ni' (of_int i), ln)) funcs;
8214-
};
8208+
name = { empty_name_section with function_names =
8209+
List.mapi (fun i (f,n,_) -> Int32.(add ni' (of_int i), n)) funcs;
8210+
locals_names =
8211+
List.mapi (fun i (f,_,ln) -> Int32.(add ni' (of_int i), ln)) funcs; };
82158212
motoko = {
82168213
labels = E.get_labs env;
82178214
};

src/linking/linkModule.ml

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -598,29 +598,38 @@ let fill_table_base_import new_base : module_' -> module_' = fun m ->
598598

599599
(* Concatenation of modules *)
600600

601-
let join_modules (em1 : extended_module) (m2 : module_') (ns2 : name_section) : extended_module =
602-
assert (m2.start = None);
601+
let join_modules
602+
(em1 : extended_module) (m2 : module_') (ns2 : name_section)
603+
(type_indices : (Wasm.Types.func_type, int32) Hashtbl.t) : extended_module =
603604
let m1 = em1.module_ in
604-
{ em1 with
605-
module_ = {
606-
types = m1.types @ m2.types;
607-
globals = m1.globals @ m2.globals;
608-
tables = m1.tables @ m2.tables;
609-
memories = m1.memories @ m2.memories;
610-
funcs = m1.funcs @ m2.funcs;
611-
start = m1.start;
612-
elems = m1.elems @ m2.elems;
613-
data = m1.data @ m2.data;
614-
imports = m1.imports @ m2.imports;
615-
exports = m1.exports @ m2.exports;
616-
};
617-
name = {
618-
em1.name with
619-
function_names = em1.name.function_names @ ns2.function_names;
620-
locals_names = em1.name.locals_names @ ns2.locals_names;
605+
let joined =
606+
{ em1 with
607+
module_ = {
608+
types = m1.types @ m2.types;
609+
globals = m1.globals @ m2.globals;
610+
tables = m1.tables @ m2.tables;
611+
memories = m1.memories @ m2.memories;
612+
funcs = m1.funcs @ m2.funcs;
613+
start = m1.start;
614+
elems = m1.elems @ m2.elems;
615+
data = m1.data @ m2.data;
616+
imports = m1.imports @ m2.imports;
617+
exports = m1.exports @ m2.exports;
621618
};
622-
motoko = em1.motoko;
623-
}
619+
name = {
620+
em1.name with
621+
function_names = em1.name.function_names @ ns2.function_names;
622+
locals_names = em1.name.locals_names @ ns2.locals_names;
623+
};
624+
motoko = em1.motoko;
625+
}
626+
in
627+
(* If second module has a start, prepend it to the first module's start.
628+
OK to use `Hashtbl.find` below as the first module will have a start, so
629+
we'll have the unit function in the type section already. *)
630+
match m2.start with
631+
| None -> joined
632+
| Some fi -> prepend_to_start fi.it (Hashtbl.find type_indices (Wasm.Types.FuncType ([], []))) joined
624633

625634
(* The main linking function *)
626635

@@ -873,8 +882,6 @@ let link (em1 : extended_module) libname (em2 : extended_module) =
873882
| Some fi -> prepend_to_start (funs2 fi) (add_or_get_ty (Wasm.Types.FuncType ([], [])))
874883
in
875884

876-
assert (dm2.globals = []);
877-
878885
let new_table_size =
879886
Int32.add (Int32.add lib_table_start dylink.table_size) (Int32.of_int (List.length got_func_imports))
880887
in
@@ -904,6 +911,7 @@ let link (em1 : extended_module) libname (em2 : extended_module) =
904911
|> remove_fun_imports_name_section fun_resolved21
905912
|> rename_funcs_name_section funs2
906913
)
914+
type_indices
907915
|> add_call_ctors
908916
|> remove_non_ic_exports (* only sane if no additional files get linked in *)
909917
in

src/wasm-exts/customModule.ml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,26 @@ type name_section = {
88
module_ : string option;
99
function_names : (int32 * string) list;
1010
locals_names : (int32 * (int32 * string) list) list;
11+
label_names : (int32 * (int32 * string) list) list;
12+
type_names : (int32 * string) list;
13+
table_names : (int32 * string) list;
14+
memory_names : (int32 * string) list;
15+
global_names : (int32 * string) list;
16+
elem_segment_names : (int32 * string) list;
17+
data_segment_names : (int32 * string) list;
1118
}
1219

1320
let empty_name_section : name_section = {
1421
module_ = None;
1522
function_names = [];
1623
locals_names = [];
24+
label_names = [];
25+
type_names = [];
26+
table_names = [];
27+
memory_names = [];
28+
global_names = [];
29+
elem_segment_names = [];
30+
data_segment_names = [];
1731
}
1832

1933
type dylink_section = {

src/wasm-exts/customModuleDecode.ml

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ let name s =
142142
try Utf8.decode (string s) with Utf8.Utf8 ->
143143
error s pos "malformed UTF-8 encoding"
144144

145-
let sized f s =
145+
let sized (f : int -> stream -> 'a) (s : stream) =
146146
let size = len32 s in
147147
let start = pos s in
148148
let x = f size s in
@@ -663,7 +663,7 @@ let data_section s =
663663

664664
(* Custom sections *)
665665

666-
let custom_section name_pred f default s =
666+
let custom_section (name_pred : int list -> bool) (f : int -> stream -> 'a) (default : 'a) (s : stream) =
667667
let p = pos s in
668668
match id s with
669669
| Some `CustomSection ->
@@ -715,7 +715,7 @@ let assoc_list f = vec (fun s ->
715715
let name_map = assoc_list string
716716
let indirect_name_map = assoc_list name_map
717717

718-
let name_section_subsection (ns : name_section) s =
718+
let name_section_subsection (ns : name_section) (s : stream) : name_section =
719719
match u8 s with
720720
| 0 -> (* module name *)
721721
let mod_name = sized (fun _ -> string) s in
@@ -726,17 +726,30 @@ let name_section_subsection (ns : name_section) s =
726726
| 2 -> (* local names *)
727727
let loc_names = sized (fun _ -> indirect_name_map) s in
728728
{ ns with locals_names = ns.locals_names @ loc_names }
729-
730-
(* We ignore additional name subsections for now, despite newer
731-
LLVM seemingly producing them.
732-
733-
We should check if these sections are indeed as spec'ed in
729+
(* The following subsections are not in the standard yet, but from the extended-name-section proposal
734730
https://github.com/WebAssembly/extended-name-section/blob/master/proposals/extended-name-section/Overview.md
735-
and implement them, for better debugging.
736731
*)
737-
| 7 ->
738-
let _global_names = sized (fun _ -> name_map) s in
739-
ns
732+
| 3 -> (* label names *)
733+
let label_names = sized (fun _ -> indirect_name_map) s in
734+
{ ns with label_names = ns.label_names @ label_names }
735+
| 4 -> (* type names *)
736+
let type_names = sized (fun _ -> name_map) s in
737+
{ ns with type_names = ns.type_names @ type_names }
738+
| 5 -> (* table names *)
739+
let table_names = sized (fun _ -> name_map) s in
740+
{ ns with table_names = ns.table_names @ table_names }
741+
| 6 -> (* memory names *)
742+
let memory_names = sized (fun _ -> name_map) s in
743+
{ ns with memory_names = ns.memory_names @ memory_names }
744+
| 7 -> (* global names *)
745+
let global_names = sized (fun _ -> name_map) s in
746+
{ ns with global_names = ns.global_names @ global_names }
747+
| 8 -> (* elem segment names *)
748+
let elem_segment_names = sized (fun _ -> name_map) s in
749+
{ ns with elem_segment_names = ns.elem_segment_names @ elem_segment_names }
750+
| 9 -> (* data segment names *)
751+
let data_segment_names = sized (fun _ -> name_map) s in
752+
{ ns with data_segment_names = ns.data_segment_names @ data_segment_names }
740753
| i -> error s (pos s) (Printf.sprintf "unknown name section subsection id %d" i)
741754

742755
let name_section_content p_end s =

0 commit comments

Comments
 (0)