@onda-lang/wasm-compiler 0.7.5 → 0.8.1
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/README.md +53 -0
- package/THIRD_PARTY_NOTICES.md +4 -2
- package/api.md +407 -0
- package/dist/backend/compiler/core.js +2544 -0
- package/dist/backend/compiler/index.js +1900 -0
- package/dist/backend/compiler/lowering.js +2297 -0
- package/dist/backend/compiler/shared.js +247 -0
- package/dist/backend/constants.js +1 -1
- package/dist/backend/index.js +1 -6012
- package/dist/build.json +3 -3
- package/dist/frontend/README.md +8 -5
- package/dist/frontend/onda_compiler_web.d.ts +21 -12
- package/dist/frontend/onda_compiler_web.js +118 -10
- package/dist/frontend/onda_compiler_web_bg.wasm +0 -0
- package/dist/frontend/onda_compiler_web_bg.wasm.d.ts +10 -7
- package/dist/frontend/package.json +2 -2
- package/dist/licenses/ONDA-LICENSE.txt +21 -0
- package/dist/licenses/RUST-DEPENDENCIES.txt +953 -0
- package/dist/version.js +1 -1
- package/package.json +6 -5
- package/src/index.d.ts +61 -1
- package/src/index.js +307 -24
- package/src/worker.js +31 -0
- /package/dist/licenses/{BINARYEN-LICENSE → BINARYEN-LICENSE.txt} +0 -0
- /package/dist/licenses/{LIBM-LICENSE → LIBM-LICENSE.txt} +0 -0
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const ONDA_VERSION = "0.
|
|
1
|
+
export const ONDA_VERSION = "0.8.1";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onda-lang/wasm-compiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Onda source-to-WebAssembly compiler for browsers and Node.js",
|
|
6
6
|
"license": "MIT",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"bin",
|
|
45
45
|
"dist",
|
|
46
46
|
"src",
|
|
47
|
+
"api.md",
|
|
47
48
|
"LICENSE",
|
|
48
49
|
"README.md",
|
|
49
50
|
"THIRD_PARTY_NOTICES.md"
|
|
@@ -54,12 +55,12 @@
|
|
|
54
55
|
"check:versions": "node ../../scripts/sync-package-versions.mjs --check",
|
|
55
56
|
"test": "npm run build && npm run test:built",
|
|
56
57
|
"test:built": "node --test ./test/*.test.js",
|
|
57
|
-
"test:pack": "node ./scripts/test-package.mjs",
|
|
58
|
-
"test:pack:built": "node ./scripts/test-package.mjs --skip-build",
|
|
59
|
-
"prepack": "npm run build"
|
|
58
|
+
"test:pack": "node ../../scripts/stage-web-api-docs.mjs && node ./scripts/test-package.mjs",
|
|
59
|
+
"test:pack:built": "node ../../scripts/stage-web-api-docs.mjs && node ./scripts/test-package.mjs --skip-build",
|
|
60
|
+
"prepack": "npm run build && node ../../scripts/stage-web-api-docs.mjs"
|
|
60
61
|
},
|
|
61
62
|
"dependencies": {
|
|
62
|
-
"@onda-lang/processor-abi": "0.
|
|
63
|
+
"@onda-lang/processor-abi": "0.8.1",
|
|
63
64
|
"binaryen": "130.0.0"
|
|
64
65
|
},
|
|
65
66
|
"publishConfig": {
|
package/src/index.d.ts
CHANGED
|
@@ -47,9 +47,56 @@ export interface OndaCodegenOptions {
|
|
|
47
47
|
export interface OndaCompileOptions {
|
|
48
48
|
sampleRate?: number;
|
|
49
49
|
blockSize?: number;
|
|
50
|
+
constants?: Map<string, OndaCompileConstValue>
|
|
51
|
+
| Record<string, OndaCompileConstValue>;
|
|
50
52
|
codegen?: OndaCodegenOptions;
|
|
51
53
|
}
|
|
52
54
|
|
|
55
|
+
export interface OndaCompileConstInspectionOptions {
|
|
56
|
+
sampleRate?: number;
|
|
57
|
+
blockSize?: number;
|
|
58
|
+
/** Optional partial overrides; omitted declarations retain their authored values. */
|
|
59
|
+
constants?: Map<string, OndaCompileConstValue>
|
|
60
|
+
| Record<string, OndaCompileConstValue>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface OndaLspAnalysisOptions {
|
|
64
|
+
sampleRate?: number;
|
|
65
|
+
blockSize?: number;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type OndaCompileConstValue =
|
|
69
|
+
| boolean
|
|
70
|
+
| number
|
|
71
|
+
| bigint
|
|
72
|
+
| boolean[]
|
|
73
|
+
| Uint8Array
|
|
74
|
+
| Int32Array
|
|
75
|
+
| BigInt64Array
|
|
76
|
+
| Float32Array
|
|
77
|
+
| Float64Array;
|
|
78
|
+
|
|
79
|
+
export type OndaCompileConstElement = "bool" | "i32" | "i64" | "f32" | "f64";
|
|
80
|
+
export type OndaCompileConstKind = "scalar" | "fixed-array" | "array";
|
|
81
|
+
export type OndaResolvedCompileConstValue =
|
|
82
|
+
| boolean
|
|
83
|
+
| number
|
|
84
|
+
| bigint
|
|
85
|
+
| Uint8Array
|
|
86
|
+
| Int32Array
|
|
87
|
+
| BigInt64Array
|
|
88
|
+
| Float32Array
|
|
89
|
+
| Float64Array;
|
|
90
|
+
|
|
91
|
+
export interface OndaCompileConstDescriptor {
|
|
92
|
+
name: string;
|
|
93
|
+
element: OndaCompileConstElement;
|
|
94
|
+
kind: OndaCompileConstKind;
|
|
95
|
+
/** One for scalars; the resolved length for either array kind. */
|
|
96
|
+
elementCount: number;
|
|
97
|
+
value: OndaResolvedCompileConstValue;
|
|
98
|
+
}
|
|
99
|
+
|
|
53
100
|
export interface OndaSourceWorkspace {
|
|
54
101
|
entry: string;
|
|
55
102
|
sources: Record<string, string>;
|
|
@@ -141,14 +188,26 @@ export interface OndaCompilerInstance {
|
|
|
141
188
|
source: string,
|
|
142
189
|
options?: OndaCompileOptions,
|
|
143
190
|
): Promise<OndaCompilationResult>;
|
|
191
|
+
inspectSourceConstants(
|
|
192
|
+
source: string,
|
|
193
|
+
options?: OndaCompileConstInspectionOptions,
|
|
194
|
+
): Promise<OndaCompileConstDescriptor[]>;
|
|
144
195
|
compileWorkspace(
|
|
145
196
|
workspace: OndaSourceWorkspace,
|
|
146
197
|
options?: OndaCompileOptions,
|
|
147
198
|
): Promise<OndaCompilationResult>;
|
|
199
|
+
inspectWorkspaceConstants(
|
|
200
|
+
workspace: OndaSourceWorkspace,
|
|
201
|
+
options?: OndaCompileConstInspectionOptions,
|
|
202
|
+
): Promise<OndaCompileConstDescriptor[]>;
|
|
148
203
|
compileProjectImage(
|
|
149
204
|
imageBytes: ArrayBuffer | ArrayBufferView,
|
|
150
205
|
options?: OndaCompileOptions,
|
|
151
206
|
): Promise<OndaCompilationResult>;
|
|
207
|
+
inspectProjectImageConstants(
|
|
208
|
+
imageBytes: ArrayBuffer | ArrayBufferView,
|
|
209
|
+
options?: OndaCompileConstInspectionOptions,
|
|
210
|
+
): Promise<OndaCompileConstDescriptor[]>;
|
|
152
211
|
createProjectImage(
|
|
153
212
|
sourceGraph: OndaSourceGraph,
|
|
154
213
|
buffers?: Map<string, ArrayBuffer | ArrayBufferView>
|
|
@@ -174,7 +233,8 @@ export interface OndaCompilerInstance {
|
|
|
174
233
|
): Promise<OndaBufferAssetBinding>;
|
|
175
234
|
projectCapabilities(): Promise<OndaProjectCapabilities>;
|
|
176
235
|
sendLspMessage(message: OndaLspMessage): Promise<OndaLspMessage[]>;
|
|
177
|
-
setLspAnalysisOptions(options?:
|
|
236
|
+
setLspAnalysisOptions(options?: OndaLspAnalysisOptions): Promise<void>;
|
|
237
|
+
/** Idempotently releases compiler resources. All subsequent operations reject. */
|
|
178
238
|
dispose(): Promise<void>;
|
|
179
239
|
}
|
|
180
240
|
|
package/src/index.js
CHANGED
|
@@ -74,9 +74,17 @@ class OndaCompiler {
|
|
|
74
74
|
this.frontend = frontend;
|
|
75
75
|
this.compileTrustedMir = compileTrustedMir;
|
|
76
76
|
this.lsp = null;
|
|
77
|
+
this.disposed = false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
assertActive() {
|
|
81
|
+
if (this.disposed) {
|
|
82
|
+
throw new OndaCompilerError("compiler was disposed");
|
|
83
|
+
}
|
|
77
84
|
}
|
|
78
85
|
|
|
79
86
|
async compileSource(source, options = {}) {
|
|
87
|
+
this.assertActive();
|
|
80
88
|
if (typeof source !== "string") {
|
|
81
89
|
throw configurationError("source must be a string");
|
|
82
90
|
}
|
|
@@ -87,6 +95,7 @@ class OndaCompiler {
|
|
|
87
95
|
source,
|
|
88
96
|
compile.sampleRate,
|
|
89
97
|
compile.blockSize,
|
|
98
|
+
compile.constantsJson,
|
|
90
99
|
);
|
|
91
100
|
} catch (error) {
|
|
92
101
|
throw diagnosticsFromFrontend(error);
|
|
@@ -101,22 +110,29 @@ class OndaCompiler {
|
|
|
101
110
|
return { artifact, sourceFiles, sourceGraph };
|
|
102
111
|
}
|
|
103
112
|
|
|
104
|
-
async
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (typeof workspace.entry !== "string" || workspace.entry.length === 0) {
|
|
109
|
-
throw configurationError("workspace.entry must be a non-empty string");
|
|
110
|
-
}
|
|
111
|
-
if (!workspace.sources || typeof workspace.sources !== "object" || Array.isArray(workspace.sources)) {
|
|
112
|
-
throw configurationError("workspace.sources must be an object of paths to source strings");
|
|
113
|
+
async inspectSourceConstants(source, options = {}) {
|
|
114
|
+
this.assertActive();
|
|
115
|
+
if (typeof source !== "string") {
|
|
116
|
+
throw configurationError("source must be a string");
|
|
113
117
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
+
const compile = normalizeCompileConstInspectionOptions(options);
|
|
119
|
+
let encoded;
|
|
120
|
+
try {
|
|
121
|
+
encoded = this.frontend.inspect_source_compile_constants(
|
|
122
|
+
source,
|
|
123
|
+
compile.sampleRate,
|
|
124
|
+
compile.blockSize,
|
|
125
|
+
compile.constantsJson,
|
|
126
|
+
);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
throw diagnosticsFromFrontend(error);
|
|
118
129
|
}
|
|
130
|
+
return decodeCompileConstDescriptors(encoded);
|
|
131
|
+
}
|
|
119
132
|
|
|
133
|
+
async compileWorkspace(workspace, options = {}) {
|
|
134
|
+
this.assertActive();
|
|
135
|
+
workspace = normalizeWorkspace(workspace);
|
|
120
136
|
const compile = normalizeCompileOptions(options);
|
|
121
137
|
let frontendCompilation;
|
|
122
138
|
try {
|
|
@@ -125,6 +141,7 @@ class OndaCompiler {
|
|
|
125
141
|
JSON.stringify(workspace.sources),
|
|
126
142
|
compile.sampleRate,
|
|
127
143
|
compile.blockSize,
|
|
144
|
+
compile.constantsJson,
|
|
128
145
|
);
|
|
129
146
|
} catch (error) {
|
|
130
147
|
throw diagnosticsFromFrontend(error);
|
|
@@ -139,7 +156,27 @@ class OndaCompiler {
|
|
|
139
156
|
return { artifact, sourceFiles, sourceGraph };
|
|
140
157
|
}
|
|
141
158
|
|
|
159
|
+
async inspectWorkspaceConstants(workspace, options = {}) {
|
|
160
|
+
this.assertActive();
|
|
161
|
+
workspace = normalizeWorkspace(workspace);
|
|
162
|
+
const compile = normalizeCompileConstInspectionOptions(options);
|
|
163
|
+
let encoded;
|
|
164
|
+
try {
|
|
165
|
+
encoded = this.frontend.inspect_source_workspace_compile_constants(
|
|
166
|
+
workspace.entry,
|
|
167
|
+
JSON.stringify(workspace.sources),
|
|
168
|
+
compile.sampleRate,
|
|
169
|
+
compile.blockSize,
|
|
170
|
+
compile.constantsJson,
|
|
171
|
+
);
|
|
172
|
+
} catch (error) {
|
|
173
|
+
throw diagnosticsFromFrontend(error);
|
|
174
|
+
}
|
|
175
|
+
return decodeCompileConstDescriptors(encoded);
|
|
176
|
+
}
|
|
177
|
+
|
|
142
178
|
async compileProjectImage(imageBytes, options = {}) {
|
|
179
|
+
this.assertActive();
|
|
143
180
|
const bytes = normalizeBytes(imageBytes, "project image");
|
|
144
181
|
const compile = normalizeCompileOptions(options);
|
|
145
182
|
let frontendCompilation;
|
|
@@ -148,6 +185,7 @@ class OndaCompiler {
|
|
|
148
185
|
bytes,
|
|
149
186
|
compile.sampleRate,
|
|
150
187
|
compile.blockSize,
|
|
188
|
+
compile.constantsJson,
|
|
151
189
|
);
|
|
152
190
|
} catch (error) {
|
|
153
191
|
throw diagnosticsFromFrontend(error);
|
|
@@ -162,7 +200,26 @@ class OndaCompiler {
|
|
|
162
200
|
return { artifact, sourceFiles, sourceGraph };
|
|
163
201
|
}
|
|
164
202
|
|
|
203
|
+
async inspectProjectImageConstants(imageBytes, options = {}) {
|
|
204
|
+
this.assertActive();
|
|
205
|
+
const bytes = normalizeBytes(imageBytes, "project image");
|
|
206
|
+
const compile = normalizeCompileConstInspectionOptions(options);
|
|
207
|
+
let encoded;
|
|
208
|
+
try {
|
|
209
|
+
encoded = this.frontend.inspect_project_image_compile_constants(
|
|
210
|
+
bytes,
|
|
211
|
+
compile.sampleRate,
|
|
212
|
+
compile.blockSize,
|
|
213
|
+
compile.constantsJson,
|
|
214
|
+
);
|
|
215
|
+
} catch (error) {
|
|
216
|
+
throw diagnosticsFromFrontend(error);
|
|
217
|
+
}
|
|
218
|
+
return decodeCompileConstDescriptors(encoded);
|
|
219
|
+
}
|
|
220
|
+
|
|
165
221
|
async createProjectImage(sourceGraph, buffers = new Map()) {
|
|
222
|
+
this.assertActive();
|
|
166
223
|
const graph = normalizeSourceGraph(sourceGraph);
|
|
167
224
|
const builder = new this.frontend.WebProjectImageBuilder(JSON.stringify(graph));
|
|
168
225
|
try {
|
|
@@ -182,6 +239,7 @@ class OndaCompiler {
|
|
|
182
239
|
}
|
|
183
240
|
|
|
184
241
|
async inspectProjectImage(imageBytes) {
|
|
242
|
+
this.assertActive();
|
|
185
243
|
try {
|
|
186
244
|
return normalizeProjectImageInfo(JSON.parse(this.frontend.inspect_project_image(
|
|
187
245
|
normalizeBytes(imageBytes, "project image"),
|
|
@@ -192,6 +250,7 @@ class OndaCompiler {
|
|
|
192
250
|
}
|
|
193
251
|
|
|
194
252
|
async loadProjectFiles(files, projectFilePath = null) {
|
|
253
|
+
this.assertActive();
|
|
195
254
|
const builder = new this.frontend.WebMaterializedProjectBuilder();
|
|
196
255
|
try {
|
|
197
256
|
if (projectFilePath !== null) {
|
|
@@ -213,6 +272,7 @@ class OndaCompiler {
|
|
|
213
272
|
}
|
|
214
273
|
|
|
215
274
|
async materializeProjectImage(imageBytes, assetFileNames = new Map()) {
|
|
275
|
+
this.assertActive();
|
|
216
276
|
let plan;
|
|
217
277
|
try {
|
|
218
278
|
plan = this.frontend.materialize_project_image(
|
|
@@ -232,6 +292,7 @@ class OndaCompiler {
|
|
|
232
292
|
}
|
|
233
293
|
|
|
234
294
|
async encodeBufferAsset(binding) {
|
|
295
|
+
this.assertActive();
|
|
235
296
|
const normalized = normalizeBufferBinding(binding);
|
|
236
297
|
try {
|
|
237
298
|
return this.frontend.encode_buffer_asset(
|
|
@@ -247,6 +308,7 @@ class OndaCompiler {
|
|
|
247
308
|
}
|
|
248
309
|
|
|
249
310
|
async decodeBufferAsset(bytes) {
|
|
311
|
+
this.assertActive();
|
|
250
312
|
return this.#decodeBuffer(
|
|
251
313
|
() => this.frontend.decode_buffer_asset(normalizeBytes(bytes, "buffer asset")),
|
|
252
314
|
"failed to decode Onda buffer asset",
|
|
@@ -254,6 +316,7 @@ class OndaCompiler {
|
|
|
254
316
|
}
|
|
255
317
|
|
|
256
318
|
async decodeBufferFile(bytes, path = "buffer") {
|
|
319
|
+
this.assertActive();
|
|
257
320
|
return this.#decodeBuffer(
|
|
258
321
|
() => this.frontend.decode_buffer_file(
|
|
259
322
|
normalizeBytes(bytes, "buffer file"),
|
|
@@ -284,6 +347,7 @@ class OndaCompiler {
|
|
|
284
347
|
}
|
|
285
348
|
|
|
286
349
|
async projectCapabilities() {
|
|
350
|
+
this.assertActive();
|
|
287
351
|
return {
|
|
288
352
|
imageFormatVersion: this.frontend.project_image_format_version(),
|
|
289
353
|
bufferAssetFormatVersion: this.frontend.buffer_asset_format_version(),
|
|
@@ -292,6 +356,7 @@ class OndaCompiler {
|
|
|
292
356
|
}
|
|
293
357
|
|
|
294
358
|
async sendLspMessage(message) {
|
|
359
|
+
this.assertActive();
|
|
295
360
|
if (!message || typeof message !== "object" || Array.isArray(message)) {
|
|
296
361
|
throw new OndaCompilerError("LSP message must be a JSON-RPC object");
|
|
297
362
|
}
|
|
@@ -308,18 +373,23 @@ class OndaCompiler {
|
|
|
308
373
|
}
|
|
309
374
|
|
|
310
375
|
async setLspAnalysisOptions(options = {}) {
|
|
311
|
-
|
|
376
|
+
this.assertActive();
|
|
377
|
+
const analysis = normalizeLspAnalysisOptions(options);
|
|
312
378
|
this.lsp ??= new this.frontend.OndaLsp();
|
|
313
379
|
try {
|
|
314
|
-
this.lsp.set_analysis_options(
|
|
380
|
+
this.lsp.set_analysis_options(analysis.sampleRate, analysis.blockSize);
|
|
315
381
|
} catch (cause) {
|
|
316
382
|
throw new OndaCompilerError("failed to configure Onda LSP analysis", { cause });
|
|
317
383
|
}
|
|
318
384
|
}
|
|
319
385
|
|
|
320
386
|
async dispose() {
|
|
387
|
+
if (this.disposed) return;
|
|
388
|
+
this.disposed = true;
|
|
321
389
|
this.lsp?.free();
|
|
322
390
|
this.lsp = null;
|
|
391
|
+
this.frontend = null;
|
|
392
|
+
this.compileTrustedMir = null;
|
|
323
393
|
}
|
|
324
394
|
}
|
|
325
395
|
|
|
@@ -328,6 +398,9 @@ class WorkerOndaCompiler {
|
|
|
328
398
|
this.worker = worker;
|
|
329
399
|
this.nextRequestId = 1;
|
|
330
400
|
this.pending = new Map();
|
|
401
|
+
this.disposed = false;
|
|
402
|
+
this.terminated = false;
|
|
403
|
+
this.disposePromise = null;
|
|
331
404
|
this.onMessage = (event) => this.handleMessage(event.data);
|
|
332
405
|
this.onError = (event) => this.failAll(event.error ?? new Error(event.message));
|
|
333
406
|
worker.addEventListener("message", this.onMessage);
|
|
@@ -342,14 +415,26 @@ class WorkerOndaCompiler {
|
|
|
342
415
|
return this.request("compileSource", { source, options });
|
|
343
416
|
}
|
|
344
417
|
|
|
418
|
+
inspectSourceConstants(source, options = {}) {
|
|
419
|
+
return this.request("inspectSourceConstants", { source, options });
|
|
420
|
+
}
|
|
421
|
+
|
|
345
422
|
compileWorkspace(workspace, options = {}) {
|
|
346
423
|
return this.request("compileWorkspace", { workspace, options });
|
|
347
424
|
}
|
|
348
425
|
|
|
426
|
+
inspectWorkspaceConstants(workspace, options = {}) {
|
|
427
|
+
return this.request("inspectWorkspaceConstants", { workspace, options });
|
|
428
|
+
}
|
|
429
|
+
|
|
349
430
|
compileProjectImage(imageBytes, options = {}) {
|
|
350
431
|
return this.request("compileProjectImage", { imageBytes, options });
|
|
351
432
|
}
|
|
352
433
|
|
|
434
|
+
inspectProjectImageConstants(imageBytes, options = {}) {
|
|
435
|
+
return this.request("inspectProjectImageConstants", { imageBytes, options });
|
|
436
|
+
}
|
|
437
|
+
|
|
353
438
|
createProjectImage(sourceGraph, buffers = new Map()) {
|
|
354
439
|
return this.request("createProjectImage", { sourceGraph, buffers });
|
|
355
440
|
}
|
|
@@ -390,15 +475,21 @@ class WorkerOndaCompiler {
|
|
|
390
475
|
return this.request("lspAnalysisOptions", { options });
|
|
391
476
|
}
|
|
392
477
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
478
|
+
dispose() {
|
|
479
|
+
if (this.disposePromise) return this.disposePromise;
|
|
480
|
+
if (this.disposed) return Promise.resolve();
|
|
481
|
+
const request = this.request("dispose");
|
|
482
|
+
this.disposed = true;
|
|
483
|
+
this.disposePromise = request.finally(() => {
|
|
397
484
|
this.terminate(new OndaCompilerError("compiler worker was disposed"));
|
|
398
|
-
}
|
|
485
|
+
});
|
|
486
|
+
return this.disposePromise;
|
|
399
487
|
}
|
|
400
488
|
|
|
401
489
|
terminate(error) {
|
|
490
|
+
if (this.terminated) return;
|
|
491
|
+
this.disposed = true;
|
|
492
|
+
this.terminated = true;
|
|
402
493
|
this.worker.removeEventListener("message", this.onMessage);
|
|
403
494
|
this.worker.removeEventListener("error", this.onError);
|
|
404
495
|
this.worker.terminate();
|
|
@@ -406,6 +497,9 @@ class WorkerOndaCompiler {
|
|
|
406
497
|
}
|
|
407
498
|
|
|
408
499
|
request(type, fields = {}) {
|
|
500
|
+
if (this.disposed) {
|
|
501
|
+
return Promise.reject(new OndaCompilerError("compiler was disposed"));
|
|
502
|
+
}
|
|
409
503
|
const requestId = this.nextRequestId;
|
|
410
504
|
this.nextRequestId += 1;
|
|
411
505
|
return new Promise((resolve, reject) => {
|
|
@@ -504,6 +598,48 @@ export function createDefaultImports() {
|
|
|
504
598
|
}
|
|
505
599
|
|
|
506
600
|
function normalizeCompileOptions(options) {
|
|
601
|
+
const compile = normalizeCompileInputOptions(options);
|
|
602
|
+
if (
|
|
603
|
+
options.codegen !== undefined
|
|
604
|
+
&& (!options.codegen || typeof options.codegen !== "object" || Array.isArray(options.codegen))
|
|
605
|
+
) {
|
|
606
|
+
throw configurationError("codegen options must be an object");
|
|
607
|
+
}
|
|
608
|
+
return {
|
|
609
|
+
...compile,
|
|
610
|
+
codegen: options.codegen ?? {},
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
function normalizeCompileConstInspectionOptions(options) {
|
|
615
|
+
const compile = normalizeCompileInputOptions(options);
|
|
616
|
+
if (options.codegen !== undefined) {
|
|
617
|
+
throw configurationError("codegen options do not apply to compile constant inspection");
|
|
618
|
+
}
|
|
619
|
+
return compile;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
function normalizeCompileInputOptions(options) {
|
|
623
|
+
return {
|
|
624
|
+
...normalizeContextOptions(options),
|
|
625
|
+
constantsJson: JSON.stringify(normalizeCompileConstants(options.constants ?? {})),
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
function normalizeLspAnalysisOptions(options) {
|
|
630
|
+
const context = normalizeContextOptions(options);
|
|
631
|
+
if (options.constants !== undefined) {
|
|
632
|
+
throw configurationError(
|
|
633
|
+
"constants are compile-request inputs and cannot be set as LSP analysis options",
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
if (options.codegen !== undefined) {
|
|
637
|
+
throw configurationError("codegen options cannot be set as LSP analysis options");
|
|
638
|
+
}
|
|
639
|
+
return context;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
function normalizeContextOptions(options) {
|
|
507
643
|
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
508
644
|
throw configurationError("compiler options must be an object");
|
|
509
645
|
}
|
|
@@ -515,13 +651,160 @@ function normalizeCompileOptions(options) {
|
|
|
515
651
|
if (!Number.isInteger(blockSize) || blockSize <= 0 || blockSize > MAX_BLOCK_SIZE) {
|
|
516
652
|
throw configurationError(`blockSize must be between 1 and ${MAX_BLOCK_SIZE} frames`);
|
|
517
653
|
}
|
|
654
|
+
return { sampleRate, blockSize };
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
function normalizeWorkspace(workspace) {
|
|
658
|
+
if (!workspace || typeof workspace !== "object" || Array.isArray(workspace)) {
|
|
659
|
+
throw configurationError("workspace must contain an entry and source map");
|
|
660
|
+
}
|
|
661
|
+
if (typeof workspace.entry !== "string" || workspace.entry.length === 0) {
|
|
662
|
+
throw configurationError("workspace.entry must be a non-empty string");
|
|
663
|
+
}
|
|
664
|
+
if (!workspace.sources || typeof workspace.sources !== "object" || Array.isArray(workspace.sources)) {
|
|
665
|
+
throw configurationError("workspace.sources must be an object of paths to source strings");
|
|
666
|
+
}
|
|
667
|
+
for (const [path, source] of Object.entries(workspace.sources)) {
|
|
668
|
+
if (typeof source !== "string") {
|
|
669
|
+
throw configurationError(`workspace source '${path}' must be a string`);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
return workspace;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
function normalizeCompileConstants(constants) {
|
|
518
676
|
if (
|
|
519
|
-
|
|
520
|
-
|
|
677
|
+
!constants
|
|
678
|
+
|| typeof constants !== "object"
|
|
679
|
+
|| Array.isArray(constants)
|
|
680
|
+
|| ArrayBuffer.isView(constants)
|
|
521
681
|
) {
|
|
522
|
-
throw configurationError("
|
|
682
|
+
throw configurationError("constants must be an object or Map");
|
|
523
683
|
}
|
|
524
|
-
|
|
684
|
+
const entries = constants instanceof Map
|
|
685
|
+
? [...constants.entries()]
|
|
686
|
+
: Object.entries(constants);
|
|
687
|
+
return entries.map(([rawName, value]) => {
|
|
688
|
+
const name = String(rawName);
|
|
689
|
+
if (name.length === 0) {
|
|
690
|
+
throw configurationError("compile constant names must be non-empty");
|
|
691
|
+
}
|
|
692
|
+
if (typeof value === "boolean") {
|
|
693
|
+
return { name, element: "bool", array: false, values: [value] };
|
|
694
|
+
}
|
|
695
|
+
if (typeof value === "number") {
|
|
696
|
+
return {
|
|
697
|
+
name,
|
|
698
|
+
element: "number",
|
|
699
|
+
array: false,
|
|
700
|
+
values: [encodeCompileNumber(value)],
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
if (typeof value === "bigint") {
|
|
704
|
+
return { name, element: "i64", array: false, values: [value.toString()] };
|
|
705
|
+
}
|
|
706
|
+
if (value instanceof Uint8Array) {
|
|
707
|
+
const values = [...value];
|
|
708
|
+
if (values.some((item) => item !== 0 && item !== 1)) {
|
|
709
|
+
throw configurationError(
|
|
710
|
+
`boolean compile constant array '${name}' may contain only 0 or 1`,
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
return {
|
|
714
|
+
name,
|
|
715
|
+
element: "bool",
|
|
716
|
+
array: true,
|
|
717
|
+
values: values.map((item) => item !== 0),
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
if (value instanceof Int32Array) {
|
|
721
|
+
return { name, element: "i32", array: true, values: [...value] };
|
|
722
|
+
}
|
|
723
|
+
if (value instanceof BigInt64Array) {
|
|
724
|
+
return {
|
|
725
|
+
name,
|
|
726
|
+
element: "i64",
|
|
727
|
+
array: true,
|
|
728
|
+
values: [...value].map((item) => item.toString()),
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
if (value instanceof Float32Array) {
|
|
732
|
+
return {
|
|
733
|
+
name,
|
|
734
|
+
element: "f32",
|
|
735
|
+
array: true,
|
|
736
|
+
values: encodeCompileFloatArray(value),
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
if (value instanceof Float64Array) {
|
|
740
|
+
return {
|
|
741
|
+
name,
|
|
742
|
+
element: "f64",
|
|
743
|
+
array: true,
|
|
744
|
+
values: encodeCompileFloatArray(value),
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
if (Array.isArray(value) && value.every((item) => typeof item === "boolean")) {
|
|
748
|
+
return { name, element: "bool", array: true, values: value };
|
|
749
|
+
}
|
|
750
|
+
throw configurationError(
|
|
751
|
+
`compile constant '${name}' must be a boolean, number, bigint, or matching typed array`,
|
|
752
|
+
);
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
function encodeCompileFloatArray(values) {
|
|
757
|
+
return [...values].map(encodeCompileNumber);
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
function encodeCompileNumber(value) {
|
|
761
|
+
if (Object.is(value, -0)) return "-0";
|
|
762
|
+
if (Number.isNaN(value)) return "NaN";
|
|
763
|
+
if (value === Number.POSITIVE_INFINITY) return "Infinity";
|
|
764
|
+
if (value === Number.NEGATIVE_INFINITY) return "-Infinity";
|
|
765
|
+
return value;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
function decodeCompileConstDescriptors(encoded) {
|
|
769
|
+
let descriptors;
|
|
770
|
+
try {
|
|
771
|
+
descriptors = JSON.parse(encoded);
|
|
772
|
+
} catch (cause) {
|
|
773
|
+
throw new OndaCompilerError("failed to decode compile constant descriptors", { cause });
|
|
774
|
+
}
|
|
775
|
+
if (!Array.isArray(descriptors)) {
|
|
776
|
+
throw new OndaCompilerError("frontend returned invalid compile constant descriptors");
|
|
777
|
+
}
|
|
778
|
+
return descriptors.map((descriptor) => ({
|
|
779
|
+
name: descriptor.name,
|
|
780
|
+
element: descriptor.element,
|
|
781
|
+
kind: descriptor.kind,
|
|
782
|
+
elementCount: descriptor.element_count,
|
|
783
|
+
value: decodeCompileConstValue(descriptor.element, descriptor.kind, descriptor.values),
|
|
784
|
+
}));
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
function decodeCompileConstValue(element, kind, values) {
|
|
788
|
+
const decoded = element === "i64"
|
|
789
|
+
? values.map((value) => BigInt(value))
|
|
790
|
+
: element === "f32" || element === "f64"
|
|
791
|
+
? values.map(decodeCompileFloat)
|
|
792
|
+
: values;
|
|
793
|
+
if (kind === "scalar") return decoded[0];
|
|
794
|
+
if (element === "bool") return Uint8Array.from(decoded, (value) => value ? 1 : 0);
|
|
795
|
+
if (element === "i32") return Int32Array.from(decoded);
|
|
796
|
+
if (element === "i64") return BigInt64Array.from(decoded);
|
|
797
|
+
if (element === "f32") return Float32Array.from(decoded);
|
|
798
|
+
if (element === "f64") return Float64Array.from(decoded);
|
|
799
|
+
throw new OndaCompilerError(`frontend returned unknown compile constant element '${element}'`);
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
function decodeCompileFloat(value) {
|
|
803
|
+
if (value === "-0") return -0;
|
|
804
|
+
if (value === "NaN") return Number.NaN;
|
|
805
|
+
if (value === "Infinity") return Number.POSITIVE_INFINITY;
|
|
806
|
+
if (value === "-Infinity") return Number.NEGATIVE_INFINITY;
|
|
807
|
+
return value;
|
|
525
808
|
}
|
|
526
809
|
|
|
527
810
|
function consumeFrontendCompilation(compilation) {
|
package/src/worker.js
CHANGED
|
@@ -19,6 +19,14 @@ globalThis.addEventListener("message", async (event) => {
|
|
|
19
19
|
respond(requestId, result, [result.artifact.wasm.buffer]);
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
|
+
if (message.type === "inspectSourceConstants") {
|
|
23
|
+
const result = await (await compiler()).inspectSourceConstants(
|
|
24
|
+
message.source,
|
|
25
|
+
message.options,
|
|
26
|
+
);
|
|
27
|
+
respond(requestId, result, compileConstTransfers(result));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
22
30
|
if (message.type === "compileWorkspace") {
|
|
23
31
|
const result = await (await compiler()).compileWorkspace(
|
|
24
32
|
message.workspace,
|
|
@@ -27,6 +35,14 @@ globalThis.addEventListener("message", async (event) => {
|
|
|
27
35
|
respond(requestId, result, [result.artifact.wasm.buffer]);
|
|
28
36
|
return;
|
|
29
37
|
}
|
|
38
|
+
if (message.type === "inspectWorkspaceConstants") {
|
|
39
|
+
const result = await (await compiler()).inspectWorkspaceConstants(
|
|
40
|
+
message.workspace,
|
|
41
|
+
message.options,
|
|
42
|
+
);
|
|
43
|
+
respond(requestId, result, compileConstTransfers(result));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
30
46
|
if (message.type === "compileProjectImage") {
|
|
31
47
|
const result = await (await compiler()).compileProjectImage(
|
|
32
48
|
message.imageBytes,
|
|
@@ -35,6 +51,14 @@ globalThis.addEventListener("message", async (event) => {
|
|
|
35
51
|
respond(requestId, result, [result.artifact.wasm.buffer]);
|
|
36
52
|
return;
|
|
37
53
|
}
|
|
54
|
+
if (message.type === "inspectProjectImageConstants") {
|
|
55
|
+
const result = await (await compiler()).inspectProjectImageConstants(
|
|
56
|
+
message.imageBytes,
|
|
57
|
+
message.options,
|
|
58
|
+
);
|
|
59
|
+
respond(requestId, result, compileConstTransfers(result));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
38
62
|
if (message.type === "createProjectImage") {
|
|
39
63
|
const result = await (await compiler()).createProjectImage(
|
|
40
64
|
message.sourceGraph,
|
|
@@ -123,3 +147,10 @@ function compiler(frontendWasm) {
|
|
|
123
147
|
function respond(requestId, value, transfer = []) {
|
|
124
148
|
globalThis.postMessage({ type: "result", requestId, value }, transfer);
|
|
125
149
|
}
|
|
150
|
+
|
|
151
|
+
function compileConstTransfers(descriptors) {
|
|
152
|
+
return descriptors
|
|
153
|
+
.map((descriptor) => descriptor.value)
|
|
154
|
+
.filter(ArrayBuffer.isView)
|
|
155
|
+
.map((value) => value.buffer);
|
|
156
|
+
}
|
|
File without changes
|
|
File without changes
|