@fraczak/k 6.3.3 → 6.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/DOCS/CODECS.md +258 -0
- package/DOCS/DICTIONARY.md +1172 -0
- package/DOCS/KIR_SPECIALIZATION_DESIGN.md +51 -46
- package/DOCS/KIR_V1.md +221 -0
- package/DOCS/KVM_EXECUTION_MODEL.md +56 -19
- package/DOCS/OBJECT_FILE_AND_PATTERN.md +2 -1
- package/DOCS/PROFILING_AND_TRACING.md +196 -0
- package/DOCS/REPL.md +61 -4
- package/DOCS/WEB_REPL_REQUIREMENTS.md +135 -0
- package/DOCS/dependency-graph.md +144 -0
- package/Examples/arithmetics.k +108 -82
- package/Examples/bnat.k +1 -1
- package/Examples/buda.k +44 -0
- package/Examples/ieee.k +300 -8671
- package/Examples/poly.k +67 -0
- package/README.md +68 -19
- package/Value.mjs +8 -2
- package/augmentation.mjs +9 -7
- package/backend-api.mjs +11 -2
- package/backends/arm64/README.md +104 -0
- package/backends/arm64/bin/k-arm64-compile.mjs +101 -0
- package/backends/arm64/bin/k-arm64-run.mjs +58 -0
- package/backends/arm64/bin/k-arm64.mjs +88 -0
- package/backends/arm64/scripts/run-tests.mjs +41 -0
- package/backends/arm64/src/arm64.mjs +229 -0
- package/backends/arm64/src/cli.mjs +155 -0
- package/backends/arm64/src/kvm2arm64.mjs +906 -0
- package/backends/arm64/src/runtime.c +728 -0
- package/backends/arm64/tests/integration.sh +112 -0
- package/backends/arm64/tests/test-arm64.mjs +240 -0
- package/backends/llvm/README.md +135 -0
- package/backends/llvm/bin/k-llvm-build.mjs +71 -0
- package/backends/llvm/bin/k-llvm-compile.mjs +68 -0
- package/backends/llvm/bin/k-llvm-jit.mjs +160 -0
- package/backends/llvm/bin/k-llvm-run.mjs +90 -0
- package/backends/llvm/runtime/krt.c +1508 -0
- package/backends/llvm/runtime/krt.h +109 -0
- package/backends/llvm/scripts/conformance.mjs +76 -0
- package/backends/llvm/scripts/run-tests.mjs +28 -0
- package/backends/llvm/src/executable.mjs +562 -0
- package/backends/llvm/src/kvm2llvm.mjs +998 -0
- package/backends/llvm/src/llvm.mjs +1092 -0
- package/backends/llvm/tests/composition-driver.c +22 -0
- package/backends/llvm/tests/identity-driver.c +27 -0
- package/backends/llvm/tests/integration.sh +153 -0
- package/backends/llvm/tests/perf-support.mjs +735 -0
- package/backends/llvm/tests/product-driver.c +23 -0
- package/backends/llvm/tests/projection-driver.c +19 -0
- package/backends/llvm/tests/relation-driver.c +29 -0
- package/backends/llvm/tests/test-llvm.mjs +240 -0
- package/backends/llvm/tests/union-driver.c +31 -0
- package/backends/llvm/tests/variant-driver.c +19 -0
- package/backends/llvm/tests/variant-projection-driver.c +21 -0
- package/backends/wasm/DOCS/USE-WEB-ASSEMBLY.md +233 -0
- package/backends/wasm/README.md +97 -0
- package/backends/wasm/TECHNICAL-DEBT.md +58 -0
- package/backends/wasm/bin/k-wasm-compile.mjs +50 -0
- package/backends/wasm/bin/k-wasm-run.mjs +140 -0
- package/backends/wasm/bin/k-wasm.mjs +49 -0
- package/backends/wasm/demo_ieee.mjs +319 -0
- package/backends/wasm/runtime.wat +475 -0
- package/backends/wasm/scripts/run-tests.mjs +41 -0
- package/backends/wasm/src/cli.mjs +133 -0
- package/backends/wasm/src/kvm2wasm.mjs +697 -0
- package/backends/wasm/src/wasm.mjs +1054 -0
- package/backends/wasm/tests/integration.sh +182 -0
- package/backends/wasm/tests/perf-support.mjs +336 -0
- package/backends/wasm/tests/test-wasm.mjs +625 -0
- package/browser/repl-browser.mjs +1584 -0
- package/browser/shims/assert.mjs +19 -0
- package/browser/shims/buffer.mjs +224 -0
- package/browser/shims/crypto.mjs +103 -0
- package/browser/shims/fs.mjs +159 -0
- package/browser/shims/os.mjs +17 -0
- package/browser/shims/path.mjs +54 -0
- package/browser/shims/process.mjs +44 -0
- package/browser/shims/readline.mjs +11 -0
- package/browser/shims/url.mjs +12 -0
- package/browser/vfs-data.mjs +19 -0
- package/codecs/README.md +3 -0
- package/codecs/runtime/show-value.mjs +12 -3
- package/conformance/helper-reuse/case.json +8 -0
- package/conformance/helper-reuse/expected.kv +1 -0
- package/conformance/helper-reuse/input.kv +1 -0
- package/conformance/helper-reuse/program.k +2 -0
- package/conformance/identity/case.json +8 -0
- package/conformance/identity/expected.kv +1 -0
- package/conformance/identity/input.kv +1 -0
- package/conformance/identity/program.k +1 -0
- package/conformance/product-projection/case.json +8 -0
- package/conformance/product-projection/expected.kv +1 -0
- package/conformance/product-projection/input.kv +1 -0
- package/conformance/product-projection/program.k +1 -0
- package/conformance/run.mjs +149 -0
- package/conformance/variant-construction/case.json +8 -0
- package/conformance/variant-construction/expected.kv +1 -0
- package/conformance/variant-construction/input.kv +1 -0
- package/conformance/variant-construction/program.k +1 -0
- package/harness/adapters/arm64.mjs +105 -0
- package/harness/adapters/kvm.mjs +144 -0
- package/harness/adapters/llvm.mjs +118 -0
- package/harness/adapters/native.mjs +77 -0
- package/harness/adapters/wasm.mjs +169 -0
- package/harness/backend.mjs +95 -0
- package/harness/cli.mjs +130 -0
- package/harness/format.mjs +95 -0
- package/harness/index.mjs +25 -0
- package/harness/persistent.mjs +121 -0
- package/harness/registry.mjs +44 -0
- package/harness/suite.mjs +257 -0
- package/harness/suites/poly.mjs +156 -0
- package/harness/trace.mjs +50 -0
- package/harness/util.mjs +92 -0
- package/intrinsics.mjs +41 -0
- package/kir.mjs +399 -0
- package/kvm.mjs +585 -81
- package/objects/README.md +37 -3
- package/objects/compile.mjs +15 -22
- package/objects/inspect.mjs +96 -0
- package/objects/validate.mjs +415 -0
- package/package.json +51 -19
- package/repl-codecs.mjs +105 -6
- package/repl.mjs +335 -49
- package/run.mjs +2 -7
- package/scripts/benchmark.mjs +406 -22
- package/scripts/build-repl-html.mjs +1784 -0
- package/scripts/perf-ieee.mjs +586 -0
- package/scripts/perf-int.mjs +531 -0
- package/scripts/perf-poly.mjs +945 -0
- package/scripts/render-benchmark.mjs +12 -8
- package/scripts/run-tests.mjs +6 -0
- package/tests/integration.sh +19 -2
- package/tests/test-arithmetics.mjs +54 -0
- package/tests/test-ieee-arithmetic.mjs +4 -0
- package/tests/test-kir.mjs +85 -0
- package/tests/test-kvm-polymorphic.mjs +278 -0
- package/tests/test-kvm.mjs +25 -6
- package/tests/test-poly.mjs +129 -0
- package/tests/test-repl-html.mjs +303 -0
- package/tests/test-repl.mjs +144 -1
- package/tests/test-validate-object.mjs +40 -0
- package/a.klib +0 -1
- package/a.kvm +0 -142676
- package/a.wasm +0 -0
- package/benchmark-results.html +0 -532
- package/benchmark-results.json +0 -480
- package/k-vscode/.vscode/launch.json +0 -14
- package/k-vscode/README.md +0 -75
- package/k-vscode/extension.js +0 -273
- package/k-vscode/language-configuration.json +0 -42
- package/k-vscode/package.json +0 -79
- package/k-vscode/snippets/k.json +0 -92
- package/k-vscode/syntaxes/k.tmLanguage.json +0 -599
- package/k-vscode/test/background-ranges.test.js +0 -50
- package/k-vscode/themes/k-contrast-color-theme.json +0 -104
- package/scripts/git-hooks/pre-commit +0 -10
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { spawnSync } from "node:child_process";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
8
|
+
const node = process.execPath;
|
|
9
|
+
const tests = [
|
|
10
|
+
["tests/test-arm64.mjs", node, ["tests/test-arm64.mjs"]],
|
|
11
|
+
["tests/integration.sh", path.join(root, "tests/integration.sh"), []]
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
function formatDuration(milliseconds) {
|
|
15
|
+
if (milliseconds < 1000) return `${milliseconds.toFixed(0)} ms`;
|
|
16
|
+
return `${(milliseconds / 1000).toFixed(2)} s`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const suiteStarted = performance.now();
|
|
20
|
+
for (const [name, command, args] of tests) {
|
|
21
|
+
console.log(`\n==> ${name}`);
|
|
22
|
+
const started = performance.now();
|
|
23
|
+
const result = spawnSync(command, args, {
|
|
24
|
+
cwd: root,
|
|
25
|
+
stdio: "inherit"
|
|
26
|
+
});
|
|
27
|
+
const duration = formatDuration(performance.now() - started);
|
|
28
|
+
|
|
29
|
+
if (result.error) {
|
|
30
|
+
console.error(`<== ${name} FAILED (${duration})`);
|
|
31
|
+
console.error(result.error.message);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
if (result.status !== 0) {
|
|
35
|
+
console.error(`<== ${name} FAILED (${duration})`);
|
|
36
|
+
process.exit(result.status ?? 1);
|
|
37
|
+
}
|
|
38
|
+
console.log(`<== ${name} passed (${duration})`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
console.log(`\nAll ARM64 tests passed (${formatDuration(performance.now() - suiteStarted)})`);
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
decodeObject,
|
|
9
|
+
decodeWire,
|
|
10
|
+
objectToKVMArtifact,
|
|
11
|
+
specializeKVM
|
|
12
|
+
} from "../../../backend-api.mjs";
|
|
13
|
+
import { compileLibrary, compileObjectBuffer, loadLibrary } from "../../../object.mjs";
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
compileKVMModuleToARM64,
|
|
17
|
+
emitMetadataC,
|
|
18
|
+
getTagEntries,
|
|
19
|
+
resetTagIds
|
|
20
|
+
} from "./kvm2arm64.mjs";
|
|
21
|
+
|
|
22
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const RUNTIME_C_PATH = path.resolve(__dirname, "runtime.c");
|
|
24
|
+
const KRT_C_PATH = path.resolve(__dirname, "../../llvm/runtime/krt.c");
|
|
25
|
+
const KRT_H_DIR = path.resolve(__dirname, "../../llvm/runtime");
|
|
26
|
+
|
|
27
|
+
export const ARTIFACT_FORMAT = "k-arm64";
|
|
28
|
+
export const ARTIFACT_VERSION = 1;
|
|
29
|
+
|
|
30
|
+
function buildExportPreamble(exports = [], libraries = []) {
|
|
31
|
+
if (exports.length === 0) return "";
|
|
32
|
+
const aliasMap = {};
|
|
33
|
+
for (const lib of libraries) {
|
|
34
|
+
for (const [name, hash] of Object.entries(lib.relAlias || {})) {
|
|
35
|
+
if (name !== "__main__") aliasMap[name] = hash;
|
|
36
|
+
}
|
|
37
|
+
for (const [hash, entry] of Object.entries(lib.meta || {})) {
|
|
38
|
+
if (entry?.type !== "rel") continue;
|
|
39
|
+
for (const origin of entry?.origins || []) {
|
|
40
|
+
if (origin?.name && origin.name !== "__main__") {
|
|
41
|
+
aliasMap[origin.name] = hash;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const lines = [];
|
|
47
|
+
for (const spec of exports) {
|
|
48
|
+
const [libName, localName] = spec.includes(":") ? spec.split(":", 2) : [spec, spec];
|
|
49
|
+
const hash = aliasMap[libName];
|
|
50
|
+
if (!hash) throw new Error(`--export: '${libName}' not found in loaded libraries`);
|
|
51
|
+
const body = hash.startsWith("@") ? hash.slice(1) : hash;
|
|
52
|
+
lines.push(`${localName} = @${body};`);
|
|
53
|
+
}
|
|
54
|
+
return lines.join("\n") + "\n";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function compileARM64ArtifactFromKVM(kvmInput, options = {}) {
|
|
58
|
+
let kvm = kvmInput;
|
|
59
|
+
if (kvm?.format === "k-vm") {
|
|
60
|
+
if (kvm.layer === "KVM-P" && options.inputEnvelopePattern) {
|
|
61
|
+
kvm = specializeKVM(kvm, options.inputEnvelopePattern);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const functions = kvm.functions || (typeof kvm === "object" && !Array.isArray(kvm) ? kvm : null);
|
|
66
|
+
if (!functions || typeof functions !== "object") {
|
|
67
|
+
throw new Error("Expected .kvm input to contain a functions object");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const entry = options.entry || kvm.entry || "__main__";
|
|
71
|
+
const entryFunc = functions[entry];
|
|
72
|
+
if (!entryFunc) {
|
|
73
|
+
throw new Error(`kVM entry relation '${entry}' not found in program`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const inputPattern = options.inputPattern || entryFunc.inputPattern || [];
|
|
77
|
+
const outputPattern = options.outputPattern || entryFunc.outputPattern || [];
|
|
78
|
+
|
|
79
|
+
resetTagIds();
|
|
80
|
+
const profile = Boolean(options.profile ?? (process.env.K_PROFILE === "1" || process.env.PROFILE === "1"));
|
|
81
|
+
const { assembly, entryName, profileFunctions } = compileKVMModuleToARM64(entry, functions, {
|
|
82
|
+
inputPattern,
|
|
83
|
+
outputPattern,
|
|
84
|
+
profile
|
|
85
|
+
});
|
|
86
|
+
const tags = getTagEntries();
|
|
87
|
+
const metadataC = emitMetadataC(tags, inputPattern, outputPattern, profileFunctions);
|
|
88
|
+
|
|
89
|
+
if (options.emit === "assembly" || options.assembly) {
|
|
90
|
+
return {
|
|
91
|
+
assembly,
|
|
92
|
+
metadataC,
|
|
93
|
+
entryName,
|
|
94
|
+
tags,
|
|
95
|
+
inputPattern,
|
|
96
|
+
outputPattern
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Compile to native ELF executable using gcc
|
|
101
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "k-arm64-"));
|
|
102
|
+
const asmPath = path.join(tmpDir, "prog.s");
|
|
103
|
+
const metaPath = path.join(tmpDir, "meta.c");
|
|
104
|
+
const outPath = options.outputPath || path.join(tmpDir, "prog");
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
fs.writeFileSync(asmPath, assembly, "utf8");
|
|
108
|
+
fs.writeFileSync(metaPath, metadataC, "utf8");
|
|
109
|
+
|
|
110
|
+
const gcc = options.gcc || process.env.CC || "gcc";
|
|
111
|
+
const optLevel = options.optLevel ?? "-O2";
|
|
112
|
+
const args = [
|
|
113
|
+
optLevel,
|
|
114
|
+
`-DENTRY_NAME=${entryName}`,
|
|
115
|
+
asmPath,
|
|
116
|
+
metaPath,
|
|
117
|
+
RUNTIME_C_PATH,
|
|
118
|
+
KRT_C_PATH,
|
|
119
|
+
`-I${KRT_H_DIR}`,
|
|
120
|
+
"-o",
|
|
121
|
+
outPath
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
execFileSync(gcc, args, { stdio: "pipe" });
|
|
125
|
+
|
|
126
|
+
if (options.outputPath) {
|
|
127
|
+
return outPath;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const binaryBuffer = fs.readFileSync(outPath);
|
|
131
|
+
return binaryBuffer;
|
|
132
|
+
} finally {
|
|
133
|
+
try {
|
|
134
|
+
if (fs.existsSync(asmPath)) fs.unlinkSync(asmPath);
|
|
135
|
+
if (fs.existsSync(metaPath)) fs.unlinkSync(metaPath);
|
|
136
|
+
if (!options.outputPath && fs.existsSync(outPath)) fs.unlinkSync(outPath);
|
|
137
|
+
if (!options.outputPath) fs.rmdirSync(tmpDir);
|
|
138
|
+
} catch {
|
|
139
|
+
// Ignore cleanup errors in temporary directory
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function compileARM64ArtifactFromObject(object, options = {}) {
|
|
145
|
+
const kvm = objectToKVMArtifact(object, options.entry, null, options);
|
|
146
|
+
return compileARM64ArtifactFromKVM(kvm, options);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function compileARM64Artifact(source, options = {}) {
|
|
150
|
+
const libraries = (options.libraries || []).map((lib) => {
|
|
151
|
+
if (lib?.rels || lib?.meta || lib?.relAlias) return lib;
|
|
152
|
+
if (typeof lib === "string") {
|
|
153
|
+
const ext = path.extname(lib).toLowerCase();
|
|
154
|
+
if (ext === ".k") {
|
|
155
|
+
return loadLibrary(compileLibrary(fs.readFileSync(lib, "utf8"), { source: lib }));
|
|
156
|
+
}
|
|
157
|
+
return loadLibrary(decodeObject(fs.readFileSync(lib)));
|
|
158
|
+
}
|
|
159
|
+
if (Buffer.isBuffer(lib)) {
|
|
160
|
+
return loadLibrary(decodeObject(lib));
|
|
161
|
+
}
|
|
162
|
+
return lib;
|
|
163
|
+
});
|
|
164
|
+
const preamble = buildExportPreamble(options.exports || options.exportSpecs || [], libraries);
|
|
165
|
+
const fullSource = preamble + source;
|
|
166
|
+
|
|
167
|
+
const objBuffer = compileObjectBuffer(fullSource, {
|
|
168
|
+
libraries,
|
|
169
|
+
source: options.source || null
|
|
170
|
+
});
|
|
171
|
+
const object = decodeObject(objBuffer);
|
|
172
|
+
return compileARM64ArtifactFromObject(object, options);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function runARM64Artifact(executablePathOrBuffer, inputBuffer, options = {}) {
|
|
176
|
+
let execPath = executablePathOrBuffer;
|
|
177
|
+
let tmpFile = null;
|
|
178
|
+
|
|
179
|
+
if (Buffer.isBuffer(executablePathOrBuffer)) {
|
|
180
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "k-arm64-run-"));
|
|
181
|
+
tmpFile = path.join(tmpDir, "k-exec");
|
|
182
|
+
fs.writeFileSync(tmpFile, executablePathOrBuffer, { mode: 0o755 });
|
|
183
|
+
execPath = tmpFile;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
const args = [];
|
|
188
|
+
if (options.json) {
|
|
189
|
+
args.push("--json");
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const result = spawnSync(execPath, args, {
|
|
193
|
+
input: inputBuffer,
|
|
194
|
+
maxBuffer: options.maxBuffer || 64 * 1024 * 1024
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
if (result.error) {
|
|
198
|
+
throw result.error;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (result.status !== 0) {
|
|
202
|
+
const stderr = result.stderr?.toString("utf8") || "";
|
|
203
|
+
throw new Error(`ARM64 executable failed with exit status ${result.status}: ${stderr}`);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (options.json) {
|
|
207
|
+
return result.stdout.toString("utf8");
|
|
208
|
+
}
|
|
209
|
+
return result.stdout;
|
|
210
|
+
} finally {
|
|
211
|
+
if (tmpFile) {
|
|
212
|
+
try {
|
|
213
|
+
fs.unlinkSync(tmpFile);
|
|
214
|
+
fs.rmdirSync(path.dirname(tmpFile));
|
|
215
|
+
} catch {
|
|
216
|
+
// Ignore temporary cleanup errors
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export default {
|
|
223
|
+
ARTIFACT_FORMAT,
|
|
224
|
+
ARTIFACT_VERSION,
|
|
225
|
+
compileARM64ArtifactFromKVM,
|
|
226
|
+
compileARM64ArtifactFromObject,
|
|
227
|
+
compileARM64Artifact,
|
|
228
|
+
runARM64Artifact
|
|
229
|
+
};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
import { compileLibrary, decodeObject, loadLibrary } from "../../../backend-api.mjs";
|
|
5
|
+
import {
|
|
6
|
+
compileARM64Artifact,
|
|
7
|
+
compileARM64ArtifactFromKVM,
|
|
8
|
+
compileARM64ArtifactFromObject
|
|
9
|
+
} from "./arm64.mjs";
|
|
10
|
+
|
|
11
|
+
export function readAll(stream) {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const chunks = [];
|
|
14
|
+
stream.on("data", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
|
|
15
|
+
stream.on("end", () => resolve(Buffer.concat(chunks)));
|
|
16
|
+
stream.on("error", reject);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function parseCompileOptions(args) {
|
|
21
|
+
const libraries = [];
|
|
22
|
+
const exportSpecs = [];
|
|
23
|
+
let loadedLibrary = false;
|
|
24
|
+
|
|
25
|
+
while (args.length > 0) {
|
|
26
|
+
if (args[0] === "--") {
|
|
27
|
+
args.shift();
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
if (args[0] === "--lib") {
|
|
31
|
+
if (loadedLibrary) throw new Error("--lib may only be specified once");
|
|
32
|
+
args.shift();
|
|
33
|
+
const libPath = args.shift();
|
|
34
|
+
if (!libPath) throw new Error("--lib requires a file argument");
|
|
35
|
+
const ext = path.extname(libPath).toLowerCase();
|
|
36
|
+
if (ext === ".k") {
|
|
37
|
+
libraries.push(loadLibrary(compileLibrary(fs.readFileSync(libPath, "utf8"), { source: libPath })));
|
|
38
|
+
} else {
|
|
39
|
+
libraries.push(loadLibrary(decodeObject(fs.readFileSync(libPath))));
|
|
40
|
+
}
|
|
41
|
+
loadedLibrary = true;
|
|
42
|
+
} else if (args[0] === "--export") {
|
|
43
|
+
args.shift();
|
|
44
|
+
const spec = args.shift();
|
|
45
|
+
if (!spec) throw new Error("--export requires a spec argument (name or libname:localname)");
|
|
46
|
+
exportSpecs.push(spec);
|
|
47
|
+
} else if (args[0].startsWith("--")) {
|
|
48
|
+
break;
|
|
49
|
+
} else {
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return { libraries, exportSpecs };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function fileInputType(filePath) {
|
|
58
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
59
|
+
if (ext === ".ko") return "ko";
|
|
60
|
+
if (ext === ".kvm") return "kvm";
|
|
61
|
+
if (ext === ".klib") return "klib";
|
|
62
|
+
return "source-file";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function resolveProgramInput(args, { allowStdinSource = false } = {}) {
|
|
66
|
+
const inputArg = args.shift() ?? null;
|
|
67
|
+
if (inputArg == null) {
|
|
68
|
+
if (!allowStdinSource) throw new Error("Missing script argument");
|
|
69
|
+
return { kind: "stdin-source", sourceName: "<stdin>" };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const ext = path.extname(inputArg).toLowerCase();
|
|
73
|
+
if (fs.existsSync(inputArg)) {
|
|
74
|
+
const kind = fileInputType(inputArg);
|
|
75
|
+
if (kind === "klib") {
|
|
76
|
+
throw new Error("Cannot compile a .klib library to ARM64 without a main relation; load it with --lib.");
|
|
77
|
+
}
|
|
78
|
+
return { kind, path: inputArg, sourceName: inputArg };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if ([".k", ".ko", ".kvm", ".klib"].includes(ext)) {
|
|
82
|
+
throw new Error(`Input file not found: ${inputArg}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return { kind: "inline-source", source: inputArg, sourceName: "<inline>" };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export async function compileProgramInput(
|
|
89
|
+
input,
|
|
90
|
+
{
|
|
91
|
+
libraries = [],
|
|
92
|
+
exportSpecs = [],
|
|
93
|
+
stdin = null,
|
|
94
|
+
inputEnvelopePattern = null,
|
|
95
|
+
entry = null,
|
|
96
|
+
emit = null,
|
|
97
|
+
outputPath = null
|
|
98
|
+
} = {}
|
|
99
|
+
) {
|
|
100
|
+
const compileOptions = {
|
|
101
|
+
libraries,
|
|
102
|
+
exports: exportSpecs,
|
|
103
|
+
inputEnvelopePattern,
|
|
104
|
+
entry,
|
|
105
|
+
emit,
|
|
106
|
+
outputPath
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
if (input.kind === "inline-source") {
|
|
110
|
+
return compileARM64Artifact(input.source, {
|
|
111
|
+
...compileOptions,
|
|
112
|
+
source: input.sourceName
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (input.kind === "stdin-source") {
|
|
117
|
+
if (!stdin) throw new Error("stdin source requested without a stdin stream");
|
|
118
|
+
const source = (await readAll(stdin)).toString("utf8");
|
|
119
|
+
return compileARM64Artifact(source, {
|
|
120
|
+
...compileOptions,
|
|
121
|
+
source: input.sourceName
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (input.kind === "source-file") {
|
|
126
|
+
return compileARM64Artifact(fs.readFileSync(input.path, "utf8"), {
|
|
127
|
+
...compileOptions,
|
|
128
|
+
source: input.sourceName
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (input.kind === "ko") {
|
|
133
|
+
return compileARM64ArtifactFromObject(
|
|
134
|
+
decodeObject(fs.readFileSync(input.path)),
|
|
135
|
+
compileOptions
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (input.kind === "kvm") {
|
|
140
|
+
return compileARM64ArtifactFromKVM(
|
|
141
|
+
JSON.parse(fs.readFileSync(input.path, "utf8")),
|
|
142
|
+
compileOptions
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
throw new Error(`Unsupported input kind: ${input.kind}`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export default {
|
|
150
|
+
compileProgramInput,
|
|
151
|
+
fileInputType,
|
|
152
|
+
parseCompileOptions,
|
|
153
|
+
readAll,
|
|
154
|
+
resolveProgramInput
|
|
155
|
+
};
|