@thi.ng/wasm-api 0.3.1 → 0.6.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/codegen.js ADDED
@@ -0,0 +1,116 @@
1
+ import { SIZEOF } from "@thi.ng/api/typedarray";
2
+ import { align } from "@thi.ng/binary/align";
3
+ import { ceilPow2 } from "@thi.ng/binary/pow";
4
+ import { compareByKey } from "@thi.ng/compare/keys";
5
+ import { compareNumDesc } from "@thi.ng/compare/numeric";
6
+ import { DEFAULT, defmulti } from "@thi.ng/defmulti/defmulti";
7
+ import { PKG_NAME, USIZE_SIZE, } from "./api.js";
8
+ import { isNumeric } from "./codegen/utils.js";
9
+ const sizeOf = defmulti((x) => x.type, {}, {
10
+ [DEFAULT]: (field, types) => {
11
+ if (field.__size)
12
+ return field.__size;
13
+ let size = 0;
14
+ if (field.tag === "ptr") {
15
+ size = USIZE_SIZE;
16
+ }
17
+ else if (field.tag === "slice") {
18
+ size = USIZE_SIZE * 2;
19
+ }
20
+ else {
21
+ size = isNumeric(field.type)
22
+ ? SIZEOF[field.type]
23
+ : sizeOf(types[field.type], types);
24
+ if (field.tag == "array" || field.tag === "vec") {
25
+ size *= field.len;
26
+ }
27
+ }
28
+ return (field.__size = align(size, field.__align));
29
+ },
30
+ enum: (type) => {
31
+ if (type.__size)
32
+ return type.__size;
33
+ return (type.__size = SIZEOF[type.tag]);
34
+ },
35
+ struct: (type, types) => {
36
+ if (type.__size)
37
+ return type.__size;
38
+ const struct = type;
39
+ let size = 0;
40
+ for (let f of struct.fields) {
41
+ size = align(size, f.__align);
42
+ f.__offset = size;
43
+ size += sizeOf(f, types);
44
+ }
45
+ return (type.__size = align(size, type.__align));
46
+ },
47
+ });
48
+ const alignOf = defmulti((x) => x.type, {}, {
49
+ [DEFAULT]: (field, types) => {
50
+ if (field.__align)
51
+ return field.__align;
52
+ let align = isNumeric(field.type)
53
+ ? SIZEOF[field.type]
54
+ : alignOf(types[field.type], types);
55
+ if (field.tag === "vec") {
56
+ align *= ceilPow2(field.len);
57
+ }
58
+ field.__align = align;
59
+ return align;
60
+ },
61
+ enum: (e) => {
62
+ return (e.__align = SIZEOF[e.tag]);
63
+ },
64
+ struct: (type, types) => {
65
+ const struct = type;
66
+ let maxAlign = 0;
67
+ for (let f of struct.fields) {
68
+ maxAlign = Math.max(maxAlign, alignOf(f, types));
69
+ }
70
+ return (type.__align = maxAlign);
71
+ },
72
+ });
73
+ const prepareType = defmulti((x) => x.type, {}, {
74
+ [DEFAULT]: (x, types) => {
75
+ if (x.__align && x.__size)
76
+ return;
77
+ alignOf(x, types);
78
+ sizeOf(x, types);
79
+ },
80
+ struct: (x, types) => {
81
+ if (x.__align && x.__size)
82
+ return;
83
+ const struct = x;
84
+ alignOf(struct, types);
85
+ if (struct.auto) {
86
+ struct.fields.sort(compareByKey("__align", compareNumDesc));
87
+ }
88
+ for (let f of struct.fields) {
89
+ if (types[f.type]) {
90
+ prepareType(types[f.type], types);
91
+ }
92
+ }
93
+ sizeOf(struct, types);
94
+ },
95
+ });
96
+ export const prepareTypes = (types) => {
97
+ for (let id in types) {
98
+ prepareType(types[id], types);
99
+ }
100
+ };
101
+ export const generateTypes = (types, codegen, opts = {}) => {
102
+ prepareTypes(types);
103
+ const res = [];
104
+ codegen.doc(`Generated by ${PKG_NAME} at ${new Date().toISOString()} - DO NOT EDIT!`, "", res, true);
105
+ res.push("");
106
+ codegen.pre && res.push(codegen.pre, "");
107
+ opts.pre && res.push(opts.pre, "");
108
+ for (let id in types) {
109
+ const type = types[id];
110
+ type.doc && codegen.doc(type.doc, "", res);
111
+ codegen[type.type](type, types, res);
112
+ }
113
+ opts.post && res.push("", opts.post);
114
+ codegen.post && res.push("", codegen.post);
115
+ return res.join("\n");
116
+ };
@@ -0,0 +1,60 @@
1
+ #pragma once
2
+
3
+ #ifdef __cplusplus
4
+ extern "C" {
5
+ #endif
6
+
7
+ #include <stddef.h>
8
+ #include <stdint.h>
9
+
10
+ #define WASM_IMPORT(MODULE, TYPE, NAME, PREFIX) \
11
+ extern __attribute__((import_module(MODULE), import_name(#NAME))) \
12
+ TYPE PREFIX##NAME
13
+ #define WASM_KEEP __attribute__((used))
14
+
15
+ // Generate stubs only if explicitly disabled by defining this symbol
16
+ #ifdef WASMAPI_NO_MALLOC
17
+ size_t WASM_KEEP _wasm_allocate(size_t num_bytes) { return 0; }
18
+ void WASM_KEEP _wasm_free(size_t addr) {}
19
+ #else
20
+ #include <stdlib.h>
21
+ size_t WASM_KEEP _wasm_allocate(size_t numBytes) {
22
+ return (size_t)malloc(numBytes);
23
+ }
24
+ void WASM_KEEP _wasm_free(size_t addr) { free((void*)addr); }
25
+ #endif
26
+
27
+ WASM_IMPORT("wasmapi", void, printI8, wasm_)(int8_t x);
28
+ WASM_IMPORT("wasmapi", void, printU8, wasm_)(uint8_t x);
29
+ WASM_IMPORT("wasmapi", void, printU8Hex, wasm_)(uint8_t x);
30
+ WASM_IMPORT("wasmapi", void, printI16, wasm_)(int16_t x);
31
+ WASM_IMPORT("wasmapi", void, printU16, wasm_)(uint16_t x);
32
+ WASM_IMPORT("wasmapi", void, printU16Hex, wasm_)(uint16_t x);
33
+ WASM_IMPORT("wasmapi", void, printI32, wasm_)(int32_t x);
34
+ WASM_IMPORT("wasmapi", void, printU32, wasm_)(uint32_t x);
35
+ WASM_IMPORT("wasmapi", void, printU32Hex, wasm_)(uint32_t x);
36
+ WASM_IMPORT("wasmapi", void, printI64, wasm_)(int64_t x);
37
+ WASM_IMPORT("wasmapi", void, printU64, wasm_)(uint64_t x);
38
+ WASM_IMPORT("wasmapi", void, printU64Hex, wasm_)(uint64_t x);
39
+ WASM_IMPORT("wasmapi", void, printF32, wasm_)(float x);
40
+ WASM_IMPORT("wasmapi", void, printF64, wasm_)(double x);
41
+
42
+ WASM_IMPORT("wasmapi", void, _printI8Array, wasm)(void* addr, size_t len);
43
+ WASM_IMPORT("wasmapi", void, _printU8Array, wasm)(void* addr, size_t len);
44
+ WASM_IMPORT("wasmapi", void, _printI16Array, wasm)(void* addr, size_t len);
45
+ WASM_IMPORT("wasmapi", void, _printU16Array, wasm)(void* addr, size_t len);
46
+ WASM_IMPORT("wasmapi", void, _printI32Array, wasm)(void* addr, size_t len);
47
+ WASM_IMPORT("wasmapi", void, _printU32Array, wasm)(void* addr, size_t len);
48
+ WASM_IMPORT("wasmapi", void, _printI64Array, wasm)(void* addr, size_t len);
49
+ WASM_IMPORT("wasmapi", void, _printU64Array, wasm)(void* addr, size_t len);
50
+ WASM_IMPORT("wasmapi", void, _printF32Array, wasm)(void* addr, size_t len);
51
+ WASM_IMPORT("wasmapi", void, _printF64Array, wasm)(void* addr, size_t len);
52
+
53
+ WASM_IMPORT("wasmapi", void, _printStr0, wasm)(void* addr);
54
+ WASM_IMPORT("wasmapi", void, _printStr, wasm)(void* addr, size_t len);
55
+
56
+ void wasm_printPtr(void* ptr) { wasm_printU32Hex((size_t)ptr); }
57
+
58
+ #ifdef __cplusplus
59
+ }
60
+ #endif
@@ -1,51 +1,93 @@
1
1
  //! JavaScript externals for https://thi.ng/wasm-api
2
2
 
3
+ const std = @import("std");
4
+ const root = @import("root");
5
+
6
+ /// Initialize the allocator to be exposed to the WASM host env
7
+ /// (via `_wasm_allocate()` and `_wasm_free()`).
8
+ /// If the user defines a public `WASM_ALLOCATOR` in their root file
9
+ /// then this allocator will be used, otherwise the implementation
10
+ /// falls back to using GPA.
11
+ /// Note: The type for this var is purposefully chosen as an optional,
12
+ /// effectively disabling allocations from the WASM host side if
13
+ /// `WASM_ALLOCATOR` is set to null.
14
+ pub const allocator: ?std.mem.Allocator = alloc: {
15
+ if (@hasDecl(root, "WASM_ALLOCATOR")) {
16
+ break :alloc root.WASM_ALLOCATOR;
17
+ } else {
18
+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
19
+ break :alloc gpa.allocator();
20
+ }
21
+ };
22
+
23
+ /// Attempts to allocate memory using configured `allocator` and if
24
+ /// successful returns address of new chunk or zero if failed
25
+ /// Note: For SIMD compatibility all allocations are aligned to 16 bytes
26
+ pub export fn _wasm_allocate(numBytes: usize) usize {
27
+ if (allocator) |alloc| {
28
+ var mem = alloc.alignedAlloc(u8, 16, numBytes) catch return 0;
29
+ return @ptrToInt(mem.ptr);
30
+ }
31
+ return 0;
32
+ }
33
+
34
+ /// Frees chunk of heap memory (previously allocated using `_wasm_allocate()`)
35
+ /// starting at given address and of given byte length.
36
+ /// Note: This is a no-op if the allocator is explicitly disabled (see `setAllocator()`),
37
+ pub export fn _wasm_free(addr: usize, numBytes: usize) void {
38
+ if (allocator) |alloc| {
39
+ var mem = [2]usize{ addr, numBytes };
40
+ printFmt("{d}", .{@ptrCast(*[]u8, &mem).*});
41
+ alloc.free(@ptrCast(*[]u8, &mem).*);
42
+ }
43
+ }
44
+
3
45
  /// Prints number using configured JS logger
4
- pub extern fn printI8(x: i8) void;
46
+ pub extern "wasmapi" fn printI8(x: i8) void;
5
47
  /// Prints number using configured JS logger
6
- pub extern fn printU8(x: u8) void;
48
+ pub extern "wasmapi" fn printU8(x: u8) void;
7
49
  /// Prints hex number using configured JS logger
8
- pub extern fn printU8Hex(x: u8) void;
50
+ pub extern "wasmapi" fn printU8Hex(x: u8) void;
9
51
 
10
52
  /// Prints number using configured JS logger
11
- pub extern fn printI16(x: i16) void;
53
+ pub extern "wasmapi" fn printI16(x: i16) void;
12
54
  /// Prints number using configured JS logger
13
- pub extern fn printU16(x: u16) void;
55
+ pub extern "wasmapi" fn printU16(x: u16) void;
14
56
  /// Prints hex number using configured JS logger
15
- pub extern fn printU16Hex(x: u16) void;
57
+ pub extern "wasmapi" fn printU16Hex(x: u16) void;
16
58
 
17
59
  /// Prints number using configured JS logger
18
- pub extern fn printI32(x: i32) void;
60
+ pub extern "wasmapi" fn printI32(x: i32) void;
19
61
  /// Prints number using configured JS logger
20
- pub extern fn printU32(x: u32) void;
62
+ pub extern "wasmapi" fn printU32(x: u32) void;
21
63
  /// Prints hex number using configured JS logger
22
- pub extern fn printU32Hex(x: u32) void;
64
+ pub extern "wasmapi" fn printU32Hex(x: u32) void;
23
65
 
24
66
  /// Prints decomposed i64 number using configured JS logger
25
- pub extern fn _printI64(hi: i32, lo: i32) void;
67
+ pub extern "wasmapi" fn _printI64(hi: i32, lo: i32) void;
26
68
  /// Convenience wrapper for _printI64(), accepting an i64
27
69
  pub fn printI64(x: i64) void {
28
70
  _printI64(@truncate(i32, x >> 32), @truncate(i32, x));
29
71
  }
30
72
 
31
73
  /// Prints decomposed u64 number using configured JS logger
32
- pub extern fn _printU64(hi: u32, lo: u32) void;
74
+ pub extern "wasmapi" fn _printU64(hi: u32, lo: u32) void;
33
75
  /// Convenience wrapper for _printU64(), accepting an u64
34
76
  pub fn printU64(x: u64) void {
35
77
  _printU64(@truncate(u32, x >> 32), @truncate(u32, x));
36
78
  }
37
79
 
38
80
  /// Prints decomposed u64 hex number using configured JS logger
39
- pub extern fn _printU64Hex(hi: u32, lo: u32) void;
81
+ pub extern "wasmapi" fn _printU64Hex(hi: u32, lo: u32) void;
40
82
  /// Convenience wrapper for _printU64Hex(), accepting an u64
41
83
  pub fn printU64Hex(x: u64) void {
42
84
  _printU64Hex(@truncate(u32, x >> 32), @truncate(u32, x));
43
85
  }
44
86
 
45
87
  /// Prints number using configured JS logger
46
- pub extern fn printF32(x: f32) void;
88
+ pub extern "wasmapi" fn printF32(x: f32) void;
47
89
  /// Prints number using configured JS logger
48
- pub extern fn printF64(x: f64) void;
90
+ pub extern "wasmapi" fn printF64(x: f64) void;
49
91
 
50
92
  /// Prints pointer as hex number using configured JS logger
51
93
  pub fn printPtr(ptr: *const anyopaque) void {
@@ -53,25 +95,25 @@ pub fn printPtr(ptr: *const anyopaque) void {
53
95
  }
54
96
 
55
97
  /// Prints number array using configured JS logger
56
- pub extern fn _printI8Array(addr: usize, len: usize) void;
98
+ pub extern "wasmapi" fn _printI8Array(addr: usize, len: usize) void;
57
99
  /// Prints number array using configured JS logger
58
- pub extern fn _printU8Array(addr: usize, len: usize) void;
100
+ pub extern "wasmapi" fn _printU8Array(addr: usize, len: usize) void;
59
101
  /// Prints number array using configured JS logger
60
- pub extern fn _printI16Array(addr: usize, len: usize) void;
102
+ pub extern "wasmapi" fn _printI16Array(addr: usize, len: usize) void;
61
103
  /// Prints number array using configured JS logger
62
- pub extern fn _printU16Array(addr: usize, len: usize) void;
104
+ pub extern "wasmapi" fn _printU16Array(addr: usize, len: usize) void;
63
105
  /// Prints number array using configured JS logger
64
- pub extern fn _printI32Array(addr: usize, len: usize) void;
106
+ pub extern "wasmapi" fn _printI32Array(addr: usize, len: usize) void;
65
107
  /// Prints number array using configured JS logger
66
- pub extern fn _printU32Array(addr: usize, len: usize) void;
108
+ pub extern "wasmapi" fn _printU32Array(addr: usize, len: usize) void;
67
109
  /// Prints number array using configured JS logger
68
- pub extern fn _printI64Array(addr: usize, len: usize) void;
110
+ pub extern "wasmapi" fn _printI64Array(addr: usize, len: usize) void;
69
111
  /// Prints number array using configured JS logger
70
- pub extern fn _printU64Array(addr: usize, len: usize) void;
112
+ pub extern "wasmapi" fn _printU64Array(addr: usize, len: usize) void;
71
113
  /// Prints number array using configured JS logger
72
- pub extern fn _printF32Array(addr: usize, len: usize) void;
114
+ pub extern "wasmapi" fn _printF32Array(addr: usize, len: usize) void;
73
115
  /// Prints number array using configured JS logger
74
- pub extern fn _printF64Array(addr: usize, len: usize) void;
116
+ pub extern "wasmapi" fn _printF64Array(addr: usize, len: usize) void;
75
117
 
76
118
  /// Prints number array using configured JS logger
77
119
  pub fn printI8Array(buf: []const i8) void {
@@ -115,10 +157,18 @@ pub fn printF64Array(buf: []const f64) void {
115
157
  }
116
158
 
117
159
  /// Prints a zero-terminated string using configured JS logger
118
- extern fn _printStr0(addr: usize) void;
160
+ pub extern "wasmapi" fn _printStr0(addr: usize) void;
119
161
  /// Prints a string of given length using configured JS logger
120
- extern fn _printStr(addr: usize, len: usize) void;
162
+ pub extern "wasmapi" fn _printStr(addr: usize, len: usize) void;
121
163
  /// Convenience wrapper for _printStr, accepting a slice as arg
122
164
  pub fn printStr(msg: []const u8) void {
123
165
  _printStr(@ptrToInt(msg.ptr), msg.len);
124
166
  }
167
+
168
+ pub fn printFmt(comptime fmt: []const u8, args: anytype) void {
169
+ if (allocator) |alloc| {
170
+ const res = std.fmt.allocPrint(alloc, fmt, args) catch return;
171
+ defer alloc.free(res);
172
+ printStr(res);
173
+ }
174
+ }
package/index.d.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  export * from "./api.js";
2
2
  export * from "./bridge.js";
3
+ export * from "./codegen.js";
3
4
  export * from "./object-index.js";
5
+ export * from "./codegen/typescript.js";
6
+ export * from "./codegen/zig.js";
7
+ export * from "./codegen/utils.js";
4
8
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -1,3 +1,7 @@
1
1
  export * from "./api.js";
2
2
  export * from "./bridge.js";
3
+ export * from "./codegen.js";
3
4
  export * from "./object-index.js";
5
+ export * from "./codegen/typescript.js";
6
+ export * from "./codegen/zig.js";
7
+ export * from "./codegen/utils.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@thi.ng/wasm-api",
3
- "version": "0.3.1",
4
- "description": "Modular, extensible API bridge and generic glue code between JS & WebAssembly",
3
+ "version": "0.6.0",
4
+ "description": "Generic, modular, extensible API bridge, glue code and bindings code generator for hybrid JS & WebAssembly projects",
5
5
  "type": "module",
6
6
  "module": "./index.js",
7
7
  "typings": "./index.d.ts",
@@ -31,13 +31,18 @@
31
31
  "doc:readme": "yarn doc:stats && tools:readme",
32
32
  "doc:stats": "tools:module-stats",
33
33
  "pub": "yarn npm publish --access public",
34
- "test": "testament test"
34
+ "test": "testament test",
35
+ "test:build-zig": "zig build-lib -O ReleaseSmall -target wasm32-freestanding -dynamic --strip --pkg-begin wasmapi include/wasmapi.zig --pkg-end test/custom.zig && wasm-dis -o custom.wast custom.wasm && cp custom.wasm test"
35
36
  },
36
37
  "dependencies": {
37
- "@thi.ng/api": "^8.3.9",
38
+ "@thi.ng/api": "^8.4.0",
39
+ "@thi.ng/binary": "^3.3.3",
40
+ "@thi.ng/checks": "^3.2.4",
41
+ "@thi.ng/compare": "^2.1.10",
42
+ "@thi.ng/defmulti": "^2.1.12",
38
43
  "@thi.ng/errors": "^2.1.10",
39
44
  "@thi.ng/hex": "^2.1.9",
40
- "@thi.ng/idgen": "^2.1.10",
45
+ "@thi.ng/idgen": "^2.1.11",
41
46
  "@thi.ng/logger": "^1.2.0"
42
47
  },
43
48
  "devDependencies": {
@@ -50,6 +55,9 @@
50
55
  },
51
56
  "keywords": [
52
57
  "api",
58
+ "bindings",
59
+ "c",
60
+ "codegen",
53
61
  "id",
54
62
  "logger",
55
63
  "memory",
@@ -72,7 +80,8 @@
72
80
  "files": [
73
81
  "*.js",
74
82
  "*.d.ts",
75
- "*.zig"
83
+ "codegen",
84
+ "include"
76
85
  ],
77
86
  "exports": {
78
87
  ".": {
@@ -84,6 +93,18 @@
84
93
  "./bridge": {
85
94
  "default": "./bridge.js"
86
95
  },
96
+ "./codegen": {
97
+ "default": "./codegen.js"
98
+ },
99
+ "./codegen/typescript": {
100
+ "default": "./codegen/typescript.js"
101
+ },
102
+ "./codegen/utils": {
103
+ "default": "./codegen/utils.js"
104
+ },
105
+ "./codegen/zig": {
106
+ "default": "./codegen/zig.js"
107
+ },
87
108
  "./object-index": {
88
109
  "default": "./object-index.js"
89
110
  }
@@ -92,5 +113,5 @@
92
113
  "status": "alpha",
93
114
  "year": 2022
94
115
  },
95
- "gitHead": "01b7a47077d88c2aefe77650ce3340040bae00ee\n"
116
+ "gitHead": "295e76c6f68ef34ba2117ff77612848e09f5c587\n"
96
117
  }
package/dev/custom.zig DELETED
@@ -1,12 +0,0 @@
1
- // Import JS core API
2
- const js = @import("wasmapi");
3
-
4
- /// Fill vec2 with random values
5
- extern fn custom_randomVec2(addr: usize) void;
6
-
7
- export fn test_random_vec2() void {
8
- var foo = [2]f32{ 0, 0 };
9
- js.printF32Array(foo[0..]);
10
- custom_randomVec2(@ptrToInt(&foo));
11
- js.printF32Array(foo[0..]);
12
- }
package/dev/fieldinfo.zig DELETED
@@ -1,135 +0,0 @@
1
- const js = @import("wasmapi");
2
- const std = @import("std");
3
-
4
- const Foo = struct {
5
- pos: [2]f32,
6
- col: [3]f32,
7
- speed: u8,
8
- acc: u16,
9
- };
10
-
11
- fn writeU32(buf: [*]u8, i: u32, x: u32) void {
12
- buf[i] = @intCast(u8, x & 0xff);
13
- buf[i + 1] = @intCast(u8, x >> 8 & 0xff);
14
- buf[i + 2] = @intCast(u8, x >> 16 & 0xff);
15
- buf[i + 3] = @intCast(u8, x >> 24);
16
- }
17
-
18
- const FieldType = enum(u8) {
19
- I8,
20
- U8,
21
- I16,
22
- U16,
23
- I32,
24
- U32,
25
- F32,
26
- F64,
27
-
28
- pub fn fromTypeInfo(comptime info: std.builtin.TypeInfo) FieldType {
29
- if (info == .Int) {
30
- const bits = info.Int.bits;
31
- if (!(bits == 8 or bits == 16 or bits == 32)) {
32
- @compileError("unsupported int type (only 8, 16, 32)");
33
- }
34
- if (info.Int.signedness == .signed) {
35
- return switch (bits) {
36
- 8 => .I8,
37
- 16 => .I16,
38
- 32 => .I32,
39
- else => unreachable,
40
- };
41
- } else {
42
- return switch (bits) {
43
- 8 => .U8,
44
- 16 => .U16,
45
- 32 => .U32,
46
- else => unreachable,
47
- };
48
- }
49
- } else if (info == .Float) {
50
- return switch (info.Float.bits) {
51
- 32 => .F32,
52
- 64 => .F64,
53
- else => @compileError("unsupported float type (only f32, f64)"),
54
- };
55
- }
56
- @compileError("unsupported field type");
57
- }
58
- };
59
-
60
- // int
61
- // float
62
- // ptr
63
- // array
64
- // slice
65
-
66
- // 8
67
- // 16
68
- // 32
69
- // 64
70
-
71
- const Field = packed struct {
72
- name: [15]u8 = [_]u8{0} ** 15,
73
- tag: FieldType = .U8,
74
- offset: u32,
75
- len: u32 = 0,
76
-
77
- pub fn fromTypeInfo(comptime T: type, comptime field: std.builtin.TypeInfo.StructField) Field {
78
- const finfo = @typeInfo(field.field_type);
79
- var ftype: FieldType = .U8;
80
- var flen = 0;
81
- if (!(finfo == .Int or finfo == .Float or finfo == .Array)) {
82
- @compileError("unsupported field type: " ++ @typeName(field.field_type));
83
- }
84
- if (finfo == .Array) {
85
- const cinfo = @typeInfo(finfo.Array.child);
86
- if (!(cinfo == .Int or cinfo == .Float)) {
87
- @compileError("unsupported field array type: " ++ @typeName(field.field_type));
88
- }
89
- ftype = FieldType.fromTypeInfo(cinfo);
90
- flen = finfo.Array.len;
91
- } else {
92
- ftype = FieldType.fromTypeInfo(finfo);
93
- }
94
- var res: Field = .{
95
- .tag = ftype,
96
- .offset = @offsetOf(T, field.name),
97
- .len = flen,
98
- };
99
- const len = @minimum(14, field.name.len);
100
- std.mem.copy(u8, res.name[0..len], field.name[0..len]);
101
- return res;
102
- }
103
- };
104
-
105
- fn writeTypeInfo(comptime T: type) []u8 {
106
- const fields = @typeInfo(T).Struct.fields;
107
- const fsize = @sizeOf(Field);
108
- var buf: [fields.len * fsize + 4]u8 = undefined;
109
- var i = 4;
110
- writeU32(&buf, 0, fields.len);
111
- for (fields) |field| {
112
- var f = Field.fromTypeInfo(T, field);
113
- std.mem.copy(
114
- u8,
115
- buf[i .. i + fsize],
116
- @ptrCast(*[fsize]u8, &f)[0..],
117
- );
118
- i += fsize;
119
- }
120
- return buf[0..];
121
- }
122
-
123
- export var Foo__info = writeTypeInfo(Foo);
124
- export var Bar__info = writeTypeInfo(struct { x: i16, y: i16 });
125
-
126
- export var U64: u64 = 0xdecafbadcafebabe;
127
- export var I64: i64 = -0x8000000000000000;
128
-
129
- export fn foo() void {
130
- js.printI64(I64);
131
- js.printU64(U64);
132
- js.printI64Array(&[_]i64{ I64, I64 });
133
- js.printU32(@truncate(u32, U64 >> 32));
134
- js.printU32Hex(@truncate(u32, U64 >> 32));
135
- }
package/dev/hello.zig DELETED
@@ -1,9 +0,0 @@
1
- //! Example Zig application (hello.zig)
2
-
3
- /// import externals
4
- /// see build command for configuration
5
- const js = @import("wasmapi");
6
-
7
- export fn start() void {
8
- js.printStr("hello world!");
9
- }
@@ -1,39 +0,0 @@
1
- const std = @import("std");
2
- /// Zig version. When writing code that supports multiple versions of Zig, prefer
3
- /// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks.
4
- pub const zig_version = std.SemanticVersion.parse("0.10.0-dev.3034+6fab6c3e4") catch unreachable;
5
- pub const zig_backend = std.builtin.CompilerBackend.stage1;
6
- /// Temporary until self-hosted supports the `cpu.arch` value.
7
- pub const stage2_arch: std.Target.Cpu.Arch = .wasm32;
8
-
9
- pub const output_mode = std.builtin.OutputMode.Lib;
10
- pub const link_mode = std.builtin.LinkMode.Dynamic;
11
- pub const is_test = false;
12
- pub const single_threaded = true;
13
- pub const abi = std.Target.Abi.musl;
14
- pub const cpu: std.Target.Cpu = .{
15
- .arch = .wasm32,
16
- .model = &std.Target.wasm.cpu.generic,
17
- .features = std.Target.wasm.featureSet(&[_]std.Target.wasm.Feature{
18
- }),
19
- };
20
- pub const os = std.Target.Os{
21
- .tag = .freestanding,
22
- .version_range = .{ .none = {} },
23
- };
24
- pub const target = std.Target{
25
- .cpu = cpu,
26
- .os = os,
27
- .abi = abi,
28
- };
29
- pub const object_format = std.Target.ObjectFormat.wasm;
30
- pub const mode = std.builtin.Mode.ReleaseSmall;
31
- pub const link_libc = false;
32
- pub const link_libcpp = false;
33
- pub const have_error_return_tracing = false;
34
- pub const valgrind_support = false;
35
- pub const sanitize_thread = false;
36
- pub const position_independent_code = true;
37
- pub const position_independent_executable = false;
38
- pub const strip_debug_info = true;
39
- pub const code_model = std.builtin.CodeModel.default;
@@ -1,39 +0,0 @@
1
- const std = @import("std");
2
- /// Zig version. When writing code that supports multiple versions of Zig, prefer
3
- /// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks.
4
- pub const zig_version = std.SemanticVersion.parse("0.10.0-dev.3034+6fab6c3e4") catch unreachable;
5
- pub const zig_backend = std.builtin.CompilerBackend.stage1;
6
- /// Temporary until self-hosted supports the `cpu.arch` value.
7
- pub const stage2_arch: std.Target.Cpu.Arch = .wasm32;
8
-
9
- pub const output_mode = std.builtin.OutputMode.Lib;
10
- pub const link_mode = std.builtin.LinkMode.Dynamic;
11
- pub const is_test = false;
12
- pub const single_threaded = true;
13
- pub const abi = std.Target.Abi.musl;
14
- pub const cpu: std.Target.Cpu = .{
15
- .arch = .wasm32,
16
- .model = &std.Target.wasm.cpu.generic,
17
- .features = std.Target.wasm.featureSet(&[_]std.Target.wasm.Feature{
18
- }),
19
- };
20
- pub const os = std.Target.Os{
21
- .tag = .freestanding,
22
- .version_range = .{ .none = {} },
23
- };
24
- pub const target = std.Target{
25
- .cpu = cpu,
26
- .os = os,
27
- .abi = abi,
28
- };
29
- pub const object_format = std.Target.ObjectFormat.wasm;
30
- pub const mode = std.builtin.Mode.ReleaseSmall;
31
- pub const link_libc = false;
32
- pub const link_libcpp = false;
33
- pub const have_error_return_tracing = false;
34
- pub const valgrind_support = false;
35
- pub const sanitize_thread = false;
36
- pub const position_independent_code = true;
37
- pub const position_independent_executable = false;
38
- pub const strip_debug_info = true;
39
- pub const code_model = std.builtin.CodeModel.default;