package wax-lib

  1. Overview
  2. Docs
Libraries for Wax, a Rust-like syntax for WebAssembly

Install

dune-project
 Dependency

Authors

Maintainers

Sources

wax-v0.2.0.tbz
sha256=4361e1324b7754a4c08ab5b505df32061f3ce0cea60443fd0d3699e0fa796b32
sha512=fcc756d2f160ba90a9aa1131f2ab22ed7f45466ccd658c21cf9df6868a6aab0cee7f404719d698a379958802f9820398f2fe0685ecc4dda018ca4f653294e39b

doc/src/wax-lib.wasm/ast_utils.ml.html

Source file ast_utils.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
open Ast
open Ast.Text

(* The canonical pre-order walk of an instruction tree: visit [i], then recurse
   into every nested instruction it carries. Keeping this in one place means a
   new instruction that nests others is handled for every traversal at once. *)
let rec fold_instr f acc (i : 'info instr) =
  let acc = f acc i in
  match i.desc with
  | Block { block; _ } | Loop { block; _ } | TryTable { block; _ } ->
      fold_instrs f acc block.desc
  | If { if_block; else_block; _ } ->
      fold_instrs f (fold_instrs f acc if_block.desc) else_block.desc
  | Try { block; catches; catch_all; _ } ->
      let acc = fold_instrs f acc block.desc in
      let acc =
        List.fold_left
          (fun acc (_, (is : (_ instr list, _) Ast.annotated)) ->
            fold_instrs f acc is.desc)
          acc catches
      in
      Option.fold ~none:acc
        ~some:(fun (b : (_ instr list, _) Ast.annotated) ->
          fold_instrs f acc b.desc)
        catch_all
  | Folded (h, is) -> fold_instrs f (fold_instr f acc h) is
  (* The remaining variants carry no nested instruction. *)
  | _ -> acc

and fold_instrs f acc l =
  (* Explicit recursion, not [List.fold_left (fold_instr f)]: this runs once per
     nested instruction list, and the partial application [(fold_instr f)] would
     allocate a closure on every call. *)
  match l with
  | [] -> acc
  | i :: r -> fold_instrs f (fold_instr f acc i) r

let iter_instr f i = fold_instr (fun () i -> f i) () i

(* compact-import-section: expand an [Import_group1]/[Import_group2] field into
   the individual [Import] fields it stands for (carrying the group's location);
   any other field is returned unchanged as a singleton. Passes that only need to
   see individual imports flatten a field list with
   [List.concat_map expand_import_group]. *)
let expand_import_group (f : (_ modulefield, _) Ast.annotated) =
  match f.desc with
  | Import_group1 { module_; items } ->
      List.map
        (fun (name, id, desc) ->
          { f with desc = Import { module_; name; id; desc; exports = [] } })
        items
  | Import_group2 { module_; desc; items } ->
      List.map
        (fun name ->
          {
            f with
            desc = Import { module_; name; id = None; desc; exports = [] };
          })
        items
  | _ -> [ f ]

(* Flatten binary import-section entries back into the individual imports they
   denote, for the passes that only need the flat import list (index counting). *)
let flatten_binary_imports (entries : Ast.Binary.import_entry list) :
    Ast.Binary.import list =
  List.concat_map
    (function
      | Ast.Binary.Single i -> [ i ]
      | Group1 { module_; items } ->
          List.map
            (fun (name, desc) -> { Ast.Binary.module_; name; desc })
            items
      | Group2 { module_; desc; names } ->
          List.map (fun name -> { Ast.Binary.module_; name; desc }) names)
    entries