2个不稳定版本
使用旧的Rust 2015
0.2.0 | 2017年12月21日 |
---|---|
0.1.1 | 2017年11月8日 |
在 内存管理 中排名第 364
83KB
1.5K SLoC
Josephine: 使用JavaScript安全地管理Rust数据的生命周期
josephine包允许将Rust数据附加到JavaScript对象上:此时Rust数据的生命周期与所附加的JS对象相同。由于JS是垃圾回收的,因此可以安全地复制和丢弃JS管理数据的引用,并允许使用双链表等示例,否则将需要引用计数。引用计数需要动态检查,例如,如果引用计数超过1,则对引用计数数据的可变访问会引发panic。
目标是
- 使用JS来管理Rust数据的生命周期。
- 允许自由复制和丢弃对JS管理数据的引用,依赖于垃圾收集器来保证安全性。
- 保持Rust内存安全性(例如,没有可变别名),而无需额外的静态分析,如lint。
- 允许通过JS管理的引用对Rust数据进行可变和不可变访问,这样我们就不需要依赖于内部可变性。
- 提供一个根API,以确保在JS管理数据被使用时不会被垃圾回收。
为了支持对JS管理数据的安全访问,API使用一个JS上下文,作为访问令牌,允许访问、分配或释放JS管理数据。对JS管理数据的可变访问需要可变访问JS上下文,这是API如何即使JS管理引用可以自由复制和丢弃也能实现内存安全的原因。
JS管理的内存分为存储区,这些存储区是单独进行垃圾回收的,这样垃圾收集器就可以避免扫描整个堆。API静态跟踪存储区,以确保存储区之间没有直接引用。
API是通过绑定到SpiderMonkey JS引擎实现的,它从其中借用垃圾收集器和存储区以及JS上下念。API允许从Rust调用JavaScript,并从JavaScript调用Rust。这些绑定是不安全的,并且旨在由受信任的绑定生成器使用。
使用
Josephine 架构基于 SpiderMonkey 引擎的 rust-mozjs
架构,它使用了夜间功能,因此 josephine
也需要夜间版本。
在你的 Cargo.toml
[dependencies]
josephine = "0.1"
使用 cargo +nightly build
构建。
示例
一个最小示例,它使用 JS 来管理字符串的生命周期
# extern crate josephine;
use ::josephine::JSContext;
// Giving JavaScript some data to manage.
pub fn main() {
// Create a new JavaScript context.
// All interaction with JavaScript takes place in a context.
let ref mut cx = JSContext::new().expect("Failed to initialize JS");
// Create a new compartment in that context.
// All memory managed by JavaScript is divided into compartments,
// which do not directly refer to each other.
// Each compartment has a global object, which we can
// give some Rust data to manage.
let native = String::from("hello");
let ref cx = cx.create_compartment().global_manage(native);
// Check that the global contains the expected "hello" message.
let global = cx.global();
assert_eq!(global.borrow(cx), "hello");
}
更大的示例包括
依赖
~78MB
~1.5M SLoC