@fraczak/k 6.3.3 → 6.4.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.
Files changed (155) hide show
  1. package/DOCS/CODECS.md +258 -0
  2. package/DOCS/DICTIONARY.md +1172 -0
  3. package/DOCS/KIR_SPECIALIZATION_DESIGN.md +51 -46
  4. package/DOCS/KIR_V1.md +221 -0
  5. package/DOCS/KVM_EXECUTION_MODEL.md +56 -19
  6. package/DOCS/OBJECT_FILE_AND_PATTERN.md +2 -1
  7. package/DOCS/PROFILING_AND_TRACING.md +196 -0
  8. package/DOCS/REPL.md +61 -4
  9. package/DOCS/WEB_REPL_REQUIREMENTS.md +135 -0
  10. package/DOCS/dependency-graph.md +144 -0
  11. package/Examples/arithmetics.k +51 -48
  12. package/Examples/bnat.k +1 -1
  13. package/Examples/buda.k +44 -0
  14. package/Examples/ieee.k +300 -8671
  15. package/Examples/poly.k +67 -0
  16. package/README.md +68 -19
  17. package/augmentation.mjs +9 -7
  18. package/backend-api.mjs +11 -2
  19. package/backends/arm64/README.md +104 -0
  20. package/backends/arm64/bin/k-arm64-compile.mjs +101 -0
  21. package/backends/arm64/bin/k-arm64-run.mjs +58 -0
  22. package/backends/arm64/bin/k-arm64.mjs +88 -0
  23. package/backends/arm64/scripts/run-tests.mjs +41 -0
  24. package/backends/arm64/src/arm64.mjs +229 -0
  25. package/backends/arm64/src/cli.mjs +155 -0
  26. package/backends/arm64/src/kvm2arm64.mjs +906 -0
  27. package/backends/arm64/src/runtime.c +728 -0
  28. package/backends/arm64/tests/integration.sh +112 -0
  29. package/backends/arm64/tests/test-arm64.mjs +240 -0
  30. package/backends/llvm/README.md +135 -0
  31. package/backends/llvm/bin/k-llvm-build.mjs +71 -0
  32. package/backends/llvm/bin/k-llvm-compile.mjs +68 -0
  33. package/backends/llvm/bin/k-llvm-jit.mjs +160 -0
  34. package/backends/llvm/bin/k-llvm-run.mjs +90 -0
  35. package/backends/llvm/runtime/krt.c +1508 -0
  36. package/backends/llvm/runtime/krt.h +109 -0
  37. package/backends/llvm/scripts/conformance.mjs +76 -0
  38. package/backends/llvm/scripts/run-tests.mjs +28 -0
  39. package/backends/llvm/src/executable.mjs +562 -0
  40. package/backends/llvm/src/kvm2llvm.mjs +998 -0
  41. package/backends/llvm/src/llvm.mjs +1092 -0
  42. package/backends/llvm/tests/composition-driver.c +22 -0
  43. package/backends/llvm/tests/identity-driver.c +27 -0
  44. package/backends/llvm/tests/integration.sh +153 -0
  45. package/backends/llvm/tests/perf-support.mjs +735 -0
  46. package/backends/llvm/tests/product-driver.c +23 -0
  47. package/backends/llvm/tests/projection-driver.c +19 -0
  48. package/backends/llvm/tests/relation-driver.c +29 -0
  49. package/backends/llvm/tests/test-llvm.mjs +240 -0
  50. package/backends/llvm/tests/union-driver.c +31 -0
  51. package/backends/llvm/tests/variant-driver.c +19 -0
  52. package/backends/llvm/tests/variant-projection-driver.c +21 -0
  53. package/backends/wasm/DOCS/USE-WEB-ASSEMBLY.md +233 -0
  54. package/backends/wasm/README.md +97 -0
  55. package/backends/wasm/TECHNICAL-DEBT.md +60 -0
  56. package/backends/wasm/bin/k-wasm-compile.mjs +50 -0
  57. package/backends/wasm/bin/k-wasm-run.mjs +140 -0
  58. package/backends/wasm/bin/k-wasm.mjs +49 -0
  59. package/backends/wasm/demo_ieee.mjs +319 -0
  60. package/backends/wasm/runtime.wat +102 -0
  61. package/backends/wasm/scripts/run-tests.mjs +41 -0
  62. package/backends/wasm/src/cli.mjs +133 -0
  63. package/backends/wasm/src/kvm2wasm.mjs +661 -0
  64. package/backends/wasm/src/wasm.mjs +1010 -0
  65. package/backends/wasm/tests/integration.sh +182 -0
  66. package/backends/wasm/tests/perf-support.mjs +336 -0
  67. package/backends/wasm/tests/test-wasm.mjs +617 -0
  68. package/browser/repl-browser.mjs +1584 -0
  69. package/browser/shims/assert.mjs +19 -0
  70. package/browser/shims/buffer.mjs +224 -0
  71. package/browser/shims/crypto.mjs +103 -0
  72. package/browser/shims/fs.mjs +159 -0
  73. package/browser/shims/os.mjs +17 -0
  74. package/browser/shims/path.mjs +54 -0
  75. package/browser/shims/process.mjs +44 -0
  76. package/browser/shims/readline.mjs +11 -0
  77. package/browser/shims/url.mjs +12 -0
  78. package/browser/vfs-data.mjs +19 -0
  79. package/codecs/README.md +3 -0
  80. package/codecs/runtime/show-value.mjs +2 -2
  81. package/conformance/helper-reuse/case.json +8 -0
  82. package/conformance/helper-reuse/expected.kv +1 -0
  83. package/conformance/helper-reuse/input.kv +1 -0
  84. package/conformance/helper-reuse/program.k +2 -0
  85. package/conformance/identity/case.json +8 -0
  86. package/conformance/identity/expected.kv +1 -0
  87. package/conformance/identity/input.kv +1 -0
  88. package/conformance/identity/program.k +1 -0
  89. package/conformance/product-projection/case.json +8 -0
  90. package/conformance/product-projection/expected.kv +1 -0
  91. package/conformance/product-projection/input.kv +1 -0
  92. package/conformance/product-projection/program.k +1 -0
  93. package/conformance/run.mjs +149 -0
  94. package/conformance/variant-construction/case.json +8 -0
  95. package/conformance/variant-construction/expected.kv +1 -0
  96. package/conformance/variant-construction/input.kv +1 -0
  97. package/conformance/variant-construction/program.k +1 -0
  98. package/harness/adapters/arm64.mjs +105 -0
  99. package/harness/adapters/kvm.mjs +144 -0
  100. package/harness/adapters/llvm.mjs +118 -0
  101. package/harness/adapters/native.mjs +77 -0
  102. package/harness/adapters/wasm.mjs +169 -0
  103. package/harness/backend.mjs +95 -0
  104. package/harness/cli.mjs +130 -0
  105. package/harness/format.mjs +95 -0
  106. package/harness/index.mjs +25 -0
  107. package/harness/persistent.mjs +121 -0
  108. package/harness/registry.mjs +44 -0
  109. package/harness/suite.mjs +257 -0
  110. package/harness/suites/poly.mjs +156 -0
  111. package/harness/trace.mjs +50 -0
  112. package/harness/util.mjs +92 -0
  113. package/intrinsics.mjs +41 -0
  114. package/kir.mjs +399 -0
  115. package/kvm.mjs +585 -81
  116. package/objects/README.md +37 -3
  117. package/objects/compile.mjs +15 -22
  118. package/objects/inspect.mjs +96 -0
  119. package/objects/validate.mjs +415 -0
  120. package/package.json +51 -19
  121. package/repl-codecs.mjs +105 -6
  122. package/repl.mjs +335 -49
  123. package/run.mjs +2 -7
  124. package/scripts/benchmark.mjs +406 -22
  125. package/scripts/build-repl-html.mjs +1784 -0
  126. package/scripts/perf-ieee.mjs +586 -0
  127. package/scripts/perf-int.mjs +531 -0
  128. package/scripts/perf-poly.mjs +945 -0
  129. package/scripts/render-benchmark.mjs +12 -8
  130. package/scripts/run-tests.mjs +6 -0
  131. package/tests/integration.sh +19 -2
  132. package/tests/test-arithmetics.mjs +54 -0
  133. package/tests/test-ieee-arithmetic.mjs +4 -0
  134. package/tests/test-kir.mjs +85 -0
  135. package/tests/test-kvm-polymorphic.mjs +278 -0
  136. package/tests/test-kvm.mjs +25 -6
  137. package/tests/test-poly.mjs +129 -0
  138. package/tests/test-repl-html.mjs +303 -0
  139. package/tests/test-repl.mjs +144 -1
  140. package/tests/test-validate-object.mjs +40 -0
  141. package/a.klib +0 -1
  142. package/a.kvm +0 -142676
  143. package/a.wasm +0 -0
  144. package/benchmark-results.html +0 -532
  145. package/benchmark-results.json +0 -480
  146. package/k-vscode/.vscode/launch.json +0 -14
  147. package/k-vscode/README.md +0 -75
  148. package/k-vscode/extension.js +0 -273
  149. package/k-vscode/language-configuration.json +0 -42
  150. package/k-vscode/package.json +0 -79
  151. package/k-vscode/snippets/k.json +0 -92
  152. package/k-vscode/syntaxes/k.tmLanguage.json +0 -599
  153. package/k-vscode/test/background-ranges.test.js +0 -50
  154. package/k-vscode/themes/k-contrast-color-theme.json +0 -104
  155. package/scripts/git-hooks/pre-commit +0 -10
