Skip to content

Commit 560f179

Browse files
committed
Updating docs
1 parent 980b85d commit 560f179

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

doc/Emscripten.md

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,44 @@ When compiling under Emscripten there are two storage types available. The defau
44

55
Additionally you can chose a "generic Unix" storage which stores `char *` and is meant to interoperate with plain Unix API. It can be selected via `#define SYS_STRING_USE_GENERIC 1` and is described under [Linux](Linux.md).
66

7-
With JavaScript-optimized storage a conversion to and from `String` is non-trivial. It incurs allocation on JavaScript or native heap and copying between them.
7+
With JavaScript-optimized storage a conversion to and from `String` is non-trivial. It incurs allocation on JavaScript or native heap and copying between them.
88

9-
Conversions rely on on `embind` [library](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html) so you will need to link with that (e.g. `-lembind`).
9+
There are two ways you can convert strings from/to JavaScript
10+
11+
### Using external references
12+
13+
Newer versions of Emscripten (actually clang that it is using) support [WASM 2.0 external references](https://github.com/WebAssembly/reference-types) via
14+
`__externref_t` type. If this feature is available (the library detects it automatically) you can convert a JavaScript `String`
15+
object to `sys_string` and create a `String` object from `sys_string` as follows:
16+
17+
```cpp
18+
//Conversions from/to JavaScript
19+
__externref_t jstr_in = ...;
20+
sys_string str(jstr);
21+
22+
...
23+
24+
__externref_t jstr_out = str.make_js_string_ref();
25+
```
26+
27+
Note that `make_js_string_ref` creates a new JavaScript string every time (the `__externref_t` handles have severe limitations on their use in C++ code
28+
and cannot be easily cached for example). Also unlike other platforms you **cannot pass `null` (or `undefined`)** as strings to C++ side. Neither will `make_js_string_ref()` ever return a handle that will convert to `null` or `undefined` on JavaScript side.
29+
30+
Using external references is the fastest conversion method available. It can be made even faster if your WASM platform supports [WASM JavaScript Builtins](https://developer.mozilla.org/en-US/docs/WebAssembly/Guides/JavaScript_builtins). In such case you can define `SYS_STRING_USE_WASM_JS_STRING` macro to 1 before including any `sys_string` headers. This will cause conversions to use built-ins which can result in significant perf improvements for JavaScript -> C++ string conversion. A few things to keep in mind:
31+
1. This WASM feature is very new and might not be supported by your version of Node or browser.
32+
2. The opposite direction, C++ -> JavaScript is currently unaffected. (The way built-ins are specified makes them useless for that scenario)
33+
3. You will need to pass `builtins: ["js-string"]` as compile options when loading the resultant WASM code as described by the link above
34+
4. You overall WASM code now will have an external dependency. You will likely need to pass flags such as:
35+
```
36+
-sMAIN_MODULE=2 -sERROR_ON_UNDEFINED_SYMBOLS=0 -sWARN_ON_UNDEFINED_SYMBOLS=0
37+
```
38+
to your build resulting in other trade-offs.
39+
40+
All in all, the WASM built-ins should be considered highly experimental at this point.
41+
42+
### Using `embind` facilities
43+
44+
In this, older, but reliably supported, method conversions rely on on `embind` [library](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html) so you will need to link with that (e.g. `-lembind`).
1045
1146
1247
```cpp

0 commit comments

Comments
 (0)