<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Boa JS Blog</title>
        <link>https://boajs.dev/blog</link>
        <description>Boa JS Blog</description>
        <lastBuildDate>Wed, 22 Oct 2025 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Boa release v0.21]]></title>
            <link>https://boajs.dev/blog/2025/10/22/boa-release-21</link>
            <guid>https://boajs.dev/blog/2025/10/22/boa-release-21</guid>
            <pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Boa release v0.21]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="summary">Summary<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>Boa v0.21 is now available! After 9 months of development we are very
happy to present you the latest release of the Boa JavaScript engine.
Boa makes it easy to embed a JS engine in your projects, and you can
even use it from WebAssembly. See the <a href="https://boajs.dev/about">about</a> page for more
info.</p>
<p>In this release, our conformance has grown from 89.92% to 94.12% in the
official ECMAScript Test Suite (Test262). Our growth in conformance is
driven by increased conformance for Temporal (discussed further below)
with the rest of the development effort being focused on performance,
internal improvements, and runtime features. We will continue to implement
more of the specification; however, as of the current moment, Boa's conformance
aligns with the major browser engine's conformance, so future increases
in conformance will be minor or bound to the feature size going forward.</p>
<p>You can check the full list of changes <a href="https://github.com/boa-dev/boa/blob/v0.21/CHANGELOG.md" target="_blank" rel="noopener noreferrer">here</a>, and the full
information on conformance <a href="https://boajs.dev/boa/test262/" target="_blank" rel="noopener noreferrer">here</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="feature-highlights">Feature Highlights<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#feature-highlights" class="hash-link" aria-label="Direct link to Feature Highlights" title="Direct link to Feature Highlights" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="temporal">Temporal<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#temporal" class="hash-link" aria-label="Direct link to Temporal" title="Direct link to Temporal" translate="no">​</a></h3>
<p>There has been a lot of progress made on Temporal, the new Stage 3
date/time proposal. With this release, Boa's conformance on Temporal
grew from 40.67% to ~97%. This implementation is backed by the <code>temporal_rs</code>
date/time Rust library, which we went over in our announcement
<a href="https://boajs.dev/blog/2025/09/24/temporal-release">blog post</a>. Give the post a read if you are
interested in <code>temporal_rs</code> and its development history.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="span-nodes-and-error-backtraces">Span nodes and error backtraces<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#span-nodes-and-error-backtraces" class="hash-link" aria-label="Direct link to Span nodes and error backtraces" title="Direct link to Span nodes and error backtraces" translate="no">​</a></h3>
<p>We added support for storing spans in our AST nodes, which allows determining the
exact location of an AST node on its original file. We already kind of
supported this feature in our lexer, but we did not store the spans after parsing.</p>
<p>Why is this important? Well, as a direct result from this, Boa now supports error backtraces
when an exception is thrown!</p>
<p><img decoding="async" loading="lazy" alt="backtrace-example" src="https://boajs.dev/assets/images/backtrace-e7d4907c722942308a2cc4e0449138e7.gif" width="1200" height="600" class="img_ev3q"></p>
<p>As an additional plus, you can enable the <code>native-backtrace</code> feature to include
"native" functions on a backtrace.</p>
<p><img decoding="async" loading="lazy" alt="native-backtrace-example" src="https://boajs.dev/assets/images/native-backtrace-40dcf10962db4b6360bd6a07c43be444.gif" width="1200" height="600" class="img_ev3q"></p>
<p>This feature has been one of the most requested ones for years,
and we hope it will
greatly help with debugging errors when using Boa.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="utility-macros">Utility macros<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#utility-macros" class="hash-link" aria-label="Direct link to Utility macros" title="Direct link to Utility macros" translate="no">​</a></h3>
<p>We introduced a new set of proc macros that make it much easier to create <a href="https://docs.rs/boa_engine/0.21.0/boa_engine/value/struct.JsValue.html" target="_blank" rel="noopener noreferrer"><code>JsValue</code></a>s,
<a href="https://docs.rs/boa_engine/0.21.0/boa_engine/object/struct.JsObject.html" target="_blank" rel="noopener noreferrer"><code>JsObject</code></a>s, <a href="https://docs.rs/boa_engine/0.21.0/boa_engine/class/trait.Class.html" target="_blank" rel="noopener noreferrer"><code>Class</code></a>es and even <a href="https://docs.rs/boa_engine/0.21.0/boa_engine/module/struct.Module.html" target="_blank" rel="noopener noreferrer"><code>Module</code></a>s. Let's see them in action!</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="js_value"><a href="https://docs.rs/boa_engine/0.21.0/boa_engine/macro.js_value.html" target="_blank" rel="noopener noreferrer"><code>js_value</code></a><a href="https://boajs.dev/blog/2025/10/22/boa-release-21#js_value" class="hash-link" aria-label="Direct link to js_value" title="Direct link to js_value" translate="no">​</a></h4>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Simple values can be created without passing the `Context`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert_eq!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token macro property" style="color:#36acaa">js_value!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert_eq!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token macro property" style="color:#36acaa">js_value!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// To create arrays and objects, the context needs to be passed in.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert_eq!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token macro property" style="color:#36acaa">js_value!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">display</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"[ 1, 2, 3 ]"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert_eq!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token macro property" style="color:#36acaa">js_value!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Comments are allowed inside.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"key"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"value"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">display</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string" style="color:#e3116c">"{\n    key: \"value\"\n}"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="js_object"><a href="https://docs.rs/boa_engine/0.21.0/boa_engine/macro.js_object.html" target="_blank" rel="noopener noreferrer"><code>js_object</code></a><a href="https://boajs.dev/blog/2025/10/22/boa-release-21#js_object" class="hash-link" aria-label="Direct link to js_object" title="Direct link to js_object" translate="no">​</a></h4>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> object </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">js_object!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Comments are allowed inside. String literals will always be transformed to `JsString`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string" style="color:#e3116c">"key"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"value"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Identifiers will be used as keys, like in JavaScript.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  alsoKey</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Expressions surrounded by brackets will be expressed, like in JavaScript.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Note that in this case, the unit value is represented by `null`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert_eq!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">object</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">display</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"{\n    3: null,\n    key: \"value\",\n    alsoKey: 1\n}"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="boa_class"><a href="https://docs.rs/boa_engine/0.21.0/boa_engine/attr.boa_class.html" target="_blank" rel="noopener noreferrer"><code>boa_class</code></a><a href="https://boajs.dev/blog/2025/10/22/boa-release-21#boa_class" class="hash-link" aria-label="Direct link to boa_class" title="Direct link to boa_class" translate="no">​</a></h4>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// All types that will be part of a class instance need to derive the</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// `Trace` and `Finalize` traits.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute attr-name" style="color:#00a4db">#[derive(Clone, Trace, Finalize, JsData)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">enum</span><span class="token plain"> </span><span class="token type-definition class-name">AnimalType</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Cat</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Dog</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Other</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute attr-name" style="color:#00a4db">#[derive(Clone, Trace, Finalize, JsData)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Animal</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ty</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">AnimalType</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    age</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute attr-name" style="color:#00a4db">#[boa_class]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">impl</span><span class="token plain"> </span><span class="token class-name">Animal</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Sets this method as the constructor of the ECMAScript class.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[boa(constructor)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> age</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">Self</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> ty </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">match</span><span class="token plain"> name</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">as_str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"cat"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token class-name">AnimalType</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Cat</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"dog"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token class-name">AnimalType</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Dog</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            _ </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token class-name">AnimalType</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Other</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">Self</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> ty</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> age </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Any method that takes `&amp;self` will be exposed as an instance method.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">speak</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attribute attr-name" style="color:#00a4db">#[boa(error = </span><span class="token attribute attr-name string" style="color:#e3116c">"`this` was not an animal"</span><span class="token attribute attr-name" style="color:#00a4db">)]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsString</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">match</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ty </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token class-name">AnimalType</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Cat</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"meow"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token class-name">AnimalType</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Dog</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"woof"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token class-name">AnimalType</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Other</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">r"¯\_(ツ)_/¯"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Force this being a method (instead of a static function) by declaring it</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// as a method.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[boa(method)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[boa(length = 11)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">method</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsObject</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> obj </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">JsObject</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">with_null_proto</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        obj</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"key"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">43</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        obj</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// You can define getter methods; `animal.age` will automatically call this</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// on read.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[boa(getter)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">age</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">age</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// You can also define setter methods; `animal.age = 5` will automatically call</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// this on write.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[boa(setter)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[boa(method)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[boa(rename = </span><span class="token attribute attr-name string" style="color:#e3116c">"age"</span><span class="token attribute attr-name" style="color:#00a4db">)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">set_age</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> age</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">age </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> age</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// This static method will be callable using the constructor function</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// (`Animal.marked_static_method()`).</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[boa(static)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">marked_static_method</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token number" style="color:#36acaa">123</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Methods without `&amp;self` are considered static methods.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">static_method</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token number" style="color:#36acaa">42</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// This registers the newly created class into the `Realm`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">register_global_class</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Animal</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">context</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">eval</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_bytes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">r#"</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        let pet = new Animal("dog", 3);</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        console.log(pet.age) // 3</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        console.log(Animal.staticMethod()) // 42</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        console.log(Animal.markedStaticMethod()) // 123</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        v = pet.method();</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        console.log(v.key) // 43</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        pet.age = 4;</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        console.log(pet.age) // 4</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    "#</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="boa_module"><a href="https://docs.rs/boa_engine/0.21.0/boa_engine/attr.boa_module.html" target="_blank" rel="noopener noreferrer"><code>boa_module</code></a><a href="https://boajs.dev/blog/2025/10/22/boa-release-21#boa_module" class="hash-link" aria-label="Direct link to boa_module" title="Direct link to boa_module" translate="no">​</a></h4>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute attr-name" style="color:#00a4db">#[boa_module]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">mod</span><span class="token plain"> </span><span class="token module-declaration namespace" style="opacity:0.7">hello</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">boa_engine</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token class-name">JsString</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> js_string</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Exports a function.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">world</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsString</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"hello world"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Exports the `Animal` class. This is the class that we defined in the</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// previous section.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token type-definition class-name">Animal</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">super</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Animal</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Exports a const variable.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">SOME_LITERAL_NUMBER</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1234</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// You can also rename exports.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[boa(rename = </span><span class="token attribute attr-name string" style="color:#e3116c">"this_is_different"</span><span class="token attribute attr-name" style="color:#00a4db">)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">SOME_OTHER_LITERAL</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5678</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Creates a new `MapModuleLoader` to load our created module into the</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// engine.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> module_loader </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Rc</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">MapModuleLoader</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">builder</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">module_loader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">module_loader</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">clone</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">build</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// The module will be exposed as `/hello.js`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">module_loader</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">insert</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/hello.js"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">hello</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token function" style="color:#d73a49">boa_module</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> module </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Module</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_bytes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">r#"</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">            import * as m from '/hello.js';</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">            console.log(m.someLiteralNumber) // 1234</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">            console.log(m.this_is_different) // 5678</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">            console.log(m.world()) // "hello world"</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">            let pet = new m.Animal("dog", 8);</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">            console.log(pet.age) // 8</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">            console.log(pet.speak()) // "woof"</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        "#</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> module</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">load_link_evaluate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">await_blocking</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="async-apis-enhancements">Async APIs enhancements<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#async-apis-enhancements" class="hash-link" aria-label="Direct link to Async APIs enhancements" title="Direct link to Async APIs enhancements" translate="no">​</a></h3>
<p>Historically, hooking functions returning a <code>Future</code> into Boa has been one of the
biggest pain points of our API. This was mostly caused by how we defined
<a href="https://docs.rs/boa_engine/0.20.0/boa_engine/job/type.FutureJob.html" target="_blank" rel="noopener noreferrer"><code>FutureJob</code></a>:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">NativeJob</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    f</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Box</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">dyn</span><span class="token plain"> </span><span class="token class-name">FnOnce</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">JsValue</span><span class="token operator" style="color:#393A34">&gt;&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    realm</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Option</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Realm</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token type-definition class-name">FutureJob</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Pin</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Box</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">dyn</span><span class="token plain"> </span><span class="token class-name">Future</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Output</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">NativeJob</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token lifetime-annotation symbol" style="color:#36acaa">'static</span><span class="token operator" style="color:#393A34">&gt;&gt;</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>With this definition, it was pretty much impossible to capture the <code>Context</code>
inside the <code>Future</code>, and functions that needed to interweave engine operations
with awaiting <code>Future</code>s needed to be split into multiple parts:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> fetch </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">move</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> body</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Result</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">_</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">isahc</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">Error</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> response </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Request</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">url</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">body</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">send_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">response</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Since the async context cannot take the `context` by ref, we have to continue</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// parsing inside a new `NativeJob` that will be enqueued into the promise job queue.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">NativeJob</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">move</span><span class="token plain"> </span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token closure-params">context</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">JsValue</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">body</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Also needed to match `NativeJob::new`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">undefined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Just enqueue the future for now. We'll advance all the enqueued futures inside our custom</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// `JobQueue`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">context</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">job_queue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">enqueue_future_job</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Box</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">pin</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fetch</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>We wanted to improve this API, and the solution we thought about was to make
<code>Context</code> shareable by wrapping it using <code>RefCell</code>. However, this proved to be
very difficult for two reasons:</p>
<ol>
<li>We needed to change all definitions to take <code>&amp;RefCell&lt;Context&gt;</code> instead
of <code>&amp;mut Context</code>, which meant changing pretty much the whole codebase.</li>
<li>Some of our VM code was reentrant, and that would cause panics in the reentrant
parts of the code when calling <code>RefCell::borrow_mut</code>; we would need to patch up
the engine to remove the reentrancy.</li>
</ol>
<p>After putting a lot of thought on this, we came up with a really nice solution;
instead of wrapping <code>Context</code> with <code>RefCell</code>, we would wrap <code>&amp;mut Context</code> with
<code>RefCell</code>, and only on the async-related APIs. This would allow not only capturing
the context on <code>Future</code>-related functions, but also doing this without having to
refactor big parts of the code. Thus, we ditched <code>FutureJob</code> and introduced a new
type of job: <a href="https://docs.rs/boa_engine/0.21.0/boa_engine/job/struct.NativeAsyncJob.html" target="_blank" rel="noopener noreferrer"><code>NativeAsyncJob</code></a>.</p>
<div class="language-Rust language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">/// An ECMAScript [Job] that can be run asynchronously.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">///</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/// This is an additional type of job that is not defined by the specification, enabling running `Future` tasks</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/// created by ECMAScript code in an easier way.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute attr-name" style="color:#00a4db">#[allow(clippy::type_complexity)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">NativeAsyncJob</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    f</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Box</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">dyn</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">for</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token lifetime-annotation symbol" style="color:#36acaa">'a</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token class-name">FnOnce</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token lifetime-annotation symbol" style="color:#36acaa">'a</span><span class="token plain"> </span><span class="token class-name">RefCell</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">BoxedFuture</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token lifetime-annotation symbol" style="color:#36acaa">'a</span><span class="token operator" style="color:#393A34">&gt;&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    realm</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Option</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Realm</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>With this change, any API that integrates with <code>Future</code> can additionally capture
the <code>&amp;RefCell&lt;&amp;mut Context&gt;</code> to run engine-related operations after awaiting on
a <code>Future</code>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="revamped-jobqueue">Revamped <code>JobQueue</code><a href="https://boajs.dev/blog/2025/10/22/boa-release-21#revamped-jobqueue" class="hash-link" aria-label="Direct link to revamped-jobqueue" title="Direct link to revamped-jobqueue" translate="no">​</a></h3>
<p>After introducing the new job type, changes had to be made on
<a href="https://docs.rs/boa_engine/0.20.0/boa_engine/job/trait.JobQueue.html" target="_blank" rel="noopener noreferrer"><code>JobQueue</code></a> to better support new types of jobs. Thus, <code>JobQueue</code> was revamped and renamed to be the
new <a href="https://docs.rs/boa_engine/0.21.0/boa_engine/job/trait.JobExecutor.html" target="_blank" rel="noopener noreferrer"><code>JobExecutor</code></a>:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">/// An executor of `ECMAscript` [Jobs].</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">///</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/// This is the main API that allows creating custom event loops.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">///</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/// [Jobs]: https://tc39.es/ecma262/#sec-jobs</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">trait</span><span class="token plain"> </span><span class="token type-definition class-name">JobExecutor</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Any</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">/// Enqueues a `Job` on the executor.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">///</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">/// This method combines all the host-defined job enqueueing operations into a single method.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">/// See the [spec] for more information on the requirements that each operation must follow.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">///</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">/// [spec]: https://tc39.es/ecma262/#sec-jobs</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">enqueue_job</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Rc</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">Self</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> job</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Job</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">/// Runs all jobs in the executor.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">run_jobs</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Rc</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">Self</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">/// Asynchronously runs all jobs in the executor.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">///</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">/// By default forwards to [`JobExecutor::run_jobs`]. Implementors using async should override this</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">/// with a proper algorithm to run jobs asynchronously.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">run_jobs_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Rc</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">Self</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">RefCell</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">where</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">Self</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Sized</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">run_jobs</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">borrow_mut</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>As you can probably tell, we made a lot of changes on <code>JobExecutor</code>:</p>
<ul>
<li>All methods now take <code>Rc&lt;Self&gt;</code> as their receiver, making it consistent with
how the <code>Context</code> itself stores the <code>JobExecutor</code>.</li>
<li><a href="https://docs.rs/boa_engine/0.20.0/boa_engine/job/trait.JobQueue.html#tymethod.enqueue_promise_job" target="_blank" rel="noopener noreferrer"><code>enqueue_promise_job</code></a> and <a href="https://docs.rs/boa_engine/0.20.0/boa_engine/job/trait.JobQueue.html#tymethod.enqueue_future_job" target="_blank" rel="noopener noreferrer"><code>enqueue_future_job</code></a> now are unified in a single
<a href="https://docs.rs/boa_engine/0.21.0/boa_engine/job/trait.JobExecutor.html#tymethod.enqueue_job" target="_blank" rel="noopener noreferrer"><code>enqueue_job</code></a>, where <a href="https://docs.rs/boa_engine/0.21.0/boa_engine/job/enum.Job.html" target="_blank" rel="noopener noreferrer"><code>Job</code></a> is an enum containing the type of job that needs to
be scheduled. This makes it much simpler to extend the engine with newer job
types in the future, such as the newly introduced <code>TimeoutJob</code> and <code>GenericJob</code>
types.</li>
<li><a href="https://docs.rs/boa_engine/0.21.0/boa_engine/job/trait.JobExecutor.html#method.run_jobs_async" target="_blank" rel="noopener noreferrer"><code>run_jobs_async</code></a> was converted to a proper async function, and excluded from
<code>JobExecutor</code>'s VTable. Additionally, this method now takes a <code>&amp;RefCell&lt;&amp;mut Context&gt;</code>
as its context, which is the missing piece that enables sharing the <code>Context</code> between
multiple <code>Future</code>s at the same time. This, however, means that we cannot provide
a convenient wrapper such as <a href="https://docs.rs/boa_engine/0.21.0/boa_engine/context/struct.Context.html#method.run_jobs" target="_blank" rel="noopener noreferrer"><code>Context::run_jobs</code></a> for it anymore, which is one of the
reasons why we decided to exclude that method from <code>JobExecutor</code>'s VTable.</li>
</ul>
<p>These changes not only made <code>JobExecutor</code> much simpler, but it also expanded
the places where we could use its async capabilities to handle "special"
features of ECMAScript that are more suited to an async way of doing things.
<code>ModuleLoader</code> is one of those places.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="asyncified-moduleloader">Asyncified <code>ModuleLoader</code><a href="https://boajs.dev/blog/2025/10/22/boa-release-21#asyncified-moduleloader" class="hash-link" aria-label="Direct link to asyncified-moduleloader" title="Direct link to asyncified-moduleloader" translate="no">​</a></h3>
<p>Looking at the previous definition of <a href="https://docs.rs/boa_engine/0.20.0/boa_engine/module/trait.ModuleLoader.html" target="_blank" rel="noopener noreferrer"><code>ModuleLoader</code></a>:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">trait</span><span class="token plain"> </span><span class="token type-definition class-name">ModuleLoader</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Required method</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">load_imported_module</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        referrer</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Referrer</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        specifier</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">JsString</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        finish_load</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Box</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">dyn</span><span class="token plain"> </span><span class="token class-name">FnOnce</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Module</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Provided methods</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">register_module</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> _specifier</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">JsString</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> _module</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Module</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">...</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">get_module</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> _specifier</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">JsString</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">Option</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Module</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">...</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">init_import_meta</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        _import_meta</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">JsObject</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        _module</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">Module</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        _context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">...</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>... the weird <code>finish_load</code> on <code>load_imported_module</code> immediately pops up as an anomaly.
In this case, <code>finish_load</code> is Boa's equivalent to
<a href="https://tc39.es/ecma262/#sec-HostLoadImportedModule" target="_blank" rel="noopener noreferrer">HostLoadImportedModule ( referrer, moduleRequest, hostDefined, payload )</a>,
which is an abstract operation that is primarily used to define how an application
will load and resolve a "module request"; think of it as a function that takes
the <code>"module-name"</code> from <code>import * as name from "module-name"</code>, then does
"things" to load the module that corresponds to <code>"module_name"</code>.</p>
<p>The peculiarity about this abstract operation is that it doesn't return anything!
Instead, it just has a special requirement:</p>
<blockquote>
<p>The host environment must perform <code>FinishLoadingImportedModule(referrer, moduleRequest, payload, result)</code>,
where result is either a normal completion containing the loaded <code>Module Record</code> or a throw completion,
either synchronously or asynchronously.</p>
</blockquote>
<p>Why expose the hook this way? Well, there is a clue in the previous requirement:</p>
<blockquote>
<p>... either synchronously or asynchronously.</p>
</blockquote>
<p>Aha! Directly returning from the hook makes it very hard to enable use cases
where an application wants to load multiple modules asynchronously. Thus, the
specification instead exposes a hook to pass the name of the module that needs to
be loaded, and delegates the task of running the "post-load" phase to the host, which
enables fetching modules synchronously or asynchronously, depending on the specific
requirements of each application.</p>
<p>One downside of this definition, however, is that any data that is required
by the engine to properly process the returned module would need to be transparently
passed to the <code>FinishLoadingImportedModule</code> abstract operation, which is why
the hook also has an additional requirement:</p>
<blockquote>
<p>The operation must treat <code>payload</code> as an opaque value to be passed through to
<code>FinishLoadingImportedModule</code>.</p>
</blockquote>
<p><code>payload</code> is precisely that data, and it may change depending on how the module
is imported in the code; <code>import "module"</code> and <code>import("module")</code> are two examples
of this.</p>
<p>We could expose this as an opaque <code>*const ()</code> pointer argument and call it a day,
but we're using Rust, dang it! and we like statically guaranteed safety!
So, instead, we exposed <code>FinishLoadingImportedModule</code> as <code>finish_load</code>, which is a
"closure" that captures <code>payload</code> on its stack, and can be called anywhere
(like inside a <code>Future</code>) on the application with a proper <code>Module</code> and <code>Context</code>
to further continue processing the module loaded by the <code>ModuleLoader</code>.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">finish_load</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Box</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">dyn</span><span class="token plain"> </span><span class="token class-name">FnOnce</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Module</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">...</span><br></span></code></pre></div></div>
<p>Unfortunately, this API has downsides:</p>
<ul>
<li>It's possible to forget to call <code>finish_load</code>, which is safer than a dangling <code>*const()</code>
pointer, but still prone to bugs.</li>
<li>It is also really painful to work with, because you cannot capture the <code>Context</code>
to further process the module after loading it. ... Sounds familiar?
<strong><a href="https://boajs.dev/blog/2025/10/22/boa-release-21#async-apis-enhancements">The async code snippet we showed before</a> has this exact problem!</strong>
And that snippet is directly taken from <a href="https://github.com/boa-dev/boa/blob/b345775138f56401bd627b1f36daadfc5bf75772/examples/src/bin/module_fetch.rs#L38" target="_blank" rel="noopener noreferrer">one of our <code>ModuleLoader</code> implementation examples</a>.</li>
</ul>
<p>Fast forward a couple of years and we're now changing big parts of <code>JobExecutor</code>:
adding new job types, tinkering with <code>JobExecutor</code>, changing API signatures, etc.
Then, while looking at the definition of <code>ModuleLoader</code>, we thought...</p>
<blockquote>
<p>Huh, can't we make <code>load_imported_module</code> async now?</p>
</blockquote>
<p>And that's exactly what we did. Behold, the new <a href="https://docs.rs/boa_engine/0.20.0/boa_engine/module/trait.ModuleLoader.html" target="_blank" rel="noopener noreferrer"><code>ModuleLoader</code></a>!</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">trait</span><span class="token plain"> </span><span class="token type-definition class-name">ModuleLoader</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Any</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">load_imported_module</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Rc</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">Self</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        referrer</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Referrer</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        specifier</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">JsString</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">RefCell</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Module</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">init_import_meta</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Rc</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">Self</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        _import_meta</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">JsObject</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        _module</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">Module</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        _context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Then, the code snippet we mentioned before nicely simplifies to:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">load_imported_module</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Rc</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">Self</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    _referrer</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">boa_engine</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">module</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">Referrer</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    specifier</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">JsString</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">RefCell</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Module</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> specifier</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_std_string_escaped</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> response </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> request </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Request</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">url</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">redirect_policy</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">RedirectPolicy</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Limit</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">body</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> response </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">send_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">response</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">map_err</span><span class="token punctuation" style="color:#393A34">(</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token closure-params">err</span><span class="token closure-params punctuation" style="color:#393A34">:</span><span class="token closure-params"> </span><span class="token closure-params namespace" style="opacity:0.7">isahc</span><span class="token closure-params namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token closure-params class-name">Error</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token plain"> </span><span class="token class-name">JsNativeError</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">typ</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">with_message</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> source </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_bytes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">response</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Module</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">source</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">borrow_mut</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<blockquote>
<p><em>What about synchronous applications?</em></p>
</blockquote>
<p>The advantage of having <code>JobExecutor</code> be the main entry point for any Rust
<code>Future</code>s that are enqueued by the engine is that an application can decide how to
handle all <code>Future</code>s received by the implementation of <code>JobExecutor</code>. Thus, an application
that doesn't want to deal with async Rust executors can implement a completely synchronous
<code>ModuleLoader</code> and poll on all futures received by <code>JobExecutor</code> using something like
<a href="https://docs.rs/futures-lite/latest/futures_lite/future/fn.poll_once.html" target="_blank" rel="noopener noreferrer"><code>futures_lite::poll_once</code></a>.</p>
<blockquote>
<p><em>Why not just block on each <code>Future</code> one by one instead?</em></p>
</blockquote>
<p>Well, there is one new built-in that was introduced on this release which heavily
depends on "properly" running <code>Future</code>s, and by "properly" we mean "not blocking
the whole thread waiting on a future to finish". More on that in a bit.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="built-ins-updates">Built-ins updates<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#built-ins-updates" class="hash-link" aria-label="Direct link to Built-ins updates" title="Direct link to Built-ins updates" translate="no">​</a></h3>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="atomicswaitasync">Atomics.waitAsync<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#atomicswaitasync" class="hash-link" aria-label="Direct link to Atomics.waitAsync" title="Direct link to Atomics.waitAsync" translate="no">​</a></h4>
<p>This release adds support for the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/waitAsync" target="_blank" rel="noopener noreferrer"><code>Atomics.waitAsync</code></a> method introduced in
ECMAScript's 2024 specification.
This method allows doing thread synchronization just like <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/wait" target="_blank" rel="noopener noreferrer"><code>Atomics.wait</code></a>, but with
the big difference that it will return a <code>Promise</code> that will resolve when the
thread gets notified with the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/notify" target="_blank" rel="noopener noreferrer"><code>Atomics.notify</code></a> method, instead of blocking until
that happens.</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Given an `Int32Array` shared between two threads:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> sab </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">SharedArrayBuffer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1024</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> int32 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Int32Array</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sab</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Thread 1 runs the following:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// { async: true, value: Promise {&lt;pending&gt;} }</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token maybe-class-name">Atomics</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">waitAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">int32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">result</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">value</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"waited!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// And thread 2 runs the following after Thread 1:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token maybe-class-name">Atomics</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">notify</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">int32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Then, in thread 1 we will (eventually) see "waited!" printed.</span><br></span></code></pre></div></div>
<p>Note that this built-in requires having a "proper" implementation of a <code>JobExecutor</code>; again, "proper"
in the sense of "not blocking the whole thread waiting on a future to finish", which can be accomplished
with <a href="https://docs.rs/futures-concurrency/latest/futures_concurrency/future/future_group/struct.FutureGroup.html" target="_blank" rel="noopener noreferrer"><code>FutureGroup</code></a> and <a href="https://docs.rs/futures-lite/latest/futures_lite/future/fn.poll_once.html" target="_blank" rel="noopener noreferrer"><code>futures_lite::poll_once</code></a> if an async executor is not required
(see <a href="https://github.com/boa-dev/boa/blob/0468498b4bb9da31caa20123201e4d8ee132c608/core/engine/src/job.rs#L678" target="_blank" rel="noopener noreferrer"><code>SimpleJobExecutor</code>'s implementation</a>).
This is because it heavily relies on <code>TimeoutJob</code> to timeout if a notification
doesn't arrive, and in <code>NativeAsyncJob</code> to communicate with the notifier threads using an
async channel. This is the reason why we don't recommend just blocking on each received <code>Future</code>;
that could cause <code>TimeoutJob</code>s to run much later than required, or even make it so that they don't
run at all!</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="set-methods">Set methods<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#set-methods" class="hash-link" aria-label="Direct link to Set methods" title="Direct link to Set methods" translate="no">​</a></h4>
<p>This release adds support for the new set methods added in ECMAScript's 2025
specification.</p>
<p>The new methods are:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/intersection" target="_blank" rel="noopener noreferrer"><code>Set.prototype.intersection(other)</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/union" target="_blank" rel="noopener noreferrer"><code>Set.prototype.union(other)</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/difference" target="_blank" rel="noopener noreferrer"><code>Set.prototype.difference(other)</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/symmetricDifference" target="_blank" rel="noopener noreferrer"><code>Set.prototype.symmetricDifference(other)</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/isSubsetOf" target="_blank" rel="noopener noreferrer"><code>Set.prototype.isSubsetOf(other)</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/isSupersetOf" target="_blank" rel="noopener noreferrer"><code>Set.prototype.isSupersetOf(other)</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/isDisjointFrom" target="_blank" rel="noopener noreferrer"><code>Set.prototype.isDisjointFrom(other)</code></a></li>
</ul>
<p>Thanks to <a href="https://github.com/@Hemenguelbindi" target="_blank" rel="noopener noreferrer">@Hemenguelbindi</a> for
their work on this feature.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="float16-support-for-typedarrays-dataview-and-math-built-ins">Float16 support for TypedArrays, Dataview and Math built-ins<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#float16-support-for-typedarrays-dataview-and-math-built-ins" class="hash-link" aria-label="Direct link to Float16 support for TypedArrays, Dataview and Math built-ins" title="Direct link to Float16 support for TypedArrays, Dataview and Math built-ins" translate="no">​</a></h4>
<p>This release adds support for <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float16Array" target="_blank" rel="noopener noreferrer"><code>f16</code> types</a> for the TypedArray, Dataview, and Math
built-ins.</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> x </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Float16Array</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">37</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">42.123456</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 42.125</span><br></span></code></pre></div></div>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="erroriserror">Error.isError<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#erroriserror" class="hash-link" aria-label="Direct link to Error.isError" title="Direct link to Error.isError" translate="no">​</a></h4>
<p>This release adds support for <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/isError" target="_blank" rel="noopener noreferrer"><code>Error.isError</code></a>, which will be introduced in
ECMAScript's 2026 specification.</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token known-class-name class-name">Error</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">isError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token known-class-name class-name">Error</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">isError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">__proto__</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">prototype</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// false</span><br></span></code></pre></div></div>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="mathsumprecise">Math.sumPrecise<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#mathsumprecise" class="hash-link" aria-label="Direct link to Math.sumPrecise" title="Direct link to Math.sumPrecise" translate="no">​</a></h4>
<p>This release adds support for <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sumPrecise" target="_blank" rel="noopener noreferrer"><code>Math.sumPrecise</code></a>, which will be introduced in
ECMAScript's 2026 specification.</p>
<p>We've opted for using the new <a href="https://crates.io/crates/xsum" target="_blank" rel="noopener noreferrer"><code>xsum</code></a> summation algorithm
for the underlying implementation.</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> sum </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">sumPrecise</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1e20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">1e20</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sum</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 0.1</span><br></span></code></pre></div></div>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="arrayfromasync">Array.fromAsync<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#arrayfromasync" class="hash-link" aria-label="Direct link to Array.fromAsync" title="Direct link to Array.fromAsync" translate="no">​</a></h4>
<p>This release adds support for <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync" target="_blank" rel="noopener noreferrer"><code>Array.fromAsync</code></a>, which will be introduced in
ECMAScript's 2026 specification.</p>
<p><code>Array.fromAsync</code> allows to conveniently create a array from an async iterable by
awaiting all of the items consecutively.</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Array.fromAsync is roughly equivalent to:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">toArray</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">asyncIterator</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> arr </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> i </span><span class="token keyword" style="color:#00009f">of</span><span class="token plain"> asyncIterator</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> arr</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> arr</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">asyncIterable</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Promise</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">resolve</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">setTimeout</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">resolve</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> i</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">yield</span><span class="token plain"> i</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token known-class-name class-name">Array</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">fromAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">asyncIterable</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">array</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">array</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// [0, 1, 2, 3, 4]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">toArray</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">asyncIterable</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">array</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">array</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// [0, 1, 2, 3, 4]</span><br></span></code></pre></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="boa-runtime">Boa Runtime<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#boa-runtime" class="hash-link" aria-label="Direct link to Boa Runtime" title="Direct link to Boa Runtime" translate="no">​</a></h2>
<p>Work on Boa's runtime crate has continued with additional APIs added.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="additional-apis">Additional APIs<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#additional-apis" class="hash-link" aria-label="Direct link to Additional APIs" title="Direct link to Additional APIs" translate="no">​</a></h3>
<p>Additional APIs added the the Runtime crate include:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch" target="_blank" rel="noopener noreferrer"><code>fetch</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout" target="_blank" rel="noopener noreferrer"><code>setTimeout</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/setInterval" target="_blank" rel="noopener noreferrer"><code>setInterval</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/clearInterval" target="_blank" rel="noopener noreferrer"><code>clearInterval</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/queueMicrotask" target="_blank" rel="noopener noreferrer"><code>queueMicrotask</code></a></li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="conformance-testing">Conformance testing<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#conformance-testing" class="hash-link" aria-label="Direct link to Conformance testing" title="Direct link to Conformance testing" translate="no">​</a></h3>
<p>We've added some support for conformance testing runtime features
against the Web Platform Tests (WPT).</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="performance">Performance<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#performance" class="hash-link" aria-label="Direct link to Performance" title="Direct link to Performance" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="nan-boxing">NaN Boxing<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#nan-boxing" class="hash-link" aria-label="Direct link to NaN Boxing" title="Direct link to NaN Boxing" translate="no">​</a></h3>
<p>With this release, Boa's <a href="https://docs.rs/boa_engine/0.21.0/boa_engine/value/struct.JsValue.html" target="_blank" rel="noopener noreferrer"><code>JsValue</code></a> will use nan-boxing by default. The NaN boxing of <code>JsValue</code>
increased memory and runtime performance over the older enum.</p>
<p>As a note, the current implementation is not compatible with all platforms. While we hope
to address this in the future, the legacy enum JsValue will be available via the <code>jsvalue-enum</code>
feature flag.</p>
<p>Unfamiliar with NaN Boxing? We won't go over it in depth here, but we recommend
<a href="https://piotrduperas.com/posts/nan-boxing" target="_blank" rel="noopener noreferrer">this article</a> to learn more.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="register-vm">Register VM<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#register-vm" class="hash-link" aria-label="Direct link to Register VM" title="Direct link to Register VM" translate="no">​</a></h3>
<p>Boa's virtual machine (VM) moved from a stack based VM to a register based VM in
<a href="https://github.com/boa-dev/boa/pull/3798" target="_blank" rel="noopener noreferrer">PR #3798</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="new-contributors">New Contributors<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#new-contributors" class="hash-link" aria-label="Direct link to New Contributors" title="Direct link to New Contributors" translate="no">​</a></h2>
<ul>
<li>@zzzdong made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4058" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4058</a></li>
<li>@albertleigh made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4097" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4097</a></li>
<li>@heygsc made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4124" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4124</a></li>
<li>@jamesthurley made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4155" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4155</a></li>
<li>@lockels made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4189" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4189</a></li>
<li>@changhc made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4176" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4176</a></li>
<li>@created-by-varun made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4198" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4198</a></li>
<li>@tomoverlund made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4254" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4254</a></li>
<li>@Hemenguelbindi made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4145" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4145</a></li>
<li>@Timkarx made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4276" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4276</a></li>
<li>@Rafferty97 made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4303" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4303</a></li>
<li>@cijiugechu made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4307" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4307</a></li>
<li>@countradooku made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4214" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4214</a></li>
<li>@xubaiwang made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4381" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4381</a></li>
<li>@hamflx made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4405" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4405</a></li>
<li>@BDeuDev made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4419" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4419</a></li>
<li>@jasonmilad made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4430" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4430</a></li>
<li>@hpp2334 made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4453" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4453</a></li>
<li>@Gumichocopengin8 made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4462" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4462</a></li>
<li>@mdrokz made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4466" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4466</a></li>
<li>@rrogerc made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4459" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4459</a></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="looking-forward">Looking Forward<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#looking-forward" class="hash-link" aria-label="Direct link to Looking Forward" title="Direct link to Looking Forward" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="garbage-collector-rewrite">Garbage collector rewrite<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#garbage-collector-rewrite" class="hash-link" aria-label="Direct link to Garbage collector rewrite" title="Direct link to Garbage collector rewrite" translate="no">​</a></h3>
<p>This has been long overdue. Boa's garbage collector is a forked and
modified version of <a href="https://github.com/Manishearth/rust-gc" target="_blank" rel="noopener noreferrer"><code>rust-gc</code></a>, and we have long
been pushing our forked gc to its limits.</p>
<p>We have seen some evidence from previous pull requests that simply swapping
allocators from Rust's global allocator can increase Boa's performance, and
work on this will hopefully resume soon. If you're interested in garbage
collectors and/or would be interested in helping out, feel free to join our
GC room on <a href="https://matrix.to/#/#boa:matrix.org" target="_blank" rel="noopener noreferrer">Matrix</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="runtime-functionality">Runtime functionality<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#runtime-functionality" class="hash-link" aria-label="Direct link to Runtime functionality" title="Direct link to Runtime functionality" translate="no">​</a></h3>
<p>The <a href="https://crates.io/crates/boa_runtime" target="_blank" rel="noopener noreferrer"><code>boa_runtime</code></a> crate was initially meant
to contain functionality that was not meant to exist in the core ECMAScript implementation,
for instance the console implementation. Noticeably, we have since added more runtime
features to the crate with even more features expected in the next release.</p>
<p>Our current plan is if there is enough interest and the crate becomes
too large, we will split <code>boa_runtime</code> into it's own repository. If you
are interested in implementing any runtime features or contributing to
a runtime, feel free to reach out.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="continuing-performance-improvements">Continuing performance improvements<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#continuing-performance-improvements" class="hash-link" aria-label="Direct link to Continuing performance improvements" title="Direct link to Continuing performance improvements" translate="no">​</a></h3>
<p>As mentioned on previous release posts, we will continue to further work
on improving Boa's overall performance.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="intl-and-ecma402-conformance"><code>Intl</code> and ECMA402 conformance<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#intl-and-ecma402-conformance" class="hash-link" aria-label="Direct link to intl-and-ecma402-conformance" title="Direct link to intl-and-ecma402-conformance" translate="no">​</a></h3>
<p>We currently have some general support for the ECMA402 and ECMAScript's <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl" target="_blank" rel="noopener noreferrer"><code>Intl</code></a> object. We
will continue to some general work on ECMA402 conformance to allow Boa to be fully usable
for internationalization use cases.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-can-you-support-boa">How can you support Boa?<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#how-can-you-support-boa" class="hash-link" aria-label="Direct link to How can you support Boa?" title="Direct link to How can you support Boa?" translate="no">​</a></h2>
<p>Boa is an independent JavaScript engine implementing the ECMAScript
specification, and we rely on the support of the community to keep it
going. If you want to support us, you can do so by donating to our <a href="https://opencollective.com/boa" target="_blank" rel="noopener noreferrer">open
collective</a>. Proceeeds here go towards this very website, the domain
name, and remunerating members of the team who have worked on the
features released.</p>
<p>If financial contribution is not your strength, you can contribute by
asking to be assigned to one of our <a href="https://github.com/boa-dev/boa/issues?q=is%3Aopen+is%3Aissue+no%3Aassignee" target="_blank" rel="noopener noreferrer">open issues</a>, and asking for
mentoring if you don't know your way around the engine. Our
<a href="https://github.com/boa-dev/boa/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">contribution guide</a> should help you here. If you are more used to
working with JavaScript or frontend web development, we also welcome
help to improve our web presence, either in <a href="https://github.com/boa-dev/boa-dev.github.io" target="_blank" rel="noopener noreferrer">our website</a>, or in our
<a href="https://github.com/boa-dev/boa/issues/820" target="_blank" rel="noopener noreferrer">testing representation</a> page or benchmarks page. You can also
contribute to our Criterion benchmark comparison GitHub <a href="https://github.com/boa-dev/criterion-compare-action" target="_blank" rel="noopener noreferrer">action</a>.</p>
<p>We are also looking to improve the documentation of the engine, both for
developers of the engine itself and for users of the engine. Feel free
to contact us in <a href="https://matrix.to/#/#boa:matrix.org" target="_blank" rel="noopener noreferrer">Matrix</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="thank-you">Thank You<a href="https://boajs.dev/blog/2025/10/22/boa-release-21#thank-you" class="hash-link" aria-label="Direct link to Thank You" title="Direct link to Thank You" translate="no">​</a></h2>
<p>Once again, big thanks to <a href="https://github.com/boa-dev/boa/graphs/contributors?from=2024-12-05&amp;to=2025-08-30&amp;type=c" target="_blank" rel="noopener noreferrer">all the contributors</a> of this
release!!!</p>]]></content:encoded>
            <category>post</category>
        </item>
        <item>
            <title><![CDATA[Temporal_rs is here! The datetime library powering Temporal in Boa, Kiesel, and V8]]></title>
            <link>https://boajs.dev/blog/2025/09/24/temporal-release</link>
            <guid>https://boajs.dev/blog/2025/09/24/temporal-release</guid>
            <pubDate>Wed, 24 Sep 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Temporal_rs is here! The datetime library powering Temporal in Boa, Kiesel, and V8]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" alt="clock banner" src="https://boajs.dev/assets/images/clock-banner-081b36b0a312f4e359b5342ef753a0d6.jpg" width="3010" height="1024" class="img_ev3q"></p>
<p>After 2 years of development, we're pleased to announce the
release of <a href="https://crates.io/crates/temporal_rs" target="_blank" rel="noopener noreferrer"><code>temporal_rs</code></a>. A calendar and time zone aware Rust date/time
library based on ECMAScript's <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal" target="_blank" rel="noopener noreferrer">Temporal API</a>.</p>
<p><code>temporal_rs</code> is a highly conformant implementation of the Temporal API
in Rust that can be used in native Rust code or embedded into ECMAScript
engines / interpreters to support their implementations, which we first
announced in our
<a href="https://boajs.dev/blog/2025/06/15/temporal-impl-1">Temporal blog post</a>, if you're
interested in learning more about small implementation details.</p>
<p>Currently, <code>temporal_rs</code> v0.1 is being used by Boa, <a href="https://kiesel.dev/" target="_blank" rel="noopener noreferrer">Kiesel</a>,
<a href="https://v8.dev/" target="_blank" rel="noopener noreferrer">V8</a>, and <a href="https://github.com/Sharktheone/yavashark" target="_blank" rel="noopener noreferrer">Yavashark</a> for their Temporal
implementations (more on that later) and is <a href="https://chromestatus.com/feature/5668291307634688" target="_blank" rel="noopener noreferrer">estimated</a> to land unflagged in <strong>Chromium v144</strong>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="why-v01-why-not-v10">Why v0.1? Why not v1.0?<a href="https://boajs.dev/blog/2025/09/24/temporal-release#why-v01-why-not-v10" class="hash-link" aria-label="Direct link to Why v0.1? Why not v1.0?" title="Direct link to Why v0.1? Why not v1.0?" translate="no">​</a></h3>
<p>Right now the <a href="https://github.com/tc39/proposal-temporal" target="_blank" rel="noopener noreferrer">Temporal proposal</a> is at Stage 3 (4 being the final stage) in the standards process. Although unlikely,
we want to remain on a minor version to catch any changes which come in (mostly bug fixes) before the proposal reaches stage 4
and thus complete. We expect that to happen in Q1 2026.</p>
<p>Fear not! temporal_rs passes over 4000 specification tests, is stable and ready to use.</p>
<p>To celebrate the release of <code>temporal_rs</code>, we'll cover a short
background of the Temporal implementation in Boa and why <code>temporal_rs</code>
was split into its own crate, we'll go over the library's general
design, and then we'll walk through a couple brief examples of using
<code>temporal_rs</code> before finally talking about the FFI and engine adoption.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="some-background-and-history">Some background and history<a href="https://boajs.dev/blog/2025/09/24/temporal-release#some-background-and-history" class="hash-link" aria-label="Direct link to Some background and history" title="Direct link to Some background and history" translate="no">​</a></h2>
<blockquote>
<p><em>"Temporal is the single biggest addition to ECMAScript since ES6"</em></p>
<cite>Jason Williams, TC39 Delegate</cite>
</blockquote>
<p>In this section, we'll reflect on the overall implementation, some
general difficulties we had along with lessons learned.</p>
<p>The temporal implementation in Boa began over two years ago and
culminated in an absolutely massive PR,
<a href="https://github.com/boa-dev/boa/pull/3277" target="_blank" rel="noopener noreferrer">#3277</a>.</p>
<p>The PR itself stubbed out a lot of the methods, implemented some
Duration and Instant functionality, and started the support for custom
calendars. There were, however, 2 major takeaways from this PR:</p>
<ul>
<li>Temporal is a massive specification update, it's the single biggest addition to ECMAScript since ES6.</li>
<li>There is a lot of room to potentially optimize Temporal if we do not deal with
<code>JsValue</code> directly.</li>
</ul>
<p>After a couple weeks, the question came up amongst maintainers of not just Boa, but also other engines:
"<em>could we separate the datetime logic and implementation off into a completely
separate library?</em>" Sure.</p>
<p>The first commit of then <code>boa_temporal</code> occurred in PR
<a href="https://github.com/boa-dev/boa/pull/3461" target="_blank" rel="noopener noreferrer">#3461</a>, which moved the
majority of the existing functionality into a separate crate with the
primary concern at the time of being able to support custom calendars,
which was then ported into its
<a href="https://github.com/boa-dev/temporal/pull/1" target="_blank" rel="noopener noreferrer">own repository later</a> a
couple months later.</p>
<p>These early versions of <code>temporal_rs</code> were vastly different than the 0.1
release version, and it can be easily seen with a short glance through
the first PR. <code>temporal_rs</code> needed to support custom calendars and time
zones. In order to do this, each calendar was generic on a
<code>CalendarProtocol</code> trait.</p>
<p>So to create a new date in the early versions of <code>temporal_rs</code>, you
would have something like the following code:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">temporal_rs</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token class-name">Date</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Calendar</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">options</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">ArithmeticOverflow</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> date </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Date</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new_with_overflow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token number" style="color:#36acaa">2025</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token number" style="color:#36acaa">9</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token number" style="color:#36acaa">21</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Calendar</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"iso8601"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">ArithmeticOverflow</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Reject</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Luckily, custom calendars and time zones were removed from the
specification in the first half of 2024, so <code>temporal_rs</code> was able to
remove that support, which greatly benefited the entire API. For
instance, here's the same code in the 0.1 version of <code>temporal_rs</code>:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">temporal_rs</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> date </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">try_new_iso</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2025</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">9</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">21</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>That was 2024 though, we're in September of 2025, so what's happened
since the crate was initially split off from Boa over a year and a half
ago? Well, plenty!</p>
<ul>
<li>In early 2024 the internal algorithm for <code>Duration</code> was overhauled in
the specification, so <code>temporal_rs</code> had a complete rewrite of
<code>Duration</code>.</li>
<li><code>Duration</code> moved from using <code>f64</code> internally to <code>FiniteF64</code>, and then
to non-floating-point integers.</li>
<li>We moved from a large <code>TemporalFields</code> type to "Partial" objects,
which better represent JavaScript property bags.</li>
<li>A good portion of missing method implementations were added as well.</li>
<li>Internal utility methods were moved to the <a href="https://arxiv.org/abs/2102.06959" target="_blank" rel="noopener noreferrer">Neri-Schneider algorithms</a>.</li>
</ul>
<p>In general, the implementation was moving along at a pretty decent pace,
and would continue to do so well into roughly April of 2025 (mostly
helped along by a group of students from the University of Bergen who
began helping with the implementation in January 2025), but there were
two final hurdles: time zone data and <code>ZonedDateTime</code>.</p>
<p>Time zones and time zone data are a topic for a completely different
blog post in the future. But suffice to say, it took a little bit of
time, and <code>ZonedDateTime</code> was developed alongside the time zone data.</p>
<p>This work began in November 2024, by stubbing out the general support of
time zone data sourcing and <code>ZonedDateTime</code>. Then, after almost 10
months of general work, the last major updates to time zone data
sourcing were merged at the beginning of September in PR
<a href="https://github.com/boa-dev/temporal/pull/537" target="_blank" rel="noopener noreferrer">#537</a> and
<a href="https://github.com/boa-dev/temporal/pull/538" target="_blank" rel="noopener noreferrer">#538</a>. As a result, we
were finally able to stabilize <code>temporal_rs</code>'s API for a 0.1 release.</p>
<p>That's it for our brief background on <code>temporal_rs</code>.</p>
<p>Date and time is hard, and there is a lot that goes into it, especially
when it comes to calendars and time zones. But that's what makes it
interesting!</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="temporal-api-overview">Temporal API overview<a href="https://boajs.dev/blog/2025/09/24/temporal-release#temporal-api-overview" class="hash-link" aria-label="Direct link to Temporal API overview" title="Direct link to Temporal API overview" translate="no">​</a></h2>
<p>The Temporal API focuses on a group of 8 date and time types, each of
which corresponds to a different aspect of date and time with varying
support for calendars and time zones, which are, unsurprisingly,
represented in <code>temporal_rs</code> by the <code>Calendar</code> and <code>TimeZone</code> types.</p>
<table><thead><tr><th>Temporal type</th><th>Category</th><th>Calendar support</th><th>Time zone support</th></tr></thead><tbody><tr><td><code>PlainDate</code></td><td>Calendar date</td><td>yes</td><td>no</td></tr><tr><td><code>PlainTime</code></td><td>Wall-clock time</td><td>no</td><td>no</td></tr><tr><td><code>PlainDateTime</code></td><td>Calendar date and wall-clock time</td><td>yes</td><td>no</td></tr><tr><td><code>ZonedDateTime</code></td><td>Calendar date and exact time</td><td>yes</td><td>yes</td></tr><tr><td><code>Instant</code></td><td>Exact time</td><td>no</td><td>no</td></tr><tr><td><code>Duration</code></td><td>Time span</td><td>no</td><td>no</td></tr><tr><td><code>PlainYearMonth</code></td><td>Calendar date</td><td>yes</td><td>no</td></tr><tr><td><code>PlainMonthDay</code></td><td>Calendar date</td><td>yes</td><td>no</td></tr></tbody></table>
<p>There is also <code>Now</code>, which provides access to the current host system
time. This can then be used to map the current <code>Instant</code> to any of the
above Temporal types.</p>
<p>The types in the same categories will share similar APIs that are
related to that category. For instance, all types that support a
calendar date will have a <code>with_calendar</code> method as well as calendar
date accessors. The exception being <code>PlainYearMonth</code> and <code>PlainMonthDay</code>
which are missing their day and year, respectively ... for all intents
and purposes.</p>
<p>For a full view of the API, we recommend checking our
<a href="https://docs.rs/temporal_rs/latest/temporal_rs/" target="_blank" rel="noopener noreferrer">documentation</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="temporal_rs-design-overview"><code>temporal_rs</code> design overview<a href="https://boajs.dev/blog/2025/09/24/temporal-release#temporal_rs-design-overview" class="hash-link" aria-label="Direct link to temporal_rs-design-overview" title="Direct link to temporal_rs-design-overview" translate="no">​</a></h2>
<p><code>temporal_rs</code> in general implements large portions of the specification
directly in the codebase. However, it does still have some dependencies,
which can be broken down into 4 main groups.</p>
<ol>
<li>Time zone data, for sourcing time zone data</li>
<li>Calendrical calculations, for handling non-ISO calendar calculations</li>
<li>RFC9557 parsing, for parsing of RFC9557's internet extended date/time
format (IXDTF)</li>
<li>Utilities</li>
</ol>
<p><img decoding="async" loading="lazy" alt="Temporal dependency graph" src="https://boajs.dev/assets/images/temporal-dependencies-a58cc2be2f3604ca72f9dd7dae52e1eb.png" width="3240" height="1240" class="img_ev3q"></p>
<p>Notably, the dependencies that are highlighted in purple come from
<a href="https://github.com/unicode-org/icu4x" target="_blank" rel="noopener noreferrer">ICU4X</a>. ICU4X is a phenomenal Rust project that takes a new approach to
Unicode's ICU in order to make a new, more modular version of ICU.</p>
<p>While ICU4X provides the majority of the internationalization (i18n),
Unicode, and formatting focused functionality, <code>temporal_rs</code> builds on
top of ICU4X to provide an ECMAScript compliant date/time API for both
native Rust and ECMAScript implementers.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="time-zone-data">Time zone data<a href="https://boajs.dev/blog/2025/09/24/temporal-release#time-zone-data" class="hash-link" aria-label="Direct link to Time zone data" title="Direct link to Time zone data" translate="no">​</a></h3>
<p>While we plan to go into time zones in a completely separate post, one
of <code>temporal_rs</code>'s primary design decisions was to offer a way to
customize the source of time zone data, while also having an optional
default source for convenience. The time zone data sourcing
functionality is provided by <code>timezone_provider</code>, a sister crate of
<code>temporal_rs</code> that provides a project agnostic crate alongside default
trait implementations for sourcing time zone data.</p>
<p>We currently expose three types of provider implementations:</p>
<ul>
<li><code>CompiledTzdbProvider</code> (current default), a provider that parses time
zone data at runtime using data compiled into the binary.</li>
<li><code>FsTzdbProvider</code>, a provider that parses time zone data at runtime
using the file system time zone database (if it exists for that OS).</li>
<li><code>ZoneInfo64TzdbProvider</code>, a provider using ICU's zoneinfo64 resource
bundle.</li>
</ul>
<p>We hope to have a zero copy compiled timezone provider available in the
near future.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="using-temporal_rs">Using <code>temporal_rs</code><a href="https://boajs.dev/blog/2025/09/24/temporal-release#using-temporal_rs" class="hash-link" aria-label="Direct link to using-temporal_rs" title="Direct link to using-temporal_rs" translate="no">​</a></h2>
<p>Let's dive into using <code>temporal_rs</code> from Rust.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="setup">Setup<a href="https://boajs.dev/blog/2025/09/24/temporal-release#setup" class="hash-link" aria-label="Direct link to Setup" title="Direct link to Setup" translate="no">​</a></h3>
<p>First, add <code>temporal_rs</code> as a dependency to your project using cargo:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cargo add temporal_rs</span><br></span></code></pre></div></div>
<p>Or include the below in your project's <code>Cargo.toml</code>.</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key property" style="color:#36acaa">temporal_rs</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"0.1.0"</span><br></span></code></pre></div></div>
<p>By default, <code>temporal_rs</code> will use a compiled time zone data provider
that compiles the time zone data into the binary. If you prefer to use
the file system time zone database or a zoneinfo64 resource bundle, you
can disable the compiled time zone data by setting
<code>default-features = false</code>; you can import your preferred provider from
the <code>timezone_provider</code> crate, then provide it to any API that requires
a time zone provider.</p>
<p>For instance, to use the <code>FsTzdbProvider</code>, your <code>Cargo.toml</code> would look
like the following.</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key property" style="color:#36acaa">timezone_provider</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token key property" style="color:#36acaa">version</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"0.0.17"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token key property" style="color:#36acaa">features</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"tzif"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key property" style="color:#36acaa">temporal_rs</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token key property" style="color:#36acaa">version</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"0.1.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token key property" style="color:#36acaa">default-features</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token key property" style="color:#36acaa">features</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"sys"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>The <code>sys</code> feature for <code>temporal_rs</code> enables the default implementation
for <code>Now</code>, and the <code>tzif</code> feature for <code>timezone_provider</code> enables the
<code>FsTzdbProvider</code>.</p>
<p>Please note: <code>timezone_provider</code> is still considered unstable for the
near future.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="some-examples">Some examples<a href="https://boajs.dev/blog/2025/09/24/temporal-release#some-examples" class="hash-link" aria-label="Direct link to Some examples" title="Direct link to Some examples" translate="no">​</a></h3>
<p>The below examples will be using <code>temporal_rs</code> with the default
features.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="retrieve-todays-date">Retrieve today's date<a href="https://boajs.dev/blog/2025/09/24/temporal-release#retrieve-todays-date" class="hash-link" aria-label="Direct link to Retrieve today's date" title="Direct link to Retrieve today's date" translate="no">​</a></h4>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">temporal_rs</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">Temporal</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can easily retrieve today's date using `Temporal::now()`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> today </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Temporal</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">now</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">plain_date_iso</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">None</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="date-operations-available">Date operations available<a href="https://boajs.dev/blog/2025/09/24/temporal-release#date-operations-available" class="hash-link" aria-label="Direct link to Date operations available" title="Direct link to Date operations available" translate="no">​</a></h4>
<p>Temporal provides a nice API for working with date and date/time via
<code>PlainDate</code> and <code>PlainDateTime</code>.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">std</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">convert</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">TryFrom</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">temporal_rs</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token class-name">Calendar</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Temporal</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">options</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">DifferenceSettings</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">partial</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">PartialDuration</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can get today's date</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> today </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Temporal</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">now</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">plain_date_iso</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">None</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can also add a Duration.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> partial </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">PartialDuration</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">empty</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">with_days</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> tomorrow </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> today</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">partial</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">try_into</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">None</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can get the difference between two dates</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> diff </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> today</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">since</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">tomorrow</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">DifferenceSettings</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can change the calendar</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> tomorrow_japanese </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> tomorrow</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">with_calendar</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Calendar</span><span class="token punctuation" style="color:#393A34">::</span><span class="token constant" style="color:#36acaa">JAPANESE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can retrieve the calendar's RFC9557 string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">println!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"{tomorrow_japanese}"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 2025-09-24[u-ca=japanese]</span><br></span></code></pre></div></div>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="working-with-dates-and-time-zones">Working with dates and time zones<a href="https://boajs.dev/blog/2025/09/24/temporal-release#working-with-dates-and-time-zones" class="hash-link" aria-label="Direct link to Working with dates and time zones" title="Direct link to Working with dates and time zones" translate="no">​</a></h4>
<p>You can also easily work with dates and time zones with the
<code>ZonedDateTime</code> type.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">temporal_rs</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">options</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token class-name">DifferenceSettings</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Disambiguation</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">OffsetDisambiguation</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Unit</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">temporal_rs</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token class-name">Calendar</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Temporal</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">TimeZone</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">ZonedDateTime</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can parse a ZonedDateTime from utf8 bytes.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> zdt </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">ZonedDateTime</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_utf8</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">b"2025-03-01T11:16:10Z[America/Chicago][u-ca=iso8601]"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Disambiguation</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Compatible</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">OffsetDisambiguation</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Reject</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can get the current ZonedDateTime</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> today </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Temporal</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">now</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">zoned_date_time_iso</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">None</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// And we can easily get the difference between two `ZonedDateTime`s</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> options </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">DifferenceSettings</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">options</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">largest_unit </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Some</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Unit</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Year</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> diff </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> today</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">since</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">zdt</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> options</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">println!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"{diff}"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// P6M23D</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can change the calendar for the `ZonedDateTime`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> today_coptic </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> today</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">with_calendar</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Calendar</span><span class="token punctuation" style="color:#393A34">::</span><span class="token constant" style="color:#36acaa">COPTIC</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">println!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"{today_coptic}"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 2025-09-24T10:36:56.914365368-05:00[America/Chicago][u-ca=coptic]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can also easily convert it into just the date.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> today_plain_date_coptic </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> today_coptic</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_plain_date</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">println!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"{today_coptic}"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 2025-09-24[u-ca=coptic]</span><br></span></code></pre></div></div>
<p>While we can extend these examples further, a more fun exercise for the
reader would be to take a look at the <a href="https://tc39.es/proposal-temporal/docs/cookbook.html" target="_blank" rel="noopener noreferrer">Temporal cookbook</a>, as
it displays the utility of the Temporal API using JavaScript and all of
these examples are now usable from Rust as well.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="ffi-and-engine-adoption">FFI and engine adoption<a href="https://boajs.dev/blog/2025/09/24/temporal-release#ffi-and-engine-adoption" class="hash-link" aria-label="Direct link to FFI and engine adoption" title="Direct link to FFI and engine adoption" translate="no">​</a></h2>
<p>As previously stated, <code>temporal_rs</code> is used in Boa, Kiesel, and V8.
There's just one thing, the latter of the two are ECMAScript
implementations written in Zig and C++, respectively, not Rust. This was
made possible through <code>temporal_rs</code>'s FFI crate <code>temporal_capi</code>, which
provides C and C++ bindings to <code>temporal_rs</code>.</p>
<p>The bindings are autogenerated via <a href="https://github.com/rust-diplomat/diplomat" target="_blank" rel="noopener noreferrer">Diplomat</a>, which is a
project for generating FFI definitions for Rust libraries. In general,
it's a really cool project and we would definitely recommend checking it
out if you're looking to generate FFI bindings for other languages for
your Rust library.</p>
<blockquote>
<p>"<em>Diplomat made the FFI code extremely easy: I basically wrote the entire temporal_capi FFI layer over the course of a couple PRs, each of which probably took me ~15 minutes each of relatively mindless "tab through docs, add API" work. Diplomat is really good at this type of thing.</em>"</p>
<cite>Manishearth <a href="https://www.reddit.com/r/rust/comments/1logjzt/chromiumv8_implementing_temporal_api_via_rust/" target="_blank" rel="noopener noreferrer">Rust Reddit Q&amp;A</a>:</cite>
</blockquote>
<p>There is some added benefits to offering C and C++ bindings beyond the
classic: oh, let's (re)write it in Rust.</p>
<p>First, this approach allows other languages and engines to benefit from
Rust's type system and memory safety guarantees without having to
rewrite everything in Rust. It's a more modular and incremental approach
that provides some level of flexibility.</p>
<p>Secondly, with how large the API is, <code>temporal_rs</code> streamlines the
ability to adopt the Temporal API for any current and future
implementations, since any future updates can be done primarily in one
place and then released downstream. <code>temporal_rs</code> plus the engine
specific integration code, while not a small amount of code, is a
relatively trivial amount of work in comparison to a from scratch
implementation.</p>
<p>Third, with adoption from multiple engines, <code>temporal_rs</code> benefits via
external test coverage beyond the native Rust unit tests. For instance,
looking at the engines that offer conformance numbers (Boa, Kiesel, and
V8), each implementation <a href="https://test262.fyi/#" target="_blank" rel="noopener noreferrer">is currently north of 95% conformance</a> with V8
reaching the highest at around 99% conformance. There is still a small
disparity in conformance, but this can be explained by the absence of
some related features, i.e. Boa still hasn't completed its
<code>Intl.DateTimeFormat</code> implementation yet, so it fails all ECMA402
<code>toLocaleString</code> tests. Nonetheless, we can still be fairly confident in
the general correctness of <code>temporal_rs</code>, and any potential bugs will
ideally be found and addressed fairly quickly.</p>
<p>In general, <code>temporal_rs</code> is a pretty good reference case for setting up
a Rust library over FFI, being used in both a C++ and Zig codebase.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="conclusion">Conclusion<a href="https://boajs.dev/blog/2025/09/24/temporal-release#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>The 0.1 release of <code>temporal_rs</code> is out. We expect the general API to
remain fairly stable moving forward, with any non-patch bumps being for
added features. Feel free to try it out, and provide feedback / file any
issues you come across. Although, we will make changes and semantic
versioning bumps based on feedback or the Temporal specification.</p>
<p>Our current plan is to have any remaining issues addressed and the API
fully stable, in preparation for the "stabilization" of Temporal and its
subsequent introduction to the ECMAScript specification. Once Temporal
is "stabilized", we will move forward with a 1.0 release.</p>
<p><code>temporal_rs</code> started as an interesting experiment in creating an engine
agnostic library of the Temporal API that could also be usable as a
date/time library in native Rust code, but seeing the wide adoption
we've been getting from other engines, we can say that this project has
been a great success! And with any luck, we hope this library will find
its place in the Rust ecosystem as well.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="special-thanks">Special thanks<a href="https://boajs.dev/blog/2025/09/24/temporal-release#special-thanks" class="hash-link" aria-label="Direct link to Special thanks" title="Direct link to Special thanks" translate="no">​</a></h2>
<p>We'd like to thank all the <a href="https://github.com/boa-dev/temporal/graphs/contributors" target="_blank" rel="noopener noreferrer">contributors</a> to <code>temporal_rs</code> for helping
it get to v0.1.</p>
<p>Thanks to the University of Bergen students who helped drive some of the
major conformance push earlier this year.</p>
<p>Also, a huge thanks to all the Temporal champions for all their work on
the specification, as well as the ICU4X project for their incredible
ongoing work on calendars and all things i18n related.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="discussion">Discussion<a href="https://boajs.dev/blog/2025/09/24/temporal-release#discussion" class="hash-link" aria-label="Direct link to Discussion" title="Direct link to Discussion" translate="no">​</a></h2>
<ul>
<li>Hackernews: <a href="https://news.ycombinator.com/item?id=45361826" target="_blank" rel="noopener noreferrer">https://news.ycombinator.com/item?id=45361826</a></li>
<li>Reddit: <a href="https://www.reddit.com/r/rust/comments/1npffdx/temporal_rs_is_here_the_datetime_library_powering/" target="_blank" rel="noopener noreferrer">https://www.reddit.com/r/rust/comments/1npffdx/temporal_rs_is_here_the_datetime_library_powering/</a></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-can-you-support-boa">How can you support Boa?<a href="https://boajs.dev/blog/2025/09/24/temporal-release#how-can-you-support-boa" class="hash-link" aria-label="Direct link to How can you support Boa?" title="Direct link to How can you support Boa?" translate="no">​</a></h2>
<p>Boa is an independent JavaScript engine implementing the ECMAScript specification, and we rely on the
support of the community to keep it going. If you want to support us, you can do so by donating to
our <a href="https://opencollective.com/boa" target="_blank" rel="noopener noreferrer">open collective</a>. Proceeeds here go towards this very website, the domain name, and remunerating
members of the team who have worked on the features released.</p>
<p>If financial contribution is not your strength, you can contribute by asking to be assigned to one of
our <a href="https://github.com/boa-dev/boa/issues?q=is%3Aopen+is%3Aissue+no%3Aassignee" target="_blank" rel="noopener noreferrer">open issues</a>, and asking for mentoring if you don't know your way around the engine. Our
<a href="https://github.com/boa-dev/boa/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">contribution guide</a> should help you here. If you are more used to working with JavaScript or frontend
web development, we also welcome help to improve our web presence, either in <a href="https://github.com/boa-dev/boa-dev.github.io" target="_blank" rel="noopener noreferrer">our website</a>, or in our
<a href="https://github.com/boa-dev/boa/issues/820" target="_blank" rel="noopener noreferrer">testing representation</a> page or benchmarks page. You can also contribute to our Criterion benchmark
comparison GitHub <a href="https://github.com/boa-dev/criterion-compare-action" target="_blank" rel="noopener noreferrer">action</a>.</p>
<p>We are also looking to improve the documentation of the engine, both for developers of the engine
itself and for users of the engine. Feel free to contact us in <a href="https://matrix.to/#/#boa:matrix.org" target="_blank" rel="noopener noreferrer">Matrix</a>.</p>]]></content:encoded>
            <category>post</category>
        </item>
        <item>
            <title><![CDATA[Implementing Temporal, the new date/time API for JavaScript (and Rust!)]]></title>
            <link>https://boajs.dev/blog/2025/06/15/temporal-impl-1</link>
            <guid>https://boajs.dev/blog/2025/06/15/temporal-impl-1</guid>
            <pubDate>Sun, 15 Jun 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[A blog post about the temporal_rs Rust crate that implements JavaScript's Temporal API and how temporal_rs supports implementing Temporal in JavaScript engines.]]></description>
            <content:encoded><![CDATA[<p>Developing a JavaScript engine in Rust can seem like pretty daunting
task to some. In order to demystify working on a feature and to go over
what we've been working on implementing in Boa recently, we thought we'd
write a post about implementing a JavaScript feature in Rust.</p>
<p>More specifically, this will be the first in a series of posts primarily
about implementing the new date/time built-in: Temporal. We'll be going
over general lessons and interesting design choices we've stumbled upon,
as well as the crates supporting that implementation.</p>
<p>Why should you care? Well, we are not only implementing Temporal for
JavaScript, but for Rust as well ... more on that in a bit.</p>
<p>First, an aside!</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-even-is-temporal">What even is Temporal?<a href="https://boajs.dev/blog/2025/06/15/temporal-impl-1#what-even-is-temporal" class="hash-link" aria-label="Direct link to What even is Temporal?" title="Direct link to What even is Temporal?" translate="no">​</a></h2>
<p>Temporal is a modern API for handling date/time in a calendar and time
zone aware manner that includes nine objects with over 200+ methods.</p>
<p>In JavaScript, Temporal is a global built-in namespace object that
includes each of these nine built-ins:</p>
<ul>
<li><code>Temporal.Now</code></li>
<li><code>Temporal.PlainDate</code></li>
<li><code>Temporal.PlainTime</code></li>
<li><code>Temporal.PlainDateTime</code></li>
<li><code>Temporal.ZonedDateTime</code></li>
<li><code>Temporal.Duration</code></li>
<li><code>Temporal.Instant</code></li>
<li><code>Temporal.PlainYearMonth</code></li>
<li><code>Temporal.PlainMonthDay</code></li>
</ul>
<p>But to be honest, this post isn't meant to give an overview of Temporal
and its general API. If Temporal is news to you and you are interested
in learning more, feel free to check out the phenomenal <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal" target="_blank" rel="noopener noreferrer">MDN
documentation</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="back-on-track">Back on track<a href="https://boajs.dev/blog/2025/06/15/temporal-impl-1#back-on-track" class="hash-link" aria-label="Direct link to Back on track" title="Direct link to Back on track" translate="no">​</a></h2>
<p>Being Boa a JavaScript engine / interpreter, developing a correct
implementation of the ECMAScript specification is our raison d'être.
This, in consequence, makes implementing Temporal one of our most
important goals, since it represents roughly 7-8% of the current
conformance test suite (~4000 of the ~50,000 tests).</p>
<p>When the PR of the first prototype of Temporal for Boa was submitted, a
few things became evident:</p>
<ol>
<li>Date/Time is a complicated beast (duh)</li>
<li>There's room for optimization and improvement</li>
<li>This would be handy to have in Rust</li>
</ol>
<p>So after the prototype was merged, we pulled it out of Boa's internal
builtins and externalized it into its own crate,
<a href="https://github.com/boa-dev/temporal" target="_blank" rel="noopener noreferrer"><code>temporal_rs</code></a>, which landed behind an experimental
flag in Boa v0.18.</p>
<p>After over a year and a half of development, Boa now sits at a
conformance of about 90% for Temporal (and growing), with the entire
implementation being backed by <code>temporal_rs</code>.</p>
<p>For its part, <code>temporal_rs</code> is shaping up to be a proper Rust date/time
library that can be used to implement Temporal in a JavaScript engine,
and even support general date/time use cases.</p>
<p>Let's take a look at Temporal: it's JavaScript API, it's Rust API in
<code>temporal_rs</code>, and how <code>temporal_rs</code> supports implementing the
specification.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="important-core-differences">Important core differences<a href="https://boajs.dev/blog/2025/06/15/temporal-impl-1#important-core-differences" class="hash-link" aria-label="Direct link to Important core differences" title="Direct link to Important core differences" translate="no">​</a></h2>
<p>First, we need to talk about JavaScript values (<code>JsValue</code>) for a bit.
This is functionally the core <code>any</code> value type of JavaScript. A
<code>JsValue</code> could be a number represented as a 64 bit floating point, a
string, a boolean, or an object. Not only is it an <code>any</code>, but <code>JsValue</code>
is ultimately engine defined, with various implementations existing
across engines.</p>
<p>While this is handy for a dynamically typed language like JavaScript, it
is not ideal for implementing deep language specifications where an
object or string may need to be cloned. Furthermore, it's just not great
for an API in a typed language like Rust.</p>
<p>To work around this, we routinely use <code>FromStr</code> and a <code>FiniteF64</code> custom
primitive to handle casting and constraining, respectively, which glues
dynamic types like <code>JsValue</code> with a typed API.</p>
<p>For instance, in Boa, we heavily lean into using the below patterns:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// (Note: this is abridged for readability)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// FiniteF64 usage</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">f64</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> js_value</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_number</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> finite_f64</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">FiniteF64</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">FiniteF64</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">try_from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">number</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> year</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> finite_f64</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">as_integer_with_truncation</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">i32</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// FromStr usage with `get_option`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> options_obj</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">JsObject</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">get_options_object</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">js_value</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> overflow</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Option</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">ArithmeticOverflow</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">get_option</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">ArithmeticOverflow</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">options_obj</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"overflow"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    context</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>This is the core glue between Boa and the <code>temporal_rs</code> API that we will
be going over below.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="implementing-constructors">Implementing constructors<a href="https://boajs.dev/blog/2025/06/15/temporal-impl-1#implementing-constructors" class="hash-link" aria-label="Direct link to Implementing constructors" title="Direct link to Implementing constructors" translate="no">​</a></h2>
<p>There are a variety of ways to construct a core component like
<code>PlainDate</code>, and that stems from the core constructor for each of the
core components: <code>new_with_overflow</code>.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">impl</span><span class="token plain"> </span><span class="token class-name">PlainDate</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">new_with_overflow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">year</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> month</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> day</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> calendar</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Calendar</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> overflow</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">ArithmeticOverflow</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">Result</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">Self</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Create PlainDate</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>This function supports the baseline construction of Temporal builtins,
which takes the usual year, month, day, alongside a calendar and also an
overflow option to constrain or reject based on whether the provided
values are in an expected range.</p>
<p>However, we can better express this in Rust with common <code>try_</code> prefix
notation.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">impl</span><span class="token plain"> </span><span class="token class-name">PlainDate</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">year</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> month</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> day</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> calendar</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Calendar</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">Result</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">Self</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">Self</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new_with_overflow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">year</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> month</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> day</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> calendar</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">ArithmeticOverflow</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Constrain</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">try_new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">year</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> month</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> day</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> calendar</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Calendar</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">Result</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">Self</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">Self</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new_with_overflow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">year</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> month</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> day</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> calendar</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">ArithmeticOverflow</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Reject</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>These three constructors, <code>new_with_overflow</code>, <code>try_new</code>, and <code>new</code>, are
fairly flexible and provide full coverage of the Temporal specification.</p>
<p>For instance, take the below snippet:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> plainDate </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Temporal</span><span class="token class-name punctuation" style="color:#393A34">.</span><span class="token class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2025</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">6</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">9</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>This code can easily be translated to Rust as:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">temporal_rs</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> plain_date </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">try_new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2025</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">6</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">9</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Calendar</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Furthermore, we actually learn some interesting things about the
JavaScript API from looking at the <code>temporal_rs</code> API:</p>
<ol>
<li>The <code>Temporal.PlainDate</code> constructor can throw.</li>
<li>When the calendar is omitted, the default calendar is used (this will
default to the <code>iso8601</code> calendar)</li>
</ol>
<p>Of course, if you somewhat prefer the brevity of the JavaScript API and
don't want to list the default <code>Calendar</code>, <code>temporal_rs</code> provides the
additional constructors <code>new_iso</code> and <code>try_new_iso</code>.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">temporal_rs</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> plain_date </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">try_new_iso</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2025</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">6</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">9</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Interestingly enough, the <code>_iso</code> constructors are mostly expressing a
part of the JavaScript API, just in native Rust. This is because in
JavaScript the <code>_iso</code> constructors are assumed to exist due to resolving
an <code>undefined</code> calendar to the default ISO calendar.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="lets-discuss-now">Let's discuss <code>Now</code><a href="https://boajs.dev/blog/2025/06/15/temporal-impl-1#lets-discuss-now" class="hash-link" aria-label="Direct link to lets-discuss-now" title="Direct link to lets-discuss-now" translate="no">​</a></h2>
<blockquote>
<p>Colonel Sandurz: Now. You're looking at now, sir. Everything that
happens now, is happening now.<br> Dark Helmet: What happened to
then?<br> Colonel Sandurz: We passed then.<br> Dark Helmet:
When?<br> Colonel Sandurz: Just now. We're at now now.<br>
Dark Helmet: Go back to then.<br> Colonel Sandurz: When?<br>
Dark Helmet: Now.<br> Colonel Sandurz: Now?<br> Dark Helmet:
Now.<br> Colonel Sandurz: I can't.<br> Dark Helmet:
Why?<br> Colonel Sandurz: We missed it.<br> Dark Helmet:
When?<br> Colonel Sandurz: Just now.<br> Dark Helmet: When
will then be now?<br> -- <cite>Spaceballs, 1987</cite></p>
</blockquote>
<p><code>Temporal.Now</code> is an incredibly strange type, yet nevertheless
important. It is the object from which the current instant can be
measured and mapped into any of the Temporal components.</p>
<p>In JavaScript, this type has no <a href="https://tc39.es/ecma262/multipage/ordinary-and-exotic-objects-behaviours.html#sec-ecmascript-function-objects-construct-argumentslist-newtarget" target="_blank" rel="noopener noreferrer"><code>[[Construct]]</code></a> or
<a href="https://tc39.es/ecma262/multipage/ordinary-and-exotic-objects-behaviours.html#sec-ecmascript-function-objects-call-thisargument-argumentslist" target="_blank" rel="noopener noreferrer"><code>[[Call]]</code></a> internal method, which is a fancy way to say
that Now has no constructor and cannot be called directly.</p>
<p>Instead, <code>Now</code> is used primarily as a namespace for its methods.</p>
<p>And this was reflected in early adaptions of <code>Now</code>, which looked more or
less like the below:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Now</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">impl</span><span class="token plain"> </span><span class="token class-name">Now</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">instant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">Instant</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">zoned_date_time_iso</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">ZonedDateTime</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Interestingly enough, the above implementation is incorrect, or at the
very least not ideal.</p>
<p>Hidden in the specification steps for <code>Now</code> are some very tricky steps
invoking the abstract operations: <code>SystemTimeZoneIdentifier</code> and
<code>SystemUtcEpochNanoseconds</code>. That's great, let's just use the usual
suspects <code>SystemTime</code> and <code>iana-time-zone</code>, merge it, and call it a day
on the implementation, right?</p>
<p>Except the core purpose of <code>temporal_rs</code> is that it can be used in any
engine implementation, and accessing a system clock and system time zone
is sometimes difficult for engines that support targets like embedded
systems. Thus, this functionality must be delegated to the engine or
runtime ... somehow.</p>
<p>How did we end up implementing <code>Now</code> if we have no access to the system
clock or time zone? Well ... a builder pattern of course!</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token attribute attr-name" style="color:#00a4db">#[derive(Default)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">NowBuilder</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    clock</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Option</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">EpochNanoseconds</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    zone</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Option</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">TimeZone</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">impl</span><span class="token plain"> </span><span class="token class-name">NowBuilder</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">with_system_nanoseconds</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> nanoseconds</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">EpochNanoseconds</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">Self</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">clock </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Some</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">nanoseconds</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">self</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">with_system_zone</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> zone</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">TimeZone</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">Self</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">zone </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Some</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">zone</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">self</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">build</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">Now</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">Now</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            clock</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">clock</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            zone</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">zone</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap_or_default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Now</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    clock</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Option</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">EpochNanoseconds</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    zone</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">TimeZone</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Once we've constructed <code>Now</code>, then we are off to the races!</p>
<p>To show the <code>NowBuilder</code> in action, in Boa, the implementation for
<code>Temporal.Now.plainDateISO()</code> with the builder API is shown below:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">impl</span><span class="token plain"> </span><span class="token class-name">Now</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// The `Temporal.Now.plainDateISO` used when building `Temporal.Now`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">plain_date_iso</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">_</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token punctuation" style="color:#393A34">[</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">JsValue</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> time_zone </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> args</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">get_or_undefined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token closure-params">v</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">to_temporal_timezone_identifier</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">v</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">transpose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> now </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">build_now</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> pd </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> now</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">plain_date_iso_with_provider</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">time_zone</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">tz_provider</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">create_temporal_date</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">pd</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Into</span><span class="token punctuation" style="color:#393A34">::</span><span class="token plain">into</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// A helper for building Now</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">build_now</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">NowInner</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">NowBuilder</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">with_system_zone</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">system_time_zone</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">with_system_nanoseconds</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">system_nanoseconds</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">build</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>The nice part about this approach is that it also allows a <code>std</code>
implementation that can be feature gated for general users that are not
concerned with <code>no_std</code>.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Available with the `sys` feature flag</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">temporal_rs</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">Temporal</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> now </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Temporal</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">now</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">instant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="partial-api">Partial API<a href="https://boajs.dev/blog/2025/06/15/temporal-impl-1#partial-api" class="hash-link" aria-label="Direct link to Partial API" title="Direct link to Partial API" translate="no">​</a></h2>
<p>There's an interesting method on each of the Temporal built-ins that I'd
assume most people who have used Rust would be familiar with: <code>from</code>.
But this isn't Rust's friendly <code>From</code> trait. No, this <code>from</code> is a
behemoth method that takes a <code>JsValue</code> and automagically gives you back
the built-in that you'd like or throws. That's right! Give it a string,
give it a property bag, give it an instance of another Temporal
built-in; <code>from</code> will figure it out for you!</p>
<p>Simple, right?</p>
<p>Folks, we're pleased to announce that <code>temporal_rs</code> won't be supporting
that! ... or at least not in that shape.</p>
<p>Again, the goal of <code>temporal_rs</code> is to implement the specification to
the highest possible degree of conformance, so when we couldn't provide
a direct translation of the specification's API, we made sure to provide
APIs that (hopefully) made the glue code between engines and
<code>temporal_rs</code> much shorter.</p>
<p>To exemplify this, let's take a look at some valid uses of <code>from</code> in
JavaScript to construct a <code>PlainDate</code>.</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Create a `PlainDateTime`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> pdt </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Temporal</span><span class="token class-name punctuation" style="color:#393A34">.</span><span class="token class-name">PlainDateTime</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2025</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can use the `PlainDateTime` (`ZonedDateTime` / `PlainDate` are also options).</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> pd_from_pdt </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token maybe-class-name">Temporal</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access maybe-class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword module" style="color:#00009f">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">pdt</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can use a string.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> pd_from_string </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token maybe-class-name">Temporal</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access maybe-class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword module" style="color:#00009f">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"2025-01-01"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can use a property bag.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> pd_from_property_bag </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token maybe-class-name">Temporal</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access maybe-class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword module" style="color:#00009f">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">year</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2025</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">month</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">day</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>If we look closely to the common usage of the method, it seems like all
that needs to be implemented by <code>temporal_rs</code> is:</p>
<ul>
<li><code>From&lt;PlainDateTime&gt;</code>: Easy.</li>
<li><code>From&lt;ZonedDateTime&gt;</code>: Simple.</li>
<li><code>FromStr</code>: Tricky but can be done.</li>
<li><code>From&lt;JsObject&gt;</code>: ... ... oh. Did I mention <code>JsObject</code>, like
<code>JsValue</code>, is engine defined as well?</li>
</ul>
<p>Fortunately, this is where <code>temporal_rs</code>'s Partial API comes in.</p>
<p>It turns out that, while property bags in JavaScript can have various
fields set, there is still a general shape for the fields that can be
provided and validated in Temporal.</p>
<p>To support this in <code>temporal_rs</code>, a "partial" component exists for each
of the components that can then be provided to that component's
<code>from_partial</code> method.</p>
<p>With this, we have fully implemented support for the <code>from</code> method in
<code>temporal_rs</code>:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">core</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token keyword" style="color:#00009f">str</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">FromStr</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">temporal_rs</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">PlainDateTime</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">partial</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">PartialDate</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> pdt </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">PlainDateTime</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">try_new_iso</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2025</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can use the `PlainDateTime` (`ZonedDateTime` / `PlainDate` are also options).</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> pd_from_pdt </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">pdt</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can use a `str`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> pd_from_string </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"2025-01-01"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We can use a `PartialDate`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> pd_from_partial </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_partial</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">PartialDate</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">with_year</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Some</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2025</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">with_month</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Some</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">with_day</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Some</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p><strong>NOTE:</strong> there may be updates to <code>PartialDate</code> in the future (see
<a href="https://github.com/boa-dev/temporal/issues/349" target="_blank" rel="noopener noreferrer">boa-dev/temporal #349</a>
for more information).</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="elephant-in-the-room-time-zones">Elephant in the room: time zones<a href="https://boajs.dev/blog/2025/06/15/temporal-impl-1#elephant-in-the-room-time-zones" class="hash-link" aria-label="Direct link to Elephant in the room: time zones" title="Direct link to Elephant in the room: time zones" translate="no">​</a></h2>
<p>So far we have not discussed time zones, and -- surprise! -- we aren't
going to ... yet. It's not because they aren't super cool and
interesting and everyone <em>totally</em> 100% loves them. No, time zones
aren't in this post because they are still being polished and deserve an
entire post of their own.</p>
<p>So stay tuned for our next post on implementing Temporal! The one where
we'll hopefully go over everyone's favorite subject, time zones; and
answer the question that some of you may have if you happen to take a
glance at <code>temporal_rs</code>'s docs or try out our <code>no_std</code> support: what in
the world is a provider API?</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="conclusion">Conclusion<a href="https://boajs.dev/blog/2025/06/15/temporal-impl-1#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>In conclusion, we're implementing Temporal in Rust to support engine
implementors as well as to have the API available in native Rust in
general.</p>
<p>If you're interested in trying Temporal using Boa, you can use it in
Boa's CLI or enable it in <code>boa_engine</code> with the <code>experimental</code> flag.</p>
<p>Outside of Boa's implementation, <code>temporal_rs</code> has implemented or
supports the implementation for a large portion of the Temporal's API in
native Rust. Furthermore, an overwhelming amount of the API can be
considered stable<sup><a href="https://boajs.dev/blog/2025/06/15/temporal-impl-1#user-content-fn-stability-f84d3c" id="user-content-fnref-stability-f84d3c" data-footnote-ref="true" aria-describedby="footnote-label" class="footnoteRefStickyNavbar_i6ta">1</a></sup> and is currently available in Boa with
only a few outstanding issues that may be considered breaking changes.</p>
<p>If you're interested in trying out <code>temporal_rs</code>, feel free to add it to
your dependencies with the command:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cargo add temporal_rs</span><br></span></code></pre></div></div>
<p>or by adding the below in the <code>[dependencies]</code> section of your
<code>Cargo.toml</code>:</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key property" style="color:#36acaa">temporal_rs</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"0.0.9"</span><br></span></code></pre></div></div>
<p>A FFI version of temporal is also available for C and C++ via
<a href="https://crates.io/crates/temporal_capi" target="_blank" rel="noopener noreferrer"><code>temporal_capi</code></a>.</p>
<!-- -->
<section data-footnotes="true" class="footnotes"><h2 class="anchor anchorWithStickyNavbar_LWe7 sr-only" id="footnote-label">Footnotes<a href="https://boajs.dev/blog/2025/06/15/temporal-impl-1#footnote-label" class="hash-link" aria-label="Direct link to Footnotes" title="Direct link to Footnotes" translate="no">​</a></h2>
<ol>
<li id="user-content-fn-stability-f84d3c">
<p>A general note on API stability</p>
<p>While the majority of the APIs discussed above are expected to be
mostly stable, Temporal is still a stage 3 proposal that is not
fully accepted into the ECMAScript specification. Any normative
change that may be made upstream in the ECMAScript or ECMA402
specification will also be reflected in <code>temporal_rs</code>.</p>
<p>There are also a few outstanding issues with changes that may be
reflected in the API.</p>
<ol>
<li>Duration's inner repr and related constructors.</li>
<li><code>ZonedDateTime.prototype.getTimeZoneTransition</code> implementation</li>
<li>TemporalError's inner repr</li>
<li>Partial objects may need some adjustments to handle differences
between <code>from_partial</code> and <code>with</code></li>
<li>Time zone provider's and the <code>TimeZoneProvider</code> trait are still
largely unstable. Although, the provider APIs that use them are
expected to be stable (spoilers!)</li>
<li>Era and month code are still be discussed in the
intl-era-month-code proposal, so some calendars and calendar
methods may have varying levels of support.</li>
</ol>
<p>The above issues are considered blocking for a 0.1.0 release. <a href="https://boajs.dev/blog/2025/06/15/temporal-impl-1#user-content-fnref-stability-f84d3c" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content:encoded>
            <category>post</category>
        </item>
        <item>
            <title><![CDATA[How ECMAScript Engines Optimize Your Variables]]></title>
            <link>https://boajs.dev/blog/2025/03/05/local-variables</link>
            <guid>https://boajs.dev/blog/2025/03/05/local-variables</guid>
            <pubDate>Wed, 05 Mar 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[In this post, we will dive into how ECMAScript engines store variables,]]></description>
            <content:encoded><![CDATA[<p>In this post, we will dive into how ECMAScript engines store variables,
go over storage optimizations, and learn about scope analysis.
If you are an ECMAScript developer, you will get some practical tips to improve the performance of your code.
If you write your own ECMAScript engine or any interpreter/compiler, you might get some implementation ideas.</p>
<p>Before we start, let's get some disclaimers out of the way:</p>
<ul>
<li>This post is written about optimizations in the Boa ECMAScript engine.
Other engines might do things different, so take everything with a grain of salt.</li>
<li>This post omits some implementation details to focus on the most relevant parts.</li>
<li>This post contains data structures written in pseudo Rust
that are only for visualization, so you should not need to understand Rust.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="scopes-and-variables">Scopes and Variables<a href="https://boajs.dev/blog/2025/03/05/local-variables#scopes-and-variables" class="hash-link" aria-label="Direct link to Scopes and Variables" title="Direct link to Scopes and Variables" translate="no">​</a></h2>
<p>To start us off, let's refresh our understanding of variables and scopes in ECMAScript.
Variables are identifiers in our code that we can use to store and retrieve values.
Scopes describe the areas of code in which variables are visible.
You might associate scopes with curly braces.</p>
<p>Let's look at an example to visualize scopes:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// &lt;- start of a block scope</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// &lt;- end of a block scope</span><br></span></code></pre></div></div>
<p>We declare and initialize two variables with the identifier <code>a</code>.
Even though both have the same identifier, they are different variables.
The variable with the value <code>1</code> is declared in the global scope.
The variable with the value <code>2</code> is declared in a block scope.</p>
<p>In this example, we always find the variable that we want to access in the current scope.
But what when the variable we access in not declared in the current scope?</p>
<p>Let's modify our example to see what happens in that case:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> b </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>In this example, our two variables have different identifiers.
Notice that when we access the variable <code>a</code> from the block scope, its value is resolved as expected.
This is because scopes are nested.
When we cannot find a variable in the current scope, we look for the same identifier in the outer scope.
In this case, we have to look for <code>a</code> in the block scope and then in the global scope.</p>
<p>Let's look at a more complex example:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// &lt;- start of a function scope</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// &lt;- start of a block scope</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 3</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// &lt;- end of a block scope</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// &lt;- end of a function scope</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 1</span><br></span></code></pre></div></div>
<p>You can see that variables are tied to their scopes.
All three variables <code>a</code> never change their values.
The variables just exist in their respective scopes, and as soon as the scope has ended, they are no longer accessible.
Instead, the previous outer scope returns to being the current scope and its variables are accessible.</p>
<p>You can see that in addition to blocks, functions also have scopes.
There are some more details to function scopes and how <code>let</code>, <code>const</code> and <code>var</code> differ.
For our proposes we will only work with <code>let</code> and <code>const</code> and skip those details for now.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="storing-variables">Storing Variables<a href="https://boajs.dev/blog/2025/03/05/local-variables#storing-variables" class="hash-link" aria-label="Direct link to Storing Variables" title="Direct link to Storing Variables" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="the-naive-approach">The Naive Approach<a href="https://boajs.dev/blog/2025/03/05/local-variables#the-naive-approach" class="hash-link" aria-label="Direct link to The Naive Approach" title="Direct link to The Naive Approach" translate="no">​</a></h3>
<p>When developing an ECMAScript engine we have to think about how we store and access scopes and variables.
Take a look at the requirements we have for that storage data structure:</p>
<ul>
<li>A variable maps an identifier to a value.</li>
<li>A scope can have multiple variables with unique identifiers.</li>
<li>A scope may have an outer scope.</li>
</ul>
<p>The variables in a scope fit a typical key-value store, like a hashmap.
The hashmap stores our variable identifiers as keys and the variable values as corresponding values:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Scope</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    variables</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">HashMap</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Identifier</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Value</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>This is a nice and easy data structure for our variables.
And because most languages come with a hashmap built-in, we do not have implement much!</p>
<p>Let's add the ability to nest our scopes.
Since all scopes are the same, we can just build a self-referential data structure:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Scope</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    variables</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">HashMap</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Identifier</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Value</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    outer</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Scope</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>This solution works and is easy to reason about.
The data structures map very well on our mental model of variables and scopes.
This was the approach we used in Boa before we switched to a different implementation over two years ago (<a href="https://github.com/boa-dev/boa/pull/1829" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/1829</a>).</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="fixed-locations">Fixed Locations<a href="https://boajs.dev/blog/2025/03/05/local-variables#fixed-locations" class="hash-link" aria-label="Direct link to Fixed Locations" title="Direct link to Fixed Locations" translate="no">​</a></h3>
<p>You may already have spotted some performance issues with this data structure.
Consider that accessing variables is one of the things happening all the time in most languages.
Therefore, the runtime performance of variable access operations should be highly optimized.
With this current data structure we have to perform at least one hashmap lookup per variable access.
Most hashmap implementations will incur significant cost compared to accessing a fixed location in memory.
This problem gets worse when the variable we want to access is not in our current scope.
In the worst case, we have to traverse all the scopes until we arrived at the global scope.</p>
<p>How would you optimize this data structure for runtime performance?
Can you find a way to locate each variable without accessing multiple hashmaps?</p>
<p>When we read code, we can use our mental model of variables and scopes to see how each variable is unique.
We just have to apply that knowledge to our data structure.
In practice, we can assign each variable two indices that make it unique and give it a defined location in memory:</p>
<ul>
<li><code>scope index</code>: The index of the scope that the variable is declared in.</li>
<li><code>variable index</code>: The index of the variable in its scope.</li>
</ul>
<p>Let's visualize this in an example:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// scope index: 0; variable index: 0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> b </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// scope index: 1; variable index: 0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> c </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// scope index: 1; variable index: 1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>You can see how each variable has a set of two unique indices.
The scope index increases with each nested scope.
The variable index increases with each variable in one specific scope.</p>
<p>Let's explore how unique these indices have to be:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// scope index: 1; variable index: 0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> b </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// scope index: 1; variable index: 0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>As you can see, both <code>a</code> and <code>b</code> have a scope index of <code>1</code> and a variable index of <code>0</code>.
This works for us, because variables do not have to be unique for the whole program.
They just have to be unique in their current nested tree of scopes.</p>
<p>With all of this in mind, we can build a data structure that allows us to access variables just based on these two indices.
It might look something like this:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Scopes</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    scopes</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Array</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Scope</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Scope</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    variables</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Array</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Value</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Instead of having a self-referential data structure, we now have a two-dimensional array.</p>
<p>While this is our runtime data structure, we still have to calculate the variable indices before running the code.
For that we can use our previous approach with some slight modifications.
Instead of storing the value of the variable, we just store its index.
Additionally, we store an index in every scope to easily access our scope indices:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Scope</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    index</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    variables</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">HashMap</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Identifier</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Variable</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    outer</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Scope</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Variable</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    index</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>While this data structure still works based on self-referential hashmaps, we only need it before running code.
Instead of doing a lookup on every variable access at runtime, we just have to do it once.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="local-variables">Local Variables<a href="https://boajs.dev/blog/2025/03/05/local-variables#local-variables" class="hash-link" aria-label="Direct link to Local Variables" title="Direct link to Local Variables" translate="no">​</a></h2>
<p>Our previous optimization changed the data structure for our variables and scopes.
But we can come up with further optimizations if we look at the usage of variables in the code.</p>
<p>Let's take a look at this example:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">addOne</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> one </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> one </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> a</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">addOne</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Currently, we store <code>a</code> and <code>one</code> in our scopes and access them when performing the addition.
But why do we need the special data structure for variables and scopes at all?
What if we could just store the variables directly where we need them?</p>
<p>A typical ECMAScript engine uses a virtual machine (VM) to execute your code.
VMs use dedicated memory for values they operate on; a stack or registers.
For the purpose of this post, we use registers, but the stack would work in the same way.
Let's try to use registers to store variables.
While compiling the ECMAScript code into operations for our VM, we assign each variable to a register.
Then we modify our variable operations to use registers instead of scopes to access variables.</p>
<p>When we test our example from above, it works fine with these changes.
Let's write down what exactly happens:</p>
<ol>
<li>The function <code>addOne</code> is called. Registers for <code>a</code> and <code>one</code> are allocated.</li>
<li>The first function argument with the value <code>2</code> is written to the register for <code>a</code>.</li>
<li>The value <code>1</code> is written to the register for <code>one</code>.</li>
<li>The values from the registers <code>a</code> and <code>one</code> are read and added together.</li>
</ol>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="nested-functions">Nested Functions<a href="https://boajs.dev/blog/2025/03/05/local-variables#nested-functions" class="hash-link" aria-label="Direct link to Nested Functions" title="Direct link to Nested Functions" translate="no">​</a></h3>
<p>When testing some more complex code we will quickly see that something does not work as expected.</p>
<p>Let's look at this example:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">addOneBuilder</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> one </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> one </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> a</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> addOne </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">addOneBuilder</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">addOne</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>While running the code, depending on the implementation, we might get a panic, a wrong result or even an unsafe memory access.
Let's try to understand what is going on here:</p>
<ol>
<li>The function <code>addOneBuilder</code> is called. A register for <code>one</code> is allocated.</li>
<li>The value <code>1</code> is written to the register for <code>one</code>.</li>
<li>The function <code>addOneBuilder</code> returns the arrow function bound to <code>addOne</code>.</li>
<li>The function <code>addOne</code> is called. A register for <code>a</code> is allocated.</li>
<li>The first function argument with the value <code>2</code> is written to the register for <code>a</code>.</li>
<li>The VM tries to access the register for <code>one</code>. This is the point where our things go wrong.</li>
</ol>
<p>Registers in a VM are local to a specific function.
In our example this means that the variable <code>one</code> can only be accessed successfully in the function <code>addOneBuilder</code>.
As soon as we try to access it from <code>addOne</code>, the register we assigned during compilation does not hold the correct value anymore.
This is why this optimization can be referred to as <code>local variables</code> or <code>function local variables</code>.</p>
<p>We now know that variables that are used in nested functions cannot be used as local variables.
But this should not stop us from using the optimization.
We just have to find all the variables that cannot be optimized.
Then we can use our existing scopes to store those, while optimizing all the other ones.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="scope-analysis">Scope Analysis<a href="https://boajs.dev/blog/2025/03/05/local-variables#scope-analysis" class="hash-link" aria-label="Direct link to Scope Analysis" title="Direct link to Scope Analysis" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="finding-variables-accessed-by-other-functions">Finding Variables accessed by other Functions<a href="https://boajs.dev/blog/2025/03/05/local-variables#finding-variables-accessed-by-other-functions" class="hash-link" aria-label="Direct link to Finding Variables accessed by other Functions" title="Direct link to Finding Variables accessed by other Functions" translate="no">​</a></h3>
<p>To determine which variables can be stored in registers, we analyze them prior to code execution.
We can reuse our previously established scope structure based on hashmaps.
It just needs some additional information to make our analysis work.
Each scope needs to be flagged to indicate if it is a function scope.
This is important, because we have to track if a variable is ever accessed from a nested function.
Additionally, each variable needs a flag to indicate if it can be a local variable.</p>
<p>Our adjusted scope structure looks like this:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Scope</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    index</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    function</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">bool</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// &lt;- This field is new</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    variables</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">HashMap</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Identifier</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Variable</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    outer</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Scope</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Variable</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    index</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    local</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">bool</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// &lt;- This field is new</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>We set the <code>function</code> flag on each scope when it is created.
The <code>local</code> flag on the variables is <code>true</code> by default.
After creating all the scopes and filling them with their variables, we traverse the ECMAScript code.
Every time we find a variable access, we check which variable in which scope is being accessed.
If a variable is not in the current scope, we go to the <code>outer</code> scope.
If any of the scopes we see until we find the variable is a function scope, we set the <code>local</code> flag to <code>false</code>.</p>
<p>Let's visualize the scope analysis by writing out the scopes for this example:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">addOneBuilder</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> one </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> one </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> a</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>These are our scopes before the scope analysis.
Notice that we start from the scope of the arrow function, since we work our way out from the most nested scope:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token class-name">Scope</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    function</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    variables</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"a"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            index</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            local</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    outer</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Scope</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        function</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        variables</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"one"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                index</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                local</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Now we apply our scope analysis.
During the access to variable <code>one</code> in the arrow function, we pass the function scope of the arrow function.
This indicates that this variable cannot be local:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token class-name">Scope</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    function</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    variables</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"a"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            index</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            local</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// &lt;- Still `true`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    outer</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Scope</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        function</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        variables</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"one"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                index</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                local</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// &lt;- Set to `false`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>After the scope analysis is finished, we compile our code for the VM.
When we encounter a variable that can be local, we assign it a register.
When we encounter a variable that cannot be local, we use the old VM operations for our scopes storage.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="other-exceptions">Other Exceptions<a href="https://boajs.dev/blog/2025/03/05/local-variables#other-exceptions" class="hash-link" aria-label="Direct link to Other Exceptions" title="Direct link to Other Exceptions" translate="no">​</a></h3>
<p>There are some more situations that prevent us from using local variables.
We have to account for every case where a variable might be accessed from outside its function.
Without going into detail on each of these cases, we can find all of them via scope analysis.</p>
<p>Here is a quick overview:</p>
<ul>
<li>
<p>Non <code>strict</code> functions create a mapped <code>arguments</code> object.
The mapped <code>arguments</code> object can be used to read and write function arguments without using their identifiers.
The reads and writes are kept in sync with the values of the argument variables.
This means that we cannot determine if the argument variables are accessed from outside the function.</p>
<p>An example of such a situation would be this code:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// initial</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    arguments</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"modified"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// modified</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"initial"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>The solution here is to mark every argument variable that might be accessed through a mapped <code>arguments</code> object as non-local.</p>
</li>
<li>
<p>Direct calls to <code>eval</code> allow potential variable access.
Direct calls to <code>eval</code> have access to the current variables.
Since any code could be executed in <code>eval</code> we cannot do proper scope analysis on any variables in such cases.</p>
<p>An example of direct <code>eval</code> usage would be this:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">eval</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"function nested() {console.log(a)}; nested();"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Our solution is this case is to mark every variable in the scopes where the direct <code>eval</code> call is as non-local.</p>
</li>
<li>
<p>Usage of the <code>with</code> statement.
Variable identifiers inside a <code>with</code> statement are not static.
A variable identifier could be the access to a variable, but it also could be the access to an object property.</p>
<p>See this example:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> a1 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">with</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">a</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">i</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">]</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>In the first loop execution <code>a1</code> is the variable.
In the second loop execution <code>a1</code> is the object property.
As a result of this behavior, every variable accessed inside a <code>with</code> statement cannot be local.</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="conclusion">Conclusion<a href="https://boajs.dev/blog/2025/03/05/local-variables#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>After implementing local variables in Boa, we saw significant performance improvements in our benchmarks.
Our overall benchmark scope improved by more than 25%.
In one specific benchmark the scope increased by over 70%.
Notice that Boa is not the most performant engine yet.
There are probably other optimizations relating to variable storage that we have not implemented yet.</p>
<p>Hopefully, you might have already picked up some practical tips to potentially improve to performance of your ECMAScript code.
Here are our observations that might help performance:</p>
<ul>
<li>Avoid accessing variables across functions.
This might just help the ECMAScript engine to optimize your code better.</li>
<li>Always use <code>strict</code> mode.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#never_use_direct_eval!" target="_blank" rel="noopener noreferrer">Never use direct <code>eval</code>!</a></li>
<li>Never use the <code>with</code> statement.</li>
</ul>]]></content:encoded>
            <category>post</category>
            <category>internals</category>
        </item>
        <item>
            <title><![CDATA[Boa release v0.20]]></title>
            <link>https://boajs.dev/blog/2024/12/05/boa-release-020</link>
            <guid>https://boajs.dev/blog/2024/12/05/boa-release-020</guid>
            <pubDate>Thu, 05 Dec 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Boa release v0.20]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="summary">Summary<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>Boa v0.20 is now available! After 5 months of development we are very happy to present you the latest
release of the Boa JavaScript engine. Boa makes it easy to embed a JS engine in your projects, and
you can even use it from WebAssembly. See the <a href="https://boajs.dev/about">about</a> page for more info.</p>
<p>In this release, our conformance has grown from 87.3% to 89.92% in the official ECMAScript Test Suite
(Test262). This small jump is expected as we're shifting most of our focus to performance as the majority of the engine is now conformant. We will continue to implement more of the specification as we go along but we expect these changes to be much smaller than we've been used to.</p>
<p>You can check the full list of changes <a href="https://github.com/boa-dev/boa/blob/v0.20/CHANGELOG.md" target="_blank" rel="noopener noreferrer">here</a>, and the full information on conformance
<a href="https://boajs.dev/conformance">here</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="feature-highlights">Feature Highlights<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#feature-highlights" class="hash-link" aria-label="Direct link to Feature Highlights" title="Direct link to Feature Highlights" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="temporal">Temporal<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#temporal" class="hash-link" aria-label="Direct link to Temporal" title="Direct link to Temporal" translate="no">​</a></h3>
<p>Boa is continuing to progress on <a href="https://github.com/tc39/proposal-temporal" target="_blank" rel="noopener noreferrer">Temporal</a>. The Temporal API is a new
set of built-in objects and functions that is designed to be a more modern replacement for the <code>Date</code>
object, providing a more feature-rich and flexible API for working with dates and times.</p>
<p>It is currently a <a href="https://tc39.es/proposal-temporal/docs/" target="_blank" rel="noopener noreferrer">stage 3 proposal</a> and we are working
alongside the TC39 champions to put together a solid Rust implementation. Since Temporal is such an
extensive specification, we have done most of the work outside of Boa so that it can be used in other
projects. This work can be found in the <a href="https://github.com/boa-dev/temporal/" target="_blank" rel="noopener noreferrer">temporal_rs</a> repository.</p>
<p>We hope to release a full blog post on Temporal in the future, but for now you can see the previous release notes for some examples on how to use it.
You can also look at the <a href="https://tc39.es/proposal-temporal/docs/cookbook.html" target="_blank" rel="noopener noreferrer">Temporal Cook Book</a> for some examples too!</p>
<p>If you're interested in learning more or want to contribute to the native Rust implementation of
Temporal, feel free to check out <code>temporal_rs</code>'s <a href="https://github.com/boa-dev/temporal/issues" target="_blank" rel="noopener noreferrer">issues</a>!</p>
<p>Boa's conformance on the Temporal test suite has grown from 24.61% to 40.67% in this release.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="nightlies">Nightlies<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#nightlies" class="hash-link" aria-label="Direct link to Nightlies" title="Direct link to Nightlies" translate="no">​</a></h3>
<p>Boa now supports nightly releases, this was originally created to aid with the testing of conformance for test262.fyi. This is a great way to see the latest changes and help offer feedback on new features or just to see the latest changes in the engine. You can find the nightly releases <a href="https://github.com/boa-dev/boa/releases/tag/nightly" target="_blank" rel="noopener noreferrer">here</a></p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="atomicspause">Atomics.pause<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#atomicspause" class="hash-link" aria-label="Direct link to Atomics.pause" title="Direct link to Atomics.pause" translate="no">​</a></h3>
<p>Boa has added support for the <a href="https://github.com/tc39/proposal-atomics-microwait" target="_blank" rel="noopener noreferrer">stage 3 proposal <code>Atomics.pause</code></a>. This function is used to pause the execution of a thread for a specified amount of time. This function is useful for implementing spinlocks and other synchronization primitives in JavaScript.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="getters-and-setters-in-the-js_class-macro">Getters and Setters in the js_class! macro<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#getters-and-setters-in-the-js_class-macro" class="hash-link" aria-label="Direct link to Getters and Setters in the js_class! macro" title="Direct link to Getters and Setters in the js_class! macro" translate="no">​</a></h3>
<p>You can now add getters and setters to the <code>js_class!</code> macro. This allows you to define getters and setters on your JavaScript classes in Rust. This is a feature that has been requested by many users of Boa, and thanks to @hansl we now have it!</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token attribute attr-name" style="color:#00a4db">#[derive(Clone, Default, Trace, Finalize, JsData)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Game</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    score</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">js_class!</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    class </span><span class="token class-name">Game</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        property score </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token function" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">this</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">JsClass</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Game</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u32</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">borrow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">score</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token function" style="color:#d73a49">set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">this</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">JsClass</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Game</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> new_value</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">borrow_mut</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">score </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> new_value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">constructor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Game</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="implement-your-own-native-errors">Implement your own native Errors<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#implement-your-own-native-errors" class="hash-link" aria-label="Direct link to Implement your own native Errors" title="Direct link to Implement your own native Errors" translate="no">​</a></h3>
<p>Embedders can now create native errors in Rust and pass them into the JavaScript environment.
The below example creates a new <code>JsError</code> from a Rust standard error <a href="https://doc.rust-lang.org/std/error/trait.Error.html" target="_blank" rel="noopener noreferrer"><code>err</code></a>. This will create a new <code>JsNativeError</code> with the message of the standard error.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">boa_engine</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">JsError</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> error </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">std</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">io</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token namespace" style="opacity:0.7">std</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">io</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">ErrorKind</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Other</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"oh no!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> js_error</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">JsError</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">JsError</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_rust</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert_eq!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">js_error</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">as_native</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">message</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"oh no!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">js_error</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">as_native</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">cause</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">is_none</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="boa-runtime">Boa Runtime<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#boa-runtime" class="hash-link" aria-label="Direct link to Boa Runtime" title="Direct link to Boa Runtime" translate="no">​</a></h2>
<p>Boa’s boa_runtime crate contains an example runtime and basic runtime features and functionality for the boa_engine crate for runtime implementors.
Shout out to <a href="https://github.com/hansl" target="_blank" rel="noopener noreferrer">@hansl</a> for their work on the additional features of the Boa runtime crate.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="additional-apis">Additional APIs<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#additional-apis" class="hash-link" aria-label="Direct link to Additional APIs" title="Direct link to Additional APIs" translate="no">​</a></h3>
<p>Additional APIs added the the Runtime crate include:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder" target="_blank" rel="noopener noreferrer"><code>TextDecoder</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder" target="_blank" rel="noopener noreferrer"><code>TextEncoder</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/URL" target="_blank" rel="noopener noreferrer"><code>URL</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams" target="_blank" rel="noopener noreferrer"><code>URLSearchParams</code></a>.</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="console-improvements">Console Improvements<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#console-improvements" class="hash-link" aria-label="Direct link to Console Improvements" title="Direct link to Console Improvements" translate="no">​</a></h3>
<p>There is also <a href="https://github.com/boa-dev/boa/pull/4005" target="_blank" rel="noopener noreferrer">context added</a> to the console's <code>Logger</code> trait. This change modifiers the <code>Logger</code> trait to accept <code>ConsoleState</code> and <code>Context</code> paramters. This allows the <code>Logger</code> to be aware of the context in which it is being called, and to log messages accordingly. This is useful for debugging and logging in Boa.</p>
<p>See <a href="https://docs.rs/boa_runtime/latest/boa_runtime/index.html" target="_blank" rel="noopener noreferrer">here</a> for more information on Boa runtime.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="performance">Performance<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#performance" class="hash-link" aria-label="Direct link to Performance" title="Direct link to Performance" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="escape-analysis-and-local-variables">Escape Analysis and local variables<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#escape-analysis-and-local-variables" class="hash-link" aria-label="Direct link to Escape Analysis and local variables" title="Direct link to Escape Analysis and local variables" translate="no">​</a></h3>
<p>Thanks to @raskad who has been <a href="https://github.com/boa-dev/boa/pull/3988" target="_blank" rel="noopener noreferrer">working on improving scope analysis</a> in the engine's AST. There has been so much improvement we plan to release a blog post shortly after detailing the changes and how they have improved the engine's performance.</p>
<p>Most of the changes in the AST are the addition of <a href="https://github.com/boa-dev/boa/blob/1c4f455554b4140910241e86f90474ae3ff9f095/core/ast/src/scope.rs#L19-L25" target="_blank" rel="noopener noreferrer">Scopes</a> to relevant AST nodes like <a href="https://github.com/boa-dev/boa/blob/main/core/ast/src/function/arrow_function.rs#L33" target="_blank" rel="noopener noreferrer">functions</a> or <a href="https://github.com/boa-dev/boa/blob/1c4f455554b4140910241e86f90474ae3ff9f095/core/ast/src/statement/block.rs#L47-L53" target="_blank" rel="noopener noreferrer">blocks</a>.
Scopes contain bindings, that we previously created during bytecode compilation.
Now they are added to the AST after parsing.</p>
<p>The scope analyzer contains new visitor code that creates bindings and looks for bindings that escape their function scope. This allows us to only visit the scope environment for variables that are used outside of their scope, whilst keeping local variables on the stack. This is a big performance improvement as we no longer need to visit the entire scope environment for every variable in the function.</p>
<!-- -->
<img src="https://boajs.dev/assets/images/perf-changes-light-099c86677eb6f3d219e5d5109a08f31c.png" alt="Performance changes in the benchmarks" class="themedComponent_mlkZ themedComponent--light_NVdE"><img src="https://boajs.dev/assets/images/perf-changes-dark-d41115ecdf7ac0cf260ad1ab4f823585.png" alt="Performance changes in the benchmarks" class="themedComponent_mlkZ themedComponent--dark_xIcU">
<center><em>V8 Benchmark overall score, higher is better...</em></center>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="error-optimizations">Error optimizations<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#error-optimizations" class="hash-link" aria-label="Direct link to Error optimizations" title="Direct link to Error optimizations" translate="no">​</a></h3>
<p>Thanks to the work from <a href="https://github.com/CrazyboyQCD" target="_blank" rel="noopener noreferrer">@CrazyboyQCD</a> we have improved performance on the Error messages and native errors. Error messages now use Rust's <a href="https://doc.rust-lang.org/std/borrow/enum.Cow.html" target="_blank" rel="noopener noreferrer">Cow</a> type to avoid unnecessary allocations. <code>JSNativeError</code> constructors are also now marked as <code>const</code> which means much fewer instructions generated when creating a new error. See the <a href="https://github.com/boa-dev/boa/pull/4020" target="_blank" rel="noopener noreferrer">PR</a> plus the changes in godbolt <a href="https://godbolt.org/z/YEq4hW49n" target="_blank" rel="noopener noreferrer">here</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="string-optimizations">String optimizations<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#string-optimizations" class="hash-link" aria-label="Direct link to String optimizations" title="Direct link to String optimizations" translate="no">​</a></h3>
<p>Our string representation was refactored by <a href="https://github.com/CrazyboyQCD" target="_blank" rel="noopener noreferrer">@CrazyboyQCD</a>.
Thanks to the changes, string literals can now be created without heap allocations.
Building on these changes, <a href="https://github.com/CrazyboyQCD" target="_blank" rel="noopener noreferrer">@CrazyboyQCD</a> also adjusted all places in our crates where this new capability could be applied.</p>
<p>You can find the details in the relevant PRs <a href="https://github.com/boa-dev/boa/pull/3935" target="_blank" rel="noopener noreferrer">3935</a> and <a href="https://github.com/boa-dev/boa/pull/4030" target="_blank" rel="noopener noreferrer">4030</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="lazy-loading-of-icu-data">Lazy loading of ICU data<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#lazy-loading-of-icu-data" class="hash-link" aria-label="Direct link to Lazy loading of ICU data" title="Direct link to Lazy loading of ICU data" translate="no">​</a></h3>
<p>Boa now lazily loads <a href="https://icu.unicode.org/design/cldr-support" target="_blank" rel="noopener noreferrer">ICU</a> data on demand instead of during startup, this is a big performance improvement as we no longer need to load all the ICU data which can be quite large. This code change includes the addition of a <a href="https://github.com/boa-dev/boa/blob/1c4f455554b4140910241e86f90474ae3ff9f095/core/icu_provider/src/lib.rs#L32-L40" target="_blank" rel="noopener noreferrer"><code>LazyBufferProvider</code></a> which lazily deserializes the ICU data when first called upon.</p>
<p>On top of this we have also broken up the ICU data into smaller chunks called postcards (datetime, plurals, segmenters, decimals), this means we can load only the data we need when we need it.</p>
<p>You can see more details on the changes in the <a href="https://github.com/boa-dev/boa/pull/3948" target="_blank" rel="noopener noreferrer">PR</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="new-contributors">New Contributors<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#new-contributors" class="hash-link" aria-label="Direct link to New Contributors" title="Direct link to New Contributors" translate="no">​</a></h2>
<p>Thank you to the new contributors to Boa for this release, you can find their contributions below:</p>
<ul>
<li><a href="https://github.com/@magic-akari" target="_blank" rel="noopener noreferrer">@magic-akari</a> made their first contribution in <a href="https://github.com/boa-dev/boa/pull/3916" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/3916</a></li>
<li><a href="https://github.com/@shurizzle" target="_blank" rel="noopener noreferrer">@shurizzle</a> made their first contribution in <a href="https://github.com/boa-dev/boa/pull/3976" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/3976</a></li>
<li><a href="https://github.com/@it-a-me" target="_blank" rel="noopener noreferrer">@it-a-me</a> made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4007" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4007</a></li>
<li><a href="https://github.com/@Nikita-str" target="_blank" rel="noopener noreferrer">@Nikita-str</a> made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4010" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4010</a></li>
<li><a href="https://github.com/@4yman-0" target="_blank" rel="noopener noreferrer">@4yman-0</a> made their first contribution in <a href="https://github.com/boa-dev/boa/pull/4046/" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/4046/</a></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="looking-forward">Looking Forward<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#looking-forward" class="hash-link" aria-label="Direct link to Looking Forward" title="Direct link to Looking Forward" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="register-vm">Register VM<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#register-vm" class="hash-link" aria-label="Direct link to Register VM" title="Direct link to Register VM" translate="no">​</a></h3>
<p>Now that we <a href="https://github.com/boa-dev/boa/pull/3942" target="_blank" rel="noopener noreferrer">have register</a> allocation merged @HalidOdat has been working on migrating from a Stack VM to a Register VM, the register VM should mean less accesses to the heap as we utilize register allocation more. Secondly, by resembling the lower level architecture (in terms of low-level operations), we can compile down to efficient machine languauge easier in future when looking into JIT compilation.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="lazy-built-ins">Lazy Built-ins<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#lazy-built-ins" class="hash-link" aria-label="Direct link to Lazy Built-ins" title="Direct link to Lazy Built-ins" translate="no">​</a></h3>
<p>All builtins are eagerly initialized when the engine starts up, this is not ideal as it can slow down the startup time of the engine. We are looking to change this so that builtins are lazily initialized when they are first accessed. This should improve the startup time of the engine and reduce the memory footprint. You can follow the progress of this work <a href="https://github.com/boa-dev/boa/pull/3973" target="_blank" rel="noopener noreferrer">here</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-can-you-support-boa">How can you support Boa?<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#how-can-you-support-boa" class="hash-link" aria-label="Direct link to How can you support Boa?" title="Direct link to How can you support Boa?" translate="no">​</a></h2>
<p>Boa is an independent JavaScript engine implementing the ECMAScript specification, and we rely on the
support of the community to keep it going. If you want to support us, you can do so by donating to
our <a href="https://opencollective.com/boa" target="_blank" rel="noopener noreferrer">open collective</a>. Proceeeds here go towards this very website, the domain name, and remunerating
members of the team who have worked on the features released.</p>
<p>If financial contribution is not your strength, you can contribute by asking to be assigned to one of
our <a href="https://github.com/boa-dev/boa/issues?q=is%3Aopen+is%3Aissue+no%3Aassignee" target="_blank" rel="noopener noreferrer">open issues</a>, and asking for mentoring if you don't know your way around the engine. Our
<a href="https://github.com/boa-dev/boa/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">contribution guide</a> should help you here. If you are more used to working with JavaScript or frontend
web development, we also welcome help to improve our web presence, either in <a href="https://github.com/boa-dev/boa-dev.github.io" target="_blank" rel="noopener noreferrer">our website</a>, or in our
<a href="https://github.com/boa-dev/boa/issues/820" target="_blank" rel="noopener noreferrer">testing representation</a> page or benchmarks page. You can also contribute to our Criterion benchmark
comparison GitHub <a href="https://github.com/boa-dev/criterion-compare-action" target="_blank" rel="noopener noreferrer">action</a>.</p>
<p>We are also looking to improve the documentation of the engine, both for developers of the engine
itself and for users of the engine. Feel free to contact us in <a href="https://matrix.to/#/#boa:matrix.org" target="_blank" rel="noopener noreferrer">Matrix</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="thank-you">Thank You<a href="https://boajs.dev/blog/2024/12/05/boa-release-020#thank-you" class="hash-link" aria-label="Direct link to Thank You" title="Direct link to Thank You" translate="no">​</a></h2>
<p>Once again, big thanks to <a href="https://github.com/boa-dev/boa/graphs/contributors?from=2024-03-05&amp;to=2024-07-11&amp;type=c" target="_blank" rel="noopener noreferrer">all the contributors</a> of this release!!</p>]]></content:encoded>
            <category>post</category>
        </item>
        <item>
            <title><![CDATA[Boa release v0.19]]></title>
            <link>https://boajs.dev/blog/2024/07/09/boa-release-19</link>
            <guid>https://boajs.dev/blog/2024/07/09/boa-release-19</guid>
            <pubDate>Tue, 09 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[More progress on Temporal, new benchmarks, migration to Matrix, and more...]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="summary">Summary<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>Boa v0.19 is now available! After 4 months of development we are very happy to present you the latest
release of the Boa JavaScript engine. Boa makes it easy to embed a JS engine in your projects, and
you can even use it from WebAssembly. See the <a href="https://boajs.dev/about">about</a> page for more info.</p>
<p>In this release, our conformance has grown from 85.03% to 87.3% in the official ECMAScript Test Suite
(Test262). Interestingly, this was partly because around 2000 tests
were <a href="https://github.com/tc39/test262/commit/ea2268aa4382013f5533b91f9ef50366ad065a86" target="_blank" rel="noopener noreferrer">removed from test262</a>
as part of the <a href="https://github.com/tc39/proposal-temporal/issues/2826" target="_blank" rel="noopener noreferrer">removal of custom calendars and timezones</a>.
Overall, Boa's conformance in real terms has improved by ~6%.</p>
<p>You can check the full list of changes <a href="https://github.com/boa-dev/boa/blob/v0.19/CHANGELOG.md" target="_blank" rel="noopener noreferrer">here</a>, and the full information on conformance
<a href="https://boajs.dev/conformance">here</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="highlights">Highlights<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#highlights" class="hash-link" aria-label="Direct link to Highlights" title="Direct link to Highlights" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="temporal">Temporal<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#temporal" class="hash-link" aria-label="Direct link to Temporal" title="Direct link to Temporal" translate="no">​</a></h3>
<p>Boa is continuing to progress on <a href="https://github.com/tc39/proposal-temporal" target="_blank" rel="noopener noreferrer">Temporal</a>. The Temporal API is a new
set of built-in objects and functions that is designed to be a more modern replacement for the <code>Date</code>
object, providing a more feature-rich and flexible API for working with dates and times.</p>
<p>It is currently a <a href="https://tc39.es/proposal-temporal/docs/" target="_blank" rel="noopener noreferrer">stage 3 proposal</a> and we are working
alongside the TC39 champions to put together a solid Rust implementation. Since Temporal is such an
extensive specification, we have done most of the work outside of Boa so that it can be used in other
projects. This work can be found in the <a href="https://github.com/boa-dev/temporal/" target="_blank" rel="noopener noreferrer">temporal_rs</a> repository.</p>
<p>We hope to release a full blog post on Temporal in the future, but for now you can see the previous release notes for some examples on how to use it.
You can also look at the <a href="https://tc39.es/proposal-temporal/docs/cookbook.html" target="_blank" rel="noopener noreferrer">Temporal Cook Book</a> for some examples too!</p>
<p>If you're interested in learning more or want to contribute to the native Rust implementation of
Temporal, feel free to check out <code>temporal_rs</code>'s <a href="https://github.com/boa-dev/temporal/issues" target="_blank" rel="noopener noreferrer">issues</a>!</p>
<p>Boa's conformance on the Temporal test suite has grown from 19.35% to 24.61% in this release.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="new-benchmark-suite-faster-ci-and-reduced-repo-size">New Benchmark Suite, Faster CI and reduced repo size<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#new-benchmark-suite-faster-ci-and-reduced-repo-size" class="hash-link" aria-label="Direct link to New Benchmark Suite, Faster CI and reduced repo size" title="Direct link to New Benchmark Suite, Faster CI and reduced repo size" translate="no">​</a></h3>
<p>Boa has had an overhaul of its older criterion benchmark suite to a new <a href="https://boajs.dev/benchmarks" target="_blank" rel="noopener noreferrer">end to end benchmark suite</a>.
We had finally outgrown the old benchmark suite and needed a new one that could handle the new features and improvements we were making to the engine.
The former benchmark suite has been there almost since the beginning, and was created as a way to keep an eye on certain functions and routines within Boa itself. Although useful, it
wasn't comparable to other engines due to being so specific on how Boa works.</p>
<p>The new suite is taken from <a href="https://github.com/mozilla/arewefastyet/tree/master/benchmarks/v8-v7" target="_blank" rel="noopener noreferrer">V8's old benchmark suite</a> which, despite being deprecated, is still for comparative performance.
Over time we will eventually need to work with other engines to have a more advanced benchmarking suite which can take into account modern JavaScript, but for now this is a good start.</p>
<p>This change also offered a nice side effect of not having benchmark or test262 data in the main repository anymore. Last time we released we had <a href="https://www.reddit.com/r/rust/comments/1b91ora/comment/ktue8rf/" target="_blank" rel="noopener noreferrer">reports</a> of the repository being too large, so we've taken steps to reduce the size of the repository by moving this data to a separate repository and building a nightly version for reporting. Not only this makes it easier for anyone cloning Boa today but pushes to <code>main</code> are now much faster due to us not having to run test262 or Benchmarks each time.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="migration-to-matrix">Migration to Matrix<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#migration-to-matrix" class="hash-link" aria-label="Direct link to Migration to Matrix" title="Direct link to Migration to Matrix" translate="no">​</a></h3>
<p>The Boa team will be migrating to Matrix from our Discord servers over the course of this year. This means we will hang out in the <a href="https://matrix.to/#/#boa:matrix.org" target="_blank" rel="noopener noreferrer"><code>#boa:matrix.org</code></a> room and will be available for questions and discussions there. We will also be using Matrix for other break-out rooms on future development in areas such as <a href="https://matrix.to/#/!odQJQiuPFJtUBzgoXY:matrix.org?via=matrix.org&amp;via=mozilla.org" target="_blank" rel="noopener noreferrer">Performance</a>, <a href="https://matrix.to/#/!rsWLMsIzfquQAbDoak:matrix.org?via=matrix.org" target="_blank" rel="noopener noreferrer">Intl</a> and <a href="https://matrix.to/#/!DeQjFAUjAPAffIsCgq:matrix.org?via=matrix.org&amp;via=mozilla.org&amp;via=igalia.com" target="_blank" rel="noopener noreferrer">Temporal</a>. We will be keeping the Discord server open for a while to allow people to migrate over, but we will eventually close it down sometime in 2025.</p>
<p>Boa has long been a user of Discord, pretty much since the beginning of the project, but as the project has grown and matured, we have chosen to move more in line to other communities who use Matrix for communication, such as TC39 who work on ECMAScript standard. With Boa's increased conformance and ability to work closer with the standard committee when implementing Temporal and other new specifications meant that a migration to Matrix was the most natural choice to ease communication with the broader JavaScript implementer communities.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="optimizations">Optimizations<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#optimizations" class="hash-link" aria-label="Direct link to Optimizations" title="Direct link to Optimizations" translate="no">​</a></h3>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="release-binary-stripping">Release binary stripping<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#release-binary-stripping" class="hash-link" aria-label="Direct link to Release binary stripping" title="Direct link to Release binary stripping" translate="no">​</a></h4>
<p>Boa's binaries are on the larger side by default due to including ICU data. We may eventually move to a system where this needs to be fed from the host. However, until then there are other tricks we can employ to bring down our size, one of those is binary stripping. We can remove debug information from the release binary to reduce the size.</p>
<table><thead><tr><th>crate</th><th>v0.18</th><th>v0.19</th></tr></thead><tbody><tr><td>boa</td><td>26MB</td><td>25MB</td></tr><tr><td>boa_tester</td><td>27MB</td><td>25MB</td></tr></tbody></table>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="dense-array-storage-variants-for-i32-and-f64">Dense array storage variants for i32 and f64<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#dense-array-storage-variants-for-i32-and-f64" class="hash-link" aria-label="Direct link to Dense array storage variants for i32 and f64" title="Direct link to Dense array storage variants for i32 and f64" translate="no">​</a></h4>
<p>This release adds <a href="https://github.com/boa-dev/boa/pull/3760" target="_blank" rel="noopener noreferrer">dense array storage</a> variants for <code>i32</code> and <code>f64</code> types. This allows us to store arrays of these types more efficiently, and also allows us to optimize certain operations on these arrays.</p>
<p>If you want to inspect the storage type of an array in Boa you can use the <code>$boa.object.indexedStorageType()</code> APi. Here are <a href="https://github.com/boa-dev/boa/blob/d3e539593fe206f18d44f20498cb54be15477a58/docs/boa_object.md#function-boaobjectindexedstoragetypeobject" target="_blank" rel="noopener noreferrer">some examples</a>:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$boa</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">indexedStorageType</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 'DenseI32'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0xdeadbeef</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$boa</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">indexedStorageType</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 'DenseI32'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0.5</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$boa</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">indexedStorageType</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 'DenseF64'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$boa</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">indexedStorageType</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 'DenseElement'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Make a hole</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$boa</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">indexedStorageType</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 'SparseElement'</span><br></span></code></pre></div></div>
<p>Much of this work is possible thanks to our implementation of <a href="https://github.com/boa-dev/boa/blob/main/docs/shapes.md" target="_blank" rel="noopener noreferrer">Object Shapes</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="new-contributors">New Contributors<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#new-contributors" class="hash-link" aria-label="Direct link to New Contributors" title="Direct link to New Contributors" translate="no">​</a></h2>
<p>Thank you to the new contributors to Boa for this release, you can find their contributions below:</p>
<ul>
<li><a href="https://github.com/robot-head" target="_blank" rel="noopener noreferrer">@robot-head</a> made their first contribution in <a href="https://github.com/boa-dev/boa/pull/3730" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/3730</a></li>
<li><a href="https://github.com/hansl" target="_blank" rel="noopener noreferrer">@hansl</a> made their first contribution in <a href="https://github.com/boa-dev/boa/pull/3755" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/3755</a></li>
<li><a href="https://github.com/NickTomlin" target="_blank" rel="noopener noreferrer">@NickTomlin</a> made their first contribution in <a href="https://github.com/boa-dev/boa/pull/3793" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/3793</a></li>
<li><a href="https://github.com/linusg" target="_blank" rel="noopener noreferrer">@linusg</a> made their first contribution in <a href="https://github.com/boa-dev/boa/pull/3800" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/3800</a></li>
<li><a href="https://github.com/getong" target="_blank" rel="noopener noreferrer">@getong</a> made their first contribution in <a href="https://github.com/boa-dev/boa/pull/3836" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/3836</a></li>
<li><a href="https://github.com/leoflalv" target="_blank" rel="noopener noreferrer">@leoflalv</a> made their first contribution in <a href="https://github.com/boa-dev/boa/pull/3867" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/3867</a></li>
<li><a href="https://github.com/CrazyboyQCD" target="_blank" rel="noopener noreferrer">@CrazyboyQCD</a> made their first contribution in <a href="https://github.com/boa-dev/boa/pull/3898" target="_blank" rel="noopener noreferrer">https://github.com/boa-dev/boa/pull/3898</a></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="looking-forward">Looking Forward<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#looking-forward" class="hash-link" aria-label="Direct link to Looking Forward" title="Direct link to Looking Forward" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="api-ergonomics">API ergonomics<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#api-ergonomics" class="hash-link" aria-label="Direct link to API ergonomics" title="Direct link to API ergonomics" translate="no">​</a></h3>
<p>Before finishing this blog post, we wanted to give a special shoutout to <a href="https://github.com/hansl" target="_blank" rel="noopener noreferrer">@hansl</a>, one of our new
contributors for this release! He's been working on improving the ergonomics around exposing
Rust functions and types as ECMAScript functions and classes with a lot of nice API enhancements.
Some notable PRs are:</p>
<ul>
<li><a href="https://github.com/boa-dev/boa/pull/3772" target="_blank" rel="noopener noreferrer">Add a boa_interop crate</a></li>
<li><a href="https://github.com/boa-dev/boa/pull/3786" target="_blank" rel="noopener noreferrer">Add a new type Convert&lt;&gt; to convert values</a></li>
<li><a href="https://github.com/boa-dev/boa/pull/3802" target="_blank" rel="noopener noreferrer">Add a ContextData struct to inject host defined types from the context</a></li>
<li><a href="https://github.com/boa-dev/boa/pull/3872" target="_blank" rel="noopener noreferrer">Add a js_class to implement the Class trait without boilerplate</a></li>
</ul>
<p>Unfortunately, the aforementioned <code>boa_interop</code> crate was not published for this version, and that's
because we would like to polish it first and integrate it within the other crates of the project.
However, we can give you a sneak peek of what some of the new APIs will allow you to do. Hopefully
this will make you look forward for v0.20!</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">boa_interop</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">js_class</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Ignore</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">JsClass</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute attr-name" style="color:#00a4db">#[derive(Clone, Trace, Finalize, JsData)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">enum</span><span class="token plain"> </span><span class="token type-definition class-name">Animal</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Cat</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Dog</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Other</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">js_class!</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Implements the [`Class`] trait for the `Animal` enum.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    class </span><span class="token class-name">Animal</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// This sets a field on the JavaScript object. The arguments to</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// `init` are the arguments passed to the constructor.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        public </span><span class="token function" style="color:#d73a49">age</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">_name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Ignore</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> age</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i32</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            age</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// This is called when a new instance of the class is created in</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// JavaScript, e.g. `new Animal("cat")`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">constructor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">match</span><span class="token plain"> name</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">as_str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token string" style="color:#e3116c">"cat"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Animal</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Cat</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token string" style="color:#e3116c">"dog"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Animal</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Dog</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                _ </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Animal</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Other</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Declare a function on the class itself.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">speak</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">this</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">JsClass</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Animal</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsString</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">match</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">borrow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token class-name">Animal</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Cat</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"meow"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token class-name">Animal</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Dog</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"woof"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token class-name">Animal</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Other</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">r"¯\_(ツ)_/¯"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="performance">Performance<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#performance" class="hash-link" aria-label="Direct link to Performance" title="Direct link to Performance" translate="no">​</a></h3>
<p>Now that our conformance is farily high (87.3% in Test262), we will be focusing on improving the performance of the engine. This will involve re-writing the Garbage Collector from the one we have now which was a fork of <a href="https://github.com/Manishearth/rust-gc" target="_blank" rel="noopener noreferrer">rust-gc</a> and modified heavily, to something which will work better for the engine and allow us to have paritioning, snapshots and other features which are not possible with the current GC. If this interests you, you can join the effort in our Matrix GC chat (see <a href="https://boajs.dev/blog/2024/07/09/boa-release-19#migration-to-matrix">Migration To Matrix</a> above).</p>
<p>Boa will also be working on <a href="https://github.com/boa-dev/boa/pull/3798" target="_blank" rel="noopener noreferrer">migrating</a> from a stack VM to a register-based VM. This will allow us to optimize the engine further and make it more competitive with other engines. We will also be working on improving the performance of the engine in general, and we will be looking at ways to make the engine faster and more efficient.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="v10">v1.0<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#v10" class="hash-link" aria-label="Direct link to v1.0" title="Direct link to v1.0" translate="no">​</a></h3>
<p>We hope that the changes mentioned above will bring us closer to a v1.0 release. We are still some way off, but we are making progress and we are confident that we will be able to release a v1.0 version of Boa in the future.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-can-you-support-boa">How can you support Boa?<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#how-can-you-support-boa" class="hash-link" aria-label="Direct link to How can you support Boa?" title="Direct link to How can you support Boa?" translate="no">​</a></h2>
<p>Boa is an independent JavaScript engine implementing the ECMAScript specification, and we rely on the
support of the community to keep it going. If you want to support us, you can do so by donating to
our <a href="https://opencollective.com/boa" target="_blank" rel="noopener noreferrer">open collective</a>. Proceeeds here go towards this very website, the domain name, and remunerating
members of the team who have worked on the features released.</p>
<p>If financial contribution is not your strength, you can contribute by asking to be assigned to one of
our <a href="https://github.com/boa-dev/boa/issues?q=is%3Aopen+is%3Aissue+no%3Aassignee" target="_blank" rel="noopener noreferrer">open issues</a>, and asking for mentoring if you don't know your way around the engine. Our
<a href="https://github.com/boa-dev/boa/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">contribution guide</a> should help you here. If you are more used to working with JavaScript or frontend
web development, we also welcome help to improve our web presence, either in <a href="https://github.com/boa-dev/boa-dev.github.io" target="_blank" rel="noopener noreferrer">our website</a>, or in our
<a href="https://github.com/boa-dev/boa/issues/820" target="_blank" rel="noopener noreferrer">testing representation</a> page or benchmarks page. You can also contribute to our Criterion benchmark
comparison GitHub <a href="https://github.com/boa-dev/criterion-compare-action" target="_blank" rel="noopener noreferrer">action</a>.</p>
<p>We are also looking to improve the documentation of the engine, both for developers of the engine
itself and for users of the engine. Feel free to contact us in <a href="https://matrix.to/#/#boa:matrix.org" target="_blank" rel="noopener noreferrer">Matrix</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="thank-you">Thank You<a href="https://boajs.dev/blog/2024/07/09/boa-release-19#thank-you" class="hash-link" aria-label="Direct link to Thank You" title="Direct link to Thank You" translate="no">​</a></h2>
<p>Once again, big thanks to <a href="https://github.com/boa-dev/boa/graphs/contributors?from=2024-03-05&amp;to=2024-07-11&amp;type=c" target="_blank" rel="noopener noreferrer">all the contributors</a> of this release!!</p>]]></content:encoded>
            <category>post</category>
        </item>
        <item>
            <title><![CDATA[Boa release v0.18]]></title>
            <link>https://boajs.dev/blog/2024/03/07/boa-release-18</link>
            <guid>https://boajs.dev/blog/2024/03/07/boa-release-18</guid>
            <pubDate>Thu, 07 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Summary]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="summary">Summary<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>Boa v0.18 is now available! After 7 months of development we are very happy to present you the latest
release of the Boa JavaScript engine. Boa makes it easy to embed a JS engine in your projects, and
you can even use it from WebAssembly. See the <a href="https://boajs.dev/about">about</a> page for more info.</p>
<p>In this release, our conformance has grown from 79.36% to 85.03% in the official ECMAScript Test Suite
(Test262). This means we now pass <strong>3,550</strong> more tests than in the previous version. Moreover, our
amount of ignored tests decreased from <strong>9,496</strong> to <strong>1,391</strong> thanks to all the new builtins we have
implemented for this release.</p>
<p>You can check the full list of changes <a href="https://github.com/boa-dev/boa/blob/v0.18/CHANGELOG.md" target="_blank" rel="noopener noreferrer">here</a>, and the full information on conformance
<a href="https://boajs.dev/conformance">here</a>.</p>
<p>You probably noticed that something seems different... This release marks a major update to the design
of our website, and the introduction of our new logo!
We'd like to thank <a href="https://github.com/ZackMitkin" target="_blank" rel="noopener noreferrer">@ZackMitkin</a> for being the one that started the
work on this nifty redesign, and <a href="https://github.com/kelbazz" target="_blank" rel="noopener noreferrer">@kelbazz</a> for designing the logo.
We're planning to add some additional pages to learn more about the APIs that Boa exposes.
Additionally, expect some more blog posts from us in the future! We would like to write about how to
use certain APIs, design challenges that we encountered while developing the engine, and internal
implementation details.
Subscribe to our <a href="https://boajs.dev/blog/rss.xml" target="_blank" rel="noopener noreferrer">RSS feed</a> if you're interested in staying up to date!</p>
<p>This big release was partly possible thanks to those who have <a href="https://opencollective.com/boa" target="_blank" rel="noopener noreferrer">supported us</a>.
Thanks to funds we've received we have been able to renew our domain name, remunerate members of the
team who have worked on the features released, and discuss the possibility of using dedicated servers
for benchmarking. If you wish to sponsor Boa, you can do so by donating to our <a href="https://opencollective.com/boa" target="_blank" rel="noopener noreferrer">open collective</a>.
You can also check <a href="https://github.com/boa-dev/boa/issues?q=is%3Aopen+is%3Aissue+label%3AE-Easy" target="_blank" rel="noopener noreferrer">easy</a> or <a href="https://github.com/boa-dev/boa/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22" target="_blank" rel="noopener noreferrer">good first issues</a> if you want to contribute
some code instead.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="highlights">Highlights<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#highlights" class="hash-link" aria-label="Direct link to Highlights" title="Direct link to Highlights" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="were-on-test262fyi">We're on <a href="https://test262.fyi/" target="_blank" rel="noopener noreferrer">test262.fyi</a><a href="https://boajs.dev/blog/2024/03/07/boa-release-18#were-on-test262fyi" class="hash-link" aria-label="Direct link to were-on-test262fyi" title="Direct link to were-on-test262fyi" translate="no">​</a></h3>
<p>Thanks to the amazing work of <a href="https://twitter.com/CanadaHonk" target="_blank" rel="noopener noreferrer">CanadaHonk</a>, Boa is now listed on
<a href="https://test262.fyi/" target="_blank" rel="noopener noreferrer">test262.fyi</a>! This is a daily runner of the official test262 test suite that
runs a nightly build of Boa, along with other engines, and updates the results every day. This is
using the tip of the main branch of Boa alongside the <a href="https://github.com/tc39/test262" target="_blank" rel="noopener noreferrer">latest test262</a>
changes pushed to their main branch.</p>
<p>This is a great achievement for us and we are very proud to be listed alongside other major JavaScript
engines. It should be much easier for users to compare Boa's conformance tests with other engines.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="temporal">Temporal<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#temporal" class="hash-link" aria-label="Direct link to Temporal" title="Direct link to Temporal" translate="no">​</a></h3>
<p>A lot of work has been put over the past few months on the Temporal API. The Temporal API is a new
set of built-in objects and functions that is designed to be a more modern replacement for the <code>Date</code>
object, providing a more feature-rich and flexible API for working with dates and times.</p>
<p>It is currently a <a href="https://tc39.es/proposal-temporal/docs/" target="_blank" rel="noopener noreferrer">stage 3 proposal</a> and we are working
alongside the TC39 champions to put together a solid implementation. Since Temporal is such an
extensive specification, we have done most of the work outside of Boa so that it can be used in other
projects. This work can be found in the <a href="https://github.com/boa-dev/temporal/" target="_blank" rel="noopener noreferrer">temporal_rs</a> repository.</p>
<p>We hope to release a full blog post on Temporal in the future, but for now, let's look at a couple small
examples of Temporal.</p>
<p>In JavaScript:</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// JavaScript's Temporal built-in object.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// For example, you can customize you're own calendar implementations!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">CustomCalendar</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name">Temporal</span><span class="token class-name punctuation" style="color:#393A34">.</span><span class="token class-name">Calendar</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">constructor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">super</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"iso8601"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">inLeapYear</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">dateLike</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    messageInACalendar </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"It's a message in a Calendar!"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> dateLike</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">daysInYear</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">366</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> messageInACalendar</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Construct the CustomCalendar.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> calendar </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">CustomCalendar</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> boaReleaseDay </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Temporal</span><span class="token class-name punctuation" style="color:#393A34">.</span><span class="token class-name">PlainDate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2024</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">7</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> calendar</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> leap </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> boaReleaseDay</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">inLeapYear</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">messageInACalendar</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Outputs: "It's a message in a Calendar!"</span><br></span></code></pre></div></div>
<p>In Rust:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Rust's `temporal_rs` crate</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">temporal_rs</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token namespace" style="opacity:0.7">components</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token namespace" style="opacity:0.7">calendar</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">CalendarSlot</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Date</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">options</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">ArithmeticOverflow</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">std</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token keyword" style="color:#00009f">str</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">FromStr</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Create a Calendar slot value from a string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> calendar </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">CalendarSlot</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"iso8601"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Create a date. The date can be made to either reject or constrain the input.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> date </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Date</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2024</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">7</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> calendar</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">ArithmeticOverflow</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Reject</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert_eq!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">date</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">iso_year</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> date</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">year</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre></div></div>
<p>Please note that Temporal is still an experimental feature, and while a lot of progress
has been made, there is still more work to be completed until it is production ready.</p>
<p>If you're interested in learning more or want to contribute to the native Rust implementation of
Temporal, feel free to check out <code>temporal_rs</code>'s <a href="https://github.com/boa-dev/temporal/issues" target="_blank" rel="noopener noreferrer">issues</a>!</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="regexp">RegExp<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#regexp" class="hash-link" aria-label="Direct link to RegExp" title="Direct link to RegExp" translate="no">​</a></h3>
<p>Over the past 7 months there has been some effort poured into an improved implementation of RegExp.
This includes:</p>
<ul>
<li>Support for <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/hasIndices" target="_blank" rel="noopener noreferrer"><code>RegExp.prototype.hasIndices</code></a> (Thanks to <a href="https://github.com/dirkdev98" target="_blank" rel="noopener noreferrer">@dirkdev98</a>!).</li>
<li>Support for Unicode sets, aka the <code>v</code> flag.</li>
<li>Support for UTF-16 text searches.</li>
<li>General fixes around <code>RegExp()</code>, <code>RegExp.toString()</code> and <code>RegExp.match()</code>.</li>
</ul>
<p>Here is a table showing the progress of RegExp between v0.17 and v0.18:</p>
<table><thead><tr><th>Test262</th><th>v0.17 (July 2023)</th><th>v0.18 (Feb 2024)</th></tr></thead><tbody><tr><td>Total</td><td>1,915</td><td>1,920</td></tr><tr><td>Pass</td><td>1,071</td><td>1,878</td></tr><tr><td>Fail</td><td>132</td><td>2</td></tr><tr><td>Skipped</td><td>712</td><td>40</td></tr></tbody></table>
<p>That's a whopping 807 more tests passed!</p>
<p>We only have two failing tests left and both are caused by the lack of Unicode 15.1 support.
The remaining skipped tests are all related to stage 3 proposals.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="shared-array-buffer--atomics">Shared Array Buffer + Atomics<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#shared-array-buffer--atomics" class="hash-link" aria-label="Direct link to Shared Array Buffer + Atomics" title="Direct link to Shared Array Buffer + Atomics" translate="no">​</a></h3>
<p>The <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer" target="_blank" rel="noopener noreferrer">SharedArrayBuffer</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics" target="_blank" rel="noopener noreferrer">Atomics</a> builtins have been implemented in this release.
This means embedders can now orchestrate <code>Context</code>s running on separate threads to execute
shared work between them.</p>
<p>The <code>Atomics</code> builtin object contains several static methods that allow executing atomic operations
on shared memory. In addition to that, it also contains the <code>wait()</code> and <code>notify()</code> methods, which
offers the same functionality as Linux futexes for JS's worker threads:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// On the main thread</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> sab </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">SharedArrayBuffer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1024</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> int32 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Int32Array</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sab</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">send</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">worker1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> int32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">send</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">worker2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> int32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// On worker1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">int32 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">receive</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token maybe-class-name">Atomics</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">wait</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">int32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">int32</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 123</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// On worker2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">int32 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">receive</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">int32</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token maybe-class-name">Atomics</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">store</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">int32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">123</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token maybe-class-name">Atomics</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">notify</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">int32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="intl-updates">Intl updates<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#intl-updates" class="hash-link" aria-label="Direct link to Intl updates" title="Direct link to Intl updates" translate="no">​</a></h2>
<p>We're keeping the good progress on our <code>Intl</code> implementation, and now we have the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules" target="_blank" rel="noopener noreferrer"><code>Intl.PluralRules</code></a>
builtin and (a first prototype of) the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat" target="_blank" rel="noopener noreferrer"><code>Intl.NumberFormat</code></a> builtin in place.</p>
<p>As mentioned by the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules#description" target="_blank" rel="noopener noreferrer">Mozilla docs</a>:</p>
<blockquote>
<p>Languages use different patterns for expressing both plural numbers of items (cardinal numbers) and
for expressing the order of items (ordinal numbers). English has two forms for expressing cardinal
numbers: one for the singular "item" (1 hour, 1 dog, 1 fish) and the other for zero or any other
number of "items" (0 hours, 2 lemmings, 100000.5 fish), while Chinese has only one form, and Arabic
has six! Similarly, English has four forms for expressing ordinal numbers: "th", "st", "nd", "rd",
giving the sequence: 0th, 1st, 2nd, 3rd, 4th, 5th, ..., 21st, 22nd, 23rd, 24th, 25th, and so on,
while both Chinese and Arabic only have one form for ordinal numbers.</p>
</blockquote>
<p>This variation between languages makes it really hard to properly localize a cardinal or ordinal number.
To fix this, the CLDR (Common Locale Data Repository) project has been collecting information about
the "plural category" of certain numeric patterns on many languages, and <code>Intl.PluralRules</code> objects
are the builtin objects that enable obtaining this information in an easy way:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> pr </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Intl</span><span class="token class-name punctuation" style="color:#393A34">.</span><span class="token class-name">PluralRules</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"en-US"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">type</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"ordinal"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> suffixes </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"one"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"st"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"two"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"nd"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"few"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"rd"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"other"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"th"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">getSuffix</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> suffixes</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">pr</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">select</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">getSuffix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// "th"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">getSuffix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// "st"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">getSuffix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// "nd"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">getSuffix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// "rd"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">getSuffix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// "th"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">getSuffix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">21</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// "st"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">getSuffix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">42</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// "nd"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">getSuffix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">73</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// "th"</span><br></span></code></pre></div></div>
<p>On the same vein, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat" target="_blank" rel="noopener noreferrer"><code>Intl.NumberFormat</code></a> objects can format numbers in a language-sensitive way:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> nf </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Intl</span><span class="token class-name punctuation" style="color:#393A34">.</span><span class="token class-name">NumberFormat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"bn"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">useGrouping</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"min2"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">minimumSignificantDigits</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">maximumSignificantDigits</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">7</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">nf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">format</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10003.1234</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// ১০,০০৩.১২</span><br></span></code></pre></div></div>
<p>However, we need to mention that <code>Intl.NumberFormat</code> is NOT feature complete at the moment, since it
only allows formatting numbers in the standard notation with no currencies or units. We're still
working on adding the missing features, but we hope that this initial prototype is at least useful
for some use cases.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="builtins-updates">Builtins updates<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#builtins-updates" class="hash-link" aria-label="Direct link to Builtins updates" title="Direct link to Builtins updates" translate="no">​</a></h2>
<p>While this new release is filled with shiny new features and APIs, it should be noted that the
ECMAScript 262 specification is constantly evolving, which is why there are also a lot of small
changes and additions to existing builtins that keep Boa updated to the latest revisions of the
specification.</p>
<p>All examples were taken from the <a href="https://developer.mozilla.org/en-US" target="_blank" rel="noopener noreferrer">Mozilla Web Docs</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="findlast-and-findlastindex-on-typedarray"><a href="https://github.com/boa-dev/boa/pull/3135" target="_blank" rel="noopener noreferrer">findLast and findLastIndex on TypedArray</a><a href="https://boajs.dev/blog/2024/03/07/boa-release-18#findlast-and-findlastindex-on-typedarray" class="hash-link" aria-label="Direct link to findlast-and-findlastindex-on-typedarray" title="Direct link to findlast-and-findlastindex-on-typedarray" translate="no">​</a></h3>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">isPrime</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">element</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">element </span><span class="token operator" style="color:#393A34">%</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> element </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> factor </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> factor </span><span class="token operator" style="color:#393A34">&lt;=</span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">sqrt</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">element</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> factor </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">element </span><span class="token operator" style="color:#393A34">%</span><span class="token plain"> factor </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> uint8 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Uint8Array</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">6</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">12</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">uint8</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">findLast</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">isPrime</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// undefined (no primes in array)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">uint8 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Uint8Array</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">7</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">9</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">11</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">12</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">uint8</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">findLast</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">isPrime</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 11</span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="stringprototypeiswellformed-and-stringprototypetowellformed"><a href="https://github.com/boa-dev/boa/pull/3187" target="_blank" rel="noopener noreferrer">String.prototype.isWellFormed and String.prototype.toWellFormed</a><a href="https://boajs.dev/blog/2024/03/07/boa-release-18#stringprototypeiswellformed-and-stringprototypetowellformed" class="hash-link" aria-label="Direct link to stringprototypeiswellformed-and-stringprototypetowellformed" title="Direct link to stringprototypeiswellformed-and-stringprototypetowellformed" translate="no">​</a></h3>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> illFormed </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"https://example.com/search?q=\uD800"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">encodeURI</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">illFormed</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// URIError: URI malformed</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">illFormed</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">isWellFormed</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">encodeURI</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">illFormed</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">warn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Ill-formed strings encountered."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Ill-formed strings encountered.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="change-array-by-copy"><a href="https://github.com/boa-dev/boa/pull/3412" target="_blank" rel="noopener noreferrer">Change Array by copy</a><a href="https://boajs.dev/blog/2024/03/07/boa-release-18#change-array-by-copy" class="hash-link" aria-label="Direct link to change-array-by-copy" title="Direct link to change-array-by-copy" translate="no">​</a></h3>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> months </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"Mar"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Jan"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Feb"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Dec"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> sortedMonths </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> months</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">toSorted</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sortedMonths</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// ['Dec', 'Feb', 'Jan', 'Mar']</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">months</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// ['Mar', 'Jan', 'Feb', 'Dec']</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> values </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">21</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> sortedValues </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> values</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">toSorted</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">a</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sortedValues</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// [1, 2, 10, 21]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">values</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// [1, 10, 21, 2]</span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="grouping-functions"><a href="https://github.com/boa-dev/boa/pull/3420" target="_blank" rel="noopener noreferrer">Grouping functions</a><a href="https://boajs.dev/blog/2024/03/07/boa-release-18#grouping-functions" class="hash-link" aria-label="Direct link to grouping-functions" title="Direct link to grouping-functions" translate="no">​</a></h3>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> array </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// `Object.groupBy` groups items by arbitrary key.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// In this case, we're grouping by even/odd keys</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token known-class-name class-name">Object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">groupBy</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">array</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">num</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> index</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> num </span><span class="token operator" style="color:#393A34">%</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"even"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"odd"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// =&gt;  { odd: [1, 3, 5], even: [2, 4] }</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// `Map.groupBy` returns items in a Map, and is useful for grouping</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// using an object key.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> odd </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">odd</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> even </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">even</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token known-class-name class-name">Map</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">groupBy</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">array</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">num</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> index</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> num </span><span class="token operator" style="color:#393A34">%</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> even </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> odd</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// =&gt;  Map { {odd: true}: [1, 3, 5], {even: true}: [2, 4] }</span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="resizable-buffers"><a href="https://github.com/boa-dev/boa/pull/3634" target="_blank" rel="noopener noreferrer">Resizable buffers</a><a href="https://boajs.dev/blog/2024/03/07/boa-release-18#resizable-buffers" class="hash-link" aria-label="Direct link to resizable-buffers" title="Direct link to resizable-buffers" translate="no">​</a></h3>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> buffer </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">ArrayBuffer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">maxByteLength</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">16</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">byteLength</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 8</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">buffer</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">resize</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">12</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">byteLength</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 12</span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="transferrable-buffers"><a href="https://github.com/boa-dev/boa/pull/3649" target="_blank" rel="noopener noreferrer">Transferrable buffers</a><a href="https://boajs.dev/blog/2024/03/07/boa-release-18#transferrable-buffers" class="hash-link" aria-label="Direct link to transferrable-buffers" title="Direct link to transferrable-buffers" translate="no">​</a></h3>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> buffer </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">ArrayBuffer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">maxByteLength</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">16</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> view </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Uint8Array</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">buffer</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">view</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">view</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">7</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Copy the buffer to a smaller size</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> buffer2 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> buffer</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">transfer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">buffer2</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">byteLength</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 4</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">buffer2</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">maxByteLength</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 16</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> view2 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Uint8Array</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">buffer2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">view2</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">view2</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">7</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// undefined</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">buffer2</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">resize</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">8</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">view2</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">7</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Copy the buffer to a larger size within maxByteLength</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> buffer3 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> buffer2</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">transfer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">12</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">buffer3</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">byteLength</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 12</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Copy the buffer to a larger size than maxByteLength</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">buffer3</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">transfer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// RangeError: Invalid array buffer length</span><br></span></code></pre></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="apis-updates">APIs updates<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#apis-updates" class="hash-link" aria-label="Direct link to APIs updates" title="Direct link to APIs updates" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="experimental-features">Experimental features<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#experimental-features" class="hash-link" aria-label="Direct link to Experimental features" title="Direct link to Experimental features" translate="no">​</a></h3>
<p>Some of you might have noticed that the previous section contained a builtin addition that isn't
technically a "spec addition", but a "proposal for a spec addition". To clarify, the
<a href="https://github.com/tc39/proposal-arraybuffer-transfer" target="_blank" rel="noopener noreferrer"><code>ArrayBuffer.prototype.transfer</code> and friends</a> proposal is, at the time of the publication
of this post, still at stage 3 on the <a href="https://tc39.es/process-document/" target="_blank" rel="noopener noreferrer">TC39 Process</a>. Generally, stages 3 and below need to be
gated by implementors; this avoids exposing experimental APIs to users.</p>
<p>Mirroring this general idea, we introduced a new <code>experimental</code> feature for the <code>boa_engine</code> crate.
Enabling this feature will make it possible to test future proposals for the ECMAScript specification
using Boa, but we do not recommend enabling the feature in production environments.</p>
<p>We're still trying to <a href="https://github.com/boa-dev/boa/issues/3377" target="_blank" rel="noopener noreferrer">find a way to enable experimental features in a more granular way</a>,
since the current flag allows enabling either all or no experimental features; definitely not ideal.
So, expect some API changes in the future around this. But for now, have fun testing the new proposals!</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="hostdefined-fields"><code>[[HostDefined]]</code> fields<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#hostdefined-fields" class="hash-link" aria-label="Direct link to hostdefined-fields" title="Direct link to hostdefined-fields" translate="no">​</a></h3>
<p>In this version, we introduced a new API to attach custom data to realms, scripts and modules.
The <a href="https://docs.rs/boa_engine/0.18.0/boa_engine/struct.HostDefined.html" target="_blank" rel="noopener noreferrer"><code>HostDefined</code></a> struct is a more composable way of attaching custom data. Instead of attaching
only a single type casted to an <code>Any</code>, you can insert many types to the <code>HostDefined</code> map, and
every separate type will have its own value stored inside the map.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Example snippet taken from https://github.com/boa-dev/boa/blob/main/examples/src/bin/host_defined.rs</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Check that file for a more extensive example.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/// Custom host-defined struct that has some state, and can be shared between JavaScript and rust.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute attr-name" style="color:#00a4db">#[derive(Default, Trace, Finalize, JsData)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">CustomHostDefinedStruct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[unsafe_ignore_trace]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    counter</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">usize</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// We create a new `Context` to create a new Javascript executor.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Get the realm from the context.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> realm </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">realm</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">clone</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Insert a default CustomHostDefinedStruct.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">realm</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">host_defined_mut</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">insert_default</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">CustomHostDefinedStruct</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">realm</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">host_defined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">has</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">CustomHostDefinedStruct</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Get the [[HostDefined]] field from the realm and downcast it to our concrete type.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> host_defined </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> realm</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">host_defined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token class-name">Some</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">host_defined</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> host_defined</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">CustomHostDefinedStruct</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token class-name">Err</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">JsNativeError</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">typ</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">with_message</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Realm does not have HostDefined field"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">into</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Assert that the [[HostDefined]] field is in it's initial state.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert_eq!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">host_defined</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">counter</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="class-redesign--api-enhancements"><code>Class</code> redesign + API enhancements<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#class-redesign--api-enhancements" class="hash-link" aria-label="Direct link to class-redesign--api-enhancements" title="Direct link to class-redesign--api-enhancements" translate="no">​</a></h3>
<p>There were some small improvements made to our <code>Class</code> trait API, including a way to cache
custom <code>Class</code> implementors into the <code>Context</code> itself for easy access to the constructor and
prototype objects. This is part of an ongoing effort about
<a href="https://github.com/boa-dev/boa/issues/3314" target="_blank" rel="noopener noreferrer">improving the APIs around the <code>Class</code> trait</a>.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// An example of what this new API allows</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Assume there's already a `Person` struct that implements `Class`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">context</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">register_global_class</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Person</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"the Person builtin shouldn't exist"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Previously, the line below had to be done manually using something like</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// let prototype = context</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//     .global_object()</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//     .get(js_string!("Person"), context)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//     .unwrap()</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//     .as_object()</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//     .cloned()</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//     .unwrap()</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//     .get(js_string("prototype"), context)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//     .unwrap()</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//     .as_object()</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//     .cloned()</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//     .unwrap();</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Yeah... it's a handful.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> prototype </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">get_global_class</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Person</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">prototype</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="runtime-limits">Runtime limits<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#runtime-limits" class="hash-link" aria-label="Direct link to Runtime limits" title="Direct link to Runtime limits" translate="no">​</a></h3>
<p>We added new APIs to limit the execution of the engine at runtime! This new API has some limitations
such as being unable to track limits inside native Rust functions, and we're still working on offering
more options for other runtime limits such as heap size limits, but we hope this is at least useful
for some users.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Snippet taken from https://github.com/boa-dev/boa/blob/main/examples/src/bin/runtime_limits.rs</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Check that file for the full example.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Create the JavaScript context.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Set the context's runtime limit on loops to 10 iterations.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">runtime_limits_mut</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">set_loop_iteration_limit</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Here we exceed the limit by 1 iteration and a `RuntimeLimit` error is thrown.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// This error cannot be caught in JavaScript, it can only be caught in Rust code.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">eval</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_bytes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">r"</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        try {</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">            for (let i = 0; i &lt; 12; ++i) { }</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        } catch (e) {</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        }</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    "</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">is_err</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="synthetic-modules">Synthetic modules<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#synthetic-modules" class="hash-link" aria-label="Direct link to Synthetic modules" title="Direct link to Synthetic modules" translate="no">​</a></h3>
<p>We added support for creating synthetic modules from Rust code. This allows exposing a set of
functions and properties to other modules without having to evaluate Javascript code.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Taken from https://github.com/boa-dev/boa/blob/main/examples/src/bin/synthetic.rs</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// See the file for the full example.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> sum </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">FunctionObjectBuilder</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">realm</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">NativeFunction</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_fn_ptr</span><span class="token punctuation" style="color:#393A34">(</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token closure-params">_</span><span class="token closure-params punctuation" style="color:#393A34">,</span><span class="token closure-params"> args</span><span class="token closure-params punctuation" style="color:#393A34">,</span><span class="token closure-params"> ctx</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">get_or_undefined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">get_or_undefined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">length</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">name</span><span class="token punctuation" style="color:#393A34">(</span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"sum"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">build</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> operations </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Module</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">synthetic</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Make sure to list all exports beforehand.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"sum"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// The initializer is evaluated every time a module imports this synthetic module,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// so we avoid creating duplicate objects by capturing and cloning them instead.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">SyntheticModuleInitializer</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_copy_closure_with_captures</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token closure-params">module</span><span class="token closure-params punctuation" style="color:#393A34">,</span><span class="token closure-params"> fns</span><span class="token closure-params punctuation" style="color:#393A34">,</span><span class="token closure-params"> _</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token macro property" style="color:#36acaa">println!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Running initializer!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            module</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">set_export</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"sum"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fns</span><span class="token number" style="color:#36acaa">.0</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">clone</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">into</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sum</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">/* ... */</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">loader</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">insert</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">PathBuf</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"./scripts/modules"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">canonicalize</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"operations.mjs"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    operations</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="async-eval">Async eval<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#async-eval" class="hash-link" aria-label="Direct link to Async eval" title="Direct link to Async eval" translate="no">​</a></h3>
<p>Due to popular demand, we added some APIs that allow running scripts in an asynchronous way, making
it possible to share some workload between async tasks and the execution of the engine itself.
Note that, by the single-threaded nature of JS engines, all futures returned by Boa cannot implement
neither <code>Send</code> nor <code>Sync</code>.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> context </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> src </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_bytes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">r#"</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">  let array = new Array([15, 20, 35, 123, 65, 12]);</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">  array.sort();</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">  console.log(array);</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">"#</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> src </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Script</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">src</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> task </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">move</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> src</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">evaluate_async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token macro property" style="color:#36acaa">println!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"{:?}"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> result</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">display</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">block_on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token macro property" style="color:#36acaa">join!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">long_task</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> task</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="jserasederror"><code>JsErasedError</code><a href="https://boajs.dev/blog/2024/03/07/boa-release-18#jserasederror" class="hash-link" aria-label="Direct link to jserasederror" title="Direct link to jserasederror" translate="no">​</a></h3>
<p>Don't you hate when you try to <code>?</code> a <code>Result&lt;T, JsError&gt;</code> and the compiler just complains saying
something like</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">error</span><span class="token punctuation" style="color:#393A34">[</span><span class="token constant" style="color:#36acaa">E0277</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> `</span><span class="token class-name">Rc</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token namespace" style="opacity:0.7">num_bigint</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">bigint</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">BigInt</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain">` cannot be sent between threads safely</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token operator" style="color:#393A34">-</span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> tests</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">tester</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">src</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rs</span><span class="token punctuation" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">190</span><span class="token punctuation" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">52</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token number" style="color:#36acaa">190</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain">     </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">eval</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_bytes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">|</span><span class="token plain">                                                    </span><span class="token operator" style="color:#393A34">^</span><span class="token plain"> `</span><span class="token class-name">Rc</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token namespace" style="opacity:0.7">num_bigint</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">bigint</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">BigInt</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain">` cannot be sent between threads safely</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> help</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> within `</span><span class="token class-name">JsError</span><span class="token plain">`</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> the </span><span class="token keyword" style="color:#00009f">trait</span><span class="token plain"> `</span><span class="token class-name">Send</span><span class="token plain">` is not implemented </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> `</span><span class="token class-name">Rc</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token namespace" style="opacity:0.7">num_bigint</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">bigint</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">BigInt</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain">`</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> help</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> the following other types implement </span><span class="token keyword" style="color:#00009f">trait</span><span class="token plain"> `</span><span class="token class-name">FromResidual</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">R</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain">`</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Result</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">T</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">F</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> </span><span class="token class-name">FromResidual</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Yeet</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">E</span><span class="token operator" style="color:#393A34">&gt;&gt;</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Result</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">T</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">F</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> </span><span class="token class-name">FromResidual</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Result</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Infallible</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">E</span><span class="token operator" style="color:#393A34">&gt;&gt;</span><span class="token operator" style="color:#393A34">&gt;</span><br></span></code></pre></div></div>
<p>Well, say no more to missing <code>Send</code>s in your daily life! We present to you, <code>JsErasedError</code>!</p>
<p>Jokes aside, using <code>JsError</code> is difficult from an embedder's perspective because <code>JsError</code> can be
any arbitrary value, including non-<code>Send</code> values such as <code>JsObject</code>, <code>JsString</code> or <code>JsBigInt</code>.
This makes <code>JsError</code> automatically incompatible with libraries like <code>anyhow</code> or <code>eyre</code> that expect
only <code>Send</code> errors.</p>
<p>To solve this, we introduced a new <code>JsError::into_erased</code> method which returns a thread-safe
version of <code>JsError</code> that is compatible with <code>anyhow</code>, <code>eyre</code> and other error-reporting libraries.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">eyre</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">Result</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> context </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> value </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> context</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">eval</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_bytes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">map_err</span><span class="token punctuation" style="color:#393A34">(</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token closure-params">err</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token plain"> err</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">into_erased</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// No compiler errors!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Why not call it <code>JsSendError</code> instead of <code>JsErasedError</code>? Well, it is generally not possible to
convert a <code>JsError</code> into a <code>JsErasedError</code> without losing some information in the conversion. However,
<code>JsSendError</code> gave the appearance of being <code>JsError</code> but <code>Send</code>, which is really not true. <code>JsErasedError</code>,
on the other hand, makes it clear the conversion is not lossless. Feel free to ping us if you have a
better name for it though!</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="optimizations">Optimizations<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#optimizations" class="hash-link" aria-label="Direct link to Optimizations" title="Direct link to Optimizations" translate="no">​</a></h2>
<p>The following benchmarks below are taken from the <a href="https://github.com/mozilla/arewefastyet/tree/master/benchmarks/v8-v7" target="_blank" rel="noopener noreferrer">v8 benchmark suite</a>. This benchmark is deprecated,
but is useful in this context to show the performance improvements between versions.</p>
<p>(higher numbers are better)</p>
<table><thead><tr><th>Boa Version</th><th>Richards</th><th>DeltaBlue</th><th>Crypto</th><th>RayTrace</th><th>EarleyBoyer</th><th>Splay</th><th>NavierStokes</th><th>Total</th></tr></thead><tbody><tr><td>v0.16</td><td>29.0</td><td>29.2</td><td>42.1</td><td>107</td><td>105</td><td>111</td><td>15.4</td><td>49.1</td></tr><tr><td>v0.17</td><td>34.3</td><td>39.1</td><td>49.1</td><td>134</td><td>119</td><td>141</td><td>11.9</td><td>56.2</td></tr><tr><td>v0.18</td><td>49.8</td><td>53.9</td><td>52.1</td><td>161</td><td>152</td><td>154</td><td>102</td><td>91.5</td></tr></tbody></table>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="inline-caching">Inline Caching<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#inline-caching" class="hash-link" aria-label="Direct link to Inline Caching" title="Direct link to Inline Caching" translate="no">​</a></h3>
<p>Thanks to the implementation of <a href="https://github.com/boa-dev/boa/blob/main/docs/shapes.md" target="_blank" rel="noopener noreferrer">Object Shapes</a>
in version <code>v0.17</code>, we were able to further improve the performance of the engine by implementing
Inline Caching. The concept of Inline Caching is based on the idea that a property access for a
variable will usually only be applied to objects of similar Shapes. To picture this, let's examine
the following code:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">attach</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">obj1</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> obj2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  obj1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">attach</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> obj2</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getHandler</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>On interpreters that don't implement any kind of caching, the previous code would have to make a
property lookup for the <code>getHandler</code> method every time that method is called. This is really inefficient
for a simple reason: <code>getHandler</code> could be inside <code>obj2</code>, or it could be inside <code>obj2.prototype</code>,
or it could be inside <code>obj2.prototype.prototype</code>... in fact, <code>getHandler</code> could be anywhere on the
inheritance chain of <code>obj2</code>!</p>
<p>The easy approach to solve this is to cache the method lookup inside <code>obj2</code> itself using an associative
map of some sorts. This is nice, but also a bit wasteful because we would be allocating a new
associative map for all instances of <code>obj2</code>, even if the map is only really used inside <code>attach</code>.</p>
<p>What then? Well, we can apply the "inline" part of an inline cache now! Just allocate an array of
all property accesses within the <code>attach</code> function and assign an index to every one of them.
Initially, a property access is uninitialized. Once we reach a particular uninitialized property access,
it performs the dynamic lookup and changes its corresponding array slot to be a
weak reference to the object's shape. If we reach the same property access again, we can retrieve the
stored shape and directly access the object's dense storage without doing a property lookup!</p>
<p>However, there's a caveat. If <code>obj2.getHandler</code> is evaluated twice with objects of different shapes,
the stored shape would be invalid for the second property access. In this case, we can rollback the
access to the uninitialized state and make a manual property lookup once again.
This is known as monomorphic inline caching. There's also polymorphic inline caching, which
stores several shapes per access instead of rolling back to the uninitialized state.</p>
<p>Currently we do eager monomorphic inline caching, so there is plently of room for improvements that
we're planning to do in the future!</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="road-to-10">Road to 1.0<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#road-to-10" class="hash-link" aria-label="Direct link to Road to 1.0" title="Direct link to Road to 1.0" translate="no">​</a></h2>
<p>As Boa is being used by more projects it is important we can provide a stable and reliable API. We
don't feel like we're quite there yet, but after a discussion with the team we have decided to aim
for a 1.0 release in the near future. This will be a big milestone for us and we hope to have a lot
of new features and improvements to show off by then.</p>
<p>We will keep our focus on the public API for those embedding Boa. We will also be working on improving
the performance of the engine. If you wanted to offer feedback on the API feel free to reach out to
us via Github or Discord.</p>
<p>You can keep an eye on the project to reach 1.0 <a href="https://github.com/orgs/boa-dev/projects/2/views/1" target="_blank" rel="noopener noreferrer">here</a>.
We hopefully don't forsee this project getting much bigger as most issues such as spec conformance
or performance are a going-concern.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="conclusion">Conclusion<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-can-you-support-boa">How can you support Boa?<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#how-can-you-support-boa" class="hash-link" aria-label="Direct link to How can you support Boa?" title="Direct link to How can you support Boa?" translate="no">​</a></h3>
<p>Boa is an independent JavaScript engine implementing the ECMAScript specification, we rely on the
support of the community to keep it going. If you want to support us, you can do so by donating to
our <a href="https://opencollective.com/boa" target="_blank" rel="noopener noreferrer">open collective</a>. Proceeeds here go towards this very website, the domain name, and remunerating
members of the team who have worked on the features released.</p>
<p>If financial contribution is not your strength, you can contribute by asking to be assigned to one of
our <a href="https://github.com/boa-dev/boa/issues?q=is%3Aopen+is%3Aissue+no%3Aassignee" target="_blank" rel="noopener noreferrer">open issues</a>, and asking for mentoring if you don't know your way around the engine. Our
<a href="https://github.com/boa-dev/boa/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">contribution guide</a> should help you here. If you are more used to working with JavaScript or frontend
web development, we also welcome help to improve our web presence, either in <a href="https://github.com/boa-dev/boa-dev.github.io" target="_blank" rel="noopener noreferrer">our website</a>, or in our
<a href="https://github.com/boa-dev/boa/issues/820" target="_blank" rel="noopener noreferrer">testing representation</a> page or benchmarks page. You can also contribute to our Criterion benchmark
comparison GitHub <a href="https://github.com/boa-dev/criterion-compare-action" target="_blank" rel="noopener noreferrer">action</a>.</p>
<p>We are also looking to improve the documentation of the engine, both for developers of the engine
itself and for users of the engine. Feel free to contact us in <a href="https://discord.gg/tUFFk9Y" target="_blank" rel="noopener noreferrer">Discord</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="thank-you">Thank You<a href="https://boajs.dev/blog/2024/03/07/boa-release-18#thank-you" class="hash-link" aria-label="Direct link to Thank You" title="Direct link to Thank You" translate="no">​</a></h3>
<p>Once again, big thanks to <a href="https://github.com/boa-dev/boa/graphs/contributors?from=2023-07-08&amp;to=2024-03-05&amp;type=c" target="_blank" rel="noopener noreferrer">all the contributors</a> of this release!!</p>]]></content:encoded>
            <category>post</category>
        </item>
        <item>
            <title><![CDATA[Boa release v0.17]]></title>
            <link>https://boajs.dev/blog/2023/07/08/boa-release-17</link>
            <guid>https://boajs.dev/blog/2023/07/08/boa-release-17</guid>
            <pubDate>Sat, 08 Jul 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Summary]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="summary">Summary<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>Boa v0.17 is now available! This is one of the biggest Boa releases since the project started, and after around 7 months
of development, we are very happy to present you the latest release of the Boa JavaScript engine. Boa makes it easy to
embed a JS engine in your projects, and you can even use it from WebAssembly. See the <a href="https://boajs.dev/about">about</a> page for more info.</p>
<p>In this release, our conformance has grown from 74.53% to 78.74% in the official ECMAScript Test Suite (Test262). While
this might look as a small increase, we now pass <strong>6,079</strong> more tests than in the previous version. In any case, the big
changes in this release are not related to conformance, but to huge internal enhancements and new APIs that you will be
able to use.</p>
<p>You can check the full list of changes <a href="https://github.com/boa-dev/boa/blob/v0.17/CHANGELOG.md" target="_blank" rel="noopener noreferrer">here</a>, and the full information on conformance <a href="https://boajs.dev/conformance">here</a>.</p>
<p>Moreover, this big release was partly possible thanks to a grant by <a href="https://litprotocol.com/" target="_blank" rel="noopener noreferrer">Lit Protocol</a>. Thanks to
this grant, we were able to remunerate 2 team members for their 20h/week work each during three and a half months. If
you wish to sponsor Boa, you can do so by donating to our <a href="https://opencollective.com/boa" target="_blank" rel="noopener noreferrer">open collective</a>. You can also check
<a href="https://github.com/boa-dev/boa/issues?q=is%3Aopen+is%3Aissue+label%3AE-Easy" target="_blank" rel="noopener noreferrer">easy</a> or <a href="https://github.com/boa-dev/boa/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22" target="_blank" rel="noopener noreferrer">good first issues</a>.</p>
<p>Furthermore, we now have a new domain for Boa, <a href="https://boajs.dev/" target="_blank" rel="noopener noreferrer">boajs.dev</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="highlights">Highlights<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#highlights" class="hash-link" aria-label="Direct link to Highlights" title="Direct link to Highlights" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="modules">Modules<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#modules" class="hash-link" aria-label="Direct link to Modules" title="Direct link to Modules" translate="no">​</a></h3>
<p>Boa finally has a module system! This implementation tries to closely follow ECMAScript's <a href="https://tc39.es/ecma262/#sec-modules" target="_blank" rel="noopener noreferrer"><strong>Modules</strong></a>
specification which includes some useful hooks to customize module loading, making it possible to load modules from
several sources, fetch modules from an URL and even asynchronously load and parse them to avoid blocking execution; see
the <a href="https://docs.rs/boa_engine/0.17.0/boa_engine/module/trait.ModuleLoader.html" target="_blank" rel="noopener noreferrer"><code>ModuleLoader</code></a> for more information.</p>
<p>We also implemented a simple loader (currently the default module loader), which should fulfill most of the simpler use cases:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Creates a new module loader that uses the current directory to resolve module imports.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> loader </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">SimpleModuleLoader</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Path</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Need to convert it to either a `&amp;dyn ModuleLoader` or a `Rc&lt;dyn ModuleLoader&gt;` in order</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// to pass it to the context.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> dyn_loader</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">dyn</span><span class="token plain"> </span><span class="token class-name">ModuleLoader</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> loader</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">builder</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">module_loader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">dyn_loader</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">build</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> source </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_bytes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"1 + 3"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> module </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Module</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">source</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// `main.mjs` or any of its imports could import `main.mjs` itself, so we</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// insert it into the loader for good measure.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">loader</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">insert</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Path</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"main.mjs"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_path_buf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> module</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">clone</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// All modules use promises to signal completion of its lifecycle.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// The utility method `load_link_evaluate` calls `load`, then `link` and</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// finally `evaluate`, returning an error if any call fails.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> promise </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> module</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">load_link_evaluate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Important to push the job queue forward! Otherwise, the modules won't progress</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// on their lifecycle.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">run_jobs</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// All modules return `undefined` if they're successfully evaluated.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert_eq!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">promise</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">state</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">PromiseState</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Fulfilled</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">undefined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>For a more extensive, descriptive example that uses a real directory, you can check out <a href="https://github.com/boa-dev/boa/blob/v0.17/boa_examples/src/bin/modules.rs" target="_blank" rel="noopener noreferrer"><strong>boa_examples</strong></a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="spec-version-conformance">Spec Version Conformance<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#spec-version-conformance" class="hash-link" aria-label="Direct link to Spec Version Conformance" title="Direct link to Spec Version Conformance" translate="no">​</a></h3>
<p>Something we get asked a lot is <em>"Do you support ES5 or ES6"</em>? or <em>"How far away are you from supporting ESX"</em>?
We're pleased to say we've updated our conformance board to show you how we're doing across ES versions.</p>
<p>Just navigate to our <a href="https://boajs.dev/conformance">Test262 Dashboard</a>, select "Test Results" on our main branch, and
then you can use the dropdown underneath to see how we're doing on each version. ES5 and ES6 are very close, you can see
we're only a few tests away from them being fully implemented.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="optimizations">Optimizations<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#optimizations" class="hash-link" aria-label="Direct link to Optimizations" title="Direct link to Optimizations" translate="no">​</a></h3>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="constant-folding-optimization">Constant folding optimization<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#constant-folding-optimization" class="hash-link" aria-label="Direct link to Constant folding optimization" title="Direct link to Constant folding optimization" translate="no">​</a></h4>
<p>Constant folding expression is a powerful compiler optimization technique that significantly enhances the efficiency and
performance of compiled programs. This optimization, now incorporated in the latest release, aims to reduce runtime
overhead by evaluating constant expressions at compile-time.</p>
<p>With constant folding expression optimization, the compiler analyzes expressions involving constants and replaces them
with their computed results. This process allows the compiler to transform arithmetic operations, comparisons, and
logical expressions into simplified forms, removing unnecessary runtime computations. By eliminating these computations,
the optimized program benefits from reduced execution time and improved overall performance.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="object-shapes-hidden-classes">Object Shapes (Hidden classes)<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#object-shapes-hidden-classes" class="hash-link" aria-label="Direct link to Object Shapes (Hidden classes)" title="Direct link to Object Shapes (Hidden classes)" translate="no">​</a></h4>
<p>Hidden Classes (called "Shapes" internally to avoid confusion with JavaScript classes) are an alternative way to
structure objects that stores the property keys (string or symbol) (i.e. <code>object.propertyName</code>) and its attributes
(writable, enumerable, configurable) as transitions from a root shape, and the values as a dense array. This is
different from the traditional way of storing properties as a hashmap from property keys to values.</p>
<p>The shapes create a transition tree, where the transitions are property names and prototype changes starting from a root
shape (no properties, no prototype).</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> o </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Shape 1: prototype `Object.prototype` and properties: empty</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">a</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token plain">   </span><span class="token comment" style="color:#999988;font-style:italic">// Shape 2: prototype `Object.prototype` and properties: 'a'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">b</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">20</span><span class="token plain">   </span><span class="token comment" style="color:#999988;font-style:italic">// Shape 3: prototype `Object.prototype` and properties: 'a', 'b'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> o2 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">a</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Shape 2: prototype `Object.prototype` and properties: 'a'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">o2</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">d</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">50</span><span class="token plain">           </span><span class="token comment" style="color:#999988;font-style:italic">// Shape 4: prototype `Object.prototype` and properties: 'a', 'd' -- fork from shape 2</span><br></span></code></pre></div></div>
<p>This separation of property keys and values allows for objects with the same property names to share the same shape,
which reduces memory consumption and unlocks the possibility for other optimizations such as inline caching.</p>
<p>Note: When creating objects with the same property keys, it's best to create them in the same order, this ensures that
the objects share the same shape.</p>
<p>For a more in depth explanation of how shared shapes work in boa see <code>shapes.md</code>
<a href="https://github.com/boa-dev/boa/blob/v0.17/docs/shapes.md" target="_blank" rel="noopener noreferrer">here</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="debug-object">Debug object<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#debug-object" class="hash-link" aria-label="Direct link to Debug object" title="Direct link to Debug object" translate="no">​</a></h3>
<p>The <code>$boa</code> debug object has been implemented for convenient JavaScript debugging using Boa's CLI interface. If you want
to use it, you will need to run the Boa CLI / REPL with the <code>--debug-object</code> command line flag.</p>
<p>The <code>$boa</code> debug object is divided into modules, so that you can trigger the garbage collection with <code>$boa.gc.collect()</code>,
or get the bytecode of a function by running <code>$boa.function.bytecode(fn_name)</code>. You can also trace function invocations,
handle compiler optimizations, set runtime limits and inspect object shapes.</p>
<p>You can find all the documentation <a href="https://github.com/boa-dev/boa/blob/v0.17/docs/boa_object.md" target="_blank" rel="noopener noreferrer">here</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="new-apis">New APIs<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#new-apis" class="hash-link" aria-label="Direct link to New APIs" title="Direct link to New APIs" translate="no">​</a></h3>
<p>We have added new built-in object wrappers, such as <a href="https://docs.rs/boa_engine/0.17.0/boa_engine/object/builtins/struct.JsPromise.html" target="_blank" rel="noopener noreferrer"><code>JsPromise</code></a>, <a href="https://docs.rs/boa_engine/0.17.0/boa_engine/object/builtins/struct.JsRegExp.html" target="_blank" rel="noopener noreferrer"><code>JsRegExp</code></a>,
<a href="https://docs.rs/boa_engine/0.17.0/boa_engine/object/builtins/struct.JsGenerator.html" target="_blank" rel="noopener noreferrer"><code>JsGenerator</code></a>, <a href="https://docs.rs/boa_engine/0.17.0/boa_engine/object/builtins/struct.JsDate.html" target="_blank" rel="noopener noreferrer"><code>JsDate</code></a> and <a href="https://docs.rs/boa_engine/0.17.0/boa_engine/object/builtins/struct.JsDataView.html" target="_blank" rel="noopener noreferrer"><code>JsDataView</code></a>. You can check all of them
<a href="https://docs.rs/boa_engine/0.17.0/boa_engine/object/builtins/index.html" target="_blank" rel="noopener noreferrer">here</a>.</p>
<p>We also want to present you a new trait that we have developed to make it easier for you to interoperate between Rust
and JavaScript: <a href="https://docs.rs/boa_engine/0.17.0/boa_engine/value/trait.TryFromJs.html" target="_blank" rel="noopener noreferrer"><code>TryFromJs</code></a>. All built-ins and Rust basic types that exist in JavaScript implement this
trait, and it adds a new static method to them that allows you to convert a [<code>JsValue</code>][js_value] into a Rust structure.
You can also convert any <code>JsValue</code> to a <code>TryFromJs</code> Rust type with <a href="https://docs.rs/boa_engine/0.17.0/boa_engine/enum.JsValue.html#method.try_js_into" target="_blank" rel="noopener noreferrer"><code>JsValue::try_js_into()</code></a> function.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> js_str </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">r#"</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">let x = /[a-z0-9]@[a-z0-9]/;</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">x;</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">"#</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> js </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_bytes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">js_str</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> res </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">eval</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">js</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> rs_regexp</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">JsRegExp</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">try_js_into</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> test_result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> rs_regexp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"hello@domain"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">test_result</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Moreover, you can derive <code>TryFromJs</code> for any Rust structure, and in the case that you want to manually convert some of
the struct attributes, you can override it:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">/// Converts the value lossly.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">lossy_conversion</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> _context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">i16</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">match</span><span class="token plain"> value </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Rational</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">round</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i16</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Integer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">*</span><span class="token plain">i </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i16</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        _ </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token class-name">Err</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">JsNativeError</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">typ</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">with_message</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"cannot convert value to an i16"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">into</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute attr-name" style="color:#00a4db">#[derive(Debug, TryFromJs)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">TestStruct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    inner</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">bool</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    hello</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// You can override the conversion of an attribute.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[boa(from_js_with = </span><span class="token attribute attr-name string" style="color:#e3116c">"lossy_conversion"</span><span class="token attribute attr-name" style="color:#00a4db">)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    my_float</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i16</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> js_str </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">r#"</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">let x = {</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    inner: false,</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    hello: "World",</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    my_float: 2.9,</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">};</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">x;</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">"#</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> context </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">eval</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_bytes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">js_str</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">str</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">TestStruct</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">try_from_js</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">result</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">println!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"{str:?}"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="source-api">Source API<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#source-api" class="hash-link" aria-label="Direct link to Source API" title="Direct link to Source API" translate="no">​</a></h4>
<p>We have introduced a new <code>Source API</code> to Boa. The new API represents JavaScript stored from a path or <code>None</code> if it's
coming from a plain string.</p>
<p>This change improves the display of <code>boa_tester</code> to show the path of the tests being run. It also enables hyperlinks to
directly jump to the tested file from the VS terminal. This will further help with error displays and debugging in the
future.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">boa_engine</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> js_file_path </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./scripts/helloworld.js"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">match</span><span class="token plain"> </span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_filepath</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Path</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">js_file_path</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">...</span><br></span></code></pre></div></div>
<p>See Boa's <a href="https://github.com/boa-dev/boa/tree/v0.17/boa_examples/src/bin" target="_blank" rel="noopener noreferrer">examples</a> for more examples on how its used.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="hooks-and-job-queues">Hooks and Job Queues<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#hooks-and-job-queues" class="hash-link" aria-label="Direct link to Hooks and Job Queues" title="Direct link to Hooks and Job Queues" translate="no">​</a></h4>
<p>In this release we have added <code>HostHooks</code> and <code>JobQueue</code> traits to <code>Context</code>. This will allow hosts to implement custom
event loops and other host specific functionality. This makes Boa more configurable for users and any future runtimes
which need to add a more complex event loop, such as Tokio or Mio.</p>
<p>As a result of this change, Boa's CLI will run all jobs until the queue is empty, even if a Job returns an <code>Err</code>.`</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="new-builtins">New Builtins<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#new-builtins" class="hash-link" aria-label="Direct link to New Builtins" title="Direct link to New Builtins" translate="no">​</a></h3>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="intl"><code>Intl</code><a href="https://boajs.dev/blog/2023/07/08/boa-release-17#intl" class="hash-link" aria-label="Direct link to intl" title="Direct link to intl" translate="no">​</a></h4>
<p>Boa now has internationalization support! Although we are still working on full compliance with the
<a href="https://tc39.es/ecma402/" target="_blank" rel="noopener noreferrer"><code>ecma402</code> specification</a>, we have a couple of <code>Intl</code> utilities in place:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator" target="_blank" rel="noopener noreferrer"><code>Intl.Collator</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat" target="_blank" rel="noopener noreferrer"><code>Intl.ListFormat</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator" target="_blank" rel="noopener noreferrer"><code>Intl.Locale</code></a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter" target="_blank" rel="noopener noreferrer"><code>Intl.Segmenter</code></a></li>
</ul>
<p>Internationalization data can be pretty expensive at times: the default data included by Boa is 10.6 MB, which is why
we allow customizing the data provider used by the engine with the <code>ContextBuilder::icu_provider</code> hook.
For more information on how to generate custom internationalization data, you can check out the
<a href="https://github.com/unicode-org/icu4x/blob/main/docs/tutorials/data_management.md#data-management-in-icu4x" target="_blank" rel="noopener noreferrer"><strong>data management tutorial</strong></a> from <a href="https://github.com/unicode-org/icu4x" target="_blank" rel="noopener noreferrer"><code>icu4x</code></a>, the internationalization library used in Boa. Shoutout to the
<code>icu4x</code> team, who are the ones that made all of this possible!</p>
<p>Additionally, we added an <code>intl</code> feature flag, which is enabled by default but can be disabled to reduce Boa's binary
size.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="weakref-weakset-and-weakmap"><code>WeakRef</code>, <code>WeakSet</code> and <code>WeakMap</code><a href="https://boajs.dev/blog/2023/07/08/boa-release-17#weakref-weakset-and-weakmap" class="hash-link" aria-label="Direct link to weakref-weakset-and-weakmap" title="Direct link to weakref-weakset-and-weakmap" translate="no">​</a></h4>
<p>We've implemented support for weak references to garbage collected objects. This allowed us to implement some builtins
like <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef/WeakRef" target="_blank" rel="noopener noreferrer"><code>WeakRef</code></a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet" target="_blank" rel="noopener noreferrer"><code>WeakSet</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap" target="_blank" rel="noopener noreferrer"><code>WeakMap</code></a>. However, garbage collectors are unpredictable! A garbage
collector could collect at unexpected moments, extend the lifetime of unreachable objects and even leak, which is why
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef#avoid_where_possible" target="_blank" rel="noopener noreferrer">mozilla recommends avoiding using those builtins where possible</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="fuzzing">Fuzzing<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#fuzzing" class="hash-link" aria-label="Direct link to Fuzzing" title="Direct link to Fuzzing" translate="no">​</a></h3>
<p>This release of Boa contains new functionalities in the <code>boa_ast</code> crate to support grammar aware fuzzing. The visitor
pattern that is implemented for the AST makes it easy to traverse the AST and either collect information or apply
modifications. In addition to the fuzzer, we also use the visitor pattern in multiple syntax directed operations. The
AST now implements the <code>Arbitrary</code> trait from the <a href="https://docs.rs/arbitrary/latest/arbitrary/" target="_blank" rel="noopener noreferrer"><code>Arbitrary</code></a> crate to generate inputs for fuzzers. Based
on these features we currently have three fuzzers targeting the parser, bytecompiler and vm. The fuzzers have already
helped us finding multiple panics that we previously had no tests for.</p>
<p>We want to extend a huge thanks to <a href="https://github.com/addisoncrump" target="_blank" rel="noopener noreferrer">@addisoncrump</a> as they have contributed not only
the fuzzers but also the visitor pattern implementation and the additional bits needed to successfully fuzz Boa.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="new-crates">New Crates<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#new-crates" class="hash-link" aria-label="Direct link to New Crates" title="Direct link to New Crates" translate="no">​</a></h3>
<p>This release of Boa will also mark the release of some new boa crates that contain various aspects of Boa's ECMAScript
implementation.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="boa_parser">boa_parser<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#boa_parser" class="hash-link" aria-label="Direct link to boa_parser" title="Direct link to boa_parser" translate="no">​</a></h4>
<p>Boa's <code>boa_parser</code> crate contains a lexer and parser that targets the latest ECMAScript language specification.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="boa_ast">boa_ast<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#boa_ast" class="hash-link" aria-label="Direct link to boa_ast" title="Direct link to boa_ast" translate="no">​</a></h4>
<p>Boa's <code>boa_ast</code> crate contains an ECMAScript abstract syntax tree implementation of Declaration, Statement, and
Expression Parse Nodes.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="boa_runtime">boa_runtime<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#boa_runtime" class="hash-link" aria-label="Direct link to boa_runtime" title="Direct link to boa_runtime" translate="no">​</a></h4>
<p>Boa's <code>boa_runtime</code> crate contains an example runtime along with basic runtime features and functionality for runtime
implementors. Note: this crate will contain any WEB API feature implementations or APIs that are not designated by the
ECMAScript specification.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="other-internal-enhancements">Other internal enhancements<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#other-internal-enhancements" class="hash-link" aria-label="Direct link to Other internal enhancements" title="Direct link to Other internal enhancements" translate="no">​</a></h3>
<p>There have also been a various number of other internal enhancements made.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="split-node-into-statement--declaration--expression">Split Node into Statement / Declaration / Expression<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#split-node-into-statement--declaration--expression" class="hash-link" aria-label="Direct link to Split Node into Statement / Declaration / Expression" title="Direct link to Split Node into Statement / Declaration / Expression" translate="no">​</a></h4>
<p>In the last release, Boa's AST used a <code>Node</code> enum to represent both the <code>Statement</code>, <code>Declaration</code> and <code>Expression</code>
parse nodes. One of the large internal improvements made for this release was to split <code>Node</code> into <code>Statement</code>,
<code>Declaration</code>, and <code>Expression</code> nodes. This refactor involved not only large changes to the AST but also further changes
to the bytecompiler and parser. The split also brings us closer in line with the ECMAScript specification.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="utf-16-strings">UTF-16 strings<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#utf-16-strings" class="hash-link" aria-label="Direct link to UTF-16 strings" title="Direct link to UTF-16 strings" translate="no">​</a></h4>
<p>With this release, Boa's <code>JsString</code>s are now implemented as utf-16 encoded strings. Along with the new <code>JsString</code>, there
are two provided macros: <code>js_string!</code> for creating a new <code>JsString</code> from a <code>&amp;str</code>, and <code>utf16!</code> for creating a utf-16
array literal from a <code>&amp;str</code>.</p>
<p>You can create a utf-16 array literal from any utf-8 <code>str</code>.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">HELLO</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token punctuation" style="color:#393A34">[</span><span class="token keyword" style="color:#00009f">u16</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">utf16!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hi! :)"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>You can create a <code>JsString</code> from a string literal with the <code>js_string</code> macro.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> hw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello, world!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert_eq!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">hw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">utf16!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello, world!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>You can also pass any number of <code>&amp;[u16]</code> string values as arguments to create a new <code>JsString</code>.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">NAME</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token punctuation" style="color:#393A34">[</span><span class="token keyword" style="color:#00009f">u16</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain">  </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">utf16!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"human! "</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> greeting </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello, "</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> msg </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">js_string!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">greeting</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token constant" style="color:#36acaa">NAME</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">utf16!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Nice to meet you!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property" style="color:#36acaa">assert_eq!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">msg</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token macro property" style="color:#36acaa">utf16!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello, human! Nice to meet you!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="conclusions">Conclusions<a href="https://boajs.dev/blog/2023/07/08/boa-release-17#conclusions" class="hash-link" aria-label="Direct link to Conclusions" title="Direct link to Conclusions" translate="no">​</a></h2>
<p>If you reached so far, you probably understand how big this release was, and you can find even more changes in the
<a href="https://github.com/boa-dev/boa/blob/v0.17/CHANGELOG.md" target="_blank" rel="noopener noreferrer">full changelog</a>. Boa is now becoming a real option for many projects, which shows with the amount of
financial support we have received these last months. Nevertheless, going forward, we need your help to get to a 1.0
version. Whether you are good with Rust, JavaScript, documentation or development, we have multiple
<a href="https://github.com/boa-dev/boa/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22" target="_blank" rel="noopener noreferrer">good first issues</a>, and places where we <a href="https://github.com/boa-dev/boa/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22" target="_blank" rel="noopener noreferrer">need help</a>, both in Boa's
<a href="https://github.com/boa-dev/boa" target="_blank" rel="noopener noreferrer">main repository</a> and <a href="https://github.com/boa-dev" target="_blank" rel="noopener noreferrer">others</a> around it.</p>
<p>Once again, big thanks to <a href="https://github.com/boa-dev/boa/graphs/contributors?from=2022-10-24&amp;to=2023-07-05&amp;type=c" target="_blank" rel="noopener noreferrer">all the contributors</a> of this release!!</p>]]></content:encoded>
            <category>post</category>
        </item>
        <item>
            <title><![CDATA[Adding a JavaScript interpreter to your Rust project]]></title>
            <link>https://boajs.dev/blog/2022/10/24/boa-usage</link>
            <guid>https://boajs.dev/blog/2022/10/24/boa-usage</guid>
            <pubDate>Mon, 24 Oct 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Introduction]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="introduction">Introduction<a href="https://boajs.dev/blog/2022/10/24/boa-usage#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction" translate="no">​</a></h2>
<p>When we develop tools for our users, we sometimes want to give them some form of control over how
they work. This is common in games, where we can add scripting for our users to be able to create
extensions, or even for business tools, where we allow our customer to change or extend the
behaviour of our platform. For those cases, using Rust, a compiled, type safe language can be a
challenge, since once a program has been compiled, it's tricky to change or extend it at runtime.
Furthermore, many of our users will prefer to use a more common scripting language, such as
JavaScript.</p>
<p>This is where Boa enters the scene. Boa is a Javascript engine fully written in Rust. Currently, it
can be used in places where you need most of the JavaScript language to work, even though, we would
advise to wait to get all our <a href="https://github.com/boa-dev/boa/issues?q=64+162+718+773+2068+1930+1922+1917+1900+1848+1805+1570+1402+1307+1180+is%3Aopen" target="_blank" rel="noopener noreferrer">known blocker bugs</a> solved before using this for critical
workloads. You can check how conformant we are with the official ECMAScript specification
<a href="https://boajs.dev/conformance">here</a>.</p>
<p>And, before going further, we would like to mention that you can contribute to Boa by solving one
of the <a href="https://github.com/boa-dev/boa/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22%2CHacktoberfest%2CE-Easy%2C%22good+first+issue%22+no%3Aassignee" target="_blank" rel="noopener noreferrer">issues</a> where we need special help, and we now also accept financial contributions
in <a href="https://opencollective.com/boa" target="_blank" rel="noopener noreferrer">our OpenCollective</a> page.</p>
<p><em>Note: You can see more examples of integrating Boa in <a href="https://github.com/boa-dev/boa/tree/main/boa_examples" target="_blank" rel="noopener noreferrer">our repository</a>.</em></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="starting-from-scratch">Starting from scratch<a href="https://boajs.dev/blog/2022/10/24/boa-usage#starting-from-scratch" class="hash-link" aria-label="Direct link to Starting from scratch" title="Direct link to Starting from scratch" translate="no">​</a></h2>
<p>Let's start a new project running <code>cargo new my_project</code>, and then add <a href="https://crates.io/crates/boa_engine" target="_blank" rel="noopener noreferrer"><code>boa_engine</code></a> as one
of our dependencies by running <code>cargo add boa_engine -F console</code> in our newly created <code>my_project</code>
directory.</p>
<p>Let's start by adding the minimal code needed to get a JavaScript interpreter working in our
<code>src/main.rs</code> file:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">boa_engine</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> js_code </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"console.log('Hello World from a JS code string!')"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Instantiate the execution context</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Parse the source code</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">match</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">eval</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">js_code</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">res</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token macro property" style="color:#36acaa">println!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"{}"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">Err</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token comment" style="color:#999988;font-style:italic">// Pretty print the error</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token macro property" style="color:#36acaa">eprintln!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Uncaught {}"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">display</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>As you can see in this example, when working with Boa, you will have to use a <a href="https://docs.rs/boa_engine/latest/boa_engine/struct.Context.html" target="_blank" rel="noopener noreferrer"><code>Context</code></a>,
which will be in charge of initializing all the internals and built-in objects (such as <code>Date</code>,
<code>Promise</code> and so on). The <code>Context</code> in Boa is also your go-to place for configuring your interpreter
as you wish. You can add custom global functions, objects, and anything you might imagine. It's also
one of the arguments you will receive if you create a Rust function and expose it to JavaScript, and
with it, you will be able to throw errors, modify the global object and return values to JavaScript.</p>
<p>Talking about values, Boa comes with its built-in <a href="https://docs.rs/boa_engine/latest/boa_engine/enum.JsValue.html" target="_blank" rel="noopener noreferrer"><code>JsValue</code></a> type. This enumeration
represents any JavaScript value that can, for example, be assigned to a variable. And, before you
ask, you can convert it to and from a <a href="https://docs.rs/serde_json/latest/serde_json/value/enum.Value.html" target="_blank" rel="noopener noreferrer"><code>serde_json::Value</code></a>, of course, by using the
<a href="https://docs.rs/boa_engine/latest/boa_engine/enum.JsValue.html#method.from_json" target="_blank" rel="noopener noreferrer"><code>JsValue::from_json()</code></a> and <a href="https://docs.rs/boa_engine/latest/boa_engine/enum.JsValue.html#method.to_json" target="_blank" rel="noopener noreferrer"><code>JsValue::to_json()</code></a> methods.</p>
<p>As you can see in those methods, or in the <code>Context::eval()</code> that we used earlier, you will
receive a <code>JsResult</code> as a response. This result type will contain a <code>JsValue</code> as its error variant,
which means you can return the error back to JavaScript for it to handle it. A <code>JsValue</code>, internally,
is a garbage-collected JavaScript value. But, isn't Rust one of the few non-garbage collected
languages? Wasn't that a good thing?</p>
<p>The answer is <em>yes, of course</em>, but JavaScript requires a garbage collector. This garbage collector
makes sure that all values are freed when they are no longer needed. It also makes a <code>JsValue</code>
extremely cheap to clone, independently of its contents.</p>
<p>If you run this example code with <code>cargo run</code>, you will notice that it will print the message sent
to <code>console.log()</code>, and it will also print <code>undefined</code> at the end. This last <code>undefined</code> is part of
the <code>Ok(res)</code> branch in the <code>match</code>, which prints the result of the execution. In this case, the
result of the execution is the result of the last statement, which is the <code>console.log()</code>, and this
statement returns <code>undefined</code>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="but-what-can-you-do-with-boa">But, what can you do with Boa?<a href="https://boajs.dev/blog/2022/10/24/boa-usage#but-what-can-you-do-with-boa" class="hash-link" aria-label="Direct link to But, what can you do with Boa?" title="Direct link to But, what can you do with Boa?" translate="no">​</a></h2>
<p>Let's start with the basics. Of course, you can execute JavaScript code. This code can be any
string or directly a byte vector (so you can load files and use them directly). You can use
<a href="https://docs.rs/boa_engine/latest/boa_engine/struct.Context.html#method.eval" target="_blank" rel="noopener noreferrer"><code>Context::eval()</code></a> in both cases, as you saw before, and you can also use
<a href="https://docs.rs/boa_engine/latest/boa_engine/struct.Context.html#method.parse" target="_blank" rel="noopener noreferrer"><code>Context::parse()</code></a>, which will give you a <a href="https://docs.rs/boa_engine/latest/boa_engine/syntax/ast/node/statement_list/struct.StatementList.html" target="_blank" rel="noopener noreferrer"><code>StatementList</code></a> that
you can use multiple times in <a href="https://docs.rs/boa_engine/latest/boa_engine/struct.Context.html#method.compile" target="_blank" rel="noopener noreferrer"><code>Context::compile()</code></a>, so that you don't need to
parse the same code more than once. The compiled source code can also be executed multiple times,
since it's <a href="https://docs.rs/boa_engine/latest/boa_engine/vm/struct.CodeBlock.html" target="_blank" rel="noopener noreferrer"><code>CodeBlock</code></a> is garbage collected, and therefore it can be cheaply cloned.
In order to execute a code block you will need to use <a href="https://docs.rs/boa_engine/latest/boa_engine/struct.Context.html#method.execute" target="_blank" rel="noopener noreferrer"><code>Context::execute()</code></a>.</p>
<p>This in itself is good enough to provide a simple scripting API for your project, but where Boa
really shines is in the ability to inter-operate Rust and JavaScript. Let's start with a simple
example: exposing a Rust function to JavaScript. A JavaScript-compatible Rust function must have
the <a href="https://docs.rs/boa_engine/latest/boa_engine/builtins/function/type.NativeFunctionSignature.html" target="_blank" rel="noopener noreferrer"><code>NativeFunctionSignature</code></a> signature:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">boa_engine</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token namespace" style="opacity:0.7">builtins</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">JsArgs</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/// Says "hello" using the first argument.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">say_hello</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">_this</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token punctuation" style="color:#393A34">[</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">JsValue</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> name </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">get_or_undefined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> name</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">is_undefined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token macro property" style="color:#36acaa">println!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello World!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token macro property" style="color:#36acaa">println!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello {}!"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> name</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">undefined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>The <a href="https://docs.rs/boa_engine/latest/boa_engine/builtins/trait.JsArgs.html" target="_blank" rel="noopener noreferrer"><code>JsArgs</code></a> trait allows you to retrieve a value if the function received it, or set it
to the <code>undefined</code> value, if not. Then, in this case, it will convert the name to a <code>JsString</code>
before printing it, since we might be receiving an object, a symbol, a boolean... one of the perks
of dynamic typing. This will then print the result in th standard output using the common
<code>println!()</code> macro in Rust. It will just return an undefined value.</p>
<p>You can register this function in the context by adding this line after the context creation (and
before executing any JS) in the <code>main()</code> function:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">register_global_builtin_function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"say_hello"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> say_hello</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>This will register it as a global function, with the <code>say_hello()</code> name, and with a <code>length</code> of 1
(which indicates the number of arguments that it receives by default). You can then try it out by
modifying the JavaScript string:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> js_code </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">r#"say_hello("Rust");"#</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>The <code>r#"..."#</code> syntax is a Rust raw <a href="https://doc.rust-lang.org/rust-by-example/std/str.html#literals-and-escapes" target="_blank" rel="noopener noreferrer">string literal</a>.</p>
<p>You can also add any <code>JsValue</code> as a property to the global object by using the
<a href="https://docs.rs/boa_engine/latest/boa_engine/struct.Context.html#method.register_global_property" target="_blank" rel="noopener noreferrer"><code>Context::register_global_property()</code></a> function:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">boa_engine</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">property</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">Attribute</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">register_global_property</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"MY_PROJECT_VERSION"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"1.0.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Attribute</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">all</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>And you can use it in JavaScript:</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">say_hello</span><span class="token punctuation" style="color:#393A34">(</span><span class="token constant" style="color:#36acaa">MY_PROJECT_VERSION</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>The <a href="https://docs.rs/boa_engine/latest/boa_engine/property/struct.Attribute.html" target="_blank" rel="noopener noreferrer"><code>Attribute</code></a> of a property indicates if it will be writable (it can be set and
modified), enumerable (it can be used in <code>for..in</code> statements) and configurable (its attributes or
type of property can be modified).</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="integrating-a-full-rust-data-structure">Integrating a full Rust data structure<a href="https://boajs.dev/blog/2022/10/24/boa-usage#integrating-a-full-rust-data-structure" class="hash-link" aria-label="Direct link to Integrating a full Rust data structure" title="Direct link to Integrating a full Rust data structure" translate="no">​</a></h2>
<p>Sometimes, adding a function or a single <code>JsValue</code> to the global scope of your JavaScript context
is not enough, and you want to enable the full power of Rust with its structures to handle more
complex scenarios. This can be achieved using the <a href="https://docs.rs/boa_engine/latest/boa_engine/class/trait.Class.html" target="_blank" rel="noopener noreferrer"><code>Class</code></a> trait. This has to be combined
with two other traits, that make any Rust object be garbage-collected: <a href="https://docs.rs/boa_gc/latest/boa_gc/trait.Trace.html" target="_blank" rel="noopener noreferrer"><code>Trace</code></a> and
<a href="https://docs.rs/boa_gc/0.16.0/boa_gc/trait.Finalize.html" target="_blank" rel="noopener noreferrer"><code>Finalize</code></a>, in the <a href="https://crates.io/crates/boa_gc" target="_blank" rel="noopener noreferrer"><code>boa_gc</code></a> crate. Luckily those two traits can be derived.</p>
<p>Let's start by implementing a <code>Person</code> type, that will showcase the potential of this API. Let's
run <code>cargo add gc boa_gc</code> and add some code:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">boa_gc</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token class-name">Finalize</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Trace</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute attr-name" style="color:#00a4db">#[derive(Debug, Trace, Finalize)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Person</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">/// The name of the person.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">/// The age of the person.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    age</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Then, we will move the <code>say_hello()</code> function to be a static method of <code>Person</code>:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">impl</span><span class="token plain"> </span><span class="token class-name">Person</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">/// Says "hello" using the name and the age of a `Person`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">say_hello</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">this</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> _args</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token punctuation" style="color:#393A34">[</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">JsValue</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> this </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> this</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">as_object</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">and_then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token closure-params">obj</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token plain"> obj</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">downcast_ref</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">Self</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">ok_or_else</span><span class="token punctuation" style="color:#393A34">(</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">construct_type_error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"`this` is not a `Person` object"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token macro property" style="color:#36acaa">println!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello {}-year-old {}!"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">age</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">undefined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>As you can see, this now uses the <code>this</code> parameter of the <code>say_hello()</code> function, which should be a
<code>Person</code>, but in JavaScript you can assign methods of some objects to others, so we must make sure
that on this invocation, we are indeed working with a <code>Person</code>, and return a <code>TypeError</code> if not.</p>
<p>Now, let's implement the <a href="https://docs.rs/boa_engine/latest/boa_engine/class/trait.Class.html" target="_blank" rel="noopener noreferrer"><code>Class</code></a> trait. This trait requires a <code>NAME</code> constant, which will
be the name of the global object property, and a <code>LENGTH</code> for the constructor (the number of
arguments, by default <code>0</code>). Then, it needs a <code>constructor()</code> function, which is a native function
that will be called when we do a <code>new Person()</code>, and an <code>init()</code> function, which will be called by
the <code>Context</code> when registering the function in the global scope. It will receive a
<a href="https://docs.rs/boa_engine/latest/boa_engine/class/struct.ClassBuilder.html" target="_blank" rel="noopener noreferrer"><code>ClassBuilder</code></a>, which allows you to add a method (both, static and <code>prototype</code>), a
<code>property</code>, also for both cases, accessor properties (to use <code>get</code> and <code>set</code>) and property
descriptors. You can also get a reference to the <code>Context</code> with the <code>ClasBuilder::context()</code> method,
in case you want to do anything fancier.</p>
<p>In this case, the constructor will take care of constructing the Rust <code>Person</code> data structure with
the two arguments it receives, and then register the <code>say_hello()</code> method:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">boa_engine</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token namespace" style="opacity:0.7">builtins</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">JsArgs</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token namespace" style="opacity:0.7">class</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token class-name">Class</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">ClassBuilder</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">impl</span><span class="token plain"> </span><span class="token class-name">Class</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token class-name">Person</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">NAME</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token lifetime-annotation symbol" style="color:#36acaa">'static</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">str</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Person"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">LENGTH</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">usize</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// This is what is called when we construct a `Person` with the expression `new Person()`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">constructor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">_this</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token punctuation" style="color:#393A34">[</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">Self</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> name </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">get_or_undefined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> age </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">get_or_undefined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_u32</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">..=</span><span class="token number" style="color:#36acaa">150</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">contains</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">age</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">throw_range_error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token macro property" style="color:#36acaa">format!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"invalid age `{age}`. Must be between 0 and 150"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> age </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">u8</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">try_from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">age</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"we already checked that it was in range"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> person </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Person</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> name</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            age</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">person</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">/// Here is where the class is initialized, to be inserted into the global object.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">init</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">class</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">ClassBuilder</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        class</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">method</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"say_hello"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">Self</span><span class="token punctuation" style="color:#393A34">::</span><span class="token plain">say_hello</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>In order to register the class, you will need to use the
<a href="https://docs.rs/boa_engine/latest/boa_engine/struct.Context.html#method.register_global_class" target="_blank" rel="noopener noreferrer"><code>Context::register_global_class()</code></a> method:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">context</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">register_global_class</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Person</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"could not register class"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>You can now adapt the JavaScript code:</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> person </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Person</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"John"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">28</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">person</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">say_hello</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>If you want to access the global object from Rust, you can use <code>Context::global_object()</code>, which
will return a <a href="https://docs.rs/boa_engine/latest/boa_engine/object/struct.JsObject.html" target="_blank" rel="noopener noreferrer"><code>JsObject</code></a>. In this object, you can use the
<a href="https://docs.rs/boa_engine/latest/boa_engine/object/struct.JsObject.html#method.get" target="_blank" rel="noopener noreferrer"><code>JsObject::get()</code></a> function to retrieve any property of the global object, such as
the <code>MY_PROJECT_VERSION</code> that you defined earlier, or any intrinsic, such as the <code>Date</code> object.</p>
<p>We are now in the process of creating Rust wrappers for all JavaScript intrinsics (<a href="https://github.com/boa-dev/boa/issues/2098" target="_blank" rel="noopener noreferrer">#2098</a>).
For example, you can create a <code>JsArray</code> from a <code>JsObject</code> to make it much easier to manipulate a
JavaScript array from Rust. In the following example, you'll create a new <code>reverseAppend()</code> global
function that will receive an array, reverse it, and then append the <em>"My Project"</em> string to it.
It will then get the <code>MY_PROJECT_VERSION</code> from the global object, and append it to the array.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">boa_engine</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token namespace" style="opacity:0.7">builtins</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">JsArgs</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">object</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">JsArray</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">property</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">Attribute</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/// Reverses an array and appends the `"My Project"` string and the `MY_PROJECT_VERSION` global</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/// property to it.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">reverse_append</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">_this</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token punctuation" style="color:#393A34">[</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">JsValue</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> arr </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> args</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">get_or_undefined</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">as_object</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">ok_or_else</span><span class="token punctuation" style="color:#393A34">(</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">construct_type_error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"argument must be an array"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> arr </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">JsArray</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_object</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">arr</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">clone</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> reverse </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> arr</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">reverse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    reverse</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"My Project"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> global_object </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">global_object</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">clone</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> version </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> global_object</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"MY_PROJECT_VERSION"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap_or_default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    reverse</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">version</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">*</span><span class="token plain">reverse</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">clone</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">into</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> js_code </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">r#"</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        let arr = ['a', 2, 5.4, "Hello"];</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        reverseAppend(arr);</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    "#</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Instantiate the execution context</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">register_global_property</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"MY_PROJECT_VERSION"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"1.0.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Attribute</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">all</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">register_global_builtin_function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"reverseAppend"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> reverse_append</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Parse the source code</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">match</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">eval</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">js_code</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">res</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token macro property" style="color:#36acaa">println!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"{}"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">Err</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token comment" style="color:#999988;font-style:italic">// Pretty print the error</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token macro property" style="color:#36acaa">eprintln!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Uncaught {}"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">display</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>We are looking for contributors to implement the rest of the wrappers, and of course, we offer mentoring!</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="whats-coming-next">What's coming next?<a href="https://boajs.dev/blog/2022/10/24/boa-usage#whats-coming-next" class="hash-link" aria-label="Direct link to What's coming next?" title="Direct link to What's coming next?" translate="no">​</a></h2>
<p>Boa's development is ongoing non-stop. The next version, v0.17, is already looking pretty nice,
with some great enhancements. For example, <a href="https://github.com/jedel1043" target="_blank" rel="noopener noreferrer">@jedel1043</a> has created new
<a href="https://github.com/boa-dev/boa/pull/2283" target="_blank" rel="noopener noreferrer">"lazy" errors</a>, that are much easier to create and throw, since they don't need a
<code>Context</code>, and also enhance the performance. <a href="https://github.com/nekevss" target="_blank" rel="noopener noreferrer">@nekevss</a> has implemented a
<a href="https://github.com/boa-dev/boa/pull/2326" target="_blank" rel="noopener noreferrer">new wrapper</a> for <code>RegExp</code>, and <a href="https://github.com/anuvratsingh" target="_blank" rel="noopener noreferrer">@anuvratsingh</a> is working on a <code>Date</code>
<a href="https://github.com/boa-dev/boa/pull/2181" target="_blank" rel="noopener noreferrer">wrapper</a>. <a href="https://github.com/Razican" target="_blank" rel="noopener noreferrer">@razican</a> is working on a JavaScript to Rust
<a href="https://github.com/boa-dev/boa/pull/2276" target="_blank" rel="noopener noreferrer">conversion trait</a> and derive, that will allow you to convert a <code>JsValue</code> to a Rust
structure and back really easily:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">boa_derive</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">TryFromJs</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">boa_engine</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token punctuation" style="color:#393A34">{</span><span class="token namespace" style="opacity:0.7">value</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">TryFromJs</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute attr-name" style="color:#00a4db">#[derive(Debug, TryFromJs)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute attr-name" style="color:#00a4db">#[allow(dead_code)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">TestStruct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    inner</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">bool</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    hello</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[boa(from_js_with = </span><span class="token attribute attr-name string" style="color:#e3116c">"lossy_conversion"</span><span class="token attribute attr-name" style="color:#00a4db">, hello = </span><span class="token attribute attr-name string" style="color:#e3116c">"myfriend"</span><span class="token attribute attr-name" style="color:#00a4db">)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    my_float</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i16</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> js </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">r#"</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    let x = {</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        inner: false,</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        hello: "World",</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        my_float: 2.9,</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    };</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    x;</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    "#</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> res </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">eval</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">js</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">str</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name">TestStruct</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">try_from_js</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">res</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">map_err</span><span class="token punctuation" style="color:#393A34">(</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token closure-params">e</span><span class="token closure-params closure-punctuation punctuation" style="color:#393A34">|</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">display</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">unwrap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token macro property" style="color:#36acaa">println!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"{str:?}"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/// Converts the value lossly</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">lossy_conversion</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> </span><span class="token class-name">Context</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">JsResult</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">i16</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">match</span><span class="token plain"> value </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Rational</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">round</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i16</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">JsValue</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Integer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">*</span><span class="token plain">i </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">i16</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        _ </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">throw_type_error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"cannot convert value to an i16"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>We love contributions, whether it's a documentation enhancement, fixing or implementing the
ECMAScript specification, adding new functionality / APIs or enhancing performance, we would love
to get new contributors on board! We are also looking for financial contributors, so feel free to
join our <a href="https://opencollective.com/boa" target="_blank" rel="noopener noreferrer">OpenCollective</a>.</p>]]></content:encoded>
            <category>post</category>
        </item>
        <item>
            <title><![CDATA[Boa release v0.16]]></title>
            <link>https://boajs.dev/blog/2022/09/25/boa-release-16</link>
            <guid>https://boajs.dev/blog/2022/09/25/boa-release-16</guid>
            <pubDate>Sun, 25 Sep 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Summary]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="summary">Summary<a href="https://boajs.dev/blog/2022/09/25/boa-release-16#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>Boa v0.16 is now available! After around 3 months of development, we are very happy to present you the newest release of
the Boa JavaScript engine. Boa makes it easy to embed a JS engine in your projects, and you can even use it from
WebAssembly. See the <a href="https://boajs.dev/about">about</a> page for more info.</p>
<p>Boa currently supports part of the JavaScript language. In this release, our conformance has grown from 62.29% to 74.53%
in the official ECMAScript Test Suite (Test262). The engine now passes 68,612 tests, coming from 56,372 in Boa 0.15
(21.7% increase), and we have closed 9 issues and merged 59 pull requests. You can check the full list of changes
<a href="https://github.com/boa-dev/boa/blob/v0.16/CHANGELOG.md" target="_blank" rel="noopener noreferrer">here</a>, and the full information on conformance
<a href="https://boajs.dev/conformance">here</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="new-ecmascript-features">New ECMAScript features<a href="https://boajs.dev/blog/2022/09/25/boa-release-16#new-ecmascript-features" class="hash-link" aria-label="Direct link to New ECMAScript features" title="Direct link to New ECMAScript features" translate="no">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="support-for-promises">Support for Promises<a href="https://boajs.dev/blog/2022/09/25/boa-release-16#support-for-promises" class="hash-link" aria-label="Direct link to Support for Promises" title="Direct link to Support for Promises" translate="no">​</a></h3>
<p>With this new release Boa ships support for ECMAScript Promises. All tests in the 262 test suite <code>built-ins/Promise</code> pass.
Promises enable asynchronous operations to be executed via an internal job queue. Starting with our work on Promises,
we have stopped ignoring the 262 tests that are flagged as <code>async</code>. We also have enabled our 262 test runner to work
with asynchronous tests. We would like to thank <a href="https://github.com/aaronmunsters" target="_blank" rel="noopener noreferrer">@aaronmunsters</a> for proposing
the initial PR for Promises (<a href="https://github.com/boa-dev/boa/pull/1923" target="_blank" rel="noopener noreferrer">#1923</a>) that we then could expand on.</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// This program will print:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//    1. End of synchronous execution.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//    2. The Promise has been resolved.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> promise </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token known-class-name class-name">Promise</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">resolve</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">promise</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"2. The Promise has been resolved."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"1. End of synchronous execution."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="support-for-asyncawait">Support for Async/Await<a href="https://boajs.dev/blog/2022/09/25/boa-release-16#support-for-asyncawait" class="hash-link" aria-label="Direct link to Support for Async/Await" title="Direct link to Support for Async/Await" translate="no">​</a></h3>
<p>The implementation of Promises has enabled us to implement async functions and the await keyword. The async/await syntax
makes it easier to use Promises within javascript. We have implemented async functions, async generators,
<code>for await...of</code> loops and the <code>await</code> keyword. While not all tests pass for these features yet, the basic functionality
should work.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="densepacked-javascript-arrays">Dense/Packed JavaScript Arrays<a href="https://boajs.dev/blog/2022/09/25/boa-release-16#densepacked-javascript-arrays" class="hash-link" aria-label="Direct link to Dense/Packed JavaScript Arrays" title="Direct link to Dense/Packed JavaScript Arrays" translate="no">​</a></h2>
<p>JavaScript Arrays are regular objects whose values are stored as indexed properties. Because arrays have no fixed
length, values can be assigned to any possible index without any of the previous indices being used. Due to this
behavior indexed properties are stored in a map instead of in a vector, as the vector would allocate a lot of unused
memory if a high index is used. We have implemented an optimization to make it possible to use optimized vector storage
for array values, as long as indices are not assigned out of order. This has improved the performance of arrays around
<strong>45%</strong> for arrays without empty slots. To learn more about this optimization take a look at the PR
<a href="https://github.com/boa-dev/boa/pull/2167" target="_blank" rel="noopener noreferrer">#2167</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="support-for-uri-encoding-and-decoding-functions">Support for URI encoding and decoding functions<a href="https://boajs.dev/blog/2022/09/25/boa-release-16#support-for-uri-encoding-and-decoding-functions" class="hash-link" aria-label="Direct link to Support for URI encoding and decoding functions" title="Direct link to Support for URI encoding and decoding functions" translate="no">​</a></h2>
<p>This version for Boa ships with support for the built-in URI encoding and decoding functions <code>encodeURI</code>, <code>decodeURI</code>,
<code>encodeURIComponent</code> and <code>decodeURIComponent</code>. With the exception of UTF-16 related test, all test in the relevant 262
test suites pass for these functions.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-can-you-contribute-to-boa">How can you contribute to Boa?<a href="https://boajs.dev/blog/2022/09/25/boa-release-16#how-can-you-contribute-to-boa" class="hash-link" aria-label="Direct link to How can you contribute to Boa?" title="Direct link to How can you contribute to Boa?" translate="no">​</a></h2>
<p>In March, Boa opened financial contributions on its <a href="https://opencollective.com/boa" target="_blank" rel="noopener noreferrer">OpenCollective page</a>.
If financial contribution is not your strength, you can contribute by asking to be assigned to one of our
<a href="https://github.com/boa-dev/boa/issues?q=is%3Aopen+is%3Aissue+no%3Aassignee" target="_blank" rel="noopener noreferrer">open issues</a>, and asking for mentoring if you
don't know your way around the engine. Our <a href="https://github.com/boa-dev/boa/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">contribution guide</a>
should help you here. If you are more used to working with JavaScript or frontend web development, we also
welcome help to improve our web presence, either in <a href="https://github.com/boa-dev/boa-dev.github.io" target="_blank" rel="noopener noreferrer">our website</a>, or in
our <a href="https://github.com/boa-dev/boa/issues/820" target="_blank" rel="noopener noreferrer">testing representation</a> page or benchmarks page. You can also contribute to
our Criterion benchmark comparison GitHub <a href="https://github.com/boa-dev/criterion-compare-action" target="_blank" rel="noopener noreferrer">action</a>.</p>
<p>We are also looking to improve the documentation of the engine, both for developers of the engine itself and for users of the
engine. Feel free to contact us in <a href="https://discord.gg/tUFFk9Y" target="_blank" rel="noopener noreferrer">Discord</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="thank-you">Thank You<a href="https://boajs.dev/blog/2022/09/25/boa-release-16#thank-you" class="hash-link" aria-label="Direct link to Thank You" title="Direct link to Thank You" translate="no">​</a></h3>
<p>Last but certainly not least, a big <strong>Thank You</strong> to
<a href="https://github.com/boa-dev/boa/graphs/contributors?from=2022-06-11&amp;to=2022-09-25&amp;type=c" target="_blank" rel="noopener noreferrer">all the contributors</a>
of this Boa release. We would like to particularly thank our new contributors:</p>
<ul>
<li><a href="https://github.com/CYBAI" target="_blank" rel="noopener noreferrer">@CYBAI</a> who made their first contribution in <a href="https://github.com/boa-dev/boa/pull/2108" target="_blank" rel="noopener noreferrer">#2108</a></li>
<li><a href="https://github.com/udhaykumarbala" target="_blank" rel="noopener noreferrer">@udhaykumarbala</a> who made their first contribution in <a href="https://github.com/boa-dev/boa/pull/2245" target="_blank" rel="noopener noreferrer">#2245</a></li>
<li><a href="https://github.com/tunz" target="_blank" rel="noopener noreferrer">@tunz</a> who made their first contribution in <a href="https://github.com/boa-dev/boa/pull/2261" target="_blank" rel="noopener noreferrer">#2261</a></li>
<li><a href="https://github.com/anuvratsingh" target="_blank" rel="noopener noreferrer">@anuvratsingh</a> who made their first contribution in <a href="https://github.com/boa-dev/boa/pull/2162" target="_blank" rel="noopener noreferrer">#2162</a></li>
<li><a href="https://github.com/creampnx-x" target="_blank" rel="noopener noreferrer">@creampnx-x</a> who made their first contribution in <a href="https://github.com/boa-dev/boa/pull/2274" target="_blank" rel="noopener noreferrer">#2274</a></li>
</ul>]]></content:encoded>
            <category>post</category>
        </item>
    </channel>
</rss>