@polyengine/runtime 0.1.0-pre.g633468a

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 (126) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +23 -0
  3. package/esm/cabi/async_values.js +162 -0
  4. package/esm/cabi/bulk_lists.js +198 -0
  5. package/esm/cabi/context.js +42 -0
  6. package/esm/cabi/flatten.js +145 -0
  7. package/esm/cabi/float.js +67 -0
  8. package/esm/cabi/handles.js +253 -0
  9. package/esm/cabi/layout.js +149 -0
  10. package/esm/cabi/lift.js +196 -0
  11. package/esm/cabi/load.js +146 -0
  12. package/esm/cabi/lower.js +141 -0
  13. package/esm/cabi/memory.js +182 -0
  14. package/esm/cabi/mod.js +22 -0
  15. package/esm/cabi/store.js +186 -0
  16. package/esm/cabi/strings.js +336 -0
  17. package/esm/cabi/trap.js +38 -0
  18. package/esm/cabi/types.js +264 -0
  19. package/esm/cabi/values.js +64 -0
  20. package/esm/cache/core.js +156 -0
  21. package/esm/cache/dir.js +170 -0
  22. package/esm/cache/mod.js +4 -0
  23. package/esm/cache/web.js +136 -0
  24. package/esm/digest/digest.js +332 -0
  25. package/esm/digest/mod.js +3 -0
  26. package/esm/digest/verify.js +129 -0
  27. package/esm/embedder/casing.js +56 -0
  28. package/esm/embedder/copy.js +42 -0
  29. package/esm/embedder/errors.js +26 -0
  30. package/esm/embedder/imports.js +63 -0
  31. package/esm/embedder/instantiate.js +978 -0
  32. package/esm/embedder/mod.js +40 -0
  33. package/esm/embedder/resources.js +406 -0
  34. package/esm/embedder/streams.js +770 -0
  35. package/esm/embedder/values.js +450 -0
  36. package/esm/embedder/version.js +273 -0
  37. package/esm/exec/boundary.js +1902 -0
  38. package/esm/exec/executor.js +1004 -0
  39. package/esm/exec/host_streams.js +818 -0
  40. package/esm/exec/mod.js +4 -0
  41. package/esm/intrinsics/async_builtins.js +510 -0
  42. package/esm/intrinsics/context.js +90 -0
  43. package/esm/intrinsics/errors.js +13 -0
  44. package/esm/intrinsics/fact_calls.js +865 -0
  45. package/esm/intrinsics/mod.js +564 -0
  46. package/esm/intrinsics/stream_builtins.js +578 -0
  47. package/esm/intrinsics/transcode.js +443 -0
  48. package/esm/jspi/bridge.js +579 -0
  49. package/esm/jspi/mechanics.js +89 -0
  50. package/esm/jspi/mod.js +5 -0
  51. package/esm/jspi/suspending.js +15 -0
  52. package/esm/jspi/types.js +29 -0
  53. package/esm/package.json +3 -0
  54. package/esm/plan/format.js +5 -0
  55. package/esm/plan/loader.js +657 -0
  56. package/esm/plan/mod.js +3 -0
  57. package/esm/shim/mod.js +2 -0
  58. package/esm/shim/translator.js +94 -0
  59. package/esm/task/mod.js +483 -0
  60. package/esm/task/scheduler.js +1028 -0
  61. package/esm/task/streams.js +786 -0
  62. package/esm/task/subtask.js +135 -0
  63. package/esm/task/thread.js +255 -0
  64. package/esm/task/waitable.js +144 -0
  65. package/package.json +91 -0
  66. package/types/cabi/async_values.d.ts +35 -0
  67. package/types/cabi/bulk_lists.d.ts +18 -0
  68. package/types/cabi/context.d.ts +59 -0
  69. package/types/cabi/flatten.d.ts +14 -0
  70. package/types/cabi/float.d.ts +14 -0
  71. package/types/cabi/handles.d.ts +70 -0
  72. package/types/cabi/layout.d.ts +13 -0
  73. package/types/cabi/lift.d.ts +25 -0
  74. package/types/cabi/load.d.ts +14 -0
  75. package/types/cabi/lower.d.ts +10 -0
  76. package/types/cabi/memory.d.ts +58 -0
  77. package/types/cabi/mod.d.ts +15 -0
  78. package/types/cabi/store.d.ts +12 -0
  79. package/types/cabi/strings.d.ts +23 -0
  80. package/types/cabi/trap.d.ts +11 -0
  81. package/types/cabi/types.d.ts +206 -0
  82. package/types/cabi/values.d.ts +5 -0
  83. package/types/cache/core.d.ts +97 -0
  84. package/types/cache/dir.d.ts +6 -0
  85. package/types/cache/mod.d.ts +3 -0
  86. package/types/cache/web.d.ts +10 -0
  87. package/types/digest/digest.d.ts +17 -0
  88. package/types/digest/mod.d.ts +2 -0
  89. package/types/digest/verify.d.ts +48 -0
  90. package/types/embedder/casing.d.ts +40 -0
  91. package/types/embedder/copy.d.ts +24 -0
  92. package/types/embedder/errors.d.ts +11 -0
  93. package/types/embedder/imports.d.ts +47 -0
  94. package/types/embedder/instantiate.d.ts +88 -0
  95. package/types/embedder/mod.d.ts +11 -0
  96. package/types/embedder/resources.d.ts +158 -0
  97. package/types/embedder/streams.d.ts +202 -0
  98. package/types/embedder/values.d.ts +70 -0
  99. package/types/embedder/version.d.ts +85 -0
  100. package/types/exec/boundary.d.ts +360 -0
  101. package/types/exec/executor.d.ts +125 -0
  102. package/types/exec/host_streams.d.ts +165 -0
  103. package/types/exec/mod.d.ts +3 -0
  104. package/types/intrinsics/async_builtins.d.ts +69 -0
  105. package/types/intrinsics/context.d.ts +28 -0
  106. package/types/intrinsics/errors.d.ts +5 -0
  107. package/types/intrinsics/fact_calls.d.ts +120 -0
  108. package/types/intrinsics/mod.d.ts +187 -0
  109. package/types/intrinsics/stream_builtins.d.ts +113 -0
  110. package/types/intrinsics/transcode.d.ts +21 -0
  111. package/types/jspi/bridge.d.ts +227 -0
  112. package/types/jspi/mechanics.d.ts +50 -0
  113. package/types/jspi/mod.d.ts +3 -0
  114. package/types/jspi/suspending.d.ts +1 -0
  115. package/types/jspi/types.d.ts +26 -0
  116. package/types/plan/format.d.ts +369 -0
  117. package/types/plan/loader.d.ts +113 -0
  118. package/types/plan/mod.d.ts +2 -0
  119. package/types/shim/mod.d.ts +1 -0
  120. package/types/shim/translator.d.ts +55 -0
  121. package/types/task/mod.d.ts +257 -0
  122. package/types/task/scheduler.d.ts +421 -0
  123. package/types/task/streams.d.ts +370 -0
  124. package/types/task/subtask.d.ts +96 -0
  125. package/types/task/thread.d.ts +73 -0
  126. package/types/task/waitable.d.ts +67 -0
