<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>JavaScript</title><link>https://blog.ast.moe/en/tags/javascript/</link><description>Recent posts: Gorimuchu</description><generator>Hugo</generator><item><title>After implementing Omoikane’s DOM and exception notifications, we ended up investigating copying and garbage‑collection lifetimes as well.</title><link>https://blog.ast.moe/en/blog/2026-10-10/</link><pubDate>Sat, 10 Oct 2026 17:42:29 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-10-10/</guid><description>&lt;p&gt;We added DOM operations such as &lt;code&gt;before()&lt;/code&gt; and &lt;code&gt;replaceChildren()&lt;/code&gt; to Omoikane, along with &lt;code&gt;window.onerror&lt;/code&gt; and notifications for unhandled Promise rejections. [&lt;a href="https://github.com/ieee0824/omoikane/pull/1322"&gt;PR #1322&lt;/a&gt;](&lt;a href="https://github.com/ieee0824/omoikane/pull/1322"&gt;https://github.com/ieee0824/omoikane/pull/1322&lt;/a&gt;) This is about that pull request. The initial issue was straightforward: the page lacked the APIs it normally calls. However, as we progressed with implementation and testing, we ended up fixing issues such as copying sibling lists when inserting HTML text, rebuilding the entire document after UTF‑16 appends, creating unnecessary iframe realms, and even addressing insufficient GC roots for Promises.&lt;/p&gt;</description></item><item><title>WeakMap and Generational Garbage Collection</title><link>https://blog.ast.moe/en/blog/2026-10-08-2/</link><pubDate>Thu, 08 Oct 2026 21:52:45 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-10-08-2/</guid><description>&lt;p&gt;Opening &lt;code&gt;https://tokyo6.tokyo/&lt;/code&gt; with Omoikane caused a bug where the script terminated with a SIGSEGV during execution. Issue #1223 (&lt;a href="https://github.com/ieee0824/omoikane/issues/1223"&gt;issue #1223&lt;/a&gt;) reproduces the problem not only in the GUI but also in the screenshot feature that renders the screen to an image. The backtrace from the debug build reproduced on a Linux aarch64 Docker development environment with Xvfb showed that Boa’s garbage collector halted while traversing references to an object.&lt;/p&gt;
&lt;p&gt;The fix in &lt;a href="https://github.com/ieee0824/omoikane/pull/1260"&gt;PR #1260&lt;/a&gt; (&lt;a href="https://github.com/ieee0824/omoikane/pull/1260"&gt;PR #1260&lt;/a&gt;) addressed the combination of an ephemeron—a conditional reference—and the generational garbage collector. A young object that was referenced by an older object was being reclaimed during the minor GC that followed a major GC. Subsequently, the major GC followed a reference that had already been freed, causing a crash.&lt;/p&gt;</description></item><item><title>What is a WeakMap?</title><link>https://blog.ast.moe/en/blog/2026-10-08/</link><pubDate>Thu, 08 Oct 2026 21:50:47 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-10-08/</guid><description>&lt;p&gt;JavaScript has &lt;code&gt;Map&lt;/code&gt;, which stores key‑value pairs, and a similarly named &lt;code&gt;WeakMap&lt;/code&gt;. Both can be registered with &lt;code&gt;set()&lt;/code&gt; and retrieved with &lt;code&gt;get()&lt;/code&gt;. However, WeakMap does not have &lt;code&gt;size&lt;/code&gt; nor &lt;code&gt;keys()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A WeakMap is a mechanism that associates information with objects without keeping the objects in memory solely because of that association. The term “weak” refers not to the data’s reliability or the accuracy of lookups, but to how the references to the keys are treated.&lt;/p&gt;</description></item><item><title>The object returned by Boa’s getter was collected by the garbage collector while the inline cache was being updated.</title><link>https://blog.ast.moe/en/blog/2026-09-30/</link><pubDate>Wed, 30 Sep 2026 08:12:00 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-30/</guid><description>&lt;p&gt;When running the test for a custom element associated with a form in Omoikane’s Web Platform Tests (WPT), it caused a SIGSEGV. The first occurrence was in a configuration that included the JIT, so we initially suspected an interaction between Boa’s JIT or its garbage collector. However, even when the JIT was disabled, the same crash could be reproduced (&lt;a href="https://github.com/ieee0824/omoikane/issues/858#issuecomment-5890658215"&gt;issue #858&lt;/a&gt;), and ultimately the problem lay in a tiny interval between when the getter’s returned object was produced and when it was stored in the VM’s registers.&lt;/p&gt;</description></item><item><title>Since generating realms with Omoikane was slow, I looked into Boa’s scope lookup and lexical analysis.</title><link>https://blog.ast.moe/en/blog/2026-09-29-2/</link><pubDate>Tue, 29 Sep 2026 18:25:00 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-29-2/</guid><description>&lt;p&gt;In the blog post investigating Omoikane’s CI wait times, we wrote about avoiding heavy verification for changes that only affect documentation and about revisiting the build cache. Separate from that, the tests that actually needed to be run were also taking a considerable amount of time. (&lt;a href="https://blog.ast.moe/en/blog/2026-09-29/"&gt;source&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Omoikane uses Boa to execute JavaScript. Each time a JavaScript realm is created for a page or an iframe, a large script that sets up the DOM API is run. This processing accounted for a substantial portion of the test runtime. In &lt;a href="https://github.com/ieee0824/omoikane/issues/1154"&gt;Issue #1154&lt;/a&gt;, instead of reducing the number of tests or realms, we investigated this initialization itself.&lt;/p&gt;</description></item><item><title>Tracing with Omoikane how a URL fragment becomes the CSS :target</title><link>https://blog.ast.moe/en/blog/2026-09-27/</link><pubDate>Sun, 27 Sep 2026 22:31:00 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-27/</guid><description>&lt;p&gt;Links that jump to headings on the page look simple.&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-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;a&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;#details&amp;#34;&lt;/span&gt;&amp;gt;Go to details&amp;lt;/&lt;span style="color:#f92672"&gt;a&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;section&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;details&amp;#34;&lt;/span&gt;&amp;gt;...&amp;lt;/&lt;span style="color:#f92672"&gt;section&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When you click this link, the URL’s end changes to &lt;code&gt;#details&lt;/code&gt;, and the corresponding element becomes the destination within the page. By using &lt;code&gt;:target&lt;/code&gt; in CSS, you can highlight only that element.&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-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:&lt;span style="color:#a6e22e"&gt;target&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;outline&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;solid&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;red&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Usually, understanding that “the part of the URL after &lt;code&gt;#&lt;/code&gt; matches &lt;code&gt;id&lt;/code&gt;” is sufficient. However, when trying to incorporate &lt;code&gt;:target&lt;/code&gt; into my own browser, &lt;a href="https://github.com/ieee0824/omoikane"&gt;Omoikane&lt;/a&gt;, that wasn’t enough. The URL‑parsing logic, the HTML rules for selecting the target, the document’s internal state, CSS selector matching, and the updates after changing &lt;code&gt;location.hash&lt;/code&gt; are all handled in separate places.&lt;/p&gt;</description></item><item><title>Fixed the origin‑boundary bypass that was present in the internal host function of Omoikane.</title><link>https://blog.ast.moe/en/blog/2026-09-26/</link><pubDate>Sat, 26 Sep 2026 07:06:58 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-26/</guid><description>&lt;p&gt;During the development of Omoikane, I happened to notice that the internal &lt;code&gt;__omoikane_*&lt;/code&gt; function was visible from the page’s JavaScript. By examining the code, I confirmed through static analysis that passing a different Document or Node ID could create a path that reaches the DOM, cookies, or storage of a cross‑origin document without going through the same‑origin policy. I did not create a proof‑of‑concept that actually reproduced the read/write behavior before the fix. After the fix, I verified in regression tests that cross‑origin access is properly blocked.&lt;/p&gt;</description></item><item><title>JavaScript Realms as Seen Through Omoikane’s iframe Implementation</title><link>https://blog.ast.moe/en/blog/2026-09-25-3/</link><pubDate>Fri, 25 Sep 2026 19:04:46 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-25-3/</guid><description>&lt;p&gt;When working with iframes in my custom browser
&lt;span&gt;
&lt;a target="_blank" href="https://github.com/ieee0824/omoikane"&gt;
Omoikane
&lt;/a&gt;
&lt;img class="external-link-icon" src="https://blog.ast.moe/images/outer-link.png" width="12" height="12" alt="" aria-hidden="true" loading="lazy"&gt;
&lt;/span&gt;
, I kept coming back to the concept of Realms. At first I thought of it as simply “creating a separate JavaScript execution environment for child frames.” However, merely creating a separate environment wasn’t enough. When a parent accesses the child’s &lt;code&gt;Array&lt;/code&gt;, when an iframe navigates to a different page, or when a timer that was scheduled in the child later fires, it becomes necessary to determine which Realm’s values are being used for which Document in each case.&lt;/p&gt;</description></item><item><title>A SIGSEGV occurred after garbage collection because the iterator function passed to Boa’s Array.from was not properly retained.</title><link>https://blog.ast.moe/en/blog/2026-09-25/</link><pubDate>Fri, 25 Sep 2026 08:46:00 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-25/</guid><description>&lt;p&gt;While running Omoikane’s Acid3 test, the process hit a SIGSEGV under the baseline JIT configuration on macOS ARM64. I briefly mentioned this in the earlier blog post about Omoikane updates, but the cause wasn’t the test itself nor the JIT’s machine‑code generation; it lay in the Boa code we’re incorporating, specifically in the &lt;code&gt;Array.from()&lt;/code&gt; section. Omoikane incorporates Boa’s source code together with the browser‑side implementation, so the fix was also applied to the engine that pulls in that code. (&lt;a href="https://blog.ast.moe/en/blog/2026-09-20/"&gt;source&lt;/a&gt;)&lt;/p&gt;</description></item><item><title>I advanced browser compatibility for cookies and scrolling in Omoikane.</title><link>https://blog.ast.moe/en/blog/2026-09-23-2/</link><pubDate>Wed, 23 Sep 2026 21:39:00 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-23-2/</guid><description>&lt;p&gt;In my custom browser
&lt;span&gt;
&lt;a target="_blank" href="https://github.com/ieee0824/omoikane"&gt;
Omoikane
&lt;/a&gt;
&lt;img class="external-link-icon" src="https://blog.ast.moe/images/outer-link.png" width="12" height="12" alt="" aria-hidden="true" loading="lazy"&gt;
&lt;/span&gt;
, I made several changes related to Web API and CSS compatibility.&lt;/p&gt;
&lt;p&gt;Looking at these changes, many of them went beyond simply adding APIs visible to JavaScript. It was necessary to convey the page’s state to the host, reflect JavaScript actions in HTTP communication, and preserve the scroll position set by CSS until the input processing is finished.&lt;/p&gt;
&lt;h2 id="cookies-were-handled-separately-for-javascript-and-http"&gt;Cookies were handled separately for JavaScript and HTTP&lt;/h2&gt;
&lt;p&gt;The first thing we fixed was how cookies are managed.&lt;/p&gt;</description></item><item><title>Implemented Pointer Lock and form‑related custom elements in Omoikane.</title><link>https://blog.ast.moe/en/blog/2026-09-20/</link><pubDate>Sun, 20 Sep 2026 11:25:48 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-20/</guid><description>&lt;p&gt;I added Pointer Lock support and custom form‑related elements to my self‑made browser (
&lt;span&gt;
&lt;a target="_blank" href="https://github.com/ieee0824/omoikane"&gt;
Omoikane
&lt;/a&gt;
&lt;img class="external-link-icon" src="https://blog.ast.moe/images/outer-link.png" width="12" height="12" alt="" aria-hidden="true" loading="lazy"&gt;
&lt;/span&gt;
).&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.ast.moe/en/blog/2026-09-19-3/"&gt;In the previous post I wrote about Fullscreen API and character‑encoding conversion streams&lt;/a&gt;. This time I’m covering the pathway for delivering mouse input to the page and the logic for integrating my custom input components into HTML forms.&lt;/p&gt;
&lt;p&gt;Neither of these is a huge undertaking if you only consider the entry‑point APIs. However, when we actually hooked everything up, we ran into issues such as mouse input being delivered twice on X11, iframe callbacks executing in a different runtime environment, and even pages that don’t use forms becoming sluggish. In the end, the macOS tests caused the entire process to crash.&lt;/p&gt;</description></item><item><title>Implemented the Fullscreen API and character‑encoding conversion streams in Omoikane.</title><link>https://blog.ast.moe/en/blog/2026-09-19-3/</link><pubDate>Sat, 19 Sep 2026 20:46:07 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-19-3/</guid><description>&lt;p&gt;I added the Fullscreen API and &lt;code&gt;TextEncoderStream&lt;/code&gt;/&lt;code&gt;TextDecoderStream&lt;/code&gt; to my custom browser,
&lt;span&gt;
&lt;a target="_blank" href="https://github.com/ieee0824/omoikane"&gt;
Omoikane
&lt;/a&gt;
&lt;img class="external-link-icon" src="https://blog.ast.moe/images/outer-link.png" width="12" height="12" alt="" aria-hidden="true" loading="lazy"&gt;
&lt;/span&gt;
.&lt;/p&gt;
&lt;p&gt;Previously, I implemented the Popover API and a top layer (see /blog/2026-09-14/). This time, I connected that rendering pipeline to the Fullscreen API and, as a separate task, made character‑encoding conversion usable via the Streams API. (&lt;a href="https://blog.ast.moe/en/blog/2026-09-14/"&gt;source&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Fullscreen display and character‑encoding conversion are fairly unrelated features. However, neither could be completed simply by adding a JavaScript method.&lt;/p&gt;</description></item><item><title>Implemented the Popover API and top layer in the custom browser Omoikane.</title><link>https://blog.ast.moe/en/blog/2026-09-14/</link><pubDate>Mon, 14 Sep 2026 16:34:41 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-14/</guid><description>&lt;p&gt;I have implemented the HTML Popover API in my custom browser, Omoikane (&lt;a href="https://github.com/ieee0824/omoikane"&gt;source&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;With the Popover API, you can open and close popovers using only HTML, without needing to manage their visibility state with JavaScript.&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-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;button&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;popovertarget&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;menu&amp;#34;&lt;/span&gt;&amp;gt;Open menu&amp;lt;/&lt;span style="color:#f92672"&gt;button&lt;/span&gt;&amp;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;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;menu&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;popover&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;button&lt;/span&gt;&amp;gt;Item 1&amp;lt;/&lt;span style="color:#f92672"&gt;button&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;button&lt;/span&gt;&amp;gt;Item 2&amp;lt;/&lt;span style="color:#f92672"&gt;button&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At first glance, it seems all you’d need to do is add an API to toggle the element’s &lt;code&gt;display&lt;/code&gt; state.&lt;/p&gt;
&lt;p&gt;In reality, popovers are rendered on a top layer that lies outside the normal stacking order. There are considerations such as light dismissal when clicking outside, closing with the Escape key, focus movement and restoration, &lt;code&gt;::backdrop&lt;/code&gt;, and the ordering relationship with dialogs.&lt;/p&gt;</description></item><item><title>I investigated why Acid3 was crashing due to memory errors in Omoikane’s baseline JIT.</title><link>https://blog.ast.moe/en/blog/2026-09-13/</link><pubDate>Sun, 13 Sep 2026 20:20:51 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-13/</guid><description>&lt;p&gt;While working on implementing CSS in my own browser, Omoikane (&lt;a href="https://github.com/ieee0824/omoikane"&gt;source&lt;/a&gt;), Acid3 began crashing due to memory errors.&lt;/p&gt;
&lt;p&gt;The problem only occurs when the baseline JIT is enabled; it runs fine with the interpreter.&lt;/p&gt;
&lt;p&gt;Furthermore, Omoikane’s Acid3 runner has two execution modes, Faithful and DirectDrive. Faithful completes all 100 points, but then it crashes during DirectDrive.&lt;/p&gt;
&lt;p&gt;The failure manifests differently depending on the environment.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Environment&lt;/th&gt;
&lt;th&gt;Observed failure&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;x86_64 Linux&lt;/td&gt;
&lt;td&gt;SIGSEGV&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ARM64 Linux&lt;/td&gt;
&lt;td&gt;SIGABRT, ~60 GB allocation, SIGSEGV on rerun&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ARM64 macOS&lt;/td&gt;
&lt;td&gt;SIGSEGV, SIGBUS on rerun&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Even though it’s the same test, the signals differ.&lt;/p&gt;</description></item><item><title>I forgot to keep a Promise alive in Boa, which broke the malloc.</title><link>https://blog.ast.moe/en/blog/2026-09-10-4/</link><pubDate>Thu, 10 Sep 2026 20:37:07 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-10-4/</guid><description>&lt;p&gt;While running Boa’s Test262, the test occasionally failed with exit code 134.&lt;/p&gt;
&lt;p&gt;The logs show the following errors:&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;malloc(): unsorted double linked list corrupted
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The issue is the “normal Test262 release run is aborted due to an allocator consistency error” (&lt;a href="https://github.com/ieee0824/omoikane/issues/638"&gt;issue #638&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;At first, I assumed some recent change was corrupting memory somewhere. However, because Test262 runs a large number of tests in parallel, the logs alone don’t reveal which specific test is causing the problem.&lt;/p&gt;</description></item><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><item><title>The Float16 conversion results differed between x86_64 and ARM64.</title><link>https://blog.ast.moe/en/blog/2026-09-10/</link><pubDate>Thu, 10 Sep 2026 19:11:38 +0900</pubDate><guid>https://blog.ast.moe/en/blog/2026-09-10/</guid><description>&lt;p&gt;In the pre‑migration verification of Boa for Omoikane (&lt;a href="https://github.com/ieee0824/omoikane/issues/655"&gt;issue #655&lt;/a&gt;), we ran the same Boa and Test262 on Linux x86_64 and ARM64, and the results differed in only 10 cases.&lt;/p&gt;
&lt;p&gt;A total of 50,595 cases were executed.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Environment&lt;/th&gt;
&lt;th style="text-align: right"&gt;Passed&lt;/th&gt;
&lt;th style="text-align: right"&gt;Failed&lt;/th&gt;
&lt;th style="text-align: right"&gt;Ignored&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Linux x86_64&lt;/td&gt;
&lt;td style="text-align: right"&gt;47,606&lt;/td&gt;
&lt;td style="text-align: right"&gt;933&lt;/td&gt;
&lt;td style="text-align: right"&gt;2,056&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linux ARM64&lt;/td&gt;
&lt;td style="text-align: right"&gt;47,616&lt;/td&gt;
&lt;td style="text-align: right"&gt;923&lt;/td&gt;
&lt;td style="text-align: right"&gt;2,056&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The ten cases that differed were all tests related to the conversion to &lt;code&gt;Float16&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It’s problematic that JavaScript results change when the CPU changes even though the source code and inputs are identical. We investigated what was happening.&lt;/p&gt;</description></item></channel></rss>