Skip to content

Commit

Permalink
Preprocessor: use the export name to name functions without id
Browse files Browse the repository at this point in the history
This provides a better debugging experience since reference to these
functions will now use an id rather than a number in disassembled code.
  • Loading branch information
vouillon committed Jan 31, 2025
1 parent b99f325 commit 22aa8ab
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 9 deletions.
40 changes: 35 additions & 5 deletions compiler/lib-wasm/wat_preprocess.ml
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,12 @@ let rec parse_string_contents lexbuf =
None
| _ -> assert false

let opt_parse_string s =
parse_string_contents
(Sedlexing.Utf8.from_string (String.sub s ~pos:1 ~len:(String.length s - 2)))

let parse_string loc s =
match
parse_string_contents
(Sedlexing.Utf8.from_string (String.sub s ~pos:1 ~len:(String.length s - 2)))
with
match opt_parse_string s with
| None ->
raise
(Error
Expand Down Expand Up @@ -284,6 +285,11 @@ let type_name (t : typ) =
| String -> "string"
| Version -> "version"

let variable_is_set st nm =
match StringMap.find_opt nm st.variables with
| Some (Bool true) -> true
| _ -> false

let check_type ?typ expr actual_typ =
match typ with
| None -> ()
Expand Down Expand Up @@ -516,6 +522,28 @@ and rewrite st elt =
| { desc = List ({ desc = Atom "@string"; _ } :: _ :: _ :: { loc; _ } :: _); _ } ->
raise
(Error (position_of_loc loc, Printf.sprintf "Expecting a closing parenthesis.\n"))
| { desc =
List
({ desc = Atom "func"; loc = _, pos }
:: { desc =
List
[ { desc = Atom "export"; _ }
; { desc = Atom export_name; loc = export_loc }
]
; loc = pos', _
}
:: l)
; _
}
when variable_is_set st "name-wasm-functions"
&&
match opt_parse_string export_name with
| None -> false
| Some s -> is_id ("$" ^ s) ->
write st pos;
insert st (Printf.sprintf " $%s " (parse_string export_loc export_name));
skip st pos';
rewrite_list st l
| { desc = List l; _ } -> rewrite_list st l
| _ -> ()

Expand All @@ -525,12 +553,14 @@ let ocaml_version =
Scanf.sscanf Sys.ocaml_version "%d.%d.%d" (fun major minor patchlevel ->
Version (major, minor, patchlevel))

let default_settings = [ "name-wasm-functions", Bool true ]

let f ~variables ~filename ~contents:text =
let variables =
List.fold_left
~f:(fun m (k, v) -> StringMap.add k v m)
~init:StringMap.empty
variables
(default_settings @ variables)
in
let variables = StringMap.add "ocaml_version" ocaml_version variables in
let lexbuf = Sedlexing.Utf8.from_string text in
Expand Down
2 changes: 2 additions & 0 deletions manual/wasm_runtime.wiki
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ To form conditional expressions, the following operators are available:

This also provides some syntactic sugar to write strings. The expression{{{(@string "ab")}}} is expanded into {{{(array.new_fixed $string 2 (i32.const 97) (i32.const 98))}}}. The statement {{{(@string $s "ab")}}} is an abbreviatiation for {{{(global $s (ref eq) (@string "ab"))}}}.

To provide a better debugging experience, the function export name is used to name functions with no explicit id: {{{(func (export "foo") ...)}}}} is expanded into {{{(func $foo (export "foo") ...)}}}}.

== Implementing primitives ==

You define a primitive by exporting a Wasm function with parameters and return value of type {{{(ref eq)}}}.
Expand Down
8 changes: 4 additions & 4 deletions runtime/wasm/jslib_js_of_ocaml.wat
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,20 @@
(import "jslib" "caml_js_from_array"
(func $caml_js_from_array (param (ref eq)) (result (ref eq))))
(import "js" "caml_js_html_escape"
(func $caml_js_html_escape (param anyref) (result anyref)))
(func $caml_js_html_escape_js (param anyref) (result anyref)))
(import "js" "caml_js_html_entities"
(func $caml_js_html_entities (param anyref) (result anyref)))
(func $caml_js_html_entities_js (param anyref) (result anyref)))

(type $block (array (mut (ref eq))))
(type $string (array (mut i8)))

(func (export "caml_js_html_escape") (param (ref eq)) (result (ref eq))
(return_call $wrap
(call $caml_js_html_escape (call $unwrap (local.get 0)))))
(call $caml_js_html_escape_js (call $unwrap (local.get 0)))))

(func (export "caml_js_html_entities") (param (ref eq)) (result (ref eq))
(return_call $wrap
(call $caml_js_html_entities (call $unwrap (local.get 0)))))
(call $caml_js_html_entities_js (call $unwrap (local.get 0)))))

(@string $console "console")

Expand Down

0 comments on commit 22aa8ab

Please sign in to comment.