@@ -0,0 +1,69 @@
1
+ import type { SuspensionMode } from "../jspi/mod.js";
2
+ import type { ValType } from "../cabi/types.js";
3
+ import type { ComponentInstanceState } from "../task/mod.js";
4
+ import type { CoreFn, ResolvedOptions } from "../exec/boundary.js";
5
+ /** Services these built-ins need from the executor. */
6
+ export interface AsyncTrampolineContext {
7
+ componentInstance(index: number): ComponentInstanceState;
8
+ /** Resolved canonical options by `canonicalOptions` index. */
9
+ options(index: number): ResolvedOptions;
10
+ /** The element types of an interned results *tuple* (`task-return`). */
11
+ resultTypes(index: number): ValType[];
12
+ }
13
+ /**
14
+ * `BLOCKED` sentinel of `canon_subtask_cancel` (definitions.py line 2467).
15
+ */
16
+ export declare const BLOCKED = 4294967295;
17
+ /** definitions.py `canon_task_return` (line 2384). */
18
+ export declare function createTaskReturn(decl: {
19
+ results: number;
20
+ resultType: number | null;
21
+ options: number;
22
+ }, ctx: AsyncTrampolineContext): CoreFn;
23
+ /** definitions.py `canon_task_cancel` (line 2397). */
24
+ export declare function createTaskCancel(): CoreFn;
25
+ /** definitions.py `canon_backpressure_inc` (line 2368). */
26
+ export declare function createBackpressureInc(inst: ComponentInstanceState): CoreFn;
27
+ /** definitions.py `canon_backpressure_dec` (line 2375). */
28
+ export declare function createBackpressureDec(inst: ComponentInstanceState): CoreFn;
29
+ /** definitions.py `canon_waitable_set_new` (line 2406). */
30
+ export declare function createWaitableSetNew(inst: ComponentInstanceState): CoreFn;
31
+ /**
32
+ * definitions.py `canon_waitable_set_wait` (line 2414).
33
+ *
34
+ * The reference blocks the calling thread until the set has an event. From a
35
+ * stackless (callback-ABI) guest there is no wasm stack to suspend, so this
36
+ * only succeeds when an event is *already* pending — which is the reference's
37
+ * own non-blocking branch of `Thread.wait_until`. Otherwise: `needsJspi`.
38
+ *
39
+ * A guest using the callback ABI is expected to return the `WAIT` callback
40
+ * code rather than call this built-in; hitting the JSPI path here means the
41
+ * component uses the stackful async ABI.
42
+ */
43
+ export declare function createWaitableSetWait(decl: {
44
+ options: number;
45
+ }, ctx: AsyncTrampolineContext, inst: ComponentInstanceState, mode?: SuspensionMode): CoreFn;
46
+ /** definitions.py `canon_waitable_set_poll` (line 2431). */
47
+ export declare function createWaitableSetPoll(decl: {
48
+ options: number;
49
+ }, ctx: AsyncTrampolineContext, inst: ComponentInstanceState): CoreFn;
50
+ /** definitions.py `canon_waitable_set_drop` (line 2441). */
51
+ export declare function createWaitableSetDrop(inst: ComponentInstanceState): CoreFn;
52
+ /** definitions.py `canon_waitable_join` (line 2451). */
53
+ export declare function createWaitableJoin(inst: ComponentInstanceState): CoreFn;
54
+ /** definitions.py `canon_subtask_drop` (line 2494). */
55
+ export declare function createSubtaskDrop(inst: ComponentInstanceState): CoreFn;
56
+ export declare function createSubtaskCancel(decl: {
57
+ async?: boolean;
58
+ }, inst: ComponentInstanceState, mode?: SuspensionMode): CoreFn;
59
+ /**
60
+ * definitions.py `canon_thread_yield` (line 2728).
61
+ *
62
+ * Yielding blocks the calling wasm frame until the scheduler comes back to
63
+ * it. A callback-ABI guest expresses the same intent by returning the `YIELD`
64
+ * callback code, which this runtime implements fully (exec/boundary.ts); the
65
+ * *built-in* form needs a suspendable stack.
66
+ */
67
+ export declare function createThreadYield(decl: {
68
+ cancellable?: boolean;
69
+ }, mode?: SuspensionMode): CoreFn;
@@ -0,0 +1,28 @@
1
+ import type { CoreFn } from "../exec/boundary.js";
2
+ /**
3
+ * Number of `i32` context slots per thread. definitions.py `Thread.storage`
4
+ * is initialised `[0,0]` (line 347) and `canon_context_{get,set}` assert
5
+ * `i < len(thread.storage)` — so exactly two, matching the intrinsic names
6
+ * `context-*-i32-0` and `context-*-i32-1`.
7
+ */
8
+ export declare const NUM_CONTEXT_SLOTS = 2;
9
+ /**
10
+ * definitions.py `canon_context_get` (line 2348).
11
+ *
12
+ * The storage is **per thread**, not per task: two threads of one task have
13
+ * independent context. wit-bindgen 0.60 keeps its async-executor task pointer
14
+ * in slot 0, which is why this intrinsic is the entry blocker for async
15
+ * guests.
16
+ */
17
+ export declare function canonContextGet(i: number): number;
18
+ export declare function ctxThreadId(t: unknown): string;
19
+ /** definitions.py `canon_context_set` (line 2358). */
20
+ export declare function canonContextSet(i: number, v: number): void;
21
+ /**
22
+ * Materialize one `unsafe-intrinsic` CoreDef as a core function.
23
+ *
24
+ * Called during initializer resolution — i.e. at instantiate time — so an
25
+ * unimplementable symbol fails instantiation rather than the first call
26
+ * (contracts/plan-format.md "Executor obligations").
27
+ */
28
+ export declare function createUnsafeIntrinsic(symbol: string): CoreFn;
@@ -0,0 +1,5 @@
1
+ /** Instantiate-time failure for functionality scheduled after M0. */
2
+ export declare class UnsupportedFeatureError extends Error {
3
+ milestone: "M1" | "M2" | "M2-streams" | "M2-jspi";
4
+ constructor(milestone: "M1" | "M2" | "M2-streams" | "M2-jspi", what: string);
5
+ }
@@ -0,0 +1,120 @@
1
+ import type { CoreValue, ValType } from "../cabi/types.js";
2
+ import { ComponentInstanceState } from "../task/mod.js";
3
+ import { type CoreFn, type ExecutionStats } from "../exec/boundary.js";
4
+ /** `START_FLAG_ASYNC_CALLEE` (`component.rs:52`). */
5
+ export declare const START_FLAG_ASYNC_CALLEE = 1;
6
+ /** The state `prepare-call` stashes for the following `*-start-call`. */
7
+ export interface PreparedCall {
8
+ /** `[async-start]` adapter export — the reference's `on_start`. */
9
+ start: CoreFn;
10
+ /** `[async-return]` adapter export — the reference's `on_resolve`. */
11
+ return_: CoreFn;
12
+ callerInst: ComponentInstanceState;
13
+ calleeInst: ComponentInstanceState;
14
+ /** `TypeTupleIndex` of the callee's (lifted) results. */
15
+ taskReturnType: number;
16
+ /** Whether the callee's *function type* is async. */
17
+ calleeAsync: boolean;
18
+ stringEncoding: number;
19
+ resultCountOrMax: number;
20
+ /** The caller's own flat arguments, as forwarded to `prepare-call`. */
21
+ params: CoreValue[];
22
+ /**
23
+ * Where the *caller's* results go, decoded from
24
+ * `result_count_or_max_if_async` exactly as wasmtime's `ResultInfo`
25
+ * (`concurrent.rs:2815-2836`):
26
+ *
27
+ * * async caller **with** a result -> `Heap`, retptr = last param
28
+ * * async caller without a result -> `Stack`
29
+ * * sync caller whose results spill (`result_count > MAX_FLAT_RESULTS`)
30
+ * -> `Heap`, retptr = last param
31
+ * * sync caller otherwise -> `Stack`
32
+ *
33
+ * In the `Heap` case the retptr must be **appended** to the
34
+ * `[async-return]` arguments (`concurrent.rs:2916-2919`) — it is the last
35
+ * parameter of `async_return_signature` (fact/signature.rs:166,178), not
36
+ * something the callee produced.
37
+ */
38
+ resultInfo: {
39
+ kind: "heap";
40
+ retptr: CoreValue;
41
+ } | {
42
+ kind: "stack";
43
+ };
44
+ /** True when the caller used the async ABI *and* has a result. */
45
+ asyncCallerWithResult: boolean;
46
+ /**
47
+ * The memory `prepare-call` names (`component/info.rs:1059`: "the memory
48
+ * used to verify that the memory specified for the `task.return` that is
49
+ * called at runtime matches the one specified in the lifted export").
50
+ *
51
+ * Decoded faithfully, but NOT usable for that verification: it is the
52
+ * *adapter's* view (`adapter.lift.options...memory`) and is `None` for
53
+ * callees whose own `task.return` options do name a memory. wasmtime gets
54
+ * away with the check because it holds the lift memory first-hand and its
55
+ * comparison is one-sided (concurrent.rs:3344-3358). Kept because it is the
56
+ * wire field and the task's options are structurally built from it; see the
57
+ * comment on the memory half of the check in async_builtins.ts.
58
+ */
59
+ memory: unknown | null;
60
+ }
61
+ /** Executor services these intrinsics need. */
62
+ export interface FactCallContext {
63
+ componentInstance(index: number): ComponentInstanceState;
64
+ /** Element types of an interned results tuple (a `plan.types` index). */
65
+ resultTypes(index: number): ValType[];
66
+ /**
67
+ * Element types for a *raw* wasmtime `TypeTupleIndex` (what `prepare-call`
68
+ * passes as `task_return_type`), or `null` if the plan maps none — plan v3,
69
+ * see `LoadedPlan.resultTupleTypes`.
70
+ */
71
+ resultTypesForTuple(tupleIndex: number): ValType[] | null;
72
+ /** `RuntimeCallbackIndex` -> the callee's callback core function. */
73
+ callback(index: number): CoreFn;
74
+ /** `RuntimeMemoryIndex` -> the memory `task.return` must match, if any. */
75
+ memoryToken(index: number): unknown;
76
+ stats: ExecutionStats;
77
+ /** Suspension discipline (jspi/bridge.ts). */
78
+ suspensionMode: import("../jspi/mod.js").SuspensionMode;
79
+ /**
80
+ * Can this specific callee's code reach a suspension point? Computed per
81
+ * core instance at instantiation (see `Executor.suspendableFuncs`). Decides
82
+ * whether the callee gets its own `promising` entry.
83
+ */
84
+ calleeCanBlock?(fn: unknown): boolean;
85
+ /**
86
+ * The single in-flight prepared call. wasmtime keeps this per *task*; a
87
+ * single slot is equivalent here because `prepare-call` and its
88
+ * `*-start-call` are emitted back-to-back in one adapter body
89
+ * (`trampoline.rs:486-508`) with no suspension point between them, so two
90
+ * preparations can never be outstanding at once. Asserted, not assumed.
91
+ */
92
+ prepared: {
93
+ current: PreparedCall | null;
94
+ };
95
+ /** See `TrampolineContext.factStartScopes` (intrinsics/mod.ts). */
96
+ factStartScopes: import("./mod.js").FactStartScope[];
97
+ }
98
+ export declare function createPrepareCall(decl: {
99
+ memory: number | null;
100
+ }, ctx: FactCallContext): CoreFn;
101
+ /**
102
+ * A sync-lowered import calling an async-lifted export
103
+ * (`compile_sync_to_async_adapter`, trampoline.rs:607). The caller's wasm frame
104
+ * is blocked for the duration, so this must produce the results *now*.
105
+ */
106
+ export declare function createSyncStartCall(decl: {
107
+ callback: number | null;
108
+ }, ctx: FactCallContext): CoreFn;
109
+ /**
110
+ * An async-lowered import calling any export (`compile_async_to_async_adapter`
111
+ * / `compile_async_to_sync_adapter`). Returns the packed subtask status the
112
+ * guest already knows how to interpret — the same
113
+ * `state | (subtaski << 4)` encoding `canon_lower` produces
114
+ * (definitions.py line 2308), so the caller's callback loop and waitable sets
115
+ * work unchanged.
116
+ */
117
+ export declare function createAsyncStartCall(decl: {
118
+ callback: number | null;
119
+ postReturn: number | null;
120
+ }, ctx: FactCallContext): CoreFn;
@@ -0,0 +1,187 @@
1
+ import { ResourceHandle } from "../cabi/handles.js";
2
+ import type { ResourceTypeInfo } from "../cabi/types.js";
3
+ import type { ComponentInstanceState } from "../task/mod.js";
4
+ import type { WireTrampoline } from "../plan/format.js";
5
+ import type { CoreFn, ExecutionStats } from "../exec/boundary.js";
6
+ import { type PreparedCall } from "./fact_calls.js";
7
+ import { type TranscodeMemory } from "./transcode.js";
8
+ export * from "./transcode.js";
9
+ export * from "./context.js";
10
+ export * from "./async_builtins.js";
11
+ export * from "./fact_calls.js";
12
+ export * from "./stream_builtins.js";
13
+ /**
14
+ * Where a host trap thrown *inside* a FACT adapter is remembered.
15
+ *
16
+ * FACT wraps every adapter body in a `try_table … catch_all` exception
17
+ * barrier (wasmtime-environ 47.0.3 `fact/trampoline.rs:3939`
18
+ * `enter_exception_barrier`) so that a guest exception escaping a component
19
+ * becomes a trap rather than unwinding into the caller. In wasmtime a host
20
+ * trap unwinds out of band and is unaffected; in a JS host our traps *are*
21
+ * JS exceptions, so the barrier swallows them and re-raises the generic
22
+ * `UncaughtException` FACT trap — which would violate contracts/intrinsics.md
23
+ * §"Universal semantics" 2 ("traps ... must not be catchable by guest code").
24
+ *
25
+ * The fix is to remember the trap on the way out and restore it when the
26
+ * barrier reports `UncaughtException`. A genuine guest exception leaves
27
+ * `pending` untouched and keeps the generic trap.
28
+ *
29
+ * **Residual limitation (inherent to a JS host).** wasmtime's traps are
30
+ * unforgeable and uncatchable: they unwind out of band, and no guest
31
+ * construct can observe or swallow one. Ours are ordinary JS exceptions, so
32
+ * a guest that wraps a call in its own `try_table (catch_all …)` *can* catch
33
+ * a host trap mid-flight and continue — the Component Model says that must be
34
+ * impossible. Recovering full unforgeability needs an out-of-band channel
35
+ * (e.g. a poison flag consulted at every host boundary crossing) and is not
36
+ * attempted here; the barrier case above is the one that occurs in practice,
37
+ * because FACT emits it on every adapter. Recorded as a known gap.
38
+ */
39
+ export interface HostTrapState {
40
+ pending: unknown;
41
+ }
42
+ export { UnsupportedFeatureError } from "./errors.js";
43
+ /**
44
+ * The borrow bookkeeping of one in-flight synchronous cross-component call,
45
+ * bracketed by the FACT adapter's `enter-sync-call` / `exit-sync-call`
46
+ * imports (wasmtime-environ 47.0.3 `fact/trampoline.rs:810,904`: enter is
47
+ * emitted *before* argument translation and exit *after* the callee returns,
48
+ * so every resource transfer for the call happens inside the bracket).
49
+ *
50
+ * It plays the role definitions.py gives the callee `Subtask`/`Task`:
51
+ *
52
+ * - `lenders` — handles lent to the callee (`Subtask.lenders`); each
53
+ * `num_lends` is dropped again when the call returns, which is what makes
54
+ * a lender's own handle liftable again afterwards.
55
+ * - `numBorrows` — borrow handles lowered into the callee's table
56
+ * (`Task.num_borrows`); the callee must drop them all before returning
57
+ * (definitions.py `Task.return_`: `trap_if(self.num_borrows > 0)`).
58
+ *
59
+ * Structurally satisfies cabi's `TaskBorrowScope` and `SubtaskBorrowScope`.
60
+ */
61
+ export declare class SyncCallScope {
62
+ numBorrows: number;
63
+ readonly lenders: ResourceHandle[];
64
+ /**
65
+ * definitions.py `Subtask.add_lender` (line 890) — note there is **no**
66
+ * `own` check, and `lift_borrow` (line 1516) calls it unconditionally: a
67
+ * component that received a borrow may lend it onward, and the borrow
68
+ * handle's own `num_lends` is what blocks `resource.drop` on it until the
69
+ * onward call returns (`canon_resource_drop`, line 2325, traps on
70
+ * `num_lends != 0` for owning *and* borrowed handles alike).
71
+ * wasmtime 47.0.3 `vm/component/resources.rs:285` (`resource_lift_borrow`)
72
+ * agrees.
73
+ */
74
+ addLender(h: ResourceHandle): void;
75
+ /** definitions.py `Subtask.deliver_resolve` (lines 902-906): releases lenders at delivery time. */
76
+ releaseLenders(): void;
77
+ }
78
+ /**
79
+ * The borrow bookkeeping of one FACT `[async-start]` argument-copy window —
80
+ * the prepare/start protocol's analogue of `SyncCallScope`. Live only for
81
+ * the synchronous `callCore(prepared.start, …)` call inside `mkCalleeTask`'s
82
+ * `on_start` (the copy adapters cannot block, so the window never suspends).
83
+ *
84
+ * Reference mapping (definitions.py): `taskScope` is the callee `Task` —
85
+ * `lower_borrow` (line 1821) counts `num_borrows` there, and
86
+ * `Task.return_`/`cancel` trap while it is non-zero; `lenders` is the
87
+ * caller-side `Subtask` (async-start-call) or a plain scope released when
88
+ * the caller's blocked frame gets its results (sync-start-call) —
89
+ * `lift_borrow` (line 1517) adds lenders there, released at
90
+ * `deliver_resolve` (line 904). Found by the #18 polymorph-tls smoke: the
91
+ * suite is the first corpus with borrow-carrying composed calls through
92
+ * prepare/start adapters, which previously asserted "transfer-borrow
93
+ * outside an enter-sync-call/exit-sync-call bracket".
94
+ */
95
+ export interface FactStartScope {
96
+ /** The callee task (satisfies cabi's `TaskBorrowScope`). */
97
+ taskScope: import("../cabi/context.js").TaskBorrowScope;
98
+ /** The caller-side lender registrar (satisfies `SubtaskBorrowScope`). */
99
+ lenders: {
100
+ addLender(h: ResourceHandle): void;
101
+ };
102
+ }
103
+ /** Executor services a trampoline body needs (provided by executor.ts). */
104
+ export interface TrampolineContext {
105
+ componentInstance(index: number): ComponentInstanceState;
106
+ resourceToken(index: number): ResourceTypeInfo;
107
+ /**
108
+ * The component instance that *owns* resource table `index`
109
+ * (`TypeResourceTable::Concrete.instance`), i.e. whose handle table the
110
+ * FACT transfer intrinsics move handles between. Throws for abstract
111
+ * (type-only) tables, which have no runtime state.
112
+ */
113
+ resourceTableInstance(index: number): ComponentInstanceState;
114
+ /**
115
+ * A live view of runtime memory `index` (`RuntimeMemoryIndex`), for the
116
+ * string-transcoder trampolines.
117
+ */
118
+ runtimeMemory(index: number): TranscodeMemory;
119
+ /**
120
+ * Stack of in-flight synchronous cross-component calls (innermost last),
121
+ * owned by the executor so all trampolines of one instantiation share it.
122
+ */
123
+ syncCallStack: SyncCallScope[];
124
+ /**
125
+ * Stack of in-flight FACT `[async-start]` argument-copy windows (innermost
126
+ * last; see `FactStartScope`). Separate from `syncCallStack` because the
127
+ * prepare/start protocol has no enter/exit-sync-call bracket — the borrow
128
+ * bookkeeping attaches to the callee `Task` and the caller-side subtask
129
+ * instead (definitions.py `lower_borrow` line 1821 / `lift_borrow` line
130
+ * 1517).
131
+ */
132
+ factStartScopes: FactStartScope[];
133
+ /** See `FactCallContext.calleeCanBlock` (intrinsics/fact_calls.ts). */
134
+ calleeCanBlock?(fn: unknown): boolean;
135
+ /** See `HostTrapState`. */
136
+ trapState: HostTrapState;
137
+ /**
138
+ * Resolved canonical options by index, and the element types of an interned
139
+ * results tuple — needed by the async built-ins (task.return,
140
+ * waitable-set.{wait,poll}). See `AsyncTrampolineContext`.
141
+ */
142
+ options(index: number): import("../exec/boundary.js").ResolvedOptions;
143
+ resultTypes(index: number): import("../cabi/types.js").ValType[];
144
+ /** `RuntimeCallbackIndex` -> the extracted callback core function. */
145
+ callback(index: number): CoreFn;
146
+ /** `RuntimeMemoryIndex` -> an identity token for `task.return` checks. */
147
+ memoryToken(index: number): unknown;
148
+ /** The single in-flight FACT preparation (see `PreparedCall`). */
149
+ prepared: {
150
+ current: PreparedCall | null;
151
+ };
152
+ /** Suspension discipline (jspi/bridge.ts). */
153
+ suspensionMode: import("../jspi/mod.js").SuspensionMode;
154
+ /** Element types of the plan v2 stream/future tables. */
155
+ streamElem(index: number): import("../cabi/types.js").ValType | null;
156
+ futureElem(index: number): import("../cabi/types.js").ValType | null;
157
+ streamTableInstance(index: number): ComponentInstanceState;
158
+ futureTableInstance(index: number): ComponentInstanceState;
159
+ /**
160
+ * The component instance owning error-context table `index`
161
+ * (`TypeComponentLocalErrorContextTableIndex`, plan v3 `errorContextTables`).
162
+ * Its own index space — NOT the resource-table one it used to borrow.
163
+ */
164
+ errorContextTableInstance(index: number): ComponentInstanceState;
165
+ /**
166
+ * Element types of the *raw* wasmtime `TypeTupleIndex` FACT's
167
+ * `prepare-call` passes as `task_return_type`, or `null` when the plan
168
+ * carries no mapping for it (see `LoadedPlan.resultTupleTypes`).
169
+ */
170
+ resultTypesForTuple(tupleIndex: number): import("../cabi/types.js").ValType[] | null;
171
+ /** Build the lowered-import body for `lowered` (LoweredIndex). */
172
+ loweredImport(decl: {
173
+ lowered: number;
174
+ options: number;
175
+ type: number;
176
+ }): CoreFn;
177
+ stats: ExecutionStats;
178
+ }
179
+ /**
180
+ * Create the JS function backing one plan trampoline. Called during
181
+ * initializer/arg/export resolution — i.e. at instantiate time — so an
182
+ * unsupported kind fails instantiation, not the first call
183
+ * (plan-format.md "Executor obligations"). Unreferenced trampolines are
184
+ * never created and therefore never fail (intrinsics.md §B tolerates e.g.
185
+ * an unreferenced task-return until M2).
186
+ */
187
+ export declare function createTrampoline(decl: WireTrampoline, ctx: TrampolineContext): CoreFn;
@@ -0,0 +1,113 @@
1
+ import type { SuspensionMode } from "../jspi/mod.js";
2
+ import type { ValType } from "../cabi/types.js";
3
+ import { type ComponentInstanceState } from "../task/mod.js";
4
+ import { type CoreFn, type ResolvedOptions } from "../exec/boundary.js";
5
+ export declare function traceCopy(msg: string): void;
6
+ /** Services the stream/future built-ins need from the executor. */
7
+ export interface StreamTrampolineContext {
8
+ componentInstance(index: number): ComponentInstanceState;
9
+ options(index: number): ResolvedOptions;
10
+ /** Element type of a `TypeStreamTableIndex` (plan v2 `streamTables`). */
11
+ streamElem(index: number): ValType | null;
12
+ /** Element type of a `TypeFutureTableIndex` (plan v2 `futureTables`). */
13
+ futureElem(index: number): ValType | null;
14
+ /** Suspension discipline; decides whether site 4 blocks or signals. */
15
+ suspensionMode?: SuspensionMode;
16
+ }
17
+ /**
18
+ * definitions.py `canon_stream_new` (line 2504) / `canon_future_new` (2512).
19
+ * Returns both handles packed into an i64: `ri | (wi << 32)`.
20
+ */
21
+ export declare function createStreamNew(decl: {
22
+ streamTable: number;
23
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
24
+ export declare function createFutureNew(decl: {
25
+ futureTable: number;
26
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
27
+ /**
28
+ * definitions.py `canon_error_context_new` (line 2778).
29
+ *
30
+ * The reference is deliberately non-committal about the message: under
31
+ * `DETERMINISTIC_PROFILE` it stores the empty string, otherwise it may apply a
32
+ * `host_defined_transformation`. We keep the guest's message verbatim — the
33
+ * most useful behaviour for a debugging aid, and within what the spec allows
34
+ * (the message is explicitly not semantically load-bearing).
35
+ */
36
+ export declare function createErrorContextNew(decl: {
37
+ options: number;
38
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
39
+ /** definitions.py `canon_error_context_debug_message` (line 2792). */
40
+ export declare function createErrorContextDebugMessage(decl: {
41
+ options: number;
42
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
43
+ /** definitions.py `canon_error_context_drop` (line 2803). */
44
+ export declare function createErrorContextDrop(inst: ComponentInstanceState): CoreFn;
45
+ export declare function createStreamRead(d: {
46
+ streamTable: number;
47
+ options: number;
48
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
49
+ export declare function createStreamWrite(d: {
50
+ streamTable: number;
51
+ options: number;
52
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
53
+ export declare function createFutureRead(d: {
54
+ futureTable: number;
55
+ options: number;
56
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
57
+ export declare function createFutureWrite(d: {
58
+ futureTable: number;
59
+ options: number;
60
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
61
+ export declare function createStreamCancelRead(d: {
62
+ streamTable: number;
63
+ async: boolean;
64
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
65
+ export declare function createStreamCancelWrite(d: {
66
+ streamTable: number;
67
+ async: boolean;
68
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
69
+ export declare function createFutureCancelRead(d: {
70
+ futureTable: number;
71
+ async: boolean;
72
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
73
+ export declare function createFutureCancelWrite(d: {
74
+ futureTable: number;
75
+ async: boolean;
76
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
77
+ export declare function createStreamDropReadable(d: {
78
+ streamTable: number;
79
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
80
+ export declare function createStreamDropWritable(d: {
81
+ streamTable: number;
82
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
83
+ export declare function createFutureDropReadable(d: {
84
+ futureTable: number;
85
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
86
+ export declare function createFutureDropWritable(d: {
87
+ futureTable: number;
88
+ }, ctx: StreamTrampolineContext, inst: ComponentInstanceState): CoreFn;
89
+ /** Services the transfer intrinsics need beyond `StreamTrampolineContext`. */
90
+ export interface AsyncTransferContext extends StreamTrampolineContext {
91
+ streamTableInstance(index: number): ComponentInstanceState;
92
+ futureTableInstance(index: number): ComponentInstanceState;
93
+ }
94
+ export declare function createStreamTransfer(ctx: AsyncTransferContext): CoreFn;
95
+ export declare function createFutureTransfer(ctx: AsyncTransferContext): CoreFn;
96
+ /**
97
+ * error-context transfer. Unlike stream/future ends, an `error-context` is
98
+ * shareable: `lift_error_context` (definitions.py line 1451) *reads* the handle
99
+ * rather than removing it, so the source keeps its own.
100
+ */
101
+ /**
102
+ * Plan v3 (contracts/plan-format.md v3 amendment 2): `instanceOf` resolves
103
+ * through the plan's `errorContextTables` section — the
104
+ * `TypeComponentLocalErrorContextTableIndex` space these arguments actually
105
+ * live in. It replaced a resource-table lookup, which shared neither the
106
+ * index space nor (in a multi-instance composition) the answer.
107
+ *
108
+ * The arguments are the trampoline's own core parameters, so a missing one is
109
+ * an arity fault, not a zero: no `?? 0` defaults — `instanceOf(undefined!)`
110
+ * would be a silent table-0 read. `assert_` instead, and the accessor itself
111
+ * raises a `PlanError` for an out-of-range table.
112
+ */
113
+ export declare function createErrorContextTransfer(ctx: AsyncTransferContext, instanceOf: (table: number) => ComponentInstanceState): CoreFn;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * A live view of one `WebAssembly.Memory`. Views are re-derived per access:
3
+ * a transcoder can be called after the guest grew a memory, which detaches
4
+ * the previous `ArrayBuffer`.
5
+ */
6
+ export declare class TranscodeMemory {
7
+ #private;
8
+ constructor(provider: () => WebAssembly.Memory | undefined, label: string);
9
+ bytes(): Uint8Array;
10
+ }
11
+ /** The `Transcode` op names as emitted by the shim (`Transcode::desc()`). */
12
+ export type TranscodeOp = "utf8-to-utf8" | "utf16-to-utf16" | "latin1-to-latin1" | "latin1-to-utf16" | "latin1-to-utf8" | "utf16-to-compact-probably-utf16" | "utf16-to-compact-utf16" | "utf16-to-latin1" | "utf16-to-utf8" | "utf8-to-compact-utf16" | "utf8-to-latin1" | "utf8-to-utf16";
13
+ export declare const TRANSCODE_OPS: readonly TranscodeOp[];
14
+ /**
15
+ * Build the JS function backing one `Transcoder` trampoline.
16
+ *
17
+ * Result shape follows the core signature in `fact/transcode.rs`: no result,
18
+ * one result (a number), or two results (a `[srcRead, dstWritten]` pair — the
19
+ * JS API delivers a multi-value return as an array).
20
+ */
21
+ export declare function createTranscoder(op: TranscodeOp, from: TranscodeMemory, to: TranscodeMemory): (...args: number[]) => unknown;