@thi.ng/wasm-api 0.4.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2022-08-07T15:28:01Z
3
+ - **Last updated**: 2022-08-15T23:41:37Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,65 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ ## [0.7.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.7.0) (2022-08-15)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add CLI wrapper for codegens ([683a560](https://github.com/thi-ng/umbrella/commit/683a560))
17
+ - update TSOpts & TS codegen ([4f6bbbf](https://github.com/thi-ng/umbrella/commit/4f6bbbf))
18
+ - add `uppercaseEnum` option to force UC enum IDs
19
+ - update helper predicates ([65b23d4](https://github.com/thi-ng/umbrella/commit/65b23d4))
20
+
21
+ #### 🩹 Bug fixes
22
+
23
+ - allow signed ints for enum tags ([78d0822](https://github.com/thi-ng/umbrella/commit/78d0822))
24
+ - correct TS __mapArray codegen ([289b137](https://github.com/thi-ng/umbrella/commit/289b137))
25
+
26
+ ## [0.6.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.6.0) (2022-08-15)
27
+
28
+ #### 🚀 Features
29
+
30
+ - add C11 header/include file, update WasmBridge ([a67dc00](https://github.com/thi-ng/umbrella/commit/a67dc00))
31
+ - migrate headers/includes to /include
32
+ - rename "core" import section => "wasmapi"
33
+ - rename WasmBridge.core => WasmBridge.api
34
+ - update pkg file
35
+ - update codegens, add opts, fix alignments ([5c1fec5](https://github.com/thi-ng/umbrella/commit/5c1fec5))
36
+ - add global CodeGenOpts
37
+ - update generateTypes() to consider new opts
38
+ - add global USIZE type (for pointer sizes & codegens)
39
+ - add options for Zig codegen (extra debug helpers)
40
+ - simplify TS codegen
41
+ - fix sizeOf() for struct fields
42
+ - make prepareType() idempotent
43
+ - add bindings code generator framework ([17ee06f](https://github.com/thi-ng/umbrella/commit/17ee06f))
44
+ - add/update deps
45
+ - add preliminary codegens for Zig & TS
46
+ - add supporting types & utils
47
+ - add generateTypes() codegen facade fn
48
+ - update allocate/free() fns, update Zig core API ([8a55989](https://github.com/thi-ng/umbrella/commit/8a55989))
49
+ - add _wasm_free() Zig impl
50
+ - add printFmt() Zig fn
51
+ - update WasmBridge.allocate() (add clear option)
52
+ - update WasmBridge.free()
53
+ - ensure memory in WasmBridge.getString()
54
+ - add/update docstrings
55
+
56
+ #### ♻️ Refactoring
57
+
58
+ - extract WasmMemViews interface, update test WASM ([4c73e65](https://github.com/thi-ng/umbrella/commit/4c73e65))
59
+
60
+ ## [0.5.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.5.0) (2022-08-08)
61
+
62
+ #### 🚀 Features
63
+
64
+ - add memory allocation ([980c1f2](https://github.com/thi-ng/umbrella/commit/980c1f2))
65
+ - add WasmBridge.allocate()/free()
66
+ - add WasmBridge.growMemory()
67
+ - extract WasmBridge.ensureMemory()
68
+ - update WasmExports
69
+ - update Zig bindings (configurable allocator, GPA as default)
70
+
12
71
  ## [0.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.4.0) (2022-08-07)
13
72
 
14
73
  #### 🚀 Features
package/README.md CHANGED
@@ -12,30 +12,52 @@ This project is part of the
12
12
  - [About](#about)
13
13
  - [Custom API modules](#custom-api-modules)
14
14
  - [Object indices & handles](#object-indices--handles)
15
+ - [Data bindings & code generators](#data-bindings--code-generators)
16
+ - [CLI generator](#cli-generator)
17
+ - [Data type definitions](#data-type-definitions)
18
+ - [Example usage](#example-usage)
15
19
  - [Status](#status)
16
20
  - [Installation](#installation)
17
21
  - [Dependencies](#dependencies)
18
22
  - [API](#api)
23
+ - [Basic usage example](#basic-usage-example)
24
+ - [Zig version](#zig-version)
25
+ - [C11 version](#c11-version)
19
26
  - [Authors](#authors)
20
27
  - [License](#license)
21
28
 
22
29
  ## About
23
30
 
24
- Modular, extensible API bridge and generic glue code between JS & WebAssembly.
31
+ Generic, modular, extensible API bridge, glue code and bindings code generator for hybrid JS & WebAssembly projects.
25
32
 
26
- This package provides a small, generic and modular
27
- [`WasmBridge`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html)
28
- class as interop basis and a much reduced boilerplate for hybrid JS/WebAssembly
29
- applications. At the moment only a minimal core API is provided (i.e. for debug
30
- output, string, pointer, typed array accessors [8/16/32/64 bit (u)ints, 32/64
31
- bit floats]), but in the future we aim to also supply support modules for DOM
32
- manipulation, WebGL, WebGPU, WebAudio etc.
33
+ This package provides a the following:
33
34
 
34
- In general, all languages with a WebAssembly target are supported, however
35
- currently only bindings for [Zig](https://ziglang.org) are included.
35
+ 1. A small, generic and modular
36
+ [`WasmBridge`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html)
37
+ class as interop basis and much reduced boilerplate for hybrid JS/WebAssembly
38
+ applications.
39
+ 2. A minimal core API for debug output, string, pointer, typed array accessors
40
+ for 8/16/32/64 bit (u)ints and 32/64 bit floats. In the future we aim to also
41
+ supply support modules for DOM manipulation, WebGL, WebGPU, WebAudio etc.
42
+ 3. [Include files for C11/C++ and
43
+ Zig](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api/include),
44
+ defining WASM imports of the JS [core
45
+ API](https://docs.thi.ng/umbrella/wasm-api/interfaces/CoreAPI.html) defined
46
+ by this package
47
+ 4. Extensible shared datatype code generators for (currently)
48
+ [Zig](https://ziglang.org) & TypeScript. The latter also generates fully type
49
+ checked memory-mapped accessors of WASM-side data. In general, all languages
50
+ with a WebAssembly target are supported, however currently only bindings for
51
+ these few langs are included.
52
+ 5. [CLI frontend/utility](#cli-generator) to invoke the code generator(s)
36
53
 
37
54
  ### Custom API modules
38
55
 
56
+ The [`WasmBridge`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html) is extensible via custom defined API modules. Such API extensions
57
+ will consist of a collection of JS/TS functions & variables, their related
58
+ counterparts (import definitions) for the WASM target and (optionally) some
59
+ shared data types ([bindings for which _can_ be generated by this package too](#data-bindings--code-generators)).
60
+
39
61
  On the JS side, custom API modules can be easily integrated via the [`IWasmAPI`
40
62
  interface](https://docs.thi.ng/umbrella/wasm-api/interfaces/IWasmAPI.html). The
41
63
  following example provides a brief overview:
@@ -113,12 +135,12 @@ export fn test_randomVec2() void {
113
135
 
114
136
  Since only numeric values can be exchanged between the WASM module and the JS
115
137
  host, any JS native objects the WASM side might want to be working with must be
116
- managed in JS. For this purpose the [`ObjectIndex`
138
+ managed manually in JS. For this purpose the [`ObjectIndex`
117
139
  class](https://docs.thi.ng/umbrella/wasm-api/classes/ObjectIndex.html) can be
118
140
  used by API modules to handle ID generation (incl. recycling, using
119
141
  [@thi.ng/idgen](https://github.com/thi-ng/umbrella/tree/develop/packages/idgen))
120
- & indexing of different types of JS objects/values. Only the numeric IDs will
121
- then need to be exchanged with the WASM module...
142
+ and the indexing of different types of JS objects/values. Only the numeric IDs
143
+ (handles) will then need to be exchanged with the WASM module...
122
144
 
123
145
  ```ts
124
146
  import { ObjectIndex } from "@thi.ng/wasm-api";
@@ -156,6 +178,257 @@ canvases.delete(0);
156
178
  // true
157
179
  ```
158
180
 
181
+ ### Data bindings & code generators
182
+
183
+ The package provides an extensible codegeneration framework to simplify the
184
+ bilateral design & exchange of data structures shared between the WASM & JS host
185
+ env. Currently, code generators for TypeScript & Zig are supplied (more are
186
+ planned). A CLI wrapper is worked on too.
187
+
188
+ #### CLI generator
189
+
190
+ The package includes a [small CLI
191
+ wrapper](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/src/cli.ts)
192
+ to invoke the codegenerator(s) from JSON type definitions and to write the
193
+ generated source code(s) to different files:
194
+
195
+ ```text
196
+ $ npx run @thi.ng/wasm-api
197
+
198
+ █ █ █ │
199
+ ██ █ │
200
+ █ █ █ █ █ █ █ █ │ @thi.ng/wasm-api 0.6.0
201
+ █ █ █ █ █ █ █ █ █ │ Multi-language data bindings code generator
202
+ █ │
203
+ █ █ │
204
+
205
+ usage: wasm-api [OPTS] JSON-INPUT-FILE(S) ...
206
+ wasm-api --help
207
+
208
+ Flags:
209
+
210
+ -d, --debug enable debug output
211
+ --dry-run enable dry run (don't overwrite files)
212
+
213
+ Main:
214
+
215
+ -c FILE, --config FILE JSON config file with codegen options
216
+ -l ID[,..], --lang ID[,..] [multiple] target language: "ts", "zig" (default: ["ts","zig"])
217
+ -o FILE, --out FILE [multiple] output file path
218
+ ```
219
+
220
+ By default, the CLI generates sources for both TypeScript and Zig (in this
221
+ order!). Order is important, since the output file paths must be given in the
222
+ same order as the target languages. It's recommended to be more explicit. An
223
+ example invocation looks like:
224
+
225
+ ```bash
226
+ wasm-api --config codegen-opts.json \
227
+ --lang ts -o src/generated.ts \
228
+ --lang zig -o src.zig/generated.zig \
229
+ typedefs.json
230
+ ```
231
+
232
+ The structure of the config file is as follows (all optional):
233
+
234
+ ```text
235
+ {
236
+ global: { ... },
237
+ ts: { ... },
238
+ zig: { ... },
239
+ }
240
+ ```
241
+
242
+ More details about possible
243
+ [`global`](https://docs.thi.ng/umbrella/wasm-api/interfaces/CodeGenOpts.html),
244
+ [`ts`](https://docs.thi.ng/umbrella/wasm-api/interfaces/TSOpts.html) and
245
+ [`zig`](https://docs.thi.ng/umbrella/wasm-api/interfaces/ZigOpts.html) config
246
+ options & values.
247
+
248
+ #### Data type definitions
249
+
250
+ Currently, the code generator supports structs and enums. See API docs for
251
+ further details:
252
+
253
+ - [`Enum`](https://docs.thi.ng/umbrella/wasm-api/interfaces/Enum.html)
254
+ - [`EnumValue`](https://docs.thi.ng/umbrella/wasm-api/interfaces/EnumValue.html)
255
+ - [`Struct`](https://docs.thi.ng/umbrella/wasm-api/interfaces/Struct.html)
256
+ - [`StructField`](https://docs.thi.ng/umbrella/wasm-api/interfaces/StructField.html)
257
+ - [`TopLevelType`](https://docs.thi.ng/umbrella/wasm-api/interfaces/TopLevelType.html)
258
+
259
+ #### Example usage
260
+
261
+ Below is an example file with JSON type definitions and the resulting source
262
+ codes:
263
+
264
+ <details><summary>types.json (Type definitions, click to expand)</summary>
265
+
266
+ ```json
267
+ [
268
+ {
269
+ "name": "Foo",
270
+ "type": "struct",
271
+ "doc": "Example struct",
272
+ "auto": true,
273
+ "fields": [
274
+ { "name": "id", "type": "u8", "doc": "Unique ID" },
275
+ { "name": "bars", "type": "Bar", "tag": "array", "len": 3 },
276
+ { "name": "color", "type": "f32", "tag": "vec", "len": 4 }
277
+ ]
278
+ },
279
+ {
280
+ "name": "Bar",
281
+ "type": "struct",
282
+ "fields": [
283
+ { "name": "kind", "type": "Kind" },
284
+ { "name": "flags", "type": "u32" }
285
+ ]
286
+ },
287
+ {
288
+ "name": "Kind",
289
+ "type": "enum",
290
+ "tag": "u16",
291
+ "values": [
292
+ "unknown",
293
+ { "name": "good", "value": 100 },
294
+ { "name": "best", "value": 1000 }
295
+ ]
296
+ }
297
+ ]
298
+ ```
299
+ </details>
300
+
301
+ <details><summary>generated.ts (generated TypeScript source, click to expand)</summary>
302
+
303
+ ```ts
304
+ /** Generated by @thi.ng/wasm-api at 2022-08-15T22:32:21.189Z - DO NOT EDIT! */
305
+
306
+ import type { WasmTypeBase, WasmTypeConstructor } from "@thi.ng/wasm-api";
307
+
308
+ /** Example struct */
309
+ export interface Foo extends WasmTypeBase {
310
+ color: Float32Array;
311
+ bars: Bar[];
312
+ /** Unique ID */
313
+ id: number;
314
+ }
315
+
316
+ export const $Foo: WasmTypeConstructor<Foo> = (mem) => ({
317
+ get align() { return 16; },
318
+ get size() { return 48; },
319
+ instance: (base) => ({
320
+ get __base() { return base; },
321
+ get __bytes() { return mem.u8.subarray(base, base + 48); },
322
+ get color(): Float32Array {
323
+ const addr = base >>> 2;
324
+ return mem.f32.subarray(addr, addr + 4);
325
+ },
326
+ get bars(): Bar[] {
327
+ const addr = (base + 16);
328
+ const inst = $Bar(mem);
329
+ const slice: Bar[] = [];
330
+ for(let i = 0; i < 3; i++) slice.push(inst.instance(addr + i * 24));
331
+ return slice;
332
+ },
333
+ get id(): number {
334
+ return mem.u8[(base + 40)];
335
+ },
336
+ set id(x: number) {
337
+ mem.u8[(base + 40)] = x;
338
+ },
339
+ })
340
+ });
341
+
342
+ export interface Bar extends WasmTypeBase {
343
+ kind: Kind;
344
+ flags: number;
345
+ }
346
+
347
+ export const $Bar: WasmTypeConstructor<Bar> = (mem) => ({
348
+ get align() { return 4; },
349
+ get size() { return 8; },
350
+ instance: (base) => ({
351
+ get __base() { return base; },
352
+ get __bytes() { return mem.u8.subarray(base, base + 8); },
353
+ get kind(): Kind {
354
+ return mem.u16[base >>> 1];
355
+ },
356
+ set kind(x: Kind) {
357
+ mem.u16[base >>> 1] = x;
358
+ },
359
+ get flags(): number {
360
+ return mem.u32[(base + 4) >>> 2];
361
+ },
362
+ set flags(x: number) {
363
+ mem.u32[(base + 4) >>> 2] = x;
364
+ },
365
+ })
366
+ });
367
+
368
+ export enum Kind {
369
+ UNKNOWN,
370
+ GOOD = 100,
371
+ BEST = 1000,
372
+ }
373
+ ```
374
+ </details>
375
+
376
+ <details><summary>generated.zig (generated Zig source, click to expand)</summary>
377
+
378
+ ```zig
379
+ //! Generated by @thi.ng/wasm-api at 2022-08-15T22:32:21.191Z - DO NOT EDIT!
380
+
381
+ /// Example struct
382
+ pub const Foo = struct {
383
+ color: @Vector(4, f32),
384
+ bars: [3]Bar,
385
+ /// Unique ID
386
+ id: u8,
387
+ };
388
+
389
+ pub const Bar = struct {
390
+ kind: Kind,
391
+ flags: u32,
392
+ };
393
+
394
+ pub const Kind = enum(u16) {
395
+ unknown,
396
+ good = 100,
397
+ best = 1000,
398
+ };
399
+ ```
400
+ </details>
401
+
402
+ On the TypeScript/JS side, the memory-mapped wrappers (e.g. `$Foo` and `$Bar`)
403
+ can be used in combination with the `WasmBridge` to obtain fully typed views
404
+ (according to the generated types) of the underlying WASM memory. Basic usage is
405
+ like:
406
+
407
+ ```ts
408
+ import { WasmBridge } from "@thi.ng/wasm-api";
409
+ import { $Foo, Kind } from "./generated.ts";
410
+
411
+ const bridge = new WasmBridge();
412
+ // bridge initialization omitted here (see other examples below)
413
+ // ...
414
+
415
+ // Create an instance using the bridge's memory views
416
+ // and mapping a `Foo` struct from given address
417
+ // (e.g. obtained from an exported WASM function/value)
418
+ const foo = $Foo(bridge).instance(0x10000);
419
+
420
+ // then use like normal JS object
421
+ foo.color
422
+ // Float32Array(4) [0.1, 0.2, 0.3, 0.4]
423
+
424
+ // this even applies to arrays using other types
425
+ // (setters are currently only supported for scalar values, incl. enums)
426
+ foo.bars[2].kind = Kind.BEST;
427
+
428
+ // IMPORTANT: any modifications like this are directly
429
+ // applied to the underlying WASM memory...
430
+ ```
431
+
159
432
  ### Status
160
433
 
161
434
  **ALPHA** - bleeding edge / work-in-progress
@@ -185,12 +458,22 @@ node --experimental-repl-await
185
458
  > const wasmApi = await import("@thi.ng/wasm-api");
186
459
  ```
187
460
 
188
- Package sizes (gzipped, pre-treeshake): ESM: 1.61 KB
461
+ Package sizes (gzipped, pre-treeshake): ESM: 4.03 KB
462
+
463
+ **IMPORTANT:** The package includes various code generators and supporting
464
+ functions which are NOT required during runtime. Hence the actual package size
465
+ in production will be MUCH smaller!
189
466
 
190
467
  ## Dependencies
191
468
 
192
469
  - [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/develop/packages/api)
470
+ - [@thi.ng/args](https://github.com/thi-ng/umbrella/tree/develop/packages/args)
471
+ - [@thi.ng/binary](https://github.com/thi-ng/umbrella/tree/develop/packages/binary)
472
+ - [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/develop/packages/checks)
473
+ - [@thi.ng/compare](https://github.com/thi-ng/umbrella/tree/develop/packages/compare)
474
+ - [@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/develop/packages/defmulti)
193
475
  - [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/develop/packages/errors)
476
+ - [@thi.ng/file-io](https://github.com/thi-ng/umbrella/tree/develop/packages/file-io)
194
477
  - [@thi.ng/hex](https://github.com/thi-ng/umbrella/tree/develop/packages/hex)
195
478
  - [@thi.ng/idgen](https://github.com/thi-ng/umbrella/tree/develop/packages/idgen)
196
479
  - [@thi.ng/logger](https://github.com/thi-ng/umbrella/tree/develop/packages/logger)
@@ -199,6 +482,8 @@ Package sizes (gzipped, pre-treeshake): ESM: 1.61 KB
199
482
 
200
483
  [Generated API docs](https://docs.thi.ng/umbrella/wasm-api/)
201
484
 
485
+ ## Basic usage example
486
+
202
487
  ```ts
203
488
  import { WasmBridge, WasmExports } from "@thi.ng/wasm-api";
204
489
  import { readFileSync } from "fs";
@@ -223,12 +508,20 @@ interface App extends WasmExports {
223
508
  })();
224
509
  ```
225
510
 
511
+ ### Zig version
512
+
513
+ Requires [Zig](https://ziglang.org) to be installed:
514
+
226
515
  ```zig
227
516
  //! Example Zig application (hello.zig)
228
517
 
229
518
  /// import externals
230
519
  /// see build command for configuration
231
520
  const js = @import("wasmapi");
521
+ const std = @import("std");
522
+
523
+ // set custom memory allocator (here to disable)
524
+ pub const WASM_ALLOCATOR: ?std.mem.Allocator = null;
232
525
 
233
526
  export fn start() void {
234
527
  js.printStr("hello world!");
@@ -242,7 +535,7 @@ folder):
242
535
  ```bash
243
536
  # compile WASM binary
244
537
  zig build-lib \
245
- --pkg-begin wasmapi node_modules/@thi.ng/wasm-api/zig/core.zig --pkg-end \
538
+ --pkg-begin wasmapi node_modules/@thi.ng/wasm-api/include/wasmapi.zig --pkg-end \
246
539
  -target wasm32-freestanding \
247
540
  -O ReleaseSmall -dynamic --strip \
248
541
  hello.zig
@@ -257,18 +550,112 @@ The resulting WASM:
257
550
  (module
258
551
  (type $i32_i32_=>_none (func (param i32 i32)))
259
552
  (type $none_=>_none (func))
260
- (import "core" "_printStr" (func $fimport$0 (param i32 i32)))
553
+ (type $i32_=>_i32 (func (param i32) (result i32)))
554
+ (import "wasmapi" "_printStr" (func $fimport$0 (param i32 i32)))
261
555
  (global $global$0 (mut i32) (i32.const 65536))
262
556
  (memory $0 2)
263
557
  (data (i32.const 65536) "hello world!\00")
264
558
  (export "memory" (memory $0))
265
559
  (export "start" (func $0))
560
+ (export "_wasm_allocate" (func $1))
561
+ (export "_wasm_free" (func $2))
266
562
  (func $0
267
563
  (call $fimport$0
268
564
  (i32.const 65536)
269
565
  (i32.const 12)
270
566
  )
271
567
  )
568
+ (func $1 (param $0 i32) (result i32)
569
+ (i32.const 0)
570
+ )
571
+ (func $2 (param $0 i32) (param $1 i32)
572
+ )
573
+ )
574
+ ```
575
+
576
+ ### C11 version
577
+
578
+ Requires [Emscripten](https://emscripten.org/) to be installed:
579
+
580
+ ```c
581
+ #include <wasmapi.h>
582
+
583
+ void WASM_KEEP start() {
584
+ wasm_printStr0("hello world!");
585
+ }
586
+ ```
587
+
588
+ Building the WASM module:
589
+
590
+ ```bash
591
+ emcc -Os -Inode_modules/@thi.ng/wasm-api/include -DWASMAPI_NO_MALLOC \
592
+ -sERROR_ON_UNDEFINED_SYMBOLS=0 --no-entry \
593
+ -o hello.wasm hello.c
594
+ ```
595
+
596
+ Resulting WASM:
597
+
598
+ ```wasm
599
+ (module
600
+ (type $i32_=>_none (func (param i32)))
601
+ (type $none_=>_none (func))
602
+ (type $i32_=>_i32 (func (param i32) (result i32)))
603
+ (type $none_=>_i32 (func (result i32)))
604
+ (import "wasmapi" "_printStr0" (func $fimport$0 (param i32)))
605
+ (global $global$0 (mut i32) (i32.const 5243936))
606
+ (memory $0 256 256)
607
+ (data (i32.const 1024) "hello world!")
608
+ (table $0 2 2 funcref)
609
+ (elem (i32.const 1) $0)
610
+ (export "memory" (memory $0))
611
+ (export "_wasm_allocate" (func $1))
612
+ (export "_wasm_free" (func $2))
613
+ (export "start" (func $3))
614
+ (export "__indirect_function_table" (table $0))
615
+ (export "_initialize" (func $0))
616
+ (export "__errno_location" (func $7))
617
+ (export "stackSave" (func $4))
618
+ (export "stackRestore" (func $5))
619
+ (export "stackAlloc" (func $6))
620
+ (func $0
621
+ (nop)
622
+ )
623
+ (func $1 (param $0 i32) (result i32)
624
+ (i32.const 0)
625
+ )
626
+ (func $2 (param $0 i32)
627
+ (nop)
628
+ )
629
+ (func $3
630
+ (call $fimport$0
631
+ (i32.const 1024)
632
+ )
633
+ )
634
+ (func $4 (result i32)
635
+ (global.get $global$0)
636
+ )
637
+ (func $5 (param $0 i32)
638
+ (global.set $global$0
639
+ (local.get $0)
640
+ )
641
+ )
642
+ (func $6 (param $0 i32) (result i32)
643
+ (global.set $global$0
644
+ (local.tee $0
645
+ (i32.and
646
+ (i32.sub
647
+ (global.get $global$0)
648
+ (local.get $0)
649
+ )
650
+ (i32.const -16)
651
+ )
652
+ )
653
+ )
654
+ (local.get $0)
655
+ )
656
+ (func $7 (result i32)
657
+ (i32.const 1040)
658
+ )
272
659
  )
273
660
  ```
274
661