Kiesel Devlog #15: Release 0.4.0

Kiesel Devlog #15: Release 0.4.0

Kiesel Devlog #15: Release 0.4.0 Published on 2026-10-08. This week I completed the update to Zig 0.17 and released Kiesel 0.4.0! It contains 64 commits across 2.5 months, see the changelog for the full list of user-facing changes.

Kiesel 开发日志 #15:版本 0.4.0 发布于 2026 年 10 月 8 日。本周我完成了向 Zig 0.17 的更新,并发布了 Kiesel 0.4.0!该版本在两个半月内包含了 64 次提交,请参阅更新日志以获取用户可见变更的完整列表。

Kiesel.args / Kiesel.env

I mostly build rather than use this project, and it shows — beyond the core language implementation only a few APIs needed for real-world programs are available. We did have file I/O for a while, and with the addition of arguments and environment reading a simple cat(1) clone becomes feasible:

Kiesel.args / Kiesel.env

我主要是构建而非使用这个项目,这一点显而易见——除了核心语言实现之外,只有少数几个用于实际程序的 API 可用。我们已经拥有文件 I/O 功能一段时间了,随着参数和环境变量读取功能的加入,实现一个简单的 cat(1) 克隆版变得可行:

#!/usr/bin/env kiesel
const [_exe, _script, ...files] = Kiesel.args;
if (files.length === 0) {
  const contents = Kiesel.readStdin();
  Kiesel.print(contents, { newline: false });
} else {
  for (const file of files) {
    const contents = Kiesel.readFile(file);
    Kiesel.print(contents, { newline: false });
  }
}

$ ./cat.js cat.js

Even More Iterator Helpers

Over the last few years JS has rapidly advanced the usability of iterators from just providing the basic protocol at the language level to a large collection of Iterator.prototype methods. The initial Iterator Helpers proposal shipped in 2024, followed by Iterator Sequencing in 2025, and Joint Iteration, Iterator Join, Iterator Includes, and Iterator Chunking all this year. Phew!

更多迭代器辅助方法

在过去几年中,JS 迭代器的易用性得到了飞速提升,从最初仅在语言层面提供基本协议,发展到如今拥有大量 Iterator.prototype 方法。最初的迭代器辅助提案于 2024 年发布,随后是 2025 年的迭代器序列化,以及今年的联合迭代、迭代器连接、迭代器包含和迭代器分块。呼!

The last three are newly implemented:

function* count() { for (let i = 1; ; ++i) yield i; }
console.log(count().take(3).join(" + "));
console.log(count().take(10).includes(5));
console.log(JSON.stringify(count().chunks(3).take(3).toArray()));

$ kiesel main.js 1 + 2 + 3 true [[1,2,3],[4,5,6],[7,8,9]] I also implemented the Await Dictionary proposal, which is still at Stage 3.

后三项是新实现的: (代码示例见上文) $ kiesel main.js 1 + 2 + 3 true [[1,2,3],[4,5,6],[7,8,9]] 我还实现了目前处于 Stage 3 阶段的 Await Dictionary 提案。

SerenityOS Port

I’ve done a number of fun ports over the years but this might be my favorite one yet! It’s an intersection of most of my notable open source work in the past six years: SerenityOS, the Zig project, and Kiesel itself.

SerenityOS 移植

多年来我做过许多有趣的移植工作,但这可能是我目前最喜欢的一个!它是过去六年来我大部分重要开源工作的交汇点:SerenityOS、Zig 项目以及 Kiesel 本身。

This required gradually upstreaming SerenityOS target support in Zig (#20913, #23192, #23198, #24561, #24633, #25457, #25779, #30756, #31916, #31931, #32172, #36465, #37064, #37065), a handful of SerenityOS LibC and Kernel changes (#25804, #26350, #26543, #26928), and the package itself (#26931), which is cross-compiled against a now minimally patched Zig standard library. I hope to have those remaining bits upstreamed by the time 0.18 is released :^)

这需要逐步将 SerenityOS 目标支持上游合并到 Zig 中(#20913, #23192, #23198, #24561, #24633, #25457, #25779, #30756, #31916, #31931, #32172, #36465, #37064, #37065),进行少量 SerenityOS LibC 和内核更改(#25804, #26350, #26543, #26928),以及软件包本身(#26931),该软件包是针对目前仅需极少补丁的 Zig 标准库进行交叉编译的。我希望在 0.18 版本发布时能将剩余部分上游合并 :^)

Other notable mentions: the long-anticipated DOS port finally became reality thanks to dos.zig being revived, and OpenBSD/NetBSD binaries are now built in CI.

其他值得一提的是:备受期待的 DOS 移植终于因 dos.zig 的复活而成为现实,OpenBSD/NetBSD 二进制文件现在也可以在 CI 中构建了。

Inline Caches

Inline caches are one of the fundamental optimizations used by virtually all JS engines (and various other dynamic programming languages). I recommend this blog post if you want to learn more about how they work.

内联缓存 (Inline Caches)

内联缓存是几乎所有 JS 引擎(以及其他各种动态编程语言)使用的基础优化之一。如果你想了解它们的工作原理,我推荐阅读这篇博客文章。

Kiesel had ICs for a long time, but the bytecode interpreter rewrite earlier this year left it with only a basic implementation of monomorphic property ICs. I’ve now fixed those gaps (#220, #221, #222):

  • Polymorphic property access (up to 4 before becoming megamorphic)
  • Computed property access
  • Prototype lookups

Kiesel 很早就有了 IC,但今年早些时候对字节码解释器的重写使其仅保留了单态属性 IC 的基本实现。现在我已经修复了这些缺失(#220, #221, #222):

  • 多态属性访问(在变为超态之前最多支持 4 个)
  • 计算属性访问
  • 原型查找

The output is rather cryptic, but you can see them in the emitted bytecode: $ kiesel —print-bytecode -c ‘o = {}; o.foo = 1; o.foo’ Bytecode (command) 0: 12 00 00 00 00 00 00 create_object r0, 0 7: 4e 00 00 00 00 00 00 set_binding @0 (“o”), r0 14: 49 00 00 00 00 00 00 get_binding r0, @0 (“o”) 21: 07 01 00 01 load_number_i8 r1, 1 25: 50 00 00 01 00 01 00 00 00 00 00 set_property r0, r1, @1 (“foo”), @0 36: 49 00 00 00 00 00 00 get_binding r0, @0 (“o”) 43: 4a 01 00 00 00 01 00 00 00 00 00 get_property r1, r0, @1 (“foo”), @0 54: 78 01 00 return r1

输出虽然有些晦涩,但你可以在生成的字节码中看到它们: (字节码示例见上文)

One (@0) set_property IC and one (@0) get_property IC. (They’re indexed by type, not shared.) The implementation is only a few hundred lines for all of them, but consistently provides speedups of 20-30% in microbenchmarks.

一个 (@0) set_property IC 和一个 (@0) get_property IC。(它们按类型索引,而非共享。)所有这些功能的实现仅需几百行代码,但在微基准测试中始终能提供 20-30% 的速度提升。

Plans for 0.5.0

The parser is about to get fast, stay tuned 👀

0.5.0 计划

解析器即将提速,敬请期待 👀