Title: Piccolo – A Stackless Lua Interpreter
短笛——一个无堆叠的Lua口译员
Text:
hn link
Url:
https://kyju.org/blog/piccolo-a-stackless-lua-interpreter/
Piccolo是一个用纯Rust编写,主要关注安全沙盒和弹性的Lua语言解释器。它使用gc-arena进行垃圾回收,并且gc-arena最初就是作为Piccolo的一部分创建的。Piccolo的设计采用了一种"无栈"(stackless)的方法,这主要是因为gc-arena的限制。这种设计使得Piccolo的Lua运行时不是"栈满"(stackful),它不依赖于Rust的函数调用栈来维护执行状态,并且可以在任何时间暂停执行。这种设计不仅适用于解释Lua字节码,还适用于从Lua调用的任何形式的Rust代码(回调),无论Lua -> Rust -> Lua调用的深度如何。
Piccolo的一些主要特性包括:
1. **取消(Cancellation)**:由于Piccolo采用了Future风格的轮询执行方式,因此执行可以随时取消,只需不再继续调用poll方法。
2. **抢占式并发(Pre-emptive Concurrency)**:Piccolo通过使用多个独立的"任务片"(tasklets)和多路复用对每个Executor::step的调用,为Lua提供了抢占式多任务处理。
3. **燃料、节奏和自定义调度(Fuel, Pacing, and Custom Scheduling)**:Piccolo中的Executor::step方法需要一个燃料参数来控制VM运行的时间,VM和回调在运行时会消耗这种燃料。
4. **"对称"协程和coroutine.yieldto**:Piccolo提供了coroutine.yieldto函数,允许协程直接向其他协程交出控制权,而不仅仅是调用者。
5. **"大谎言"(The "Big Lie")**:作者指出,尽管Piccolo的设计独特,但PUC-Rio Lua实际上已经能够实现Piccolo约70%的功能。Piccolo并不是独一无二的设计,而是PUC-Rio Lua工作方式的必然结果。
6. **Rust协程、Lua协程和Snarfing**:作者讨论了如何使用Rust协程来实现Piccolo,以及如何将Rust的特性"snarf"到Lua中。
7. **缩放视角(Zooming Out)**:作者讨论了系统编程语言的核心理念,以及如何使用Piccolo来创建一个可以在任何环境中完美适应的Lua版本。
Piccolo的最终目标是创建一个可以在任何环境中使用的Lua版本,具有最小的对程序结构的意见,并且能够处理不受信任的输入和取消。作者认为,无栈解释器设计实际上比传统的语言解释器更适合这个目标,因为垃圾回收系统通常与"适应任何环境"的理念相冲突。作者还提出,新的抽象(如协程)的发明,为系统编程语言带来了新的基本能力,而不引入更多的必需假设。
Post by: vvoruganti
Comments:
10000truths: > However, piccolo works very hard to guarantee that piccolo::Executor::step returns in a bounded amount of time, even without the cooperation of the running Lua code.<p>The issue is that there exist ways to make a single bytecode instruction take an unbounded amount of time to execute. For example, Lua's "string.find()" is implemented in native code. The interpreter only sees a single OP_CALL opcode, so it will count it as 1 instruction executed. But the <i>actual</i> execution time of the native implementation of string.find() is dependent on its inputs, which are not only variable length strings, but can be maliciously crafted to run in exponential time. Here's an example, shamelessly stolen from Mike Pall himself:<p><pre><code> string.find(string.rep("a", 50), string.rep("a?", 50)..string.rep("a", 50))
</code></pre>
The only way to solve this is to track execution time <i>within</i> the native code as well (i.e. make them fuel-aware), and ensure that they abort immediately if they exhaust the fuel.
10000truths: >;然而,piccolo非常努力地保证piccolo::Executor::step在有限的时间内返回,即使没有运行的Lua代码的配合<p> 问题是,存在一些方法可以使单个字节码指令花费无限长的时间来执行。例如;s〃;string.find()";在本机代码中实现。解释器只看到一个OP_CALL操作码,因此它将把它算作执行的1条指令。但是,string.find()的本机实现的<i>实际</i>执行时间取决于其输入,这些输入不仅是可变长度的字符串,而且可能被恶意设计为在指数时间内运行。这里;这是一个无耻地从Mike Pall自己那里偷来的例子:<p><pre><code>string.fund(string.rep(“a”,50),string.ret(“a?”,50。。string.rep(“a”,50))</code></pre>解决这一问题的唯一方法是在</i>本地代码中跟踪执行时间<i>(即使它们了解燃料),并确保它们在耗尽燃料时立即中止。
wesamco: I love how there are many Piccolo REPLs embedded in the article and interleaved with the paragraphs.<p>Piccolo looks amazing, I got a perfect use case for it, and I'm excited for when I get the chance to use it, thank you for working on it.
wesamco: 我喜欢文章中嵌入了许多短笛REPL,并与段落交织在一起<p> Piccolo看起来很神奇,我有一个完美的用例,我;当我有机会使用它时,我很兴奋,谢谢你的努力。
rnmmrnm: A bit off topic: I just wrote a bunch of lua C debug api code (lua_sethook) to pre-emptively run and context-switch multiple lua "coroutines" (well not so "co").<p>Is this library offering a lua implementation more well-designed for this use-case? I got all this code to unload the coroutine stack to store and and reload it before continuing it later. Does having C bindings to this library makes sense?
rnmmrnm: 有点偏离主题:我刚刚写了一堆lua C调试api代码(lua_sethook),用于预先运行和上下文切换多个lua";coroutines”;(好吧,不是这样的“co”)<p> 这个库是否为这个用例提供了一个更精心设计的lua实现?我得到了所有这些代码来卸载协程堆栈以存储和重新加载它,然后再继续。将C绑定到这个库有意义吗?
alberth: Monospace font<p>Please don’t use monospaced fonts for long-form text.<p>It’s extremely different to read because your eye struggles to see the “shape” of each word, when everything is equally spaced apart.
alberth: 单格字体<p>请不要对长格式文本使用单格字体<p> 阅读起来非常不同,因为当所有单词都等距时,你的眼睛很难看清每个单词的“形状”。
klaussilveira: I wonder if a Rust reimplementation of Lua will, one day, be faster than LuaJIT.
klaussilveira: 我想知道Rust重新实现Lua是否有一天会比LuaJIT更快。