Skip to content

Commit

Permalink
Update linker in prep for updating LLVM
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
osa1 committed Sep 1, 2021
1 parent 10d1a5d commit ab23fba
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 42 deletions.
11 changes: 4 additions & 7 deletions src/codegen/compile.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8205,13 +8205,10 @@ and conclude_module env start_fi_o =
let open Wasm_exts.CustomModule in
{ module_;
dylink = None;
name = {
module_ = None;
function_names =
List.mapi (fun i (f,n,_) -> Int32.(add ni' (of_int i), n)) funcs;
locals_names =
List.mapi (fun i (f,_,ln) -> Int32.(add ni' (of_int i), ln)) funcs;
};
name = { empty_name_section with function_names =
List.mapi (fun i (f,n,_) -> Int32.(add ni' (of_int i), n)) funcs;
locals_names =
List.mapi (fun i (f,_,ln) -> Int32.(add ni' (of_int i), ln)) funcs; };
motoko = {
labels = E.get_labs env;
};
Expand Down
54 changes: 31 additions & 23 deletions src/linking/linkModule.ml
Original file line number Diff line number Diff line change
Expand Up @@ -598,29 +598,38 @@ let fill_table_base_import new_base : module_' -> module_' = fun m ->

(* Concatenation of modules *)

let join_modules (em1 : extended_module) (m2 : module_') (ns2 : name_section) : extended_module =
assert (m2.start = None);
let join_modules
(em1 : extended_module) (m2 : module_') (ns2 : name_section)
(type_indices : (Wasm.Types.func_type, int32) Hashtbl.t) : extended_module =
let m1 = em1.module_ in
{ em1 with
module_ = {
types = m1.types @ m2.types;
globals = m1.globals @ m2.globals;
tables = m1.tables @ m2.tables;
memories = m1.memories @ m2.memories;
funcs = m1.funcs @ m2.funcs;
start = m1.start;
elems = m1.elems @ m2.elems;
data = m1.data @ m2.data;
imports = m1.imports @ m2.imports;
exports = m1.exports @ m2.exports;
};
name = {
em1.name with
function_names = em1.name.function_names @ ns2.function_names;
locals_names = em1.name.locals_names @ ns2.locals_names;
let joined =
{ em1 with
module_ = {
types = m1.types @ m2.types;
globals = m1.globals @ m2.globals;
tables = m1.tables @ m2.tables;
memories = m1.memories @ m2.memories;
funcs = m1.funcs @ m2.funcs;
start = m1.start;
elems = m1.elems @ m2.elems;
data = m1.data @ m2.data;
imports = m1.imports @ m2.imports;
exports = m1.exports @ m2.exports;
};
motoko = em1.motoko;
}
name = {
em1.name with
function_names = em1.name.function_names @ ns2.function_names;
locals_names = em1.name.locals_names @ ns2.locals_names;
};
motoko = em1.motoko;
}
in
(* If second module has a start, prepend it to the first module's start.
OK to use `Hashtbl.find` below as the first module will have a start, so
we'll have the unit function in the type section already. *)
match m2.start with
| None -> joined
| Some fi -> prepend_to_start fi.it (Hashtbl.find type_indices (Wasm.Types.FuncType ([], []))) joined

(* The main linking function *)

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

assert (dm2.globals = []);

let new_table_size =
Int32.add (Int32.add lib_table_start dylink.table_size) (Int32.of_int (List.length got_func_imports))
in
Expand Down Expand Up @@ -904,6 +911,7 @@ let link (em1 : extended_module) libname (em2 : extended_module) =
|> remove_fun_imports_name_section fun_resolved21
|> rename_funcs_name_section funs2
)
type_indices
|> add_call_ctors
|> remove_non_ic_exports (* only sane if no additional files get linked in *)
in
Expand Down
14 changes: 14 additions & 0 deletions src/wasm-exts/customModule.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,26 @@ type name_section = {
module_ : string option;
function_names : (int32 * string) list;
locals_names : (int32 * (int32 * string) list) list;
label_names : (int32 * (int32 * string) list) list;
type_names : (int32 * string) list;
table_names : (int32 * string) list;
memory_names : (int32 * string) list;
global_names : (int32 * string) list;
elem_segment_names : (int32 * string) list;
data_segment_names : (int32 * string) list;
}

let empty_name_section : name_section = {
module_ = None;
function_names = [];
locals_names = [];
label_names = [];
type_names = [];
table_names = [];
memory_names = [];
global_names = [];
elem_segment_names = [];
data_segment_names = [];
}

type dylink_section = {
Expand Down
37 changes: 25 additions & 12 deletions src/wasm-exts/customModuleDecode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ let name s =
try Utf8.decode (string s) with Utf8.Utf8 ->
error s pos "malformed UTF-8 encoding"

let sized f s =
let sized (f : int -> stream -> 'a) (s : stream) =
let size = len32 s in
let start = pos s in
let x = f size s in
Expand Down Expand Up @@ -663,7 +663,7 @@ let data_section s =

(* Custom sections *)

let custom_section name_pred f default s =
let custom_section (name_pred : int list -> bool) (f : int -> stream -> 'a) (default : 'a) (s : stream) =
let p = pos s in
match id s with
| Some `CustomSection ->
Expand Down Expand Up @@ -715,7 +715,7 @@ let assoc_list f = vec (fun s ->
let name_map = assoc_list string
let indirect_name_map = assoc_list name_map

let name_section_subsection (ns : name_section) s =
let name_section_subsection (ns : name_section) (s : stream) : name_section =
match u8 s with
| 0 -> (* module name *)
let mod_name = sized (fun _ -> string) s in
Expand All @@ -726,17 +726,30 @@ let name_section_subsection (ns : name_section) s =
| 2 -> (* local names *)
let loc_names = sized (fun _ -> indirect_name_map) s in
{ ns with locals_names = ns.locals_names @ loc_names }

(* We ignore additional name subsections for now, despite newer
LLVM seemingly producing them.
We should check if these sections are indeed as spec'ed in
(* The following subsections are not in the standard yet, but from the extended-name-section proposal
https://github.com/WebAssembly/extended-name-section/blob/master/proposals/extended-name-section/Overview.md
and implement them, for better debugging.
*)
| 7 ->
let _global_names = sized (fun _ -> name_map) s in
ns
| 3 -> (* label names *)
let label_names = sized (fun _ -> indirect_name_map) s in
{ ns with label_names = ns.label_names @ label_names }
| 4 -> (* type names *)
let type_names = sized (fun _ -> name_map) s in
{ ns with type_names = ns.type_names @ type_names }
| 5 -> (* table names *)
let table_names = sized (fun _ -> name_map) s in
{ ns with table_names = ns.table_names @ table_names }
| 6 -> (* memory names *)
let memory_names = sized (fun _ -> name_map) s in
{ ns with memory_names = ns.memory_names @ memory_names }
| 7 -> (* global names *)
let global_names = sized (fun _ -> name_map) s in
{ ns with global_names = ns.global_names @ global_names }
| 8 -> (* elem segment names *)
let elem_segment_names = sized (fun _ -> name_map) s in
{ ns with elem_segment_names = ns.elem_segment_names @ elem_segment_names }
| 9 -> (* data segment names *)
let data_segment_names = sized (fun _ -> name_map) s in
{ ns with data_segment_names = ns.data_segment_names @ data_segment_names }
| i -> error s (pos s) (Printf.sprintf "unknown name section subsection id %d" i)

let name_section_content p_end s =
Expand Down

0 comments on commit ab23fba

Please sign in to comment.