Skip to content

Commit 2d04645

Browse files
Update exporting-function.md
* Replace the recommended WASI implementation with `@bjorn3/browser_wasi_shim` for better quality and maintainability. * Remove error-prone top-level code and `main` function from the example by recommending `-parse-as-library` option. * Use ESM syntax for the JavaScript example since `@bjorn3/browser_wasi_shim` works with ESM only.
1 parent c0ccc59 commit 2d04645

File tree

1 file changed

+29
-40
lines changed

1 file changed

+29
-40
lines changed

src/examples/exporting-function.md

Lines changed: 29 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
You can expose a Swift function for host environment using special attribute and linker option.
44

55
```swift
6+
// File name: lib.swift
67
@_cdecl("add")
78
func add(_ lhs: Int, _ rhs: Int) -> Int {
89
return lhs + rhs
@@ -17,56 +18,44 @@ To call the exported function as a library multiple times, you need to:
1718
The default execution model is *command*, so you need to pass `-mexec-model=reactor` to linker.
1819
2. Call `_initialize` function before interacting with the instance.
1920

20-
If your code has any top-level code, you need to export `main` function as well, and call it after `_initialize` function.
21-
2221
```bash
2322
$ swiftc \
2423
-target wasm32-unknown-wasi \
24+
-parse-as-library \
2525
lib.swift -o lib.wasm \
2626
-Xlinker --export=add \
27-
-Xclang-linker -mexec-model=reactor \
28-
-Xlinker --export=main # Optional
27+
-Xclang-linker -mexec-model=reactor
2928
```
3029

3130
Then, you can use the exported function from host environment.
3231

3332
```javascript
34-
const WASI = require("@wasmer/wasi").WASI;
35-
const WasmFs = require("@wasmer/wasmfs").WasmFs;
36-
37-
const promisify = require("util").promisify;
38-
const fs = require("fs");
39-
const readFile = promisify(fs.readFile);
40-
41-
const main = async () => {
42-
// Instantiate a new WASI Instance
43-
const wasmFs = new WasmFs();
44-
let wasi = new WASI({
45-
args: [],
46-
env: {},
47-
bindings: {
48-
...WASI.defaultBindings,
49-
fs: wasmFs.fs,
50-
},
51-
});
52-
53-
const wasmBinary = await readFile("lib.wasm");
54-
55-
// Instantiate the WebAssembly file
56-
const { instance } = await WebAssembly.instantiate(wasmBinary, {
57-
wasi_snapshot_preview1: wasi.wasiImport,
58-
});
59-
// Initialize the instance by following WASI reactor ABI
60-
instance.exports._initialize();
61-
// (Optional) Run the top-level code
62-
instance.exports.main();
63-
// Get the exported function
64-
const addFn = instance.exports.add;
65-
console.log("2 + 3 = " + addFn(2, 3))
66-
67-
};
68-
69-
main()
33+
// File name: main.mjs
34+
import { WASI, File, OpenFile, ConsoleStdout } from "@bjorn3/browser_wasi_shim";
35+
import fs from "fs/promises";
36+
37+
// Instantiate a new WASI Instance
38+
// See https://github.com/bjorn3/browser_wasi_shim/ for more detail about constructor options
39+
let wasi = new WASI([], [],
40+
[
41+
new OpenFile(new File([])), // stdin
42+
ConsoleStdout.lineBuffered(msg => console.log(`[WASI stdout] ${msg}`)),
43+
ConsoleStdout.lineBuffered(msg => console.warn(`[WASI stderr] ${msg}`)),
44+
],
45+
{ debug: false }
46+
);
47+
48+
const wasmBinary = await fs.readFile("lib.wasm");
49+
50+
// Instantiate the WebAssembly file
51+
const { instance } = await WebAssembly.instantiate(wasmBinary, {
52+
wasi_snapshot_preview1: wasi.wasiImport,
53+
});
54+
// Initialize the instance by following WASI reactor ABI
55+
wasi.initialize(instance);
56+
// Get the exported function
57+
const addFn = instance.exports.add;
58+
console.log("2 + 3 = " + addFn(2, 3))
7059
```
7160

7261
If you use SwiftPM package, you can omit linker flag using clang's `__atribute__`. Please see [swiftwasm/JavaScriptKit#91](https://github.com/swiftwasm/JavaScriptKit/pull/91/files) for more detail info

0 commit comments

Comments
 (0)