<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Parser</title><link>https://blog.ast.moe/en/tags/parser/</link><description>Recent posts: Gorimuchu</description><generator>Hugo</generator><item><title>Boa incorrectly judged stack usage due to ASAN's fake stack.</title><link>https://blog.ast.moe/en/blog/2026-09-10-3/</link><pubDate>Thu, 10 Sep 2026 20:14:12 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-10-3/</guid><description>&lt;p&gt;In the previous article, we fixed the issue where Boa’s parser exhausted a 2 MiB stack. (&lt;a href="https://blog.ast.moe/en/blog/2026-09-10-2/"&gt;related article&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;We reduced the frame size during recursion and made it return an error for inputs that are too deep. With a normal build, the original Test262 now also passes within the 2 MiB limit.&lt;/p&gt;
&lt;p&gt;When we continued diagnosing with AddressSanitizer (ASAN) in that state, it started rejecting even shallow inputs.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;parser recursion limit exceeded
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The protection we added to prevent stack exhaustion was stopping prematurely, even though the stack hadn’t been fully used. This concerns &lt;a href="https://github.com/ieee0824/omoikane/issues/640"&gt;Issue #640&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Boa's parser exhausted a 2 MiB stack</title><link>https://blog.ast.moe/en/blog/2026-09-10-2/</link><pubDate>Thu, 10 Sep 2026 19:58:13 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-10-2/</guid><description>&lt;p&gt;While running Test262 before importing Boa into Omoikane, we discovered a case where an unoptimized parser aborts due to a stack overflow (&lt;a href="https://github.com/ieee0824/omoikane/issues/633"&gt;issue #633&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The failure occurred in Test262’s &lt;a href="https://github.com/tc39/test262/blob/a073f479f80b336256b7fc4e04700c827293e2fe/test/staging/sm/regress/regress-672893.js"&gt;&lt;code&gt;regress-672893.js&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It wasn’t a matter of nesting tens of thousands of invalid JavaScript statements. It was valid JavaScript with about fifteen levels of nested function expressions.&lt;/p&gt;
&lt;p&gt;If we omit the structural details, the code looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;function f() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; return function () {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; return function () {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...continues in the same pattern up to 15 steps...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; return function (a) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; var v = a;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; return function () { return v; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;f()()() ... ()(42)();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When this code is passed to a Boa built with the dev profile and the thread stack is set to 2 MiB, the parser triggers a stack overflow and exits with status 134.&lt;/p&gt;</description></item></channel></rss>