smelt_stdlib/runtime_symbols.rs
1//! The codegen↔runtime helper symbol contract.
2//!
3//! The Rust backend (`smelt-codegen-rust`) emits generated programs that call a
4//! fixed set of runtime helper functions. Those helpers are themselves emitted
5//! into every generated crate as a prelude (see `lib.rs` in the codegen crate).
6//! Both halves — the *definition* of a helper in the prelude and every *call
7//! site* the expression emitter writes — must agree on the exact symbol name.
8//! When they drift apart the mismatch is invisible until the generated crate
9//! reaches `rustc`, far from the codegen change that caused it.
10//!
11//! This module is the single, enumerable source of truth for those names. Each
12//! constant is the literal Rust identifier of one runtime helper. Codegen
13//! references these constants instead of inlining string literals, so renaming
14//! a helper is a one-line edit here that updates the prelude definition and all
15//! call sites at once.
16//!
17//! Scope: this table covers only the *fixed* runtime helper set — symbols whose
18//! names are baked into the runtime prelude and shared with the emitter. It
19//! intentionally does **not** cover per-program or generated identifiers (e.g.
20//! `smelt_object`, `smelt_args`, locals like `smelt_callback`), which are
21//! synthesized per emission and are not part of the cross-crate contract.
22
23/// Timer and microtask-queue runtime helpers.
24///
25/// These back the JavaScript timer surface (`setTimeout`/`clearTimeout`),
26/// `await`-based sleeping, and the cooperative promise-task pump that the async
27/// lowering drives. They are emitted into the prelude and called from the
28/// async-op and statement emitters.
29pub mod timers {
30 /// `async fn` that advances virtual time and drains pending timers/tasks;
31 /// backs `await sleep(...)` and the Promise busy-wait loop.
32 pub const SLEEP_MS: &str = "smelt_sleep_ms";
33
34 /// Registers a timer callback with a delay; backs `setTimeout`.
35 pub const SET_TIMEOUT: &str = "smelt_set_timeout";
36
37 /// Cancels a previously registered timer by handle; backs `clearTimeout`.
38 pub const CLEAR_TIMEOUT: &str = "smelt_clear_timeout";
39
40 /// Registers a repeating timer callback with a period; backs `setInterval`.
41 ///
42 /// The callback re-arms itself for the next period each time it fires, so the
43 /// existing virtual-time timer queue drives it without special-casing.
44 pub const SET_INTERVAL: &str = "smelt_set_interval";
45
46 /// Cancels a previously registered repeating timer by handle; backs
47 /// `clearInterval`. Intervals share the timer queue with timeouts, so this is
48 /// the same cancel-by-id operation as `clearTimeout`.
49 pub const CLEAR_INTERVAL: &str = "smelt_clear_interval";
50
51 /// Resets all timer/promise-queue thread-local state; emitted at the start
52 /// of generated `main`/entry wrappers so each run starts clean.
53 pub const RESET_TIMERS: &str = "smelt_reset_timers";
54
55 /// Pushes a detached future onto the cooperative promise-task queue; backs
56 /// fire-and-forget async calls.
57 pub const SPAWN_PROMISE_TASK: &str = "smelt_spawn_promise_task";
58
59 /// Drains queued promise tasks by polling them to completion. Defined in
60 /// the prelude and referenced only by other prelude helpers.
61 pub const DRAIN_PROMISE_TASKS: &str = "smelt_drain_promise_tasks";
62
63 /// Fires all timers whose due time has elapsed. Defined in the prelude and
64 /// referenced only by other prelude helpers.
65 pub const DRAIN_DUE_TIMERS: &str = "smelt_drain_due_timers";
66
67 /// Builds a no-op `Waker` used to poll detached futures. Defined in the
68 /// prelude and referenced only by other prelude helpers.
69 pub const NOOP_WAKER: &str = "smelt_noop_waker";
70}
71
72/// JSON / dynamic-`unknown` boundary helpers.
73///
74/// These bridge `serde_json` values and the runtime's tagged `SmeltUnknown`
75/// dynamic value, used at JSON parse boundaries.
76pub mod json {
77 /// Recursively converts a `serde_json::Value` into a `SmeltUnknown`; backs
78 /// `JSON.parse` and other JSON-ingest boundaries.
79 pub const UNKNOWN_FROM_JSON_VALUE: &str = "smelt_unknown_from_json_value";
80}
81
82/// String runtime helpers.
83///
84/// These back JavaScript global string functions that need more than a direct
85/// Rust std method call.
86pub mod strings {
87 /// Percent-encodes a string; backs `encodeURI(value)` (`Rvalue::UriEncode`).
88 ///
89 /// The ECMA-262 `encodeURI` character set stays literal (ASCII
90 /// alphanumerics, unreserved marks, URI reserved separators, and `#`);
91 /// everything else becomes uppercase `%XX` UTF-8 triplets.
92 pub const ENCODE_URI: &str = "smelt_encode_uri";
93}
94
95/// Host-object construction helpers.
96///
97/// These build the marker records that model JavaScript host builtins (see
98/// `host_object.rs` for the marker registry itself).
99pub mod host {
100 /// Builds the modeled `Blob`/`File` record from its `BlobPart` contents.
101 ///
102 /// Backs `new Blob(parts?, options?)` and `new File(parts, name, options?)`
103 /// (`Rvalue::BlobFromParts`). Concatenates part contents, stores the UTF-8
104 /// byte `size`, and stamps `__smelt_file` on top of `__smelt_blob` when a
105 /// file name is supplied.
106 pub const BLOB_RECORD_FROM_PARTS: &str = "smelt_blob_record_from_parts";
107}
108
109/// Host-global override-slot runtime helpers.
110///
111/// These back the bounded whole-global reassignment of modeled host
112/// constructors (`globalThis.File = ...`, `globalThis.Blob = undefined`,
113/// save/restore). The generated crate emits one `thread_local!` slot per host
114/// name the crate actually writes (`SMELT_HOST_OVERRIDE_<NAME>`), initialized to
115/// the fixed `SmeltHostOverride::Native` state, plus the fixed enum and the
116/// three helpers named here. See the `HostGlobalRead`/`HostGlobalWrite`/
117/// `HostGlobalPresent` MIR rvalues.
118///
119/// Per-test-thread semantics: each `#[test]` runs on its own thread and gets a
120/// fresh `Native` slot, matching the specs' save/restore discipline (they
121/// snapshot the native handle, override the slot, then restore it within one
122/// test).
123pub mod host_override {
124 /// Name of the fixed runtime enum modeling a host constructor's override
125 /// state: `Native` (unmodified), `Absent` (set to `undefined`), or
126 /// `Ctor(SmeltUnknown)` (reassigned to a constructor value).
127 pub const OVERRIDE_ENUM: &str = "SmeltHostOverride";
128
129 /// Prefix of the per-name `thread_local!` override slot
130 /// (`SMELT_HOST_OVERRIDE_<NAME>`). The suffix is the upper-cased host
131 /// constructor name.
132 pub const SLOT_PREFIX: &str = "SMELT_HOST_OVERRIDE_";
133
134 /// Read helper: returns the override state as a value. `Native` yields the
135 /// native-handle marker record, `Absent` yields JS `undefined`, `Ctor(v)`
136 /// yields the stored constructor value.
137 pub const READ: &str = "smelt_host_override_read";
138
139 /// Write helper: classifies the stored value into a slot state (`undefined`
140 /// → `Absent`; native-handle marker → `Native`; function/class value →
141 /// `Ctor`) and returns the stored value.
142 pub const WRITE: &str = "smelt_host_override_write";
143
144 /// Presence helper: `false` only when the slot is `Absent`.
145 pub const PRESENT: &str = "smelt_host_override_present";
146
147 /// The identity marker key stamped onto the native-handle record produced by
148 /// reading a `Native` slot. Its presence classifies a written-back value as
149 /// a restore-to-`Native`.
150 pub const NATIVE_CTOR_MARKER: &str = "__smelt_native_ctor";
151}