<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Wasm on kenji.blog</title><link>http://kenji.blog/fr/tags/wasm/</link><description>Recent content in Wasm on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>fr</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 10:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/fr/tags/wasm/index.xml" rel="self" type="application/rss+xml"/><item><title>Générer du WebAssembly (Wasm) depuis C++ et Rust pour une exécution dans le navigateur</title><link>http://kenji.blog/fr/p/webassembly-wasm-from-cpp-and-rust/</link><pubDate>Sat, 12 Sep 2026 10:00:00 +0900</pubDate><guid>http://kenji.blog/fr/p/webassembly-wasm-from-cpp-and-rust/</guid><description>&lt;img src="http://kenji.blog/p/webassembly-wasm-from-cpp-and-rust/img/eyecatch.jpg" alt="Featured image of post Générer du WebAssembly (Wasm) depuis C++ et Rust pour une exécution dans le navigateur" />&lt;h2 id="1-introduction">1. Introduction
&lt;/h2>&lt;p>Dans le développement Web moderne, JavaScript (et TypeScript) s&amp;rsquo;est longtemps imposé comme le seul langage de programmation s&amp;rsquo;exécutant dans le navigateur. Cependant, ces dernières années, on observe une demande croissante pour des calculs plus avancés directement dans le navigateur, tels que le traitement d&amp;rsquo;images, l&amp;rsquo;encodage vidéo, les jeux 3D et les simulations physiques. C&amp;rsquo;est là qu&amp;rsquo;intervient &lt;strong>WebAssembly (communément appelé Wasm)&lt;/strong>.&lt;/p>
&lt;p>Dans cet article, nous allons explorer les bases de WebAssembly, puis détailler les étapes et la structure interne pour générer du Wasm à partir de deux puissants langages de programmation système : C++ (en utilisant Emscripten) et Rust (en utilisant &lt;code>wasm-pack&lt;/code>), afin de les intégrer à l&amp;rsquo;environnement JavaScript. De plus, nous approfondirons la gestion des limites de la mémoire, la transmission de données complexes comme les chaînes de caractères et les tableaux, les surcoûts liés aux performances, ainsi que le format binaire Wasm (&lt;code>.wasm&lt;/code>).&lt;/p>
&lt;h2 id="2-vue-densemble-et-architecture-de-webassembly-wasm">2. Vue d&amp;rsquo;ensemble et architecture de WebAssembly (Wasm)
&lt;/h2>&lt;p>WebAssembly est un format d&amp;rsquo;instructions binaire conçu pour une machine virtuelle basée sur une pile. Il a été conçu comme une cible de compilation portable pouvant être compilée à partir de langages tels que C/C++, Rust, Go, Zig, etc., dans le but de s&amp;rsquo;exécuter à une vitesse proche de la vitesse native dans les navigateurs Web.&lt;/p>
&lt;p>Le diagramme suivant illustre le flux général de la chaîne d&amp;rsquo;outils, depuis la génération de WebAssembly à partir de C++ et Rust jusqu&amp;rsquo;à son exécution dans le navigateur.&lt;/p>
&lt;div class="mermaid">graph TD
A["Code source C++ (.cpp)"] --> B["Emscripten (clang/LLVM)"]
B --> C["Sortie .wasm"]
B --> D["Sortie JS Glue"]
E["Code source Rust (.rs)"] --> F["cargo / rustc / LLVM"]
F --> G["wasm-bindgen / wasm-pack"]
G --> H["Sortie .wasm"]
G --> I["Sortie JS Wrappers"]
C --> J["Navigateur (V8 / SpiderMonkey / JavaScriptCore)"]
D --> J
H --> J
I --> J&lt;/div>
&lt;p>Wasm n&amp;rsquo;est pas destiné à remplacer JavaScript. Il est conçu pour fonctionner avec JavaScript, en déchargeant les tâches de calcul intensif sur Wasm afin de tirer parti des forces de chacun.&lt;/p>
&lt;h2 id="3-défi-mathématique--calcul-de-lensemble-de-mandelbrot">3. Défi mathématique : Calcul de l&amp;rsquo;ensemble de Mandelbrot
&lt;/h2>&lt;p>Dans cet article, nous utiliserons l&amp;rsquo;algorithme de rendu de l&amp;rsquo;ensemble de Mandelbrot, qui impose une forte charge au processeur, et nous l&amp;rsquo;implémenterons en C++ et en Rust.&lt;/p>
&lt;p>L&amp;rsquo;ensemble de Mandelbrot est défini par la relation de récurrence complexe suivante :&lt;/p>
$$ z_{n+1} = z_n^2 + c $$
&lt;p>Ici, $z$ et $c$ sont des nombres complexes, et le calcul commence avec $z_0 = 0$. Pour un nombre complexe donné $c$, l&amp;rsquo;ensemble de Mandelbrot est l&amp;rsquo;ensemble des valeurs de $c$ pour lesquelles la valeur absolue de $z_n$ ne diverge pas lorsque le calcul est répété indéfiniment. En général, lors du calcul sur un ordinateur, on considère que la suite diverge si la condition suivante est remplie :&lt;/p>
$$ |z_n| > 2 $$
&lt;p>Autrement dit, pour la partie réelle $x$ et la partie imaginaire $y$, nous vérifions si la condition suivante est satisfaite jusqu&amp;rsquo;à un nombre maximal de boucles (par exemple $N = 1000$).&lt;/p>
$$ x^2 + y^2 > 4 $$
&lt;h2 id="4-approche-avec-c-et-emscripten">4. Approche avec C++ et Emscripten
&lt;/h2>&lt;p>Emscripten est une chaîne d&amp;rsquo;outils de compilation basée sur LLVM et constitue le standard de facto pour compiler du code C/C++ vers WebAssembly. Il fournit un runtime puissant qui émule les appels système POSIX avec des API de navigateur (Web API).&lt;/p>
&lt;h3 id="code-dimplémentation-c">Code d&amp;rsquo;implémentation C++
&lt;/h3>&lt;p>Le code C++ suivant calcule l&amp;rsquo;ensemble de Mandelbrot pour une largeur et une hauteur spécifiées, et stocke le résultat (le nombre d&amp;rsquo;itérations pour chaque pixel) dans un tableau unidimensionnel.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;emscripten/emscripten.h&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Spécifier l&amp;#39;édition de liens C pour pouvoir l&amp;#39;appeler depuis JavaScript
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">extern&lt;/span> &lt;span class="s">&amp;#34;C&amp;#34;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Renvoie un pointeur vers le tampon contenant le résultat du calcul
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">EMSCRIPTEN_KEEPALIVE&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="nf">compute_mandelbrot&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">width&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">height&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">max_iter&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Allouer le tampon en tant que variable statique (pour simplifier)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">static&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">buffer&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">buffer&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">resize&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">width&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">height&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">row&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">row&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">height&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">row&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">col&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">col&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">width&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">col&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">double&lt;/span> &lt;span class="n">c_re&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">col&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">width&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="mf">2.0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="mf">4.0&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">width&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">double&lt;/span> &lt;span class="n">c_im&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">row&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">height&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="mf">2.0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="mf">4.0&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">width&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">double&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">y&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">iteration&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">y&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="mi">4&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="n">iteration&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">max_iter&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">double&lt;/span> &lt;span class="n">x_new&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">y&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">c_re&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">y&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">y&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">c_im&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x_new&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">iteration&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">buffer&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">row&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">width&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">col&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">iteration&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">buffer&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Fonction de libération de mémoire (si nécessaire)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">EMSCRIPTEN_KEEPALIVE&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="nf">free_buffer&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="compilation-et-appel-depuis-javascript">Compilation et appel depuis JavaScript
&lt;/h3>&lt;p>Nous utilisons Emscripten pour compiler ce code.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">emcc mandelbrot.cpp -O3 -s &lt;span class="nv">WASM&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span> -s &lt;span class="nv">EXPORTED_FUNCTIONS&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;[&amp;#39;_compute_mandelbrot&amp;#39;, &amp;#39;_malloc&amp;#39;, &amp;#39;_free&amp;#39;]&amp;#34;&lt;/span> -s &lt;span class="nv">EXPORTED_RUNTIME_METHODS&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;[&amp;#39;ccall&amp;#39;, &amp;#39;cwrap&amp;#39;]&amp;#34;&lt;/span> -o mandelbrot.js
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Du côté JavaScript, nous chargeons le code de liaison (&lt;code>mandelbrot.js&lt;/code>) généré par Emscripten et l&amp;rsquo;appelons en utilisant l&amp;rsquo;API WebAssembly comme suit.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">Module&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">onRuntimeInitialized&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">width&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">800&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">height&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">600&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">maxIter&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1000&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Appeler la fonction C++ et obtenir le pointeur
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kr">const&lt;/span> &lt;span class="nx">resultPtr&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">Module&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ccall&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;compute_mandelbrot&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Nom de la fonction C
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="s1">&amp;#39;number&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Type de valeur de retour (le pointeur est un nombre)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;number&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;number&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;number&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="c1">// Types des arguments
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="nx">width&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">height&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">maxIter&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Lire directement les données du tableau depuis la mémoire linéaire (Module.HEAP32)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kr">const&lt;/span> &lt;span class="nx">numElements&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">width&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="nx">height&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">resultView&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">Int32Array&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">Module&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">HEAP32&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">buffer&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">resultPtr&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">numElements&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Calcul terminé. Données du premier pixel : &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">resultView&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="5-approche-avec-rust-et-wasm-pack">5. Approche avec Rust et &lt;code>wasm-pack&lt;/code>
&lt;/h2>&lt;p>Rust offre un support de première classe pour WebAssembly, et l&amp;rsquo;utilisation des outils &lt;code>wasm-bindgen&lt;/code> et &lt;code>wasm-pack&lt;/code> permet une intégration avancée entre JavaScript et Rust. Alors qu&amp;rsquo;Emscripten adopte une approche consistant à apporter un énorme runtime C/C++ dans le navigateur, &lt;code>wasm-pack&lt;/code> de Rust adopte une approche consistant à générer uniquement les liaisons (code de liaison JS) strictement nécessaires.&lt;/p>
&lt;h3 id="code-dimplémentation-rust">Code d&amp;rsquo;implémentation Rust
&lt;/h3>&lt;p>Créez un projet Cargo et spécifiez &lt;code>cdylib&lt;/code> et &lt;code>wasm-bindgen&lt;/code> dans &lt;code>Cargo.toml&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">lib&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">crate-type&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;cdylib&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">wasm-bindgen&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;0.2&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Ensuite, écrivez l&amp;rsquo;implémentation dans &lt;code>src/lib.rs&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="k">use&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">wasm_bindgen&lt;/span>::&lt;span class="n">prelude&lt;/span>::&lt;span class="o">*&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="cp">#[wasm_bindgen]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">pub&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">fn&lt;/span> &lt;span class="nf">compute_mandelbrot_rust&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">width&lt;/span>: &lt;span class="kt">usize&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">height&lt;/span>: &lt;span class="kt">usize&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">max_iter&lt;/span>: &lt;span class="kt">u32&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>-&amp;gt; &lt;span class="nb">Vec&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">i32&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">mut&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">buffer&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="fm">vec!&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">width&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">height&lt;/span>&lt;span class="p">];&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">row&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="o">..&lt;/span>&lt;span class="n">height&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">col&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="o">..&lt;/span>&lt;span class="n">width&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">c_re&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">col&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">as&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">f64&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">width&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">as&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">f64&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">2.0&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">4.0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">width&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">as&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">f64&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">c_im&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">row&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">as&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">f64&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">height&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">as&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">f64&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">2.0&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">4.0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">width&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">as&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">f64&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">mut&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">0.0&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">mut&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">0.0&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">mut&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">iteration&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">while&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">4.0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&amp;amp;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">iteration&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">max_iter&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">x_new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">c_re&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mf">2.0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">c_im&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">x_new&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">iteration&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">+=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">buffer&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">row&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">width&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">col&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">iteration&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">as&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">i32&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">buffer&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="compilation-et-appel-depuis-javascript-1">Compilation et appel depuis JavaScript
&lt;/h3>&lt;p>Compilez avec la commande &lt;code>wasm-pack&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">wasm-pack build --target web
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Importez le package généré depuis JavaScript. Grâce à &lt;code>wasm-bindgen&lt;/code>, le &lt;code>Vec&amp;lt;i32&amp;gt;&lt;/code> de Rust est automatiquement converti en &lt;code>Int32Array&lt;/code> de JavaScript (cachant la manipulation des pointeurs).&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nx">init&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">compute_mandelbrot_rust&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;./pkg/mandelbrot_wasm.js&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">async&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="nx">run&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">await&lt;/span> &lt;span class="nx">init&lt;/span>&lt;span class="p">();&lt;/span> &lt;span class="c1">// Initialisation du module WebAssembly
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">width&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">800&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">height&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">600&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">maxIter&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1000&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Le résultat peut être reçu directement sous forme de tableau JavaScript
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kr">const&lt;/span> &lt;span class="nx">resultView&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">compute_mandelbrot_rust&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">width&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">height&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">maxIter&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Calcul terminé. Données du premier pixel : &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">resultView&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">run&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="6-approfondissement--limites-de-la-mémoire-et-transmission-de-types-de-données">6. Approfondissement : Limites de la mémoire et transmission de types de données
&lt;/h2>&lt;p>L&amp;rsquo;un des concepts les plus importants dans WebAssembly est la mémoire linéaire (Linear Memory). Le code Wasm ne peut pas accéder directement à l&amp;rsquo;espace mémoire de l&amp;rsquo;hôte (le navigateur) ; à la place, on lui attribue un énorme &lt;code>ArrayBuffer&lt;/code> isolé. C&amp;rsquo;est la mémoire linéaire.&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant JS as "Environnement JavaScript"
participant Wasm as "Runtime WebAssembly"
participant Mem as "Mémoire linéaire (ArrayBuffer)"
JS->>Wasm: "Appeler calculate(10, 20)"
note over JS,Wasm: "Primitifs (int, float) passés directement via Registres/Pile"
Wasm-->>JS: "Retourner 30"
note over JS, Mem: "Pour les données complexes (Chaînes, Tableaux)"
JS->>Mem: "Écrire la chaîne en mémoire"
JS->>Wasm: "Appeler process_string(pointer, length)"
Wasm->>Mem: "Lire à partir du pointeur"
Wasm->>Mem: "Écrire le résultat vers un nouveau pointeur"
Wasm-->>JS: "Retourner le nouveau pointeur &amp; la longueur"
JS->>Mem: "Lire les données de résultat depuis la mémoire"&lt;/div>
&lt;h3 id="comment-passer-des-chaînes-de-caractères-et-des-tableaux">Comment passer des chaînes de caractères et des tableaux
&lt;/h3>&lt;p>Les nombres entiers et à virgule flottante (&lt;code>i32&lt;/code>, &lt;code>i64&lt;/code>, &lt;code>f32&lt;/code>, &lt;code>f64&lt;/code>) peuvent être passés directement aux fonctions Wasm en tant que valeurs. Cependant, les types complexes comme les chaînes, les tableaux et les structures ne peuvent pas être passés directement dans la signature de la fonction Wasm.&lt;/p>
&lt;p>&lt;strong>Dans le cas d&amp;rsquo;Emscripten&lt;/strong> :&lt;/p>
&lt;ol>
&lt;li>Du côté JS, appelez &lt;code>Module._malloc&lt;/code> pour allouer un espace dans la mémoire linéaire du côté Wasm.&lt;/li>
&lt;li>Écrivez les données depuis JS à l&amp;rsquo;adresse mémoire allouée (pointeur) en utilisant, par exemple, &lt;code>Module.HEAPU8.set()&lt;/code>.&lt;/li>
&lt;li>Passez le pointeur à la fonction C++.&lt;/li>
&lt;li>Après le calcul, lisez le résultat depuis le pointeur du côté JS, et appelez enfin &lt;code>Module._free&lt;/code>.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Dans le cas de wasm-bindgen (Rust)&lt;/strong> :
Le flux complexe de gestion de la mémoire décrit ci-dessus est entièrement masqué dans le code de liaison (enveloppeur JS) généré automatiquement. Lorsque vous passez simplement une &lt;code>String&lt;/code> ou un &lt;code>Array&lt;/code> de JS à une fonction Rust, une série d&amp;rsquo;opérations telles que l&amp;rsquo;allocation du tampon (équivalent à &lt;code>malloc&lt;/code>), la copie, le passage de pointeur et la libération de la mémoire sont effectuées automatiquement en arrière-plan.&lt;/p>
&lt;h2 id="7-surcharge-de-performance-et-optimisation">7. Surcharge de performance et optimisation
&lt;/h2>&lt;p>Bien que WebAssembly puisse s&amp;rsquo;exécuter à une vitesse proche de la vitesse native, il existe une surcharge (overhead) lors de la communication franchissant la frontière entre JavaScript et WebAssembly (Interop).&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Surcharge d&amp;rsquo;appel&lt;/strong> : C&amp;rsquo;est le coût de commutation pour le moteur JavaScript afin d&amp;rsquo;appeler une fonction Wasm. Bien que cela soit fortement optimisé aujourd&amp;rsquo;hui, vous devriez éviter une architecture qui appelle des fonctions très légères des dizaines de milliers de fois par image.&lt;/li>
&lt;li>&lt;strong>Coût de copie de mémoire&lt;/strong> : Lors du passage de chaînes ou de tableaux à Wasm, les données sont copiées de la mémoire gérée par le ramasse-miettes de JS vers la mémoire linéaire de Wasm (ArrayBuffer). Si vous passez de grandes quantités de données, une conception &amp;ldquo;zéro copie&amp;rdquo; est nécessaire, où les données sont construites directement sur la mémoire Wasm dès le départ et accédées du côté JS via des vues TypedArray (comme &lt;code>Uint8Array&lt;/code>).&lt;/li>
&lt;/ul>
&lt;p>Par exemple, dans les moteurs de jeux ou de physique, une architecture courante consiste à conserver tout l&amp;rsquo;état dans la mémoire linéaire de Wasm, JavaScript n&amp;rsquo;étant responsable que du déclenchement des mises à jour à chaque image et du rendu de l&amp;rsquo;écran (appel des API WebGL/WebGPU).&lt;/p>
&lt;h2 id="8-anatomie-du-format-binaire-webassembly-wasm">8. Anatomie du format binaire WebAssembly (.wasm)
&lt;/h2>&lt;p>Regardons maintenant la structure interne du fichier &lt;code>.wasm&lt;/code> produit par le compilateur. Les binaires Wasm sont constitués d&amp;rsquo;une collection de blocs logiques appelés &amp;ldquo;sections&amp;rdquo;, mettant l&amp;rsquo;accent sur l&amp;rsquo;extensibilité et la vitesse d&amp;rsquo;analyse.&lt;/p>
&lt;div class="mermaid">graph TD
Root["Binaire Wasm (.wasm)"] --> Magic["Nombre magique : '\0asm' (0x00 0x61 0x73 0x6D)"]
Root --> Version["Version : 1 (0x01 0x00 0x00 0x00)"]
Root --> Sections["Sections"]
Sections --> S1["1 : Section Type (Signatures de fonction)"]
Sections --> S2["2 : Section Import (Fonctions JS à importer)"]
Sections --> S3["3 : Section Function (Déclarations de fonction)"]
Sections --> S4["4 : Section Table (Pointeurs de fonction)"]
Sections --> S5["5 : Section Memory (Taille de la mémoire linéaire)"]
Sections --> S7["7 : Section Export (Fonctions exposées à JS)"]
Sections --> S10["10 : Section Code (Instructions de bytecode Wasm)"]
Sections --> S11["11 : Section Data (Chaînes/Constantes statiques)"]&lt;/div>
&lt;p>Le nombre magique du fichier commence toujours par &lt;code>0x00 0x61 0x73 0x6D&lt;/code> (&lt;code>\0asm&lt;/code>). Chaque section suivante a un ID.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Section Type&lt;/strong> : Définit toutes les signatures de fonction utilisées (types des arguments et des valeurs de retour).&lt;/li>
&lt;li>&lt;strong>Section Import&lt;/strong> : Une liste des fonctions et de la mémoire fournies à Wasm depuis l&amp;rsquo;environnement JavaScript. Par exemple, si &lt;code>console.log&lt;/code> est appelé depuis C++, il sera déclaré ici.&lt;/li>
&lt;li>&lt;strong>Section Code&lt;/strong> : Contient les instructions réelles du bytecode (comme &lt;code>i32.add&lt;/code>, &lt;code>call&lt;/code>, &lt;code>loop&lt;/code>). Comme il s&amp;rsquo;agit d&amp;rsquo;une machine à pile, les opérandes sont empilés avant d&amp;rsquo;appeler les instructions d&amp;rsquo;opération.&lt;/li>
&lt;li>&lt;strong>Section Data&lt;/strong> : Les littéraux de chaîne statiques et les données d&amp;rsquo;initialisation définis dans le code C++ ou Rust sont chargés dans la mémoire linéaire depuis cette section.&lt;/li>
&lt;/ul>
&lt;p>Le moteur Wasm du navigateur réalise une accélération spectaculaire du démarrage en compilant ces sections en flux (streaming compilation) - en les compilant en code machine en parallèle pendant leur téléchargement.&lt;/p>
&lt;h2 id="9-c-vs-rust--lequel-devriez-vous-choisir-">9. C++ vs Rust : Lequel devriez-vous choisir ?
&lt;/h2>&lt;p>Lors de la génération de WebAssembly, le choix entre C++ et Rust dépend fortement des exigences du projet et des ressources existantes.&lt;/p>
&lt;p>&lt;strong>Cas où vous devriez choisir C++ / Emscripten&lt;/strong> :&lt;/p>
&lt;ul>
&lt;li>Si vous souhaitez porter des bibliothèques C/C++ existantes (FFmpeg, OpenCV, SQLite, etc.) vers le navigateur.&lt;/li>
&lt;li>Les projets de portage de jeux qui souhaitent utiliser les capacités de traduction de l&amp;rsquo;API graphique (comme OpenGL vers WebGL via la couche d&amp;rsquo;émulation GL d&amp;rsquo;Emscripten) telles quelles.&lt;/li>
&lt;li>Lorsqu&amp;rsquo;une fonctionnalité du système d&amp;rsquo;exploitation virtualisée est nécessaire, telle que l&amp;rsquo;émulation du système de fichiers (MEMFS).&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Cas où vous devriez choisir Rust / wasm-pack&lt;/strong> :&lt;/p>
&lt;ul>
&lt;li>Si vous développez de nouveaux modules haute performance à partir de zéro dans le cadre d&amp;rsquo;une application Web.&lt;/li>
&lt;li>Si vous souhaitez une intégration forte et sûre du point de vue du type avec l&amp;rsquo;écosystème JavaScript (modules NPM et TypeScript).&lt;/li>
&lt;li>Si vous recherchez une taille de binaire relativement petite et une gestion de mémoire sécurisée (modèle de possession (ownership) de Rust).&lt;/li>
&lt;li>Si vous souhaitez bénéficier d&amp;rsquo;une chaîne d&amp;rsquo;outils moderne comme la gestion des dépendances via Cargo.&lt;/li>
&lt;/ul>
&lt;h2 id="10-résumé">10. Résumé
&lt;/h2>&lt;p>WebAssembly est une technologie révolutionnaire pour exécuter des calculs intensifs directement dans le navigateur. L&amp;rsquo;approche de portage complet utilisant C++ et Emscripten, ainsi que l&amp;rsquo;approche modulaire étroitement couplée à JavaScript utilisant Rust et wasm-bindgen, ont chacune leurs propres avantages.&lt;/p>
&lt;p>Dans des calculs comme l&amp;rsquo;ensemble de Mandelbrot, Wasm peut offrir une amélioration de la vitesse allant de plusieurs fois à plusieurs dizaines de fois par rapport à JavaScript seul. Cependant, vous ne pourrez exploiter ses véritables performances que si vous comprenez correctement le fonctionnement de la frontière de la mémoire entre Wasm et JS, et si vous concevez votre système de manière à éviter les copies de mémoire inutiles.&lt;/p>
&lt;p>Nous espérons qu&amp;rsquo;à travers cet article, vous aurez acquis une compréhension plus approfondie de l&amp;rsquo;ensemble du processus de génération de Wasm à partir de C++ et Rust et de son exécution dans le navigateur, ainsi que de l&amp;rsquo;architecture sous-jacente. Dans le développement des applications Web de nouvelle génération, WebAssembly sera sans aucun doute une arme puissante.&lt;/p></description></item></channel></rss>