diff --git a/README.md b/README.md index 1eda3c5..8815c79 100644 --- a/README.md +++ b/README.md @@ -690,8 +690,8 @@ if err != nil { **行号指向 `.ts` 源文件而不是打包产物**:esbuild 输出 inline sourcemap,goja 自带 sourcemap 支持。 -哨兵错误:`ErrTimeout`、`ErrFuncNotFound`、`ErrScriptNotFound`、`ErrValueEscape`、 -`ErrClosed`、`ErrUnsupportedSignature`、`ErrPromiseRejected`、`ErrPromisePending`、`ErrBadGlobal`。 +哨兵错误:`ErrTimeout`、`ErrInterrupted`、`ErrFuncNotFound`、`ErrScriptNotFound`、 +`ErrValueEscape`、`ErrClosed`、`ErrPromiseRejected`、`ErrPromisePending`、`ErrBadGlobal`。 ## 热更新 diff --git a/docs/call-flow.md b/docs/call-flow.md index ce50cdb..932007e 100644 --- a/docs/call-flow.md +++ b/docs/call-flow.md @@ -109,8 +109,12 @@ flowchart TD I --> J ``` -白名单注入时**逐层拷贝成只读对象**,不是直接 `rt.Set`:否则同一个 Go map 会被所有 VM 共享, -脚本一句 `db.C = null` 既污染别的 VM,又是实打实的数据竞争。 +白名单注入时不是直接 `rt.Set`,而是过一道 `freeze`。但**它只对 `map[string]any` 逐层拷贝**: +那种值会拷成只读 JS 对象,各个 VM 拿到各自的副本,脚本一句 `db.C = null` 影响不到别人。 + +放行的是结构体指针、slice 或别的 Go 对象时,`freeze` 直接 `rt.ToValue`——**各个 VM 共享 +同一个对象**。要跨 VM 共享可变状态就该这么用(扩展走的正是这条路),但别把它当成隔离保证: +脚本通过那个对象的方法改到的东西是真改了。 顶层代码同样受超时保护——脚本在顶层写死循环不会把调用方卡住。 diff --git a/docs/lifecycle.md b/docs/lifecycle.md index f16655b..cc000a2 100644 --- a/docs/lifecycle.md +++ b/docs/lifecycle.md @@ -75,8 +75,8 @@ stateDiagram-v2 ```mermaid stateDiagram-v2 - [*] --> 池中: newVM() - 池中 --> 借出: borrow() + [*] --> 借出: newVM()(池里没有就现造) + 池中 --> 借出: borrow() 命中 借出 --> 池中: release(healthy=true) 借出 --> 丢弃: release(healthy=false) 池中 --> 丢弃: Script.Close()