1 个不稳定版本
0.1.0 | 2021 年 10 月 22 日 |
---|
720 在 编程语言 中
5MB
39K SLoC
包含 (DOS 可执行文件, 1.5MB) wren_c/projects/premake/premake5.exe
safe_wren
Wren 语言 (wren.io) 的一个几乎完整的 Rust 实现。
来自 wren.io 的原始 https://github.com/wren-lang/wren 被称为 wren_c
,以区分于这个 safe_wren
。
与 wren_c 的相似之处
- 通过 ~90% 的 wren_c 测试
- 公开 ~90% 的 wren_c C API
与 wren_c 的不同之处
- 不会因为错误输入而崩溃(但当前仍可能通过无限循环超时)
- 引用计数,没有垃圾收集(正在进行中)
- 在第一个编译错误时停止(而不是继续)
- 需要 utf8 输入,并且字符串始终是 utf8(不允许无效的 utf8 字节)
- 不允许覆盖分配器(尚不支持)
- 缺少 opt-meta 和类属性
- 在某些微基准测试中比 wren_c 慢约 2 倍(GC 工作完成后应可比较)
用法
从现有的 C 项目
cargo build --release
生成 target/release/libsafe_wren.a
和 target/release/libsafe_wren.so
,它们是 wren.a
和 wren.so
的替代品,与在 (wren_c/src/include/wren.h
) 中找到的 wren.h
兼容。
从 Rust
在您的 cargo.toml
中添加依赖项,例如
[dependencies]
safe_wren = "0.1.0"
开发
有两个二进制文件
wren_test
— 仅用于测试,仅使用公共 APIwren_debug
— 用于调试 vm,使用私有调用。
cargo run FILENAME_OR_STRING
将运行 wren_test
对文件或字符串进行测试。
cargo run --bin=wren_debug FILENAME_OR_STRING
将运行 wren_debug
wren_debug
子命令:tokenize
输出标记流。 compile
输出编译器字节码。 interpret
类似于没有参数的情况,除了在运行后打印虚拟机状态。
python3 util/test.py
将运行测试,包括将任何失败的测试的错误文本更新到 test_results/*
。 test.py
还将更新 test_results/passes.txt
,包含通过测试的列表。
test_results/test_expectations.txt
列出所有当前跳过的测试及其原因。
还有哪些工作要做
启动列表?
- 使用 Rust API 的示例
- 使用 C API 的示例
- 发布到 Cargo
- 通知 wren-lang
- 生成并发布 Rust 文档。
有序的目标?
- 修复 delta blue(闭包错误!)
- 修复 local_outside_method.wren
- 计时测试/使其更快(下一个是 vec::alloc 来自方法调用)
- 更高级的测试期望系统 ** 配置 / 期望对(c | FAIL,RUST | TIMEOUT)
- 教
utils/test.py
如何轻松地在 rust 和 c_rust 以及 c 之间切换 - 移除所有对 'as' 的使用(使用 into() 代替)。
- validate_superclass 现在可以使用 ClassSource 验证内部等。
- 字符串代码点 API(包括 String.iterate)
- 外部方法运行时错误中的行号不正确。
- 属性
- Rust 实现的元包。
- 编译失败后继续?
- \x 不应该通过 char 重复往返。
- 垃圾收集?
- 排序方法以匹配 wren_c 顺序?
- 变量应该对每个作用域类型使用不同的类型。
- 同时模糊 wren_c 和 safe_wren 并比较输出?
- 查看一些慢单元模糊的结果 ** fuzz/artifacts/fuzz_target_1/slow-unit-63ea01d2d5ba869bdb889c3b51b21350d5a4ffea (lookup_symbol 应该是散列) ** fuzz/artifacts/fuzz_target_1/slow-unit-355b25c3fc10bfd14a363cf737abf3a07bab4a1e (不必要的堆栈调整)
wren_debug interpret wren_c/test/language/static_field/nested_class.wren
在 line_for_pc 中执行越界查找。
导致追求
- 使 InputManager 成为 Iterator,可能使 "跳过直到" 模式更容易
- https://docs.rs/once_cell/1.8.0/once_cell/
- https://docs.rs/anyhow/1.0.41/anyhow/
- 尝试优化大小: https://github.com/johnthagen/min-sized-rust
- 为了尝试真正的小尺寸,无 std + https://doc.rust-lang.net.cn/alloc/
- Box 与 C 指针具有相同的布局,这可能简化了我们的 FFI? https://stackoverflow.com/questions/62338832/how-to-hold-rust-objects-in-rust-code-created-through-c https://doc.rust-lang.net.cn/nomicon/ffi.html#representing-opaque-structs 似乎暗示了这一点?
基准测试说明
- 当前的数字显示 safe_wren 在各种微基准测试中比 wren_c 慢约 2.5 倍到 9 倍。不清楚这对现实世界的影响是什么。
- Value::clone 在许多基准测试中都很明显。
- 在从堆栈调用参数时使用 move/drain 语义可以帮助避免在将它们转换为 try_into_X 时需要克隆值。或者至少使 try_into_X 使用 move 语义,并在调用者中明确克隆。
- class_for_value 在 call_method 中出现在 ~5% 的几个基准测试中。
- map_numeric 重度测试 Value::PartialEq
- binary_trees 依赖于 ptr::drop_in_place(分配)的 RefCell,至少 20% 的时间。GC 将减少这一点。
- map_string在core::string_plus中花费了57%的时间,并且20%的时间用于截断堆栈。
wren_c错误
- 在wren_core.wren中定义的闭包/函数最终会得到一个空类指针吗?
- 如果你从根处yield,它会被设置为state=OTHER,可能后来你能够调用它上的某些东西?
- 对于每个构建/销毁的WrenVM,WrenConfiguration可能都会泄漏?