@@ -0,0 +1,1010 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import {
5
+ annotate,
6
+ decodeWire,
7
+ encodeToWire,
8
+ exportPatternGraph,
9
+ isProduct,
10
+ isVariant,
11
+ lowerToKVM,
12
+ NODE_KIND,
13
+ patternToPropertyList,
14
+ propertyListToPattern,
15
+ Value,
16
+ specializeKVM
17
+ } from "@fraczak/k/backend-api.mjs";
18
+ import { intersectPropertyListPatterns } from "@fraczak/k/codecs/runtime/codec.mjs";
19
+ import { propertyListToFilter } from "@fraczak/k/codecs/runtime/show-value.mjs";
20
+ import { parse } from "@fraczak/k/index.mjs";
21
+ import { compileTypes } from "@fraczak/k/compiler.mjs";
22
+ import codes from "@fraczak/k/codes.mjs";
23
+ import { cloneSubpattern, withPattern } from "@fraczak/k/Value.mjs";
24
+ import { lowerToWasm, getTagEntries, resetTagIds } from "./kvm2wasm.mjs";
25
+
26
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
27
+ const runtimeWat = fs.readFileSync(path.join(__dirname, "../runtime.wat"), "utf8");
28
+ let wabtPromise;
29
+
30
+ const METADATA_SECTION = "k.metadata";
31
+ const ARTIFACT_FORMAT = "k-wasm";
32
+ const ARTIFACT_VERSION = 1;
33
+
34
+ const cleanName = (name) => "rel_" + name.replace(/[^a-zA-Z0-9_]/g, "_");
35
+
36
+ async function getWabt() {
37
+ if (!wabtPromise) {
38
+ wabtPromise = import("wabt").then(({ default: wabtFactory }) => wabtFactory());
39
+ }
40
+ return wabtPromise;
41
+ }
42
+
43
+ async function compileWat(watText) {
44
+ const wabtInstance = await getWabt();
45
+ const watModule = wabtInstance.parseWat("k_wasm.wat", watText, {
46
+ mutable_globals: true,
47
+ sat_float_to_int: true,
48
+ sign_extension: true,
49
+ multi_value: true,
50
+ bulk_memory: true,
51
+ reference_types: true
52
+ });
53
+ watModule.resolveNames();
54
+ watModule.validate();
55
+ return Buffer.from(watModule.toBinary({
56
+ log: false,
57
+ canonicalize_lebs: true,
58
+ relocatable: false,
59
+ write_debug_names: true
60
+ }).buffer);
61
+ }
62
+
63
+ function scanCalls(insts, compiled, queue) {
64
+ for (const inst of insts) {
65
+ if (inst.op === "call" && !compiled.has(inst.func) && !queue.includes(inst.func)) {
66
+ queue.push(inst.func);
67
+ }
68
+ if (inst.branches) {
69
+ for (const branch of inst.branches) {
70
+ scanCalls(branch.body, compiled, queue);
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ function injectLibraries(rels, libraries = []) {
77
+ for (const lib of libraries) {
78
+ const libRels = lib.rels || lib.defs?.rels || {};
79
+ for (const [name, rel] of Object.entries(libRels)) {
80
+ if (!(name in rels)) {
81
+ rels[name] = { ...rel, _library: true };
82
+ }
83
+ }
84
+ }
85
+ }
86
+
87
+ function cloneForRetyping(value) {
88
+ if (Array.isArray(value)) return value.map(cloneForRetyping);
89
+ if (!value || typeof value !== "object") return value;
90
+
91
+ const clone = {};
92
+ for (const [key, child] of Object.entries(value)) {
93
+ if (key === "patterns") continue;
94
+ clone[key] = cloneForRetyping(child);
95
+ }
96
+ return clone;
97
+ }
98
+
99
+ function composeInputFilter(filterExp, exp) {
100
+ return {
101
+ op: "comp",
102
+ comp: [filterExp, exp],
103
+ ...(filterExp.start ? { start: filterExp.start } : exp.start ? { start: exp.start } : {}),
104
+ ...(exp.end ? { end: exp.end } : filterExp.end ? { end: filterExp.end } : {})
105
+ };
106
+ }
107
+
108
+ function compileParsedDefs(parsed, mainExp, options = {}) {
109
+ const representatives = codes.register(parsed.defs.codes || {});
110
+ const rels = Object.fromEntries(
111
+ Object.entries(parsed.defs.rels || {}).map(([name, rel]) => [
112
+ name,
113
+ { ...cloneForRetyping(rel), def: cloneForRetyping(rel.def) }
114
+ ])
115
+ );
116
+ rels.__main__ = { def: mainExp };
117
+ injectLibraries(rels, options.libraries);
118
+
119
+ const { relAlias, compileStats } = compileTypes(representatives, rels, options);
120
+ return {
121
+ rels,
122
+ representatives,
123
+ relAlias,
124
+ compileStats,
125
+ sourceDefs: parsed.defs
126
+ };
127
+ }
128
+
129
+ function compileObjectDefs(object, mainRelName, mainExp = null, options = {}) {
130
+ const representatives = codes.register(object.codes || {});
131
+ const rels = Object.fromEntries(
132
+ Object.entries(object.rels || {}).map(([name, rel]) => {
133
+ if (name === mainRelName) {
134
+ return [name, { def: cloneForRetyping(mainExp ? mainExp : rel.def) }];
135
+ }
136
+ if (rel.typePatternGraph) {
137
+ return [name, { ...rel, _library: true }];
138
+ }
139
+ return [name, { def: cloneForRetyping(rel.def) }];
140
+ })
141
+ );
142
+ injectLibraries(rels, options.libraries);
143
+
144
+ const { relAlias, compileStats } = compileTypes(representatives, rels, options);
145
+ return {
146
+ rels,
147
+ representatives,
148
+ relAlias,
149
+ compileStats: {
150
+ ...object.compileStats,
151
+ ...compileStats,
152
+ sccs: [
153
+ ...(object.compileStats?.sccs || []),
154
+ ...(compileStats?.sccs || [])
155
+ ]
156
+ }
157
+ };
158
+ }
159
+
160
+ function collectFilterNames(filter, names) {
161
+ if (!filter || typeof filter !== "object") return;
162
+ if (filter.name) names.add(filter.name);
163
+ if (filter.fields) {
164
+ for (const f of Object.values(filter.fields)) collectFilterNames(f, names);
165
+ }
166
+ }
167
+
168
+ function collectFilterVarNames(node, names = new Set()) {
169
+ if (!node || typeof node !== "object") return names;
170
+ if (node.op === "filter" && node.filter) {
171
+ collectFilterNames(node.filter, names);
172
+ }
173
+ for (const val of Object.values(node)) {
174
+ if (Array.isArray(val)) {
175
+ for (const item of val) collectFilterVarNames(item, names);
176
+ } else if (typeof val === "object") {
177
+ collectFilterVarNames(val, names);
178
+ }
179
+ }
180
+ return names;
181
+ }
182
+
183
+ function freshFilterVarPrefix(node) {
184
+ const names = collectFilterVarNames(node);
185
+ let prefix = "__in_";
186
+ let count = 0;
187
+ while (Array.from(names).some((name) => name.startsWith(prefix))) {
188
+ prefix = `__in_${count++}_`;
189
+ }
190
+ return prefix;
191
+ }
192
+
193
+ function annotateSourceWithInputFilter(source, inputPattern, valuePattern, options = {}) {
194
+ const intersection = intersectInputEnvelope(inputPattern, valuePattern);
195
+ const parsed = parse(source);
196
+ const prefix = freshFilterVarPrefix(parsed.exp);
197
+ const filter = propertyListToFilter(intersection, prefix);
198
+ const filterExp = parse(`?${filter}`).exp;
199
+ return compileParsedDefs(
200
+ parsed,
201
+ composeInputFilter(filterExp, cloneForRetyping(parsed.exp)),
202
+ options
203
+ );
204
+ }
205
+
206
+ function annotateObjectWithInputFilter(object, mainRelName, inputPattern, valuePattern, options = {}) {
207
+ const intersection = intersectInputEnvelope(inputPattern, valuePattern);
208
+ const mainRel = object.rels?.[mainRelName];
209
+ if (!mainRel) throw new Error(`No main relation (${mainRelName}) defined in object`);
210
+ const prefix = freshFilterVarPrefix(mainRel.def);
211
+ const filter = propertyListToFilter(intersection, prefix);
212
+ const filterExp = parse(`?${filter}`).exp;
213
+ const mainExp = composeInputFilter(filterExp, cloneForRetyping(mainRel.def));
214
+ return compileObjectDefs(object, mainRelName, mainExp, options);
215
+ }
216
+
217
+ function cleanFunctionNameMap(names) {
218
+ const used = new Set();
219
+ const nameMap = new Map();
220
+ for (const name of names) {
221
+ const base = cleanName(name);
222
+ let candidate = base;
223
+ let suffix = 1;
224
+ while (used.has(candidate)) {
225
+ candidate = `${base}_${suffix++}`;
226
+ }
227
+ used.add(candidate);
228
+ nameMap.set(name, candidate);
229
+ }
230
+ return nameMap;
231
+ }
232
+
233
+ function cleanCallNames(insts, nameMap = null) {
234
+ for (const inst of insts) {
235
+ if (inst.op === "call") {
236
+ inst.func = nameMap?.get(inst.func) || cleanName(inst.func);
237
+ }
238
+ if (inst.branches) {
239
+ for (const branch of inst.branches) {
240
+ cleanCallNames(branch.body, nameMap);
241
+ }
242
+ }
243
+ }
244
+ }
245
+
246
+ function cloneKVMInstructions(insts) {
247
+ return insts.map((inst) => ({
248
+ ...inst,
249
+ ...(inst.branches
250
+ ? {
251
+ branches: inst.branches.map((branch) => ({
252
+ label: branch.label,
253
+ body: cloneKVMInstructions(branch.body)
254
+ }))
255
+ }
256
+ : {})
257
+ }));
258
+ }
259
+
260
+ function cloneKVMFunction(kvmFunc) {
261
+ return {
262
+ ...kvmFunc,
263
+ body: cloneKVMInstructions(kvmFunc.body)
264
+ };
265
+ }
266
+
267
+ function compileModule(mainRelName, defs) {
268
+ const compiled = new Set();
269
+ const queue = [mainRelName];
270
+ const wats = [];
271
+ const nameMap = cleanFunctionNameMap(Object.keys(defs.rels));
272
+
273
+ while (queue.length > 0) {
274
+ const name = queue.shift();
275
+ if (compiled.has(name)) continue;
276
+ compiled.add(name);
277
+
278
+ const relDef = defs.rels[name];
279
+ if (!relDef) {
280
+ throw new Error(`Relation ${name} not found`);
281
+ }
282
+
283
+ const kvmFunc = lowerToKVM(relDef, name);
284
+ kvmFunc.typePatternGraph = relDef.typePatternGraph;
285
+ scanCalls(kvmFunc.body, compiled, queue);
286
+
287
+ kvmFunc.name = nameMap.get(name) || cleanName(name);
288
+ cleanCallNames(kvmFunc.body, nameMap);
289
+ wats.push(lowerToWasm(kvmFunc, kvmFunc.name));
290
+ }
291
+
292
+ return {
293
+ wat: wats.join("\n\n"),
294
+ relationNames: [...compiled],
295
+ entryName: nameMap.get(mainRelName) || cleanName(mainRelName)
296
+ };
297
+ }
298
+
299
+ function compileKVMModule(mainRelName, kvmProgram) {
300
+ const compiled = new Set();
301
+ const queue = [mainRelName];
302
+ const wats = [];
303
+ const nameMap = cleanFunctionNameMap(Object.keys(kvmProgram));
304
+ const cleanKVMProgram = Object.fromEntries(
305
+ Object.entries(kvmProgram).map(([name, kvmFunc]) => [nameMap.get(name), kvmFunc])
306
+ );
307
+
308
+ while (queue.length > 0) {
309
+ const name = queue.shift();
310
+ if (compiled.has(name)) continue;
311
+ compiled.add(name);
312
+
313
+ const originalFunc = kvmProgram[name];
314
+ if (!originalFunc || !Array.isArray(originalFunc.body)) {
315
+ throw new Error(`kVM function ${name} not found`);
316
+ }
317
+
318
+ scanCalls(originalFunc.body, compiled, queue);
319
+
320
+ const kvmFunc = cloneKVMFunction(originalFunc);
321
+ kvmFunc.name = nameMap.get(name);
322
+ cleanCallNames(kvmFunc.body, nameMap);
323
+ wats.push(lowerToWasm(kvmFunc, kvmFunc.name, { kvmProgram: cleanKVMProgram }));
324
+ }
325
+
326
+ return {
327
+ wat: wats.join("\n\n"),
328
+ entryName: nameMap.get(mainRelName)
329
+ };
330
+ }
331
+
332
+ function getPatternPropertyList(graph, patternId) {
333
+ const nodeId = graph.find(patternId);
334
+ return patternToPropertyList(exportPatternGraph(graph, nodeId));
335
+ }
336
+
337
+ function encodeU32(value) {
338
+ const bytes = [];
339
+ do {
340
+ let byte = value & 0x7f;
341
+ value = Math.floor(value / 128);
342
+ if (value > 0) byte |= 0x80;
343
+ bytes.push(byte);
344
+ } while (value > 0);
345
+ return Buffer.from(bytes);
346
+ }
347
+
348
+ function appendCustomSection(wasmBuffer, name, data) {
349
+ const nameBuffer = Buffer.from(name, "utf8");
350
+ const dataBuffer = Buffer.isBuffer(data) ? data : Buffer.from(data);
351
+ const payload = Buffer.concat([
352
+ encodeU32(nameBuffer.length),
353
+ nameBuffer,
354
+ dataBuffer
355
+ ]);
356
+ return Buffer.concat([
357
+ Buffer.from(wasmBuffer),
358
+ Buffer.from([0]),
359
+ encodeU32(payload.length),
360
+ payload
361
+ ]);
362
+ }
363
+
364
+ function validateMetadata(metadata) {
365
+ if (!metadata || metadata.format !== ARTIFACT_FORMAT || metadata.version !== ARTIFACT_VERSION) {
366
+ throw new Error("Unsupported k WebAssembly artifact metadata");
367
+ }
368
+ if (typeof metadata.entry !== "string") {
369
+ throw new Error("WebAssembly artifact metadata is missing its entry point");
370
+ }
371
+ if (!Array.isArray(metadata.inputPattern) || !Array.isArray(metadata.outputPattern)) {
372
+ throw new Error("WebAssembly artifact metadata is missing its input/output patterns");
373
+ }
374
+ if (!Array.isArray(metadata.tags)) {
375
+ throw new Error("WebAssembly artifact metadata is missing its tag table");
376
+ }
377
+ propertyListToPattern(metadata.inputPattern);
378
+ propertyListToPattern(metadata.outputPattern);
379
+ return metadata;
380
+ }
381
+
382
+ function metadataFromModule(module) {
383
+ const sections = WebAssembly.Module.customSections(module, METADATA_SECTION);
384
+ if (sections.length !== 1) {
385
+ throw new Error(`Expected one '${METADATA_SECTION}' custom section, found ${sections.length}`);
386
+ }
387
+ return validateMetadata(JSON.parse(Buffer.from(sections[0]).toString("utf8")));
388
+ }
389
+
390
+ function isMonomorphicPattern(pattern) {
391
+ return Array.isArray(pattern) &&
392
+ pattern.length > 0 &&
393
+ pattern.every(([kind]) => kind === "closed-product" || kind === "closed-union");
394
+ }
395
+
396
+ function classifyTyping(inputPattern, outputPattern, status = "unknown", mode = "generic") {
397
+ const input = isMonomorphicPattern(inputPattern) ? "monomorphic" : "polymorphic";
398
+ const output = isMonomorphicPattern(outputPattern) ? "monomorphic" : "polymorphic";
399
+ return {
400
+ status,
401
+ mode,
402
+ input,
403
+ output,
404
+ program: input === "monomorphic" && output === "monomorphic" ? "monomorphic" : "polymorphic"
405
+ };
406
+ }
407
+
408
+ function compileStatsByRelName(compileStats = {}) {
409
+ const byName = new Map();
410
+ for (const scc of compileStats.sccs || []) {
411
+ for (const member of scc.members || []) {
412
+ byName.set(member, scc);
413
+ }
414
+ }
415
+ return byName;
416
+ }
417
+
418
+ function relTypeStatus(defs, name) {
419
+ const rel = defs.rels?.[name];
420
+ const explicit = rel?.typeDerivation?.status;
421
+ if (explicit) return explicit;
422
+ const scc = compileStatsByRelName(defs.compileStats).get(name);
423
+ if (scc) return scc.converged ? "converged" : "not-converged";
424
+ return "unknown";
425
+ }
426
+
427
+ function assertRelationsConverged(defs, relationNames) {
428
+ for (const name of relationNames) {
429
+ const status = relTypeStatus(defs, name);
430
+ if (status !== "converged") {
431
+ throw new Error(`Cannot compile '${name}' to WebAssembly: type derivation is ${status}`);
432
+ }
433
+ }
434
+ }
435
+
436
+ function intersectInputEnvelope(inputPattern, valuePattern) {
437
+ try {
438
+ return intersectPropertyListPatterns(inputPattern, valuePattern);
439
+ } catch (error) {
440
+ throw new TypeError(
441
+ "Input value envelope does not intersect WebAssembly artifact input pattern.\n" +
442
+ ` - input pattern: ${JSON.stringify(inputPattern)}\n` +
443
+ ` - value envelope: ${JSON.stringify(valuePattern)}`
444
+ );
445
+ }
446
+ }
447
+
448
+ function validateInputEnvelope(inputPattern, valuePattern) {
449
+ intersectInputEnvelope(inputPattern, valuePattern);
450
+ }
451
+
452
+ function buildExportPreamble(exportSpecs, libraries) {
453
+ if (exportSpecs.length === 0) return "";
454
+
455
+ const aliasMap = {};
456
+ for (const lib of libraries) {
457
+ for (const [name, hash] of Object.entries(lib.relAlias || {})) {
458
+ if (name !== "__main__") aliasMap[name] = hash;
459
+ }
460
+ for (const [hash, entry] of Object.entries(lib.meta || {})) {
461
+ if (entry?.type !== "rel") continue;
462
+ for (const origin of entry?.origins || []) {
463
+ if (origin?.name && origin.name !== "__main__") {
464
+ aliasMap[origin.name] = hash;
465
+ }
466
+ }
467
+ }
468
+ }
469
+
470
+ const lines = [];
471
+ for (const spec of exportSpecs) {
472
+ const [libName, localName] = spec.includes(":") ? spec.split(":", 2) : [spec, spec];
473
+ const hash = aliasMap[libName];
474
+ if (!hash) throw new Error(`--export: '${libName}' not found in loaded libraries`);
475
+ const body = hash.startsWith("@") ? hash.slice(1) : hash;
476
+ lines.push(`${localName} = @${body};`);
477
+ }
478
+ return lines.join("\n") + "\n";
479
+ }
480
+
481
+ async function compileWasmArtifactFromDefs(
482
+ defs,
483
+ mainRelName = "__main__",
484
+ { typingMode = "generic" } = {}
485
+ ) {
486
+ resetTagIds();
487
+ const mainRel = defs.rels[mainRelName];
488
+ if (!mainRel) {
489
+ throw new Error(`No main relation (${mainRelName}) defined in script`);
490
+ }
491
+
492
+ const { wat: moduleWatBody, relationNames, entryName } = compileModule(mainRelName, defs);
493
+ assertRelationsConverged(defs, relationNames);
494
+ const fullWat = runtimeWat.trim().slice(0, -1) + "\n" + moduleWatBody + "\n)";
495
+ const graph = mainRel.typePatternGraph;
496
+ const inputPattern = getPatternPropertyList(graph, mainRel.def.patterns[0]);
497
+ const outputPattern = getPatternPropertyList(graph, mainRel.def.patterns[1]);
498
+ const metadata = {
499
+ format: ARTIFACT_FORMAT,
500
+ version: ARTIFACT_VERSION,
501
+ abi: "arena-v1",
502
+ entry: entryName || cleanName(mainRelName),
503
+ inputPattern,
504
+ outputPattern,
505
+ typing: classifyTyping(inputPattern, outputPattern, relTypeStatus(defs, mainRelName), typingMode),
506
+ tags: getTagEntries()
507
+ };
508
+ return appendCustomSection(await compileWat(fullWat), METADATA_SECTION, JSON.stringify(metadata));
509
+ }
510
+
511
+ function normalizeKVMInput(kvmInput, { entry = "__main__", typingMode = "generic", inputEnvelopePattern = null } = {}) {
512
+ if (kvmInput?.format === "k-vm") {
513
+ if (kvmInput.layer === "KVM-P" && inputEnvelopePattern) {
514
+ kvmInput = specializeKVM(kvmInput, inputEnvelopePattern);
515
+ }
516
+ const program = kvmInput.functions;
517
+ if (!program || typeof program !== "object" || Array.isArray(program)) {
518
+ throw new Error("Expected .kvm artifact to contain a functions object");
519
+ }
520
+ if (kvmInput.layer != null && kvmInput.layer !== "KVM" && kvmInput.layer !== "KVM-P") {
521
+ throw new Error(`Unsupported .kvm artifact layer '${kvmInput.layer}'`);
522
+ }
523
+ return {
524
+ program,
525
+ entry: kvmInput.entry || entry,
526
+ typingMode: kvmInput.layer === "KVM" ? "specialized" : typingMode,
527
+ relation: kvmInput.relation || null
528
+ };
529
+ }
530
+
531
+ return {
532
+ program: kvmInput,
533
+ entry,
534
+ typingMode,
535
+ relation: null
536
+ };
537
+ }
538
+
539
+ async function compileWasmArtifactFromKVM(kvmInput, options = {}) {
540
+ resetTagIds();
541
+ const normalized = normalizeKVMInput(kvmInput, options);
542
+ const { program: kvmProgram, relation } = normalized;
543
+ const entry = normalized.entry;
544
+ const typingMode = normalized.typingMode;
545
+
546
+ if (!kvmProgram || typeof kvmProgram !== "object" || Array.isArray(kvmProgram)) {
547
+ throw new Error("Expected .kvm input to contain a JSON object of kVM functions");
548
+ }
549
+
550
+ const mainFunc = kvmProgram[entry];
551
+ if (!mainFunc) {
552
+ throw new Error(`No kVM entry function (${entry}) defined in program`);
553
+ }
554
+ if (!Array.isArray(mainFunc.inputPattern) || !Array.isArray(mainFunc.outputPattern)) {
555
+ throw new Error(`kVM entry function (${entry}) is missing input/output patterns`);
556
+ }
557
+
558
+ const moduleWat = compileKVMModule(entry, kvmProgram);
559
+ const moduleWatBody = moduleWat.wat;
560
+ const fullWat = runtimeWat.trim().slice(0, -1) + "\n" + moduleWatBody + "\n)";
561
+ const metadata = {
562
+ format: ARTIFACT_FORMAT,
563
+ version: ARTIFACT_VERSION,
564
+ abi: "arena-v1",
565
+ entry: moduleWat.entryName,
566
+ relation,
567
+ inputPattern: mainFunc.inputPattern,
568
+ outputPattern: mainFunc.outputPattern,
569
+ typing: classifyTyping(
570
+ mainFunc.inputPattern,
571
+ mainFunc.outputPattern,
572
+ mainFunc.isConverged ? "converged" : "unknown",
573
+ typingMode
574
+ ),
575
+ tags: getTagEntries()
576
+ };
577
+ return appendCustomSection(await compileWat(fullWat), METADATA_SECTION, JSON.stringify(metadata));
578
+ }
579
+
580
+ async function compileWasmArtifactFromObject(object, { entry = null, inputEnvelopePattern = null } = {}) {
581
+ if (!object?.rels) {
582
+ throw new Error("Expected .ko input to contain k object relations");
583
+ }
584
+ if (object.main == null) {
585
+ throw new Error("Cannot compile a .klib library to WebAssembly without a main relation");
586
+ }
587
+ const mainRelName = entry || object.main || "__main__";
588
+ let defs = { rels: object.rels, compileStats: object.compileStats };
589
+ let typingMode = "generic";
590
+
591
+ if (inputEnvelopePattern) {
592
+ const mainRel = object.rels[mainRelName];
593
+ if (!mainRel) throw new Error(`No main relation (${mainRelName}) defined in object`);
594
+ const inputPattern = getPatternPropertyList(mainRel.typePatternGraph, mainRel.def.patterns[0]);
595
+ const outputPattern = getPatternPropertyList(mainRel.typePatternGraph, mainRel.def.patterns[1]);
596
+ if (classifyTyping(inputPattern, outputPattern).program === "polymorphic") {
597
+ defs = annotateObjectWithInputFilter(object, mainRelName, inputPattern, inputEnvelopePattern);
598
+ typingMode = "specialized";
599
+ }
600
+ }
601
+
602
+ return compileWasmArtifactFromDefs(defs, mainRelName, { typingMode });
603
+ }
604
+
605
+ async function compileWasmArtifact(
606
+ source,
607
+ { libraries = [], exports = [], source: sourceName = null, inputEnvelopePattern = null } = {}
608
+ ) {
609
+ const preamble = buildExportPreamble(exports, libraries);
610
+ const fullSource = preamble + source;
611
+ const options = { libraries, ...(sourceName ? { source: sourceName } : {}) };
612
+ let defs = annotate(fullSource, options);
613
+
614
+ let typingMode = "generic";
615
+ if (inputEnvelopePattern) {
616
+ const mainRel = defs.rels.__main__;
617
+ const inputPattern = getPatternPropertyList(mainRel.typePatternGraph, mainRel.def.patterns[0]);
618
+ const outputPattern = getPatternPropertyList(mainRel.typePatternGraph, mainRel.def.patterns[1]);
619
+ if (classifyTyping(inputPattern, outputPattern).program === "polymorphic") {
620
+ defs = annotateSourceWithInputFilter(fullSource, inputPattern, inputEnvelopePattern, options);
621
+ typingMode = "specialized";
622
+ }
623
+ }
624
+
625
+ return compileWasmArtifactFromDefs(defs, "__main__", { typingMode });
626
+ }
627
+
628
+ function createTagRegistry(entries) {
629
+ const tagToId = new Map();
630
+ const idToTag = new Map();
631
+ let nextId = 1;
632
+
633
+ for (const entry of entries) {
634
+ if (!entry || typeof entry.tag !== "string" || !Number.isInteger(entry.id) || entry.id < 1) {
635
+ throw new Error("WebAssembly artifact metadata contains an invalid tag entry");
636
+ }
637
+ if (tagToId.has(entry.tag) || idToTag.has(entry.id)) {
638
+ throw new Error("WebAssembly artifact metadata contains a duplicate tag entry");
639
+ }
640
+ tagToId.set(entry.tag, entry.id);
641
+ idToTag.set(entry.id, entry.tag);
642
+ nextId = Math.max(nextId, entry.id + 1);
643
+ }
644
+
645
+ return {
646
+ getId(tag) {
647
+ if (!tagToId.has(tag)) {
648
+ tagToId.set(tag, nextId);
649
+ idToTag.set(nextId, tag);
650
+ nextId++;
651
+ }
652
+ return tagToId.get(tag);
653
+ },
654
+ getTag(id) {
655
+ return idToTag.get(id) ?? null;
656
+ }
657
+ };
658
+ }
659
+
660
+ function patternForNode(patternPropertyList, patternNodeId) {
661
+ if (!patternPropertyList || patternNodeId == null) return null;
662
+ const subpattern = cloneSubpattern(patternPropertyList, patternNodeId);
663
+ return subpattern?.[0]?.[0] === "any" ? null : subpattern;
664
+ }
665
+
666
+ function valueWithPatternNode(value, patternPropertyList, patternNodeId) {
667
+ const pattern = patternForNode(patternPropertyList, patternNodeId);
668
+ return pattern ? withPattern(value, pattern) : value;
669
+ }
670
+
671
+ function constrainArenaValue(value, patternPropertyList, patternNodeId) {
672
+ const staticPattern = patternForNode(patternPropertyList, patternNodeId);
673
+ if (!staticPattern) return value;
674
+ if (!value.pattern) return withPattern(value, staticPattern);
675
+ return withPattern(value, intersectInputEnvelope(staticPattern, value.pattern));
676
+ }
677
+
678
+ function wasmPtr(ptr) {
679
+ return ptr >>> 0;
680
+ }
681
+
682
+ function readArenaValue(exports, ptr, pattern, patternNodeId, patternPropertyList, arenaValues, tags) {
683
+ let result;
684
+ const stack = [{
685
+ ptr: wasmPtr(ptr),
686
+ patternNodeId,
687
+ assign(value) {
688
+ result = value;
689
+ }
690
+ }];
691
+
692
+ while (stack.length > 0) {
693
+ const frame = stack.pop();
694
+ const patternNode = pattern.nodes[frame.patternNodeId];
695
+ const view = new DataView(exports.memory.buffer);
696
+
697
+ if (arenaValues.has(frame.ptr)) {
698
+ frame.assign(constrainArenaValue(arenaValues.get(frame.ptr), patternPropertyList, frame.patternNodeId));
699
+ continue;
700
+ }
701
+
702
+ if (patternNode.kind === NODE_KIND.ANY) {
703
+ throw new Error(`Cannot decode arena pointer ${frame.ptr} through an unconstrained output pattern`);
704
+ }
705
+
706
+ if (patternNode.kind === NODE_KIND.OPEN_PRODUCT || patternNode.kind === NODE_KIND.CLOSED_PRODUCT) {
707
+ const N = view.getUint32(frame.ptr + 4, true);
708
+ if (N !== patternNode.edges.length) {
709
+ throw new Error(`Cannot decode product pointer ${frame.ptr}: arena field count ${N} does not match output pattern`);
710
+ }
711
+ const product = {};
712
+ frame.assign(Value.product(product, patternForNode(patternPropertyList, frame.patternNodeId)));
713
+ for (let i = N - 1; i >= 0; i--) {
714
+ const edge = patternNode.edges[i];
715
+ const offset = view.getUint32(frame.ptr + 8 + 4 * i, true);
716
+ const childPtr = view.getUint32(frame.ptr + offset, true);
717
+ stack.push({
718
+ ptr: wasmPtr(childPtr),
719
+ patternNodeId: edge.target,
720
+ assign(value) {
721
+ product[edge.label] = value;
722
+ }
723
+ });
724
+ }
725
+ continue;
726
+ }
727
+
728
+ if (patternNode.kind === NODE_KIND.OPEN_UNION || patternNode.kind === NODE_KIND.CLOSED_UNION) {
729
+ const tag = tags.getTag(view.getUint32(frame.ptr + 4, true));
730
+ const edge = patternNode.edges.find((candidate) => candidate.label === tag);
731
+ if (!edge) {
732
+ throw new Error(`Variant tag '${tag}' not found in output pattern edges`);
733
+ }
734
+ const payloadPtr = view.getUint32(frame.ptr + 8, true);
735
+ const variant = Value.variant(tag, undefined, patternForNode(patternPropertyList, frame.patternNodeId));
736
+ frame.assign(variant);
737
+ stack.push({
738
+ ptr: wasmPtr(payloadPtr),
739
+ patternNodeId: edge.target,
740
+ assign(value) {
741
+ variant.value = value;
742
+ }
743
+ });
744
+ continue;
745
+ }
746
+
747
+ throw new Error(`Unsupported pattern kind: ${patternNode.kind}`);
748
+ }
749
+
750
+ return result;
751
+ }
752
+
753
+ function writeValueToArena(exports, value, pattern, patternNodeId, arenaValues, tags, patternPropertyList = null) {
754
+ let result;
755
+ const stack = [{
756
+ value,
757
+ patternNodeId,
758
+ assign(ptr) {
759
+ result = ptr;
760
+ }
761
+ }];
762
+
763
+ while (stack.length > 0) {
764
+ const frame = stack.pop();
765
+
766
+ if (frame.finishProduct) {
767
+ const N = frame.childPtrs.length;
768
+ const view = new DataView(exports.memory.buffer);
769
+ view.setUint32(frame.ptr, 8 + 8 * N, true);
770
+ view.setUint32(frame.ptr + 4, N, true);
771
+ for (let i = 0; i < N; i++) {
772
+ const offset = 8 + 4 * N + 4 * i;
773
+ view.setUint32(frame.ptr + 8 + 4 * i, offset, true);
774
+ view.setUint32(frame.ptr + offset, frame.childPtrs[i], true);
775
+ }
776
+ arenaValues.set(frame.ptr, valueWithPatternNode(frame.value, patternPropertyList, frame.patternNodeId));
777
+ frame.assign(frame.ptr);
778
+ continue;
779
+ }
780
+
781
+ if (frame.finishVariant) {
782
+ const ptr = wasmPtr(exports.alloc(12));
783
+ const view = new DataView(exports.memory.buffer);
784
+ view.setUint32(ptr, 12, true);
785
+ view.setUint32(ptr + 4, tags.getId(frame.value.tag), true);
786
+ view.setUint32(ptr + 8, frame.childPtr, true);
787
+ arenaValues.set(ptr, valueWithPatternNode(frame.value, patternPropertyList, frame.patternNodeId));
788
+ frame.assign(ptr);
789
+ continue;
790
+ }
791
+
792
+ const patternNode = frame.patternNodeId == null ? null : pattern.nodes[frame.patternNodeId];
793
+ if (isProduct(frame.value)) {
794
+ const isAny = patternNode == null || patternNode.kind === NODE_KIND.ANY;
795
+ const isOpenProduct = patternNode?.kind === NODE_KIND.OPEN_PRODUCT;
796
+ const isClosedProduct = patternNode?.kind === NODE_KIND.CLOSED_PRODUCT;
797
+ if (!isAny && !isOpenProduct && !isClosedProduct) {
798
+ throw new Error(`Cannot encode product value through input pattern node ${frame.patternNodeId}`);
799
+ }
800
+
801
+ const fields = isAny
802
+ ? Object.keys(frame.value.product)
803
+ .sort()
804
+ .map((label) => ({ label, patternNodeId: frame.patternNodeId }))
805
+ : patternNode.edges.map((edge) => ({ label: edge.label, patternNodeId: edge.target }));
806
+ const fieldLabels = new Set(fields.map(({ label }) => label));
807
+ if (isClosedProduct) {
808
+ for (const label of Object.keys(frame.value.product)) {
809
+ if (!fieldLabels.has(label)) {
810
+ throw new Error(`Product field '${label}' is not present in input pattern node ${frame.patternNodeId}`);
811
+ }
812
+ }
813
+ }
814
+ for (const { label } of fields) {
815
+ if (!Object.hasOwn(frame.value.product, label)) {
816
+ throw new Error(`Product field '${label}' is required by input pattern node ${frame.patternNodeId}`);
817
+ }
818
+ }
819
+
820
+ const childPtrs = new Array(fields.length);
821
+ const ptr = wasmPtr(exports.alloc(8 + 8 * fields.length));
822
+ stack.push({
823
+ finishProduct: true,
824
+ value: frame.value,
825
+ patternNodeId: frame.patternNodeId,
826
+ ptr,
827
+ childPtrs,
828
+ assign: frame.assign
829
+ });
830
+ for (let i = fields.length - 1; i >= 0; i--) {
831
+ const field = fields[i];
832
+ stack.push({
833
+ value: frame.value.product[field.label],
834
+ patternNodeId: field.patternNodeId,
835
+ assign(ptr) {
836
+ childPtrs[i] = ptr;
837
+ }
838
+ });
839
+ }
840
+ continue;
841
+ }
842
+
843
+ if (isVariant(frame.value)) {
844
+ const isAny = patternNode == null || patternNode.kind === NODE_KIND.ANY;
845
+ const isOpenUnion = patternNode?.kind === NODE_KIND.OPEN_UNION;
846
+ const isClosedUnion = patternNode?.kind === NODE_KIND.CLOSED_UNION;
847
+ if (!isAny && !isOpenUnion && !isClosedUnion) {
848
+ throw new Error(`Cannot encode variant value through input pattern node ${frame.patternNodeId}`);
849
+ }
850
+
851
+ const edge = isAny ? null : patternNode.edges.find((candidate) => candidate.label === frame.value.tag);
852
+ if (isClosedUnion && !edge) {
853
+ throw new Error(`Variant tag '${frame.value.tag}' is not present in input pattern node ${frame.patternNodeId}`);
854
+ }
855
+ const variantFrame = {
856
+ finishVariant: true,
857
+ value: frame.value,
858
+ patternNodeId: frame.patternNodeId,
859
+ childPtr: null,
860
+ assign: frame.assign
861
+ };
862
+ stack.push(variantFrame);
863
+ stack.push({
864
+ value: frame.value.value,
865
+ patternNodeId: edge ? edge.target : null,
866
+ assign(ptr) {
867
+ variantFrame.childPtr = ptr;
868
+ }
869
+ });
870
+ continue;
871
+ }
872
+
873
+ throw new Error(`Unsupported value type: ${frame.value}`);
874
+ }
875
+
876
+ return result;
877
+ }
878
+
879
+ async function instantiateWasmArtifact(wasmBuffer) {
880
+ const module = await WebAssembly.compile(wasmBuffer);
881
+ const metadata = metadataFromModule(module);
882
+ const instance = await WebAssembly.instantiate(module);
883
+ const exports = instance.exports;
884
+ const tags = createTagRegistry(metadata.tags);
885
+ const inputPattern = propertyListToPattern(metadata.inputPattern);
886
+ const outputPattern = propertyListToPattern(metadata.outputPattern);
887
+
888
+ function execute(inputBuffer, options = {}) {
889
+ const t0 = process.hrtime.bigint();
890
+ const { pattern: valuePattern, value } = decodeWire(inputBuffer);
891
+ if (!isMonomorphicPattern(metadata.inputPattern)) {
892
+ validateInputEnvelope(metadata.inputPattern, valuePattern);
893
+ }
894
+ const t1 = process.hrtime.bigint();
895
+ const mark = exports.arena_mark ? exports.arena_mark() : 0;
896
+ const arenaValues = new Map();
897
+ const ptrIn = writeValueToArena(exports, value, inputPattern, 0, arenaValues, tags, metadata.inputPattern);
898
+ const t2 = process.hrtime.bigint();
899
+ const result = exports[metadata.entry](ptrIn);
900
+ if (result[1] !== 1) {
901
+ if (exports.arena_reset) exports.arena_reset(mark);
902
+ throw new Error("Wasm relation execution failed (returned false)");
903
+ }
904
+ const t3 = process.hrtime.bigint();
905
+ const output = readArenaValue(exports, wasmPtr(result[0]), outputPattern, 0, metadata.outputPattern, arenaValues, tags);
906
+ const t4 = process.hrtime.bigint();
907
+ const outWire = encodeToWire(output, output.pattern);
908
+ const t5 = process.hrtime.bigint();
909
+ if (exports.arena_reset) exports.arena_reset(mark);
910
+
911
+ if (options.trace) {
912
+ return {
913
+ outputWire: outWire,
914
+ trace: {
915
+ decodeNs: Number(t1 - t0),
916
+ flatInNs: Number(t2 - t1),
917
+ evalNs: Number(t3 - t2),
918
+ flatOutNs: Number(t4 - t3),
919
+ encodeNs: Number(t5 - t4),
920
+ totalNs: Number(t5 - t0)
921
+ }
922
+ };
923
+ }
924
+ return outWire;
925
+ }
926
+
927
+ function executeValue(inputValue, options = {}) {
928
+ const t0 = process.hrtime.bigint();
929
+ const valuePattern = inputValue?.pattern || null;
930
+ if (valuePattern && !isMonomorphicPattern(metadata.inputPattern)) {
931
+ validateInputEnvelope(metadata.inputPattern, valuePattern);
932
+ }
933
+ const t1 = process.hrtime.bigint();
934
+ const mark = exports.arena_mark ? exports.arena_mark() : 0;
935
+ const arenaValues = new Map();
936
+ const ptrIn = writeValueToArena(exports, inputValue, inputPattern, 0, arenaValues, tags, metadata.inputPattern);
937
+ const t2 = process.hrtime.bigint();
938
+ const result = exports[metadata.entry](ptrIn);
939
+ if (result[1] !== 1) {
940
+ if (exports.arena_reset) exports.arena_reset(mark);
941
+ return undefined;
942
+ }
943
+ const t3 = process.hrtime.bigint();
944
+ const output = readArenaValue(exports, wasmPtr(result[0]), outputPattern, 0, metadata.outputPattern, arenaValues, tags);
945
+ const t4 = process.hrtime.bigint();
946
+ if (exports.arena_reset) exports.arena_reset(mark);
947
+
948
+ if (options.trace) {
949
+ return {
950
+ output,
951
+ trace: {
952
+ validateNs: Number(t1 - t0),
953
+ flatInNs: Number(t2 - t1),
954
+ evalNs: Number(t3 - t2),
955
+ flatOutNs: Number(t4 - t3),
956
+ totalNs: Number(t4 - t0)
957
+ }
958
+ };
959
+ }
960
+ return output;
961
+ }
962
+
963
+ return {
964
+ module,
965
+ instance,
966
+ exports,
967
+ metadata,
968
+ tags,
969
+ inputPattern,
970
+ outputPattern,
971
+ execute,
972
+ executeValue
973
+ };
974
+ }
975
+
976
+ async function runWasmArtifact(wasmBuffer, inputBuffer) {
977
+ const runner = await instantiateWasmArtifact(wasmBuffer);
978
+ return runner.execute(inputBuffer);
979
+ }
980
+
981
+ export {
982
+ ARTIFACT_FORMAT,
983
+ ARTIFACT_VERSION,
984
+ METADATA_SECTION,
985
+ appendCustomSection,
986
+ compileWasmArtifactFromKVM,
987
+ compileWasmArtifactFromObject,
988
+ compileWasmArtifact,
989
+ instantiateWasmArtifact,
990
+ metadataFromModule,
991
+ readArenaValue,
992
+ runWasmArtifact,
993
+ wasmPtr,
994
+ writeValueToArena
995
+ };
996
+
997
+ export default {
998
+ ARTIFACT_FORMAT,
999
+ ARTIFACT_VERSION,
1000
+ METADATA_SECTION,
1001
+ appendCustomSection,
1002
+ compileWasmArtifactFromKVM,
1003
+ compileWasmArtifactFromObject,
1004
+ compileWasmArtifact,
1005
+ metadataFromModule,
1006
+ readArenaValue,
1007
+ runWasmArtifact,
1008
+ wasmPtr,
1009
+ writeValueToArena
1010
+ };