bonsai-js 1.0.0 → 1.2.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 +20 -0
- package/README.md +24 -4
- package/dist/artifact.d.mts +47 -0
- package/dist/artifact.mjs +139 -0
- package/dist/artifact.mjs.map +1 -0
- package/dist/builtins/index.d.mts +91 -0
- package/dist/builtins/index.mjs +93 -0
- package/dist/builtins/index.mjs.map +1 -0
- package/dist/check/bind.mjs +117 -0
- package/dist/check/bind.mjs.map +1 -0
- package/dist/check/checker.mjs +34 -120
- package/dist/check/checker.mjs.map +1 -1
- package/dist/compile/compiler.mjs +2 -3
- package/dist/compile/compiler.mjs.map +1 -1
- package/dist/declared.mjs +8 -1
- package/dist/declared.mjs.map +1 -1
- package/dist/digest.mjs +109 -0
- package/dist/digest.mjs.map +1 -0
- package/dist/environment.d.mts +14 -1
- package/dist/environment.mjs +65 -315
- package/dist/environment.mjs.map +1 -1
- package/dist/errors.d.mts +21 -2
- package/dist/errors.mjs +17 -1
- package/dist/errors.mjs.map +1 -1
- package/dist/features.mjs +3 -3
- package/dist/features.mjs.map +1 -1
- package/dist/functions/builtins.mjs +551 -474
- package/dist/functions/builtins.mjs.map +1 -1
- package/dist/functions/define.mjs +53 -11
- package/dist/functions/define.mjs.map +1 -1
- package/dist/functions/descriptions.mjs +110 -0
- package/dist/functions/descriptions.mjs.map +1 -0
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +3 -2
- package/dist/lite/index.d.mts +4 -3
- package/dist/lite/index.mjs +3 -2
- package/dist/lite/index.mjs.map +1 -1
- package/dist/load.mjs +307 -0
- package/dist/load.mjs.map +1 -0
- package/dist/program.mjs +321 -0
- package/dist/program.mjs.map +1 -0
- package/dist/query/index.mjs +1 -1
- package/dist/runtime/core.d.mts +18 -0
- package/dist/runtime/core.mjs +31 -0
- package/dist/runtime/core.mjs.map +1 -0
- package/dist/runtime/create.d.mts +61 -0
- package/dist/runtime/create.mjs +76 -0
- package/dist/runtime/create.mjs.map +1 -0
- package/dist/runtime/index.d.mts +24 -0
- package/dist/runtime/index.mjs +34 -0
- package/dist/runtime/index.mjs.map +1 -0
- package/dist/service/index.mjs +12 -8
- package/dist/service/index.mjs.map +1 -1
- package/dist/syntax/parser.mjs +1 -1
- package/dist/syntax/printer.mjs +1 -1
- package/dist/types.mjs +103 -23
- package/dist/types.mjs.map +1 -1
- package/dist/version.mjs +7 -0
- package/dist/version.mjs.map +1 -0
- package/package.json +26 -2
package/dist/load.mjs
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { BonsaiArtifactError, BonsaiError } from "./errors.mjs";
|
|
2
|
+
import { assertType } from "./functions/define.mjs";
|
|
3
|
+
import { forEachChild } from "./syntax/ast.mjs";
|
|
4
|
+
import { bindImplicit } from "./check/bind.mjs";
|
|
5
|
+
import { parse } from "./syntax/parser.mjs";
|
|
6
|
+
import { programRunner, warmZones } from "./program.mjs";
|
|
7
|
+
import { encodeType, lengthPrefixed } from "./digest.mjs";
|
|
8
|
+
import { MAX_EXPECT_NODES, artifactDigest, treeNames } from "./artifact.mjs";
|
|
9
|
+
//#region src/load.ts
|
|
10
|
+
const ARTIFACT_KEYS = /* @__PURE__ */ new Set([
|
|
11
|
+
"bonsai",
|
|
12
|
+
"by",
|
|
13
|
+
"source",
|
|
14
|
+
"plans",
|
|
15
|
+
"expect",
|
|
16
|
+
"guard",
|
|
17
|
+
"async",
|
|
18
|
+
"digest"
|
|
19
|
+
]);
|
|
20
|
+
/** The nesting assertType accepts. */
|
|
21
|
+
const MAX_TYPE_DEPTH = 64;
|
|
22
|
+
/** A type object holds its kind and at most two other fields (`fields` and `rest`). */
|
|
23
|
+
const MAX_TYPE_KEYS = 3;
|
|
24
|
+
/**
|
|
25
|
+
* A plan holds a name position, a name, and fewer overload indices than the
|
|
26
|
+
* function has overloads (built-ins have at most five, host functions one);
|
|
27
|
+
* this bounds how much of a hostile entry is read.
|
|
28
|
+
*/
|
|
29
|
+
const MAX_PLAN_LENGTH = 34;
|
|
30
|
+
/**
|
|
31
|
+
* The errors the current readArtifact call raises itself, as opposed to
|
|
32
|
+
* anything a host object throws while it is read (including a loader error
|
|
33
|
+
* from another call, rethrown by a Proxy trap). Reads nest when a trap loads
|
|
34
|
+
* another artifact, so each call has its own set.
|
|
35
|
+
*/
|
|
36
|
+
let raisedHere;
|
|
37
|
+
const fail = (reason, message, cause) => {
|
|
38
|
+
const error = new BonsaiArtifactError(reason, message, cause === void 0 ? {} : { cause });
|
|
39
|
+
raisedHere?.add(error);
|
|
40
|
+
throw error;
|
|
41
|
+
};
|
|
42
|
+
function notArtifact() {
|
|
43
|
+
const error = /* @__PURE__ */ new TypeError("An artifact must be an object made by toArtifact()");
|
|
44
|
+
raisedHere?.add(error);
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Reads the own properties of an object exactly once each, through their
|
|
49
|
+
* descriptors, so no getter runs (a Proxy's traps run once per property).
|
|
50
|
+
* More than `maxKeys` keys, accessors, and symbol keys are refused.
|
|
51
|
+
*/
|
|
52
|
+
function ownData(value, what, maxKeys, known = /* @__PURE__ */ new Map()) {
|
|
53
|
+
const keys = Reflect.ownKeys(value);
|
|
54
|
+
if (keys.length > maxKeys) fail("limit", `${what} has more than ${maxKeys} keys`);
|
|
55
|
+
const out = /* @__PURE__ */ new Map();
|
|
56
|
+
for (const key of keys) {
|
|
57
|
+
if (typeof key !== "string") return fail("shape", `${what} has a symbol key`);
|
|
58
|
+
if (known.has(key)) {
|
|
59
|
+
out.set(key, known.get(key));
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
|
|
63
|
+
if (descriptor === void 0) continue;
|
|
64
|
+
if (!("value" in descriptor)) fail("shape", `${what}.${key} is an accessor`);
|
|
65
|
+
out.set(key, descriptor.value);
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
/** The elements of an array, read once each, its length checked against `max` before any element is read. */
|
|
70
|
+
function arrayData(value, max, what, tooLong) {
|
|
71
|
+
if (!Array.isArray(value)) return fail("shape", `${what} must be an array`);
|
|
72
|
+
const length = Reflect.getOwnPropertyDescriptor(value, "length")?.value;
|
|
73
|
+
if (typeof length !== "number") return fail("shape", `${what} has no length`);
|
|
74
|
+
if (length > max) return fail(tooLong, `${what} has more than ${max} entries`);
|
|
75
|
+
const out = [];
|
|
76
|
+
for (let i = 0; i < length; i++) {
|
|
77
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(value, String(i));
|
|
78
|
+
if (descriptor !== void 0 && !("value" in descriptor)) fail("shape", `${what}[${i}] is an accessor`);
|
|
79
|
+
out.push(descriptor?.value);
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* A copy of an expected type, read by its kind so only a type's own fields are
|
|
85
|
+
* read, with field records as null-prototype objects (so a `__proto__` key
|
|
86
|
+
* stays a field). Type nodes are counted along every path, as toArtifact
|
|
87
|
+
* counts them, so shared subtrees cannot hide its size.
|
|
88
|
+
*/
|
|
89
|
+
function copyType(value) {
|
|
90
|
+
let nodes = 0;
|
|
91
|
+
const copy = (node, depth) => {
|
|
92
|
+
if (typeof node !== "object" || node === null || Array.isArray(node)) return fail("shape", "The artifact's expected type must be a type built with t");
|
|
93
|
+
if (++nodes > 1e5) fail("limit", `The artifact's expected type has more than ${MAX_EXPECT_NODES} type nodes`);
|
|
94
|
+
if (depth > MAX_TYPE_DEPTH) fail("shape", `The artifact's expected type nests deeper than ${MAX_TYPE_DEPTH}`);
|
|
95
|
+
const data = ownData(node, "expect", MAX_TYPE_KEYS);
|
|
96
|
+
const kind = data.get("kind");
|
|
97
|
+
switch (kind) {
|
|
98
|
+
case "list": return Object.freeze({
|
|
99
|
+
kind,
|
|
100
|
+
element: copy(data.get("element"), depth + 1)
|
|
101
|
+
});
|
|
102
|
+
case "union": {
|
|
103
|
+
const members = arrayData(data.get("types"), MAX_EXPECT_NODES - nodes, "expect.types", "limit");
|
|
104
|
+
return Object.freeze({
|
|
105
|
+
kind,
|
|
106
|
+
types: Object.freeze(members.map((m) => copy(m, depth + 1)))
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
case "map": {
|
|
110
|
+
const record = data.get("fields");
|
|
111
|
+
if (typeof record !== "object" || record === null) return fail("shape", "The artifact's expected type has map fields that are not an object");
|
|
112
|
+
const fields = Object.create(null);
|
|
113
|
+
for (const [key, field] of ownData(record, "expect.fields", MAX_EXPECT_NODES - nodes)) Object.defineProperty(fields, key, {
|
|
114
|
+
value: copy(field, depth + 1),
|
|
115
|
+
enumerable: true
|
|
116
|
+
});
|
|
117
|
+
const rest = data.get("rest");
|
|
118
|
+
return Object.freeze({
|
|
119
|
+
kind,
|
|
120
|
+
fields: Object.freeze(fields),
|
|
121
|
+
...rest === void 0 ? {} : { rest: copy(rest, depth + 1) }
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
case "literal": return Object.freeze({
|
|
125
|
+
kind,
|
|
126
|
+
value: data.get("value")
|
|
127
|
+
});
|
|
128
|
+
case "opaque": return Object.freeze({
|
|
129
|
+
kind,
|
|
130
|
+
name: data.get("name")
|
|
131
|
+
});
|
|
132
|
+
default: return Object.freeze({ kind });
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
const type = copy(value, 0);
|
|
136
|
+
try {
|
|
137
|
+
assertType(type, "The artifact's expected type");
|
|
138
|
+
} catch (error) {
|
|
139
|
+
return fail("shape", error.message, error);
|
|
140
|
+
}
|
|
141
|
+
return type;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* An artifact's fields, copied once and checked for shape and size before
|
|
145
|
+
* anything is parsed. A value that is not an artifact is a TypeError, and so
|
|
146
|
+
* is anything thrown while reading it (a Proxy trap), with the thrown value as
|
|
147
|
+
* its cause.
|
|
148
|
+
*/
|
|
149
|
+
function readArtifact(value, settings) {
|
|
150
|
+
const outer = raisedHere;
|
|
151
|
+
const mine = /* @__PURE__ */ new WeakSet();
|
|
152
|
+
raisedHere = mine;
|
|
153
|
+
try {
|
|
154
|
+
return read(value, settings);
|
|
155
|
+
} catch (error) {
|
|
156
|
+
if (typeof error === "object" && error !== null && mine.has(error)) throw error;
|
|
157
|
+
throw new TypeError("The artifact could not be read", { cause: error });
|
|
158
|
+
} finally {
|
|
159
|
+
raisedHere = outer;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function read(value, settings) {
|
|
163
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) notArtifact();
|
|
164
|
+
const formatField = Reflect.getOwnPropertyDescriptor(value, "bonsai");
|
|
165
|
+
if (formatField === void 0) return notArtifact();
|
|
166
|
+
if (!("value" in formatField)) fail("shape", "The artifact format is an accessor");
|
|
167
|
+
const format = formatField.value;
|
|
168
|
+
if (typeof format !== "number" || !Number.isSafeInteger(format) || format < 1) fail("shape", "The artifact format must be a positive integer");
|
|
169
|
+
if (format !== 1) fail("version", `Artifact format ${String(format)} is not supported (this runtime reads format 1)`);
|
|
170
|
+
const data = ownData(value, "The artifact", ARTIFACT_KEYS.size, /* @__PURE__ */ new Map([["bonsai", format]]));
|
|
171
|
+
for (const key of data.keys()) if (!ARTIFACT_KEYS.has(key)) fail("version", `The artifact has a field "${key}" this runtime does not know`);
|
|
172
|
+
const string = (key) => {
|
|
173
|
+
const field = data.get(key);
|
|
174
|
+
return typeof field === "string" ? field : fail("shape", `The artifact's ${key} must be a string`);
|
|
175
|
+
};
|
|
176
|
+
const flag = (key) => {
|
|
177
|
+
const field = data.get(key);
|
|
178
|
+
return typeof field === "boolean" ? field : fail("shape", `The artifact's ${key} must be true or false`);
|
|
179
|
+
};
|
|
180
|
+
const source = string("source");
|
|
181
|
+
if (source.length > settings.parseLimits.maxSourceLength) fail("limit", `The artifact's source is longer than ${settings.parseLimits.maxSourceLength} characters`);
|
|
182
|
+
const plans = arrayData(data.get("plans"), settings.parseLimits.maxNodes, "plans", "limit").map((entry, i) => {
|
|
183
|
+
const [start, name, ...candidates] = arrayData(entry, MAX_PLAN_LENGTH, `plans[${i}]`, "plan");
|
|
184
|
+
if (typeof start !== "number" || typeof name !== "string" || !candidates.every((c) => typeof c === "number")) fail("shape", `plans[${i}] must be [nameStart, name, ...overload indices]`);
|
|
185
|
+
return [
|
|
186
|
+
start,
|
|
187
|
+
name,
|
|
188
|
+
...candidates
|
|
189
|
+
];
|
|
190
|
+
});
|
|
191
|
+
const expect = data.has("expect") ? copyType(data.get("expect")) : void 0;
|
|
192
|
+
return {
|
|
193
|
+
bonsai: 1,
|
|
194
|
+
by: string("by"),
|
|
195
|
+
source,
|
|
196
|
+
plans,
|
|
197
|
+
...expect === void 0 ? {} : { expect },
|
|
198
|
+
guard: flag("guard"),
|
|
199
|
+
async: flag("async"),
|
|
200
|
+
digest: string("digest")
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/** The calls of a bound tree by where their names start. */
|
|
204
|
+
function callsByStart(root) {
|
|
205
|
+
const calls = /* @__PURE__ */ new Map();
|
|
206
|
+
const stack = [root];
|
|
207
|
+
while (stack.length > 0) {
|
|
208
|
+
const node = stack.pop();
|
|
209
|
+
if (node.type === "Call" && node.nameStart !== void 0) calls.set(node.nameStart, node);
|
|
210
|
+
forEachChild(node, (child) => {
|
|
211
|
+
stack.push(child);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return calls;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Loads an artifact against a runtime's definitions, refusing it with a
|
|
218
|
+
* BonsaiArtifactError when it does not reproduce the checked program exactly:
|
|
219
|
+
* a different format, source, plan, function, or declared variable type.
|
|
220
|
+
*/
|
|
221
|
+
function loadArtifact(artifact, settings, expect) {
|
|
222
|
+
const outer = raisedHere;
|
|
223
|
+
raisedHere = void 0;
|
|
224
|
+
try {
|
|
225
|
+
return loadRead(artifact, settings, expect);
|
|
226
|
+
} finally {
|
|
227
|
+
raisedHere = outer;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function loadRead(artifact, settings, expect) {
|
|
231
|
+
const { source } = artifact;
|
|
232
|
+
let parsed;
|
|
233
|
+
try {
|
|
234
|
+
parsed = parse(source, settings.parseLimits);
|
|
235
|
+
} catch (error) {
|
|
236
|
+
if (!(error instanceof BonsaiError)) throw error;
|
|
237
|
+
return fail(error.code === "SYNTAX" ? "syntax" : "limit", `The artifact's source cannot be parsed: ${error.message}`, error);
|
|
238
|
+
}
|
|
239
|
+
const lookup = (name) => settings.host.get(name) ?? settings.builtins.get(name);
|
|
240
|
+
const names = treeNames(parsed);
|
|
241
|
+
for (const name of names.functions) if (lookup(name) === void 0) fail("function", `The artifact calls ${name}(), which this runtime does not define`);
|
|
242
|
+
if (settings.strict) {
|
|
243
|
+
for (const name of names.variables) if (settings.variables === void 0 || !Object.hasOwn(settings.variables, name)) fail("variable", `The artifact reads ${name}, which this strict runtime does not declare`);
|
|
244
|
+
}
|
|
245
|
+
const { digest, ...fields } = artifact;
|
|
246
|
+
if (artifactDigest(fields, parsed, lookup, settings.variables) !== digest) fail("digest", "The artifact was made for different definitions than this runtime has; make it again from its source");
|
|
247
|
+
const bound = bindImplicit(parsed, lookup);
|
|
248
|
+
if (bound.problems.length > 0) fail("binding", bound.problems[0].message);
|
|
249
|
+
const root = bound.root;
|
|
250
|
+
const calls = /* @__PURE__ */ new Map();
|
|
251
|
+
const byStart = callsByStart(root);
|
|
252
|
+
for (const call of byStart.values()) {
|
|
253
|
+
const def = lookup(call.name);
|
|
254
|
+
calls.set(call, {
|
|
255
|
+
def,
|
|
256
|
+
candidates: def.overloads.map((_, i) => i)
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
let previous = -1;
|
|
260
|
+
for (const [start, name, ...candidates] of artifact.plans) {
|
|
261
|
+
const call = byStart.get(start);
|
|
262
|
+
if (start <= previous || call === void 0 || call.name !== name) fail("plan", `The artifact's plan for ${name}() at ${start} matches no call`);
|
|
263
|
+
previous = start;
|
|
264
|
+
const def = lookup(name);
|
|
265
|
+
const count = def.overloads.length;
|
|
266
|
+
if (candidates.length === 0 || candidates.length >= count || !candidates.every((c, i) => Number.isSafeInteger(c) && c >= 0 && c < count && (i === 0 || c > candidates[i - 1]))) fail("plan", `The artifact's plan for ${name}() at ${start} is not a narrower set of its overloads`);
|
|
267
|
+
calls.set(call, {
|
|
268
|
+
def,
|
|
269
|
+
candidates
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
if (expect !== void 0 && (artifact.expect === void 0 || encodeType(artifact.expect) !== encodeType(expect))) fail("expect", "The artifact was not compiled for the expected type passed to load()");
|
|
273
|
+
const analysis = {
|
|
274
|
+
root,
|
|
275
|
+
calls,
|
|
276
|
+
async: artifact.async
|
|
277
|
+
};
|
|
278
|
+
warmZones(analysis);
|
|
279
|
+
return {
|
|
280
|
+
source,
|
|
281
|
+
analysis,
|
|
282
|
+
guard: expect ?? (artifact.guard ? artifact.expect : void 0)
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
/** A key equal for two artifacts exactly when every field is (read with readArtifact). */
|
|
286
|
+
function artifactKey(artifact) {
|
|
287
|
+
return [
|
|
288
|
+
lengthPrefixed(artifact.digest),
|
|
289
|
+
lengthPrefixed(artifact.by),
|
|
290
|
+
lengthPrefixed(artifact.source),
|
|
291
|
+
lengthPrefixed(JSON.stringify(artifact.plans)),
|
|
292
|
+
artifact.expect === void 0 ? "-" : lengthPrefixed(JSON.stringify(artifact.expect)),
|
|
293
|
+
artifact.guard ? "g" : "-",
|
|
294
|
+
artifact.async ? "a" : "-"
|
|
295
|
+
].join("");
|
|
296
|
+
}
|
|
297
|
+
/** Runs a loaded artifact as a program does. */
|
|
298
|
+
function loadedRunner(loaded, settings) {
|
|
299
|
+
return programRunner({
|
|
300
|
+
...loaded,
|
|
301
|
+
settings
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
//#endregion
|
|
305
|
+
export { artifactKey, loadArtifact, loadedRunner, readArtifact };
|
|
306
|
+
|
|
307
|
+
//# sourceMappingURL=load.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.mjs","names":[],"sources":["../src/load.ts"],"sourcesContent":["import {\n ARTIFACT_FORMAT,\n MAX_EXPECT_NODES,\n artifactDigest,\n treeNames,\n type Artifact,\n type Plan,\n} from './artifact.js'\nimport { bindImplicit } from './check/bind.js'\nimport type { CallPlan } from './check/checker.js'\nimport { encodeType, lengthPrefixed } from './digest.js'\nimport type { Settings } from './environment.js'\nimport { BonsaiArtifactError, BonsaiError, type ArtifactProblem } from './errors.js'\nimport { assertType, type FunctionDef } from './functions/define.js'\nimport { programRunner, warmZones, type ProgramAnalysis } from './program.js'\nimport { forEachChild, type CallNode, type Node } from './syntax/ast.js'\nimport { parse } from './syntax/parser.js'\nimport type { Type } from './types.js'\n\nconst ARTIFACT_KEYS: ReadonlySet<string> = new Set([\n 'bonsai',\n 'by',\n 'source',\n 'plans',\n 'expect',\n 'guard',\n 'async',\n 'digest',\n])\n\n/** The nesting assertType accepts. */\nconst MAX_TYPE_DEPTH = 64\n\n/** A type object holds its kind and at most two other fields (`fields` and `rest`). */\nconst MAX_TYPE_KEYS = 3\n\n/**\n * A plan holds a name position, a name, and fewer overload indices than the\n * function has overloads (built-ins have at most five, host functions one);\n * this bounds how much of a hostile entry is read.\n */\nconst MAX_PLAN_LENGTH = 34\n\n/**\n * The errors the current readArtifact call raises itself, as opposed to\n * anything a host object throws while it is read (including a loader error\n * from another call, rethrown by a Proxy trap). Reads nest when a trap loads\n * another artifact, so each call has its own set.\n */\nlet raisedHere: WeakSet<WeakKey> | undefined\n\nconst fail = (reason: ArtifactProblem, message: string, cause?: unknown): never => {\n const error = new BonsaiArtifactError(reason, message, cause === undefined ? {} : { cause })\n raisedHere?.add(error)\n throw error\n}\n\nfunction notArtifact(): never {\n const error = new TypeError('An artifact must be an object made by toArtifact()')\n raisedHere?.add(error)\n throw error\n}\n\n/**\n * Reads the own properties of an object exactly once each, through their\n * descriptors, so no getter runs (a Proxy's traps run once per property).\n * More than `maxKeys` keys, accessors, and symbol keys are refused.\n */\nfunction ownData(\n value: object,\n what: string,\n maxKeys: number,\n known: ReadonlyMap<string, unknown> = new Map(),\n): Map<string, unknown> {\n const keys = Reflect.ownKeys(value)\n if (keys.length > maxKeys) fail('limit', `${what} has more than ${maxKeys} keys`)\n const out = new Map<string, unknown>()\n for (const key of keys) {\n if (typeof key !== 'string') return fail('shape', `${what} has a symbol key`)\n // Fields read already are not read again, so each trap runs once per field.\n if (known.has(key)) {\n out.set(key, known.get(key))\n continue\n }\n const descriptor = Reflect.getOwnPropertyDescriptor(value, key)\n if (descriptor === undefined) continue\n if (!('value' in descriptor)) fail('shape', `${what}.${key} is an accessor`)\n out.set(key, descriptor.value)\n }\n return out\n}\n\n/** The elements of an array, read once each, its length checked against `max` before any element is read. */\nfunction arrayData(value: unknown, max: number, what: string, tooLong: ArtifactProblem): unknown[] {\n if (!Array.isArray(value)) return fail('shape', `${what} must be an array`)\n const length = Reflect.getOwnPropertyDescriptor(value, 'length')?.value as unknown\n if (typeof length !== 'number') return fail('shape', `${what} has no length`)\n if (length > max) return fail(tooLong, `${what} has more than ${max} entries`)\n const out: unknown[] = []\n for (let i = 0; i < length; i++) {\n const descriptor = Reflect.getOwnPropertyDescriptor(value, String(i))\n if (descriptor !== undefined && !('value' in descriptor))\n fail('shape', `${what}[${i}] is an accessor`)\n out.push(descriptor?.value)\n }\n return out\n}\n\n/**\n * A copy of an expected type, read by its kind so only a type's own fields are\n * read, with field records as null-prototype objects (so a `__proto__` key\n * stays a field). Type nodes are counted along every path, as toArtifact\n * counts them, so shared subtrees cannot hide its size.\n */\nfunction copyType(value: unknown): Type {\n let nodes = 0\n const copy = (node: unknown, depth: number): unknown => {\n if (typeof node !== 'object' || node === null || Array.isArray(node))\n return fail('shape', \"The artifact's expected type must be a type built with t\")\n if (++nodes > MAX_EXPECT_NODES)\n fail('limit', `The artifact's expected type has more than ${MAX_EXPECT_NODES} type nodes`)\n if (depth > MAX_TYPE_DEPTH)\n fail('shape', `The artifact's expected type nests deeper than ${MAX_TYPE_DEPTH}`)\n const data = ownData(node, 'expect', MAX_TYPE_KEYS)\n const kind = data.get('kind')\n switch (kind) {\n case 'list':\n return Object.freeze({ kind, element: copy(data.get('element'), depth + 1) })\n case 'union': {\n // Every member is at least one more node, so a longer list cannot fit.\n const members = arrayData(\n data.get('types'),\n MAX_EXPECT_NODES - nodes,\n 'expect.types',\n 'limit',\n )\n return Object.freeze({ kind, types: Object.freeze(members.map((m) => copy(m, depth + 1))) })\n }\n case 'map': {\n const record = data.get('fields')\n if (typeof record !== 'object' || record === null)\n return fail('shape', \"The artifact's expected type has map fields that are not an object\")\n const fields = Object.create(null) as Record<string, unknown>\n for (const [key, field] of ownData(record, 'expect.fields', MAX_EXPECT_NODES - nodes))\n Object.defineProperty(fields, key, { value: copy(field, depth + 1), enumerable: true })\n const rest = data.get('rest')\n return Object.freeze({\n kind,\n fields: Object.freeze(fields),\n ...(rest === undefined ? {} : { rest: copy(rest, depth + 1) }),\n })\n }\n case 'literal':\n return Object.freeze({ kind, value: data.get('value') })\n case 'opaque':\n return Object.freeze({ kind, name: data.get('name') })\n default:\n return Object.freeze({ kind })\n }\n }\n const type = copy(value, 0)\n try {\n assertType(type, \"The artifact's expected type\")\n } catch (error) {\n return fail('shape', (error as Error).message, error)\n }\n return type\n}\n\n/**\n * An artifact's fields, copied once and checked for shape and size before\n * anything is parsed. A value that is not an artifact is a TypeError, and so\n * is anything thrown while reading it (a Proxy trap), with the thrown value as\n * its cause.\n */\nexport function readArtifact(value: unknown, settings: Settings): Artifact {\n const outer = raisedHere\n const mine = new WeakSet()\n raisedHere = mine\n try {\n return read(value, settings)\n } catch (error) {\n if (typeof error === 'object' && error !== null && mine.has(error)) throw error\n throw new TypeError('The artifact could not be read', { cause: error })\n } finally {\n raisedHere = outer\n }\n}\n\nfunction read(value: unknown, settings: Settings): Artifact {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) notArtifact()\n // The format is read first and alone: a later format may rename or add any other field.\n const formatField = Reflect.getOwnPropertyDescriptor(value, 'bonsai')\n if (formatField === undefined) return notArtifact()\n if (!('value' in formatField)) fail('shape', 'The artifact format is an accessor')\n const format: unknown = formatField.value\n if (typeof format !== 'number' || !Number.isSafeInteger(format) || format < 1)\n fail('shape', 'The artifact format must be a positive integer')\n if (format !== ARTIFACT_FORMAT)\n fail(\n 'version',\n `Artifact format ${String(format)} is not supported (this runtime reads format ${ARTIFACT_FORMAT})`,\n )\n const data = ownData(value, 'The artifact', ARTIFACT_KEYS.size, new Map([['bonsai', format]]))\n for (const key of data.keys()) {\n if (!ARTIFACT_KEYS.has(key))\n fail('version', `The artifact has a field \"${key}\" this runtime does not know`)\n }\n const string = (key: string): string => {\n const field = data.get(key)\n return typeof field === 'string'\n ? field\n : fail('shape', `The artifact's ${key} must be a string`)\n }\n const flag = (key: string): boolean => {\n const field = data.get(key)\n return typeof field === 'boolean'\n ? field\n : fail('shape', `The artifact's ${key} must be true or false`)\n }\n const source = string('source')\n if (source.length > settings.parseLimits.maxSourceLength)\n fail(\n 'limit',\n `The artifact's source is longer than ${settings.parseLimits.maxSourceLength} characters`,\n )\n const plans = arrayData(data.get('plans'), settings.parseLimits.maxNodes, 'plans', 'limit').map(\n (entry, i): Plan => {\n const items = arrayData(entry, MAX_PLAN_LENGTH, `plans[${i}]`, 'plan')\n const [start, name, ...candidates] = items\n if (\n typeof start !== 'number' ||\n typeof name !== 'string' ||\n !candidates.every((c) => typeof c === 'number')\n )\n fail('shape', `plans[${i}] must be [nameStart, name, ...overload indices]`)\n return [start as number, name as string, ...(candidates as number[])]\n },\n )\n const expect = data.has('expect') ? copyType(data.get('expect')) : undefined\n return {\n bonsai: ARTIFACT_FORMAT,\n by: string('by'),\n source,\n plans,\n ...(expect === undefined ? {} : { expect }),\n guard: flag('guard'),\n async: flag('async'),\n digest: string('digest'),\n }\n}\n\n/** The calls of a bound tree by where their names start. */\nfunction callsByStart(root: Node): Map<number, CallNode> {\n const calls = new Map<number, CallNode>()\n const stack: Node[] = [root]\n while (stack.length > 0) {\n const node = stack.pop() as Node\n if (node.type === 'Call' && node.nameStart !== undefined) calls.set(node.nameStart, node)\n forEachChild(node, (child) => {\n stack.push(child)\n })\n }\n return calls\n}\n\n/** What a loaded artifact runs with: its analysis, result guard, and source. */\nexport interface Loaded {\n readonly source: string\n readonly analysis: ProgramAnalysis\n readonly guard: Type | undefined\n}\n\n/**\n * Loads an artifact against a runtime's definitions, refusing it with a\n * BonsaiArtifactError when it does not reproduce the checked program exactly:\n * a different format, source, plan, function, or declared variable type.\n */\nexport function loadArtifact(\n artifact: Artifact,\n settings: Settings,\n expect: Type | undefined,\n): Loaded {\n // Loading is not part of any read: a load that a Proxy trap runs while an\n // outer artifact is read must not mark its errors as that read's own.\n const outer = raisedHere\n raisedHere = undefined\n try {\n return loadRead(artifact, settings, expect)\n } finally {\n raisedHere = outer\n }\n}\n\nfunction loadRead(artifact: Artifact, settings: Settings, expect: Type | undefined): Loaded {\n const { source } = artifact\n let parsed: Node\n try {\n parsed = parse(source, settings.parseLimits)\n } catch (error) {\n if (!(error instanceof BonsaiError)) throw error\n return fail(\n error.code === 'SYNTAX' ? 'syntax' : 'limit',\n `The artifact's source cannot be parsed: ${error.message}`,\n error,\n )\n }\n const lookup = (name: string): FunctionDef | undefined =>\n settings.host.get(name) ?? settings.builtins.get(name)\n // Binding adds lambdas around arguments but no calls or variables, so the\n // digest is computed from the parsed tree as it is from the checked one:\n // different definitions are reported as such, before binding with them.\n const names = treeNames(parsed)\n for (const name of names.functions) {\n if (lookup(name) === undefined)\n fail('function', `The artifact calls ${name}(), which this runtime does not define`)\n }\n // A strict checker refuses every undeclared variable, so a strict runtime\n // refuses artifacts that read one rather than reading it from the context.\n if (settings.strict) {\n for (const name of names.variables) {\n if (settings.variables === undefined || !Object.hasOwn(settings.variables, name))\n fail('variable', `The artifact reads ${name}, which this strict runtime does not declare`)\n }\n }\n const { digest, ...fields } = artifact\n if (artifactDigest(fields, parsed, lookup, settings.variables) !== digest)\n fail(\n 'digest',\n 'The artifact was made for different definitions than this runtime has; make it again from its source',\n )\n const bound = bindImplicit(parsed, lookup)\n if (bound.problems.length > 0) fail('binding', bound.problems[0].message)\n const root = bound.root\n\n const calls = new Map<CallNode, CallPlan>()\n const byStart = callsByStart(root)\n for (const call of byStart.values()) {\n const def = lookup(call.name) as FunctionDef\n calls.set(call, { def, candidates: def.overloads.map((_, i) => i) })\n }\n let previous = -1\n for (const [start, name, ...candidates] of artifact.plans) {\n const call = byStart.get(start)\n if (start <= previous || call === undefined || call.name !== name)\n fail('plan', `The artifact's plan for ${name}() at ${start} matches no call`)\n previous = start\n const def = lookup(name) as FunctionDef\n const count = def.overloads.length\n if (\n candidates.length === 0 ||\n candidates.length >= count ||\n !candidates.every(\n (c, i) =>\n Number.isSafeInteger(c) && c >= 0 && c < count && (i === 0 || c > candidates[i - 1]),\n )\n )\n fail(\n 'plan',\n `The artifact's plan for ${name}() at ${start} is not a narrower set of its overloads`,\n )\n calls.set(call as CallNode, { def, candidates })\n }\n\n if (\n expect !== undefined &&\n (artifact.expect === undefined || encodeType(artifact.expect) !== encodeType(expect))\n )\n fail('expect', 'The artifact was not compiled for the expected type passed to load()')\n const analysis: ProgramAnalysis = { root, calls, async: artifact.async }\n warmZones(analysis)\n return {\n source,\n analysis,\n // The host's own expected type is always checked; the artifact's only where the checker asked.\n guard: expect ?? (artifact.guard ? artifact.expect : undefined),\n }\n}\n\n/** A key equal for two artifacts exactly when every field is (read with readArtifact). */\nexport function artifactKey(artifact: Artifact): string {\n return [\n lengthPrefixed(artifact.digest),\n lengthPrefixed(artifact.by),\n lengthPrefixed(artifact.source),\n lengthPrefixed(JSON.stringify(artifact.plans)),\n // As written, not canonically: equal types written differently report\n // themselves differently in result-mismatch messages.\n artifact.expect === undefined ? '-' : lengthPrefixed(JSON.stringify(artifact.expect)),\n artifact.guard ? 'g' : '-',\n artifact.async ? 'a' : '-',\n ].join('')\n}\n\n/** Runs a loaded artifact as a program does. */\nexport function loadedRunner<R>(loaded: Loaded, settings: Settings) {\n return programRunner<R>({ ...loaded, settings })\n}\n"],"mappings":"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"}
|