You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/callable-runtime.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@ RustScript bytecode format version 9 introduces runtime script call frames and f
9
9
- callable environments are bound through the internal builtin call path; callable creation adds no bytecode opcode.
10
10
-`ret` completes the active script frame. A nested frame leaves exactly one result at the caller segment base, using `null` when the body produced no value. Root `ret` keeps the historical program-result stack behavior.
11
11
12
-
VMBC v9 is a hard format boundary. Decoders reject older versions. The stream includes script-function entry ranges, callable prototypes, function regions, and root callable bindings. PDRC recordings and AOT artifacts use their corresponding bumped format/ABI versions and include callable metadata in cache identity.
12
+
VMBC v9 is a hard format boundary. Decoders reject older versions. The stream includes script-function entry ranges, callable prototypes, function regions, and root callable bindings. PDRC v4 recordings and AOT artifacts use their corresponding bumped format/ABI versions and include callable metadata in cache identity.
13
13
14
14
## Runtime model
15
15
@@ -26,11 +26,11 @@ Branches are restricted to the active function region. Validation rejects cross-
26
26
27
27
## Callable identity and lifetime
28
28
29
-
A callable contains the owning program-instance ID, prototype ID, kind, and optional environment. Capture-free function items compare by program/prototype identity. Closures compare by runtime identity. Callable constants are forbidden; functions are initialized from program metadata and closures are materialized at their declaration site.
29
+
A callable contains its prototype ID, kind, and optional environment. The Program/Store owns the callable lifetime. Capture-free function items compare by prototype identity inside that Program; closures compare by runtime environment identity. Callable constants are forbidden; functions are initialized from Program metadata and closures are materialized at their declaration site.
30
30
31
-
Resetting or replacing the VM program assigns a new program-instance ID. Calling a value from an older instance reports `StaleCallable`.
31
+
Reset clears Program runtime values and rebinds root function items from Program metadata. Program replacement cancels and releases the old Store callback registry before dropping the old Program. Raw callable values are Program-local and are not portable across Program/Store boundaries.
32
32
33
-
`Vm::invoke_callable` is the synchronous host-entry API for a callable retained after the root program halts. For resumable work, `Vm::start_callable` returns `VmStatus`; after `Yielded` or `Waiting`, continue with `Vm::resume` and read the completed value with `Vm::take_callable_result`. `ScriptCallback::start` and `Store::take_callback_result` expose the same flow for typed callbacks. `Store::script_callback` validates the Store identity, Program instance, arity, and copied callable schema and returns a typed `ScriptCallback<Args, Ret>`. A callback can invoke directly, create a `Send` queued invocation on another thread, unsubscribe all aliases, or enter the Store FIFO through `enqueue_callback`; queue errors propagate and no implicit coalescing occurs. `Vm::shutdown` clears queued work, runtime values and host resources before invalidating every exported callable.
33
+
`Vm::invoke_callable` is the synchronous host-entry API for a callable retained while the current Program is active. For resumable work, `Vm::start_callable` returns `VmStatus`; after `Yielded` or `Waiting`, continue with `Vm::resume` and read the completed value with `Vm::take_callable_result`. `ScriptCallback::start` and `Store::take_callback_result` expose the same flow for typed callbacks. `Store::script_callback` validates Store ownership, arity, and the copied callable schema and returns a typed `ScriptCallback<Args, Ret>` with no stale identity field. A callback can invoke directly, create a `Send` queued invocation on another thread, unsubscribe all aliases, or enter the Store FIFO through `enqueue_callback`; queue errors propagate and no implicit coalescing occurs. `Vm::shutdown` clears queued work, runtime values and host resources before invalidating every exported callback through the Store registry.
34
34
35
35
PDRC recordings preserve full execution-frame metadata. Callable environments use identity-table encoding, so aliases still share one environment after decode.
- Add `Value::Callable { program_instance, prototype_id, kind, env }`; it must not own `Arc<Program>`.
26
+
- Add Program-owned `Value::Callable { prototype_id, kind, env }`. Callable values follow their Program/Store lifetime and never retain an old `Program`.
27
27
- Add frame-relative locals, a real execution-frame stack, and one `Ret` rule: complete the active frame and follow its typed continuation. Root execution uses an explicit `Halt` continuation; nested RSS calls use `ResumeBytecode`; Rust invocation uses `ReturnToHost`. Never infer return meaning from an empty call stack.
28
28
- Add `CallValue(argc)` as the common RSS function-item/closure invocation path; retain existing `Call` for direct host/builtin imports.
29
29
- Initialize capture-free named bindings from Program metadata.
30
30
- Add one shared environment-binding path for every capture-bearing callable. Introduce a dedicated runtime operation only if existing VM operations cannot bind captures.
31
-
-Validate `ProgramInstanceId` before prototype lookup; replaced/reset Program handles return `StaleCallable`.
31
+
-Keep callable values inside their owning Program/Store. Program replacement and reset invalidate the old callable registry as a lifecycle operation; callable dispatch does not compare stale identities.
32
32
33
-
**Acceptance:** Named calls, recursion, closure calls, arity failures, stale handles, return values, yield/pending, and resume all use real frames.
33
+
**Acceptance:** Named calls, recursion, closure calls, arity failures, return values, yield/pending, and resume all use real frames.
34
34
35
35
## 3. Integrate captures, types, and generics
36
36
@@ -59,7 +59,7 @@
59
59
- Release environments correctly on clone, overwrite, `Drop`, unwind, collection removal, return, cancellation, and reset; reject ownership cycles until cycle collection exists.
60
60
- On Program replacement, REPL installation, or reuse reset: cancel callback work, remove listeners, clear callable roots/persisted callables, drop the old Program, and invalidate all external old handles.
61
61
- Add Rust APIs to resolve exported RSS functions and invoke function items or closures through one resumable path.
62
-
- Add typed `ScriptCallback<Args, Ret>` with Store identity, Program instance ID, and copied callable schema.
62
+
- Add typed `ScriptCallback<Args, Ret>` with Store ownership and copied callable schema. It follows the Program registry and stores no stale Program identity.
63
63
- Serialize callbacks through the Store queue; define FIFO/coalescing, cross-thread enqueue, unsubscribe, teardown, error, and return-value policies.
64
64
- Verify that the final Rust-held callback releases captures exactly once.
Copy file name to clipboardExpand all lines: plans/real_script_call_frames_plan.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,7 +29,7 @@ First-class value typing, generic schemas, lifecycle, and retained callback APIs
29
29
- Apply a hard internal format break; no backward decoder, migration, opcode reinterpretation, or compatibility branch is required:
30
30
- bump VMBC `ENCODE_VERSION` from 8 to 9 and accept only version 9;
31
31
- bump AOT artifact `VERSION` from 2 to 3 and native `ABI_VERSION` from 1 to 2 because Program/VM/native layouts and return control flow change;
32
-
- bump debugger recording `PDRC` from 2 to 3, accept only version 3, and remove legacy version-1 recording acceptance;
32
+
- bump debugger recording `PDRC` from 2 to 4, accept only version 4, and reject legacy versions 1 through 3;
33
33
- add the bytecode ABI revision to Program/native trace cache keys together with callable tables, function regions, and slot layouts so old in-memory entries cannot match;
34
34
- regenerate internal fixtures/artifacts and make every old format fail with its existing unsupported-version error.
35
35
@@ -42,8 +42,8 @@ First-class value typing, generic schemas, lifecycle, and retained callback APIs
- Add `Value::Callable { program_instance, prototype_id, kind, env }`; it stores no `Arc<Program>`.
46
-
-Assign a fresh `ProgramInstanceId` on Program installation/replacement/reset. `CallValue` validates it before prototype lookup and returns `StaleCallable` for old handles.
45
+
- Add Program-owned `Value::Callable { prototype_id, kind, env }`; it stores no `Arc<Program>` and never outlives the owning Program/Store registry.
46
+
-On Program installation/replacement/reset, clear runtime callable values and invalidate external callbacks through the owning Store registry. Callable dispatch does not compare stale identities.
47
47
- Add an execution-frame stack. Each frame records:
48
48
- typed continuation (`Halt`, `ResumeBytecode`, or `ReturnToHost`);
49
49
- prototype/function identity;
@@ -52,7 +52,7 @@ First-class value typing, generic schemas, lifecycle, and retained callback APIs
52
52
- active callable/environment root;
53
53
- recursion, fuel/epoch, suspension, and debug state required for exact resume.
54
54
- Resolve logical locals through metadata such as `SlotLocation::Frame(offset)` or `SlotLocation::Capture(cell)`. A logical slot must map to exactly one storage class in each prototype.
55
-
- On `CallValue`, validate value kind, Program instance, arity, and recursion limit; preserve caller state; allocate callee locals; bind arguments/self/environment; then enter the target.
55
+
- On `CallValue`, validate value kind, prototype, arity, and recursion limit; preserve caller state; allocate callee locals; bind arguments/self/environment; then enter the target.
56
56
- On `Ret`, normalize the result, release callee roots/locals, restore the typed continuation, and either resume bytecode, return to Rust, or report halt.
57
57
- Emit root code and every RSS function body once in one code blob, with explicit root/function regions.
58
58
- Validate `Br` and `Brfalse` targets remain inside their current root/function region; cross-function control flow is valid only through `CallValue` and `Ret`.
@@ -93,7 +93,7 @@ First-class value typing, generic schemas, lifecycle, and retained callback APIs
-`Pop` and `Dup` apply normal callable/environment clone/drop ownership;
96
-
-`Ceq` compares function items by Program instance/prototype identity and closure aliases by callable/environment identity; separate closure evaluations compare unequal;
96
+
-`Ceq` compares function items by prototype identity inside their owning Program and closure aliases by callable/environment identity; separate closure evaluations compare unequal;
97
97
- arithmetic, bitwise, ordering, and shift opcodes reject callable operands through existing type-error paths.
98
98
- Remove or redesign the current interpreter `Call + Ret` fusion. It may run only when typed continuation/frame semantics, fuel ticks, epoch checks, result normalization, and lifecycle behavior remain identical to unfused execution.
99
99
- Change the current interpreter mapping from unconditional `Ret -> Halted` to frame completion.
@@ -112,7 +112,7 @@ First-class value typing, generic schemas, lifecycle, and retained callback APIs
0 commit comments