1 个不稳定版本
0.1.0 | 2024年7月2日 |
---|
#116 in 内存管理
10KB
166 行
Panic Room
这是非 unwinding 抛出异常处理的一个小实验。
想法是将类似区域的东西附加到 sj/lj 上,使得
- 你可以使用 panic=abort 编译,但是...
- 在一个 "房间" 内,它实际上永远不会终止,它会恢复
- 你可以在房间内分配、获取、借用和修改借用东西
- 所有分配的东西在成功 或 抛出异常恢复时都会被销毁
- 如果那些东西有析构函数,它们也会像平常一样运行
这是一种类似半事务的微型,类似于 catch-unwind,但没有实际的 unwinding,只是 sj/lj。SEH 的一个奇怪的突变亲属。
考虑事项
- 我不确定将内存分配与这种控制方式连接起来是否有理由。也许这两部分应该保持独立。我认为将区域堆栈、jmp_buf 堆栈、恐慌处理程序和析构函数全部纠缠在一起可能是方便的,但我可能是在想象。
限制
-
由于无法访问单个内部 API,它无法重置恐慌编号,因此它将永远认为它仍然在恐慌。这只是一个在 stdlib 中的数字。它应该由想要掌握自己命运的人进行调整。如果您知道如何访问它,请发送补丁。
-
“区域”根本不是区域,它是一个 vec-refcell-option-box-dyn-any 东西。仅仅足以绘制正确的 API。如果您想让它像真正的区域一样运行,我怀疑您需要更多的 unsafe 代码。就目前而言,我仅在 sj/lj 上使用 unsafe。
-
每个人都认为 sj/lj 在本质上是不安全的和糟糕的。好吧,是的,但 unwinding 几乎一样糟糕,并且它还会生成大量的代码用于着陆垫,并让你不得不怀疑哪些代码路径将 unwinding 并在什么半构造状态上运行析构函数。使用这个 crate,析构函数仅在您的代码的愉快路径上运行,在 您在房间中分配的对象 的悲伤路径上,以及在房间的生命结束时运行;想法是让您在愉快的路径中不必太费心考虑析构函数(并且也不必进行代码生成着陆垫)。因此,您的代码 "稍微更原子",尽管当然它仍然可能由于 longjmp 而在执行过程中停止。
-
为了不关心析构函数在结束时运行,您的对象通常会存活更长时间(直到结束!)除非您在句柄上调用 Room::take 并丢弃结果。这样您可以强制析构函数提前运行。
依赖项
~0–1.9MB
~36K SLoC