@swiftbrowser/wasm-compiler 0.0.0-stage → 0.8.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/dist/wasm.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ /** The custom section the Swift frontend fills with `-l` flags for the linker. */
2
+ export declare const AUTOLINK_SECTION = ".swift1_autolink_entries";
3
+ /** Every custom section of a module or object file, by name, in order. */
4
+ export declare function customSections(module: Uint8Array): {
5
+ name: string;
6
+ payload: Uint8Array;
7
+ }[];
8
+ /**
9
+ * The linker flags an object asks for (`-lswiftCore` and so on), as
10
+ * `swift-autolink-extract` prints them: NUL-separated in the section.
11
+ */
12
+ export declare function autolinkEntries(object: Uint8Array): string[];
13
+ /**
14
+ * The runtime libraries `swift-autolink-extract` recognizes, in the order it
15
+ * prints them (lib/DriverTool/autolink_extract_main.cpp, Swift 6.4): after
16
+ * every other flag, each once, so a library comes before the ones it uses.
17
+ */
18
+ export declare const SWIFT_RUNTIME_LIBRARIES_ORDERED: readonly string[];
19
+ /**
20
+ * What `swift-autolink-extract` prints for these objects: every flag that is
21
+ * not a known runtime library, in order and repeats kept, then the runtime
22
+ * libraries any object named, once each, in SWIFT_RUNTIME_LIBRARIES_ORDERED.
23
+ */
24
+ export declare function extractAutolink(objects: readonly Uint8Array[]): string[];
package/dist/wasm.js ADDED
@@ -0,0 +1,90 @@
1
+ // Reading a WebAssembly object file's custom sections, for the autolink
2
+ // record the Swift frontend writes into every object. `swift-autolink-extract`
3
+ // does this for the native driver; it is a few lines here instead of one more
4
+ // program to port. Plain Uint8Array, no Node APIs, so the browser can use it.
5
+ // The same section layout is parsed by packages/cli/src/wasm.ts for linked
6
+ // modules.
7
+ const MAGIC = [0x00, 0x61, 0x73, 0x6d];
8
+ /** The custom section the Swift frontend fills with `-l` flags for the linker. */
9
+ export const AUTOLINK_SECTION = '.swift1_autolink_entries';
10
+ function readLeb(bytes, pos) {
11
+ let result = 0;
12
+ let shift = 0;
13
+ let byte;
14
+ do {
15
+ if (pos.at >= bytes.length)
16
+ throw new Error('truncated LEB128 number');
17
+ byte = bytes[pos.at++];
18
+ result += (byte & 0x7f) * 2 ** shift;
19
+ shift += 7;
20
+ } while (byte & 0x80);
21
+ return result;
22
+ }
23
+ /** Every custom section of a module or object file, by name, in order. */
24
+ export function customSections(module) {
25
+ if (module.length < 8 || MAGIC.some((b, i) => module[i] !== b))
26
+ throw new Error('not a WebAssembly module');
27
+ const sections = [];
28
+ const decoder = new TextDecoder();
29
+ const pos = { at: 8 };
30
+ while (pos.at < module.length) {
31
+ const id = module[pos.at++];
32
+ const size = readLeb(module, pos);
33
+ const end = pos.at + size;
34
+ if (end > module.length)
35
+ throw new Error(`section ${id} runs past the end of the module`);
36
+ if (id === 0) {
37
+ const nameLength = readLeb(module, pos);
38
+ const name = decoder.decode(module.subarray(pos.at, pos.at + nameLength));
39
+ sections.push({ name, payload: module.subarray(pos.at + nameLength, end) });
40
+ }
41
+ pos.at = end;
42
+ }
43
+ return sections;
44
+ }
45
+ /**
46
+ * The linker flags an object asks for (`-lswiftCore` and so on), as
47
+ * `swift-autolink-extract` prints them: NUL-separated in the section.
48
+ */
49
+ export function autolinkEntries(object) {
50
+ const section = customSections(object).find((s) => s.name === AUTOLINK_SECTION);
51
+ if (!section)
52
+ return [];
53
+ return new TextDecoder().decode(section.payload).split('\0').filter((entry) => entry.length > 0);
54
+ }
55
+ /**
56
+ * The runtime libraries `swift-autolink-extract` recognizes, in the order it
57
+ * prints them (lib/DriverTool/autolink_extract_main.cpp, Swift 6.4): after
58
+ * every other flag, each once, so a library comes before the ones it uses.
59
+ */
60
+ export const SWIFT_RUNTIME_LIBRARIES_ORDERED = [
61
+ '-lswiftSwiftOnoneSupport', '-lswiftCore', '-lswiftObservation', '-lswift_Concurrency',
62
+ '-lswift_StringProcessing', '-lswiftRegexBuilder', '-lswift_RegexParser', '-lswift_Builtin_float',
63
+ '-lswift_math', '-lswiftRuntime', '-lswiftSynchronization', '-lswiftGlibc', '-lswiftAndroid',
64
+ '-lswiftWASILibc', '-lBlocksRuntime', '-ldispatch', '-lDispatchStubs', '-lswiftDispatch',
65
+ '-l_FoundationICU', '-lCoreFoundation', '-lFoundation', '-lFoundationEssentials',
66
+ '-lFoundationInternationalization', '-lFoundationNetworking', '-lFoundationXML',
67
+ '-l_CFXMLInterface', '-l_FoundationCShims', '-l_FoundationCollections', '-lcurl', '-lxml2',
68
+ '-luuid', '-lTesting', '-lXCTest', '-l_TestingInternals', '-l_TestDiscovery',
69
+ '-l_Testing_Foundation', '-lm', '-lpthread', '-lutil', '-ldl', '-lz',
70
+ '-lwasi-emulated-getpid', '-lwasi-emulated-mman', '-lwasi-emulated-signal',
71
+ ];
72
+ /**
73
+ * What `swift-autolink-extract` prints for these objects: every flag that is
74
+ * not a known runtime library, in order and repeats kept, then the runtime
75
+ * libraries any object named, once each, in SWIFT_RUNTIME_LIBRARIES_ORDERED.
76
+ */
77
+ export function extractAutolink(objects) {
78
+ const runtime = new Set(SWIFT_RUNTIME_LIBRARIES_ORDERED);
79
+ const flags = [];
80
+ const seenRuntime = new Set();
81
+ for (const object of objects) {
82
+ for (const entry of autolinkEntries(object)) {
83
+ if (runtime.has(entry))
84
+ seenRuntime.add(entry);
85
+ else
86
+ flags.push(entry);
87
+ }
88
+ }
89
+ return [...flags, ...SWIFT_RUNTIME_LIBRARIES_ORDERED.filter((lib) => seenRuntime.has(lib))];
90
+ }
package/package.json CHANGED
@@ -1,6 +1,52 @@
1
1
  {
2
2
  "name": "@swiftbrowser/wasm-compiler",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.8.0",
4
+ "description": "Compiles Swift with the Swift compiler built as WebAssembly: a driver, WASI hosts and a CLI. See docs/in-browser-compiler.md.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/noya-app/SwiftBrowser.git",
8
+ "directory": "packages/wasm-compiler"
9
+ },
10
+ "type": "module",
11
+ "main": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.js"
17
+ },
18
+ "./node": {
19
+ "types": "./dist/node/index.d.ts",
20
+ "default": "./dist/node/index.js"
21
+ },
22
+ "./plugin-executable": {
23
+ "types": "./dist/node/plugin-executable.d.ts",
24
+ "default": "./dist/node/plugin-executable.js"
25
+ }
26
+ },
27
+ "bin": {
28
+ "swiftbrowser-wasmc": "bin/swiftbrowser-wasmc.js"
29
+ },
30
+ "files": [
31
+ "bin",
32
+ "dist",
33
+ "README.md"
34
+ ],
35
+ "scripts": {
36
+ "typecheck": "tsc --noEmit -p tsconfig.json",
37
+ "test:unit": "vitest run",
38
+ "build": "tsc -p tsconfig.build.json"
39
+ },
40
+ "dependencies": {
41
+ "@bjorn3/browser_wasi_shim": "^0.4.2",
42
+ "@swiftbrowser/wasm-tools": "0.8.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^26.6.4",
46
+ "typescript": "^5.9.2",
47
+ "vitest": "^5.0.3"
48
+ },
49
+ "engines": {
50
+ "node": ">=22"
51
+ }
52
+ }