Skip to content

Commit 4f76417

Browse files
authored
Merge pull request #132 from ocaml-wasm/string-conv
Use JS String Builtins to convert ASCII OCaml strings to Javascript strings
2 parents e83dd90 + 6239d59 commit 4f76417

File tree

2 files changed

+54
-5
lines changed

2 files changed

+54
-5
lines changed

runtime/wasm/jsstring.wat

Lines changed: 53 additions & 5 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,21 @@
4145
(func $append_string (param anyref) (param anyref) (result anyref)))
4246

4347
(type $string (array (mut i8)))
48+
(type $wstring (array (mut i16)))
49+
50+
(global $text_converters_available (mut i32) (i32.const 0))
51+
(global $string_builtins_available (mut i32) (i32.const 0))
4452

45-
(global $builtins_available (mut i32) (i32.const 0))
53+
(global $utf16_buffer_size i32 (i32.const 32768))
54+
(global $buffer (mut (ref $wstring))
55+
(array.new $wstring (i32.const 0) (i32.const 0)))
4656

4757
(start $init)
4858

4959
(func $init
5060
;; Our dummy implementation of string conversion always returns
5161
;; the empty string.
52-
(global.set $builtins_available
62+
(global.set $text_converters_available
5363
(i32.ne
5464
(i32.const 0)
5565
(call $compare_strings
@@ -58,7 +68,24 @@
5868
(i32.const 0) (i32.const 1))
5969
(call $decodeStringFromUTF8Array
6070
(array.new_fixed $string 1 (i32.const 1))
61-
(i32.const 0) (i32.const 1))))))
71+
(i32.const 0) (i32.const 1)))))
72+
(global.set $string_builtins_available
73+
(i32.ne
74+
(i32.const 0)
75+
(call $compare_strings
76+
(call $fromCharCodeArray
77+
(array.new_fixed $wstring 1 (i32.const 0))
78+
(i32.const 0) (i32.const 1))
79+
(call $fromCharCodeArray
80+
(array.new_fixed $wstring 1 (i32.const 1))
81+
(i32.const 0) (i32.const 1)))))
82+
(if (i32.eqz (global.get $text_converters_available))
83+
(then
84+
(if (global.get $string_builtins_available)
85+
(then
86+
(global.set $buffer
87+
(array.new $wstring (i32.const 0)
88+
(global.get $utf16_buffer_size))))))))
6289

6390
(func (export "jsstring_compare")
6491
(param $s anyref) (param $s' anyref) (result i32)
@@ -75,13 +102,34 @@
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 $c i32)
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 $continue
114+
(i32.and (global.get $string_builtins_available)
115+
(i32.le_u (local.get $len) (global.get $utf16_buffer_size)))
116+
(then
117+
(loop $loop
118+
(if (i32.lt_u (local.get $i) (local.get $len))
119+
(then
120+
(local.set $c
121+
(array.get $string (local.get $s)
122+
(i32.add (local.get $pos) (local.get $i))))
123+
(br_if $continue
124+
(i32.ge_u (local.get $c) (i32.const 128)))
125+
(array.set $wstring (global.get $buffer) (local.get $i)
126+
(local.get $c))
127+
(local.set $i (i32.add (local.get $i) (i32.const 1)))
128+
(br $loop))))
129+
(return
130+
(any.convert_extern
131+
(call $fromCharCodeArray (global.get $buffer)
132+
(i32.const 0) (local.get $len))))))
85133
(return_call $jsstring_of_substring_fallback
86134
(local.get $s) (local.get $pos) (local.get $len)))
87135

@@ -90,7 +138,7 @@
90138
(local.get $s) (i32.const 0) (array.len (local.get $s))))
91139

92140
(func (export "string_of_jsstring") (param $s anyref) (result (ref $string))
93-
(if (global.get $builtins_available)
141+
(if (global.get $text_converters_available)
94142
(then
95143
(return_call $encodeStringToUTF8Array
96144
(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)