【Rust 日报】2022-05-12 [博文] 我们将YJIT Ruby编译器移植到Rust的经验

2022-06-10 15:00:21 浏览数 (1)

[博文] 我们将YJIT Ruby编译器移植到Rust的经验

去年,我在Shopify的团队实现了YJIT,一个用于CRuby的新的即时编译器(JIT),它最近作为Ruby 3.1的一部分被上游化。因为CRuby代码库是用C99实现的,所以我们也决定用C99实现YJIT,这样与CRuby代码库的其他部分的集成就会尽可能的简单。然而,我们发现用纯C语言实现JIT编译器很快就变得乏味了,而且随着我们不断为YJIT增加功能,我们发现我们项目的复杂性变得难以管理。

附上reddit热评:

我大体上同意你所写的,但有几个地方我觉得失败的原因不在于语言本身,而在于你打算如何使用它的文档,以及为什么它被做成这样。

This is how to convert a C string to a Rust string according to Stack Overflow:(根据Stack Overflow的说法,这就是如何将C语言字符串转换为Rust字符串。)

我不是这种事情的专家,但假设我没有搞砸,你更有可能看到有经验的Rust开发者这样写出同样的一系列转换。

代码语言:javascript复制
 let str_buf = unsafe { CStr::from_ptr(hello()).to_str()?.to_owned() };

另外,Rust手册中的CStr页面在 "将外部C语言字符串转换为Rust字符串 "的标题下实际上提供了一个类似的例子。

代码语言:javascript复制
fn my_string_safe() -> String {
  unsafe {
      CStr::from_ptr(my_string()).to_string_lossy().into_owned()
  }
}

(用.to_string_lossy()避免unwrap或错误传播的步骤,因为它用U FFFD REPLACEMENT CHARACTER替换了任何不是有效的UTF-8的字节。)

However, it’s definitely an area where Rust prioritizes safety above ergonomics and user-friendliness(然而,这绝对是Rust公司将安全性置于人体工程学和用户友好性之上的一个领域。)

在这种特殊情况下,它与安全无关,更多的是与可组合性有关。

出于同样的原因,Rust有Rc<T>Arc<T>Mutex<T>RWLock<T>和任何你想与之组合的第三方东西,而不是ArcMutex<T>等等,没有hello().to_string_panicking()将这一系列的检查和转换结合到一个函数中。)

The unsafe blocks act as a trap door into a universe where the rules of the Rust type system aren’t enforced.(unsafe块就像一扇陷阱之门,进入一个不遵守Rust类型系统规则的宇宙。)

这篇文章是给Rust老手看的,但实际上一直在试图纠正新手对不安全区块的一个常见误解,你的措辞就是这样的:

  1. unsafe并没有放松对现有语言结构的任何检查,也没有取消对如何使用它们的任何要求。它只是允许你访问额外的语言特性。
  2. 无论你是否使用asraw指针强行为同一分配创建第二个&mut,LLVM IR仍然会得到noalias这样的注解,因此,仍然会调用未定义行为(Undefined Behaviour),所以说unsafe不遵守这些规则,有点像暗示你可以走到高速公路上,因为unsafe拆除了安全栅栏。(有时公路工人需要在公路上工作,但如果你在一个视野盲区的拐角处放置 "道路封闭标志 "并认为你现在是安全的,那么人类走到公路上的能力并不能神奇地阻止各种汽车向你飞来)

Why do I need to wrap every C function call into an unsafe block?(为什么我需要把每个C函数的调用都包装成一个unsafe的块?)

这样做的话,如果有什么东西发生故障或损坏,grep unsafe可以为你指出正确的方向,而对PR的审计也知道应该把最多的注意力放在哪里。

