Skip to content

Commit 083a60a

Browse files
committed
docs: correct divergences found in full implementation audit
- Cargo.toml: bump rust-version 1.94 -> 1.96 to match rust-toolchain.toml pin and the "Rust 1.96+" claim in README/install docs. - architecture.md: the generated php.* facade leaf is a plain function using Array.prototype.slice.call(arguments), not an arrow with rest params; name the re-entrancy depth cap (200). - execution-modes.md: the isolated-realm stored-callback error is a plain \Exception (PhpException::default), not QuickJSException. - docs/README.md: add the missing src/sandbox.rs row and roundtrip() to the lib.rs method list in the source map. - api.md: document roundtrip() so the reference covers every public method.
1 parent 94009a0 commit 083a60a

5 files changed

Lines changed: 16 additions & 7 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "php_quickjs"
33
version = "0.0.2"
44
edition = "2021"
5-
rust-version = "1.94"
5+
rust-version = "1.96"
66
description = "Embed a QuickJS sandbox in PHP with typed, bidirectional communication"
77
license = "MIT"
88
authors = ["Edd Mann <the@eddmann.com>"]

docs/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ php -d extension=$(pwd)/target/debug/libphp_quickjs.so examples/kitchen_sink.php
3030

3131
| File | Responsibility |
3232
|------|----------------|
33-
| `src/lib.rs` | The `QuickJS` PHP class: `eval` / `register` / `grant` / `resolve` / `revoke` / `manifest` / `dts`. |
33+
| `src/lib.rs` | The `QuickJS` PHP class: `eval` / `register` / `grant` / `resolve` / `revoke` / `manifest` / `dts` / `roundtrip`. |
3434
| `src/engine.rs` | Owns the QuickJS `Runtime`; realm lifecycle (shared vs isolated); deadline + re-entrancy state; the current-context stack. |
35+
| `src/sandbox.rs` | In-engine resource containment: the memory limit, native stack size, and wall-clock deadline (interrupt handler). |
3536
| `src/transpile.rs` | TypeScript → JavaScript via oxc, plus the content-hash transpile cache. |
3637
| `src/bridge.rs` | The `__host` / `__php_invoke` imports, the dispatch table, the frozen `php.*` facade, and registries. |
3738
| `src/marshal.rs` | `JS value ↔ MiddleValue ↔ PHP zval`, with native-msgpack (de)serialization. |

docs/api.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,9 @@ $js->register('db.query', fn(int $handle, string $sql) => $js->resolve($handle)-
3737

3838
The registration manifest and a generated TypeScript `.d.ts` for the `php` global,
3939
both from the same source of truth.
40+
41+
### `roundtrip(mixed $value): mixed`
42+
43+
Diagnostic helper: send a PHP value through the full marshaling pipeline
44+
(PHP → MiddleValue → JS → MiddleValue → PHP) and return the result. Useful for
45+
testing value fidelity across the boundary; not needed in normal use.

docs/architecture.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@ Take `php.math.add(2, 3)` from a guest script.
2929

3030
2. The guest calls `php.math.add(2, 3)`. `php` is not magic — it is a **frozen JS
3131
object tree** that `bridge.rs` generated from the registration manifest. The
32-
leaf `php.math.add` is an arrow function:
32+
leaf `php.math.add` is a function:
3333

3434
```js
35-
php.math.add = (...args) => globalThis.__rt.callHost("math.add", args);
35+
php.math.add = function () {
36+
return globalThis.__rt.callHost("math.add", Array.prototype.slice.call(arguments));
37+
};
3638
```
3739

3840
3. `__rt.callHost` (`src/js/runtime.js`) **msgpack-encodes** the argument array
@@ -56,7 +58,7 @@ surface.
5658
### The facade is generated, and frozen
5759

5860
`bridge.rs::build_facade` walks the manifest's dotted names into a nested object
59-
tree, makes each leaf an arrow calling `__rt.callHost("dotted.name", args)`, then
61+
tree, makes each leaf a function calling `__rt.callHost("dotted.name", args)`, then
6062
**deep-freezes** the whole tree. Freezing is a security requirement, not a
6163
nicety: a guest must not be able to reassign `php.http.get` to fool other code.
6264
The facade is (re)built at the start of every `eval` so newly registered
@@ -123,7 +125,7 @@ while a host call is already running* (e.g. `php.mapEach(xs, fn)` — PHP calls
123125
eval) is active, the live `Ctx` pointer is published on a thread-local
124126
**current-context stack** (`engine.rs`), and `Js\Callback` reuses it instead of
125127
re-locking. Only when invoked *between* evals (no realm active) does it acquire
126-
the lock fresh on the persistent realm. A re-entrancy **depth cap** bounds
128+
the lock fresh on the persistent realm. A re-entrancy **depth cap** (200) bounds
127129
runaway PHP→JS→PHP→… recursion.
128130

129131
## Capability handles

docs/execution-modes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ error rather than misbehaving:
7575
$held = null;
7676
$js->register('keep', function ($cb) use (&$held) { $held = $cb; });
7777
$js->eval('php.keep(() => 1)');
78-
$held(); // QuickJSException: "JS callback invoked outside its eval (isolated …)"
78+
$held(); // Exception: "JS callback invoked outside its eval (isolated …)"
7979
```
8080

8181
## Why exactly those differences (the mechanism)

0 commit comments

Comments
 (0)