1212
1313#include < sys_string/impl/util/generic_impl.h>
1414
15+ // Like EM_JS but with inline and extern "C" only on data
16+ #define SYSSTR_EM_JS (ret, c_name, js_name, params, ...) \
17+ ret c_name params EM_IMPORT (js_name); \
18+ extern " C" \
19+ __attribute__ ((visibility(" hidden" ))) \
20+ inline void * __em_js_ref_##c_name = (void *)&c_name; \
21+ extern " C" \
22+ EMSCRIPTEN_KEEPALIVE \
23+ __attribute__ ((section(" em_js" ), aligned(1 ))) \
24+ inline char __em_js__##js_name[] = \
25+ #params " <::>" #__VA_ARGS__;
26+
27+
1528namespace sysstr ::util
1629{
1730 struct emscripten_traits
@@ -33,6 +46,40 @@ namespace sysstr::util
3346
3447 using emscripten_char_access = generic::char_access<emscripten_traits::storage_type, emscripten_traits::size_type>;
3548
49+ #ifdef __wasm_reference_types__
50+
51+ #if SYS_STRING_USE_WASM_JS_STRING
52+ uint32_t js_length (__externref_t str) __attribute__((import_module(" wasm:js-string" ), import_name(" length" )));
53+ uint32_t js_charCodeAt (__externref_t str, uint32_t idx) __attribute__((import_module(" wasm:js-string" ), import_name(" charCodeAt" )));
54+ #else
55+
56+ SYSSTR_EM_JS (uint32_t , js_length, sysstr_length, (__externref_t str), {
57+ return str.length ;
58+ });
59+
60+ SYSSTR_EM_JS (uint32_t , js_charCodeAt, sysstr_charCodeAt, (__externref_t str, uint32_t idx), {
61+ return str.charCodeAt (idx);
62+ });
63+ #endif
64+
65+ SYSSTR_EM_JS (__externref_t , js_UTF16ToString, sysstr_UTF16ToString, (const void * ptr, size_t length), {
66+ let start = (ptr>>1 );
67+ if (length > 16 && UTF16Decoder)
68+ return UTF16Decoder.decode (HEAPU16.subarray (start, start + length));
69+
70+ let ret = " " ;
71+
72+ for (let i = 0 ; i < length; ++i) {
73+ const codeUnit = HEAPU16[start];
74+ ret += String.fromCharCode (codeUnit);
75+ ++start;
76+ }
77+
78+ return ret;
79+ });
80+
81+ #endif
82+
3683}
3784
3885namespace sysstr
@@ -59,6 +106,12 @@ namespace sysstr
59106 super (create_buffer(js_str))
60107 {}
61108
109+ #ifdef __wasm_reference_types__
110+ emscripten_storage (__externref_t js_str):
111+ super(create_buffer(js_str))
112+ {}
113+ #endif
114+
62115#ifdef _MSC_VER
63116 template <has_utf_encoding Char>
64117 emscripten_storage (const Char * str, size_t len):
@@ -78,26 +131,12 @@ namespace sysstr
78131 using super::data;
79132 using super::copy_data;
80133
81- auto make_js_string () const noexcept -> emscripten::EM_VAL
82- {
134+ auto make_js_string () const noexcept -> emscripten::EM_VAL {
83135 #pragma clang diagnostic push
84136 #pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
85137
86138 auto ret = (emscripten::EM_VAL)EM_ASM_PTR ({
87- let ptr = $0 ;
88- let length = $1 ;
89- if (length > 16 && UTF16Decoder)
90- return Emval.toHandle (UTF16Decoder.decode (HEAPU8.subarray (ptr, ptr + length * 2 )));
91-
92- let ret = " " ;
93-
94- for (let i = 0 ; i < length; ++i) {
95- const codeUnit = HEAP16[((ptr)>>1 )];
96- ret += String.fromCharCode (codeUnit);
97- ptr += 2 ;
98- }
99-
100- return Emval.toHandle (ret);
139+ return Emval.toHandle (sysstr_UTF16ToString ($0 , $1 ));
101140 }, data (), size ());
102141
103142 return ret;
@@ -106,6 +145,12 @@ namespace sysstr
106145
107146 }
108147
148+ #ifdef __wasm_reference_types__
149+ auto make_js_string_ref () const noexcept -> __externref_t {
150+ return util::js_UTF16ToString (data (), size ());
151+ }
152+ #endif
153+
109154 protected:
110155 using super::size;
111156 using super::operator [];
@@ -133,14 +178,29 @@ namespace sysstr
133178 let ptr = $1 ;
134179 let length = str.length ;
135180 for (let i = 0 ; i < length; ++i) {
136- HEAP16 [((ptr)>>1 )] = str.charCodeAt (i);
181+ HEAPU16 [((ptr)>>1 )] = str.charCodeAt (i);
137182 ptr += 2 ;
138183 }
139184 }, js_str, ret.data ());
140185 return ret;
141186
142187 #pragma clang diagnostic pop
143188 }
189+
190+ #ifdef __wasm_reference_types__
191+ static auto create_buffer (__externref_t js_str) -> buffer {
192+ uint32_t len = util::js_length (js_str);
193+
194+ if (len == 0 )
195+ return buffer ();
196+
197+ buffer ret (len);
198+ auto ptr = ret.data ();
199+ for (uint32_t i = 0 ; i < len; ++i)
200+ ptr[i] = util::js_charCodeAt (js_str, i);
201+ return ret;
202+ }
203+ #endif
144204 };
145205}
146206
0 commit comments