The Rust compiler knows I’m calling a C function and that this function doesn’t follow the Rust typing rules. Am I really telling the compiler anything by wrapping each individual C function call into an unsafe block? A C function call is by definition “unsafe”, I shouldn’t have to tell the Rust compiler that. Having to write unsafe every time I call a C function seems like it adds unnecessary friction. A constant reminder that the Rust compiler is silently judging me for relying on C.(Rust编译器知道我在调用一个C函数,而且这个函数并不遵循Rust的类型规则。我把每个单独的C函数调用包装成一个unsafe的块,真的能告诉编译器什么吗?根据定义,C函数调用是 unsafe,我不应该告诉Rust编译器这一点。每次调用C函数时都要写上unsafe,这似乎增加了不必要的麻烦。不断地提醒我,Rust编译器正在默默地评判我对C语言的依赖性。)

unsafe块不是为编译器准备的。它们是为其他人准备的......尤其是未来十年或更久以后新加入的团队成员。

Rust的很多安全特性都让人意识到"经验证明,单个人也许能写出好的C和C ,但一群人却不能"。

...它之所以被称为unsafe,是因为把每一种静态不可检查的东西分割成一个单独的关键字(如ffi_call)并没有带来任何好处,即使这在表面上更能让人联想到Ruby和Python等脚本语言如何处理FFI支持。

...不过,事后看来,像unchecked这样的东西可能会被认为更符合它的本意。

Rust offers many trap doors to work around the type system. There are unsafe blocks and the unsafe integer “as” cast without bounds checking. Many Rust types, like Rc, also have methods such as into_raw and from_raw. This can feel inconsistent and strange. On the one hand, you have a language with a sometimes painfully strict type system and a compiler that issues warnings about “incorrect” code style, but you also have a wide assortment of ways to tell the compiler to hold your beer so you can selectively bend and potentially break the safety assumptions the compiler makes whenever you want.(Rust提供了许多绕过类型系统的陷阱门。有一些unsafe的块和不安全的整数 as 转换,没有边界检查。许多Rust类型,如Rc,也有一些方法,如into_rawfrom_raw。这让人感到不一致和奇怪。一方面,你是一门有时严格得令人痛苦的类型系统的语言,以及一个对 "不正确 "的代码风格发出警告的编译器,但你也有各种各样的方法来告诉编译器,让它听你的话,所以你可以有选择地余地,并可能在你想要的时候打破编译器的安全假设。)

from_raw是一个unsafe的函数,像#![forbid(unsafe_code)]这样的东西存在是为了把 “unsafe的代码 "和 "新手可以接触的代码 "分开。

into_raw不是unsafe的,因为让它在创建原始指针时unsafe,只会增加更多的混乱,而实际上只有解读阶段才有风险。

人们普遍认为这是一个有问题的决定,现在我们有了TryFromTryInto这两个trait,人们正在讨论不鼓励甚至废除它,以支持T::from()/T.into()T::try_from()/T.try_into()的想法。

博文: https://shopify.engineering/porting-yjit-ruby-compiler-to-rust

2022年StackOverflow开发者调查已经开始

空气中闪烁着期待的光芒,今年最受欢迎的编程语言会是谁呢?

地址: https://stackoverflow.blog/2022/05/11/stack-overflow-2022-developer-survey-is-open/

[博文] C 中的多范式其实很糟糕

这是我比较C 和Rust的系列博客的下一篇文章,作为一个有多年低延迟系统C 程序员经验的人,现在已经非常喜欢Rust。这篇文章的重点是C 程序员普遍声称它是多范式的,以及这实际上是一个问题,因为C 的特性会相互冲突。通常情况下,当人们宣称C 的特性相互冲突时,他们并没有完全证实这一说法。

博文: https://www.thecodedmessage.com/posts/2022-05-11-programming-multiparadigm/

This Week in Rust 442

新一期的 Rust 周报速递发布,快来看看有哪些内容你曾经关注过 :)

This Week in Rust 442: https://this-week-in-rust.org/blog/2022/05/11/this-week-in-rust-442/

From 日报小组 Cupnfish

0 人点赞