Skip to content

Commit 8c76482

Browse files
committed
Use JS String Builtins to convert ASCII OCaml strings to Javascript strings
1 parent bb3fb63 commit 8c76482

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

runtime/wasm/jsstring.wat

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
(func $is_string (param externref) (result i32)))
2323
(import "wasm:js-string" "hash"
2424
(func $hash_string (param i32) (param anyref) (result i32)))
25+
(import "wasm:js-string" "fromCharCodeArray"
26+
(func $fromCharCodeArray
27+
(param (ref null $wstring)) (param i32) (param i32)
28+
(result (ref extern))))
2529

2630
(import "wasm:text-decoder" "decodeStringFromUTF8Array"
2731
(func $decodeStringFromUTF8Array
@@ -41,15 +45,17 @@
4145
(func $append_string (param anyref) (param anyref) (result anyref)))
4246

4347
(type $string (array (mut i8)))
48+
(type $wstring (array (mut i16)))
4449

45-
(global $builtins_available (mut i32) (i32.const 0))
50+
(global $text_converters_available (mut i32) (i32.const 0))
51+
(global $string_builtins_available (mut i32) (i32.const 0))
4652

4753
(start $init)
4854

4955
(func $init
5056
;; Our dummy implementation of string conversion always returns
5157
;; the empty string.
52-
(global.set $builtins_available
58+
(global.set $text_converters_available
5359
(i32.ne
5460
(i32.const 0)
5561
(call $compare_strings
@@ -58,6 +64,16 @@
5864
(i32.const 0) (i32.const 1))
5965
(call $decodeStringFromUTF8Array
6066
(array.new_fixed $string 1 (i32.const 1))
67+
(i32.const 0) (i32.const 1)))))
68+
(global.set $string_builtins_available
69+
(i32.ne
70+
(i32.const 0)
71+
(call $compare_strings
72+
(call $fromCharCodeArray
73+
(array.new_fixed $wstring 1 (i32.const 0))
74+
(i32.const 0) (i32.const 1))
75+
(call $fromCharCodeArray
76+
(array.new_fixed $wstring 1 (i32.const 1))
6177
(i32.const 0) (i32.const 1))))))
6278

6379
(func (export "jsstring_compare")
@@ -71,17 +87,48 @@
7187

7288
(export "jsstring_hash" (func $hash_string))
7389

90+
(func $is_ascii
91+
(param $s (ref $string)) (param $i i32) (param $end i32) (result i32)
92+
(loop $loop
93+
(if (i32.eq (local.get $i) (local.get $end))
94+
(then (return (i32.const 1))))
95+
(if (i32.gt_u (array.get_u $string (local.get $s) (local.get $i))
96+
(i32.const 127))
97+
(then (return (i32.const 0))))
98+
(local.set $i (i32.add (local.get $i) (i32.const 1)))
99+
(br $loop)))
100+
74101
;; Used by package zarith_stubs_js
75102
(func $jsstring_of_substring (export "jsstring_of_substring")
76103
(param $s (ref $string)) (param $pos i32) (param $len i32)
77104
(result anyref)
78-
(if (global.get $builtins_available)
105+
(local $i i32) (local $ws (ref $wstring))
106+
(if (global.get $text_converters_available)
79107
(then
80108
(return
81109
(any.convert_extern
82110
(call $decodeStringFromUTF8Array (local.get $s)
83111
(local.get $pos)
84112
(i32.add (local.get $pos) (local.get $len)))))))
113+
(if (i32.and (global.get $string_builtins_available)
114+
(call $is_ascii
115+
(local.get $s) (local.get $pos)
116+
(i32.add (local.get $pos) (local.get $len))))
117+
(then
118+
(local.set $ws (array.new $wstring (i32.const 0) (local.get $len)))
119+
(loop $loop
120+
(if (i32.lt_u (local.get $i) (local.get $len))
121+
(then
122+
(array.set $wstring (local.get $ws) (local.get $i)
123+
(array.get $string (local.get $s)
124+
(i32.add (local.get $pos) (local.get $i))))
125+
(local.set $i (i32.add (local.get $i) (i32.const 1)))
126+
127+
(br $loop))))
128+
(return
129+
(any.convert_extern
130+
(call $fromCharCodeArray (local.get $ws)
131+
(i32.const 0) (local.get $len))))))
85132
(return_call $jsstring_of_substring_fallback
86133
(local.get $s) (local.get $pos) (local.get $len)))
87134

@@ -90,7 +137,7 @@
90137
(local.get $s) (i32.const 0) (array.len (local.get $s))))
91138

92139
(func (export "string_of_jsstring") (param $s anyref) (result (ref $string))
93-
(if (global.get $builtins_available)
140+
(if (global.get $text_converters_available)
94141
(then
95142
(return_call $encodeStringToUTF8Array
96143
(extern.convert_any (local.get $s)))))

runtime/wasm/runtime.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,7 @@
465465
hash: hash_string,
466466
decodeStringFromUTF8Array: () => "",
467467
encodeStringToUTF8Array: () => 0,
468+
fromCharCodeArray: () => "",
468469
};
469470
const imports = Object.assign(
470471
{

0 commit comments

Comments
 (0)