<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>WebAssembly on kenji.blog</title><link>http://kenji.blog/id/categories/webassembly/</link><description>Recent content in WebAssembly on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>id</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 10:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/id/categories/webassembly/index.xml" rel="self" type="application/rss+xml"/><item><title>Menghasilkan WebAssembly (Wasm) dari C++ atau Rust dan Menjalankannya di Browser</title><link>http://kenji.blog/id/p/webassembly-wasm-from-cpp-and-rust/</link><pubDate>Sat, 12 Sep 2026 10:00:00 +0900</pubDate><guid>http://kenji.blog/id/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 Menghasilkan WebAssembly (Wasm) dari C++ atau Rust dan Menjalankannya di Browser" />&lt;h2 id="1-pendahuluan">1. Pendahuluan
&lt;/h2>&lt;p>Dalam pengembangan web modern, JavaScript (dan TypeScript) telah lama memantapkan posisinya sebagai satu-satunya bahasa pemrograman yang berjalan di browser. Namun, belakangan ini kebutuhan untuk menjalankan komputasi yang lebih canggih langsung di browser, seperti pemrosesan gambar, encoding video, game 3D, dan simulasi fisika, semakin meningkat. Di sinilah &lt;strong>WebAssembly (biasa disebut Wasm)&lt;/strong> muncul.&lt;/p>
&lt;p>Artikel ini akan membahas secara mendalam mulai dari dasar-dasar WebAssembly, cara menghasilkan Wasm dari dua bahasa pemrograman sistem yang kuat, yaitu C++ (menggunakan Emscripten) dan Rust (menggunakan &lt;code>wasm-pack&lt;/code>), hingga langkah-langkah detail dan struktur internal untuk mengintegrasikannya dengan lingkungan JavaScript. Lebih jauh, kita akan mengeksplorasi manajemen batas memori (memory boundaries), cara melewatkan data kompleks seperti string dan array, overhead performa, hingga format biner Wasm (&lt;code>.wasm&lt;/code>).&lt;/p>
&lt;h2 id="2-gambaran-umum-dan-arsitektur-webassembly-wasm">2. Gambaran Umum dan Arsitektur WebAssembly (Wasm)
&lt;/h2>&lt;p>WebAssembly adalah format instruksi biner untuk mesin virtual berbasis stack. Ia dirancang sebagai &amp;ldquo;target kompilasi portabel&amp;rdquo; yang dapat dikompilasi dari bahasa seperti C/C++, Rust, Go, Zig, dll., dengan tujuan untuk dieksekusi pada kecepatan yang mendekati native di browser web.&lt;/p>
&lt;p>Diagram berikut menunjukkan gambaran umum alur toolchain dari pembuatan WebAssembly menggunakan C++ dan Rust, hingga dieksekusi di dalam browser.&lt;/p>
&lt;div class="mermaid">graph TD
A["Kode Sumber C++ (.cpp)"] --> B["Emscripten (clang/LLVM)"]
B --> C["Output .wasm"]
B --> D["Output Glue JS"]
E["Kode Sumber Rust (.rs)"] --> F["cargo / rustc / LLVM"]
F --> G["wasm-bindgen / wasm-pack"]
G --> H["Output .wasm"]
G --> I["Output JS Wrappers"]
C --> J["Browser (V8 / SpiderMonkey / JavaScriptCore)"]
D --> J
H --> J
I --> J&lt;/div>
&lt;p>Wasm tidak dirancang untuk menggantikan JavaScript. Ia dirancang untuk bekerja bersama JavaScript, memanfaatkan kekuatan masing-masing dengan mengalihkan tugas-tugas komputasi berat ke Wasm.&lt;/p>
&lt;h2 id="3-tantangan-matematis-menghitung-himpunan-mandelbrot">3. Tantangan Matematis: Menghitung Himpunan Mandelbrot
&lt;/h2>&lt;p>Dalam artikel ini, kita akan mengimplementasikan algoritma penggambaran &amp;ldquo;Himpunan Mandelbrot (Mandelbrot set)&amp;rdquo;, yang memberikan beban tinggi pada CPU, menggunakan C++ dan Rust.&lt;/p>
&lt;p>Himpunan Mandelbrot didefinisikan oleh relasi perulangan kompleks berikut:&lt;/p>
$$ z_{n+1} = z_n^2 + c $$
&lt;p>Di sini, $z$ dan $c$ adalah bilangan kompleks, dan komputasi dimulai dari $z_0 = 0$. Untuk suatu bilangan kompleks $c$, himpunan $c$ yang nilai absolut $z_n$-nya tidak menyimpang (divergen) ketika perhitungan diulang tak terhingga kali disebut Himpunan Mandelbrot. Umumnya, saat menghitung di komputer, deret dianggap divergen jika memenuhi kondisi berikut:&lt;/p>
$$ |z_n| > 2 $$
&lt;p>Yaitu, untuk bagian real $x$ dan imajiner $y$, kita menentukan apakah kondisi berikut terpenuhi hingga jumlah perulangan maksimum (misalnya $N = 1000$):&lt;/p>
$$ x^2 + y^2 > 4 $$
&lt;h2 id="4-pendekatan-dengan-c-dan-emscripten">4. Pendekatan dengan C++ dan Emscripten
&lt;/h2>&lt;p>Emscripten adalah toolchain kompilator berbasis LLVM dan merupakan standar de facto untuk mengkompilasi kode C/C++ menjadi WebAssembly. Ia menyediakan runtime yang kuat yang mengemulasi panggilan sistem POSIX dengan API browser (Web API).&lt;/p>
&lt;h3 id="kode-implementasi-c">Kode Implementasi C++
&lt;/h3>&lt;p>Kode C++ di bawah ini menghitung Himpunan Mandelbrot dengan lebar dan tinggi yang ditentukan, lalu menyimpan hasilnya (jumlah iterasi tiap piksel) dalam array satu dimensi.&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">// Menentukan linkage C agar dapat dipanggil dari 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">// Mengembalikan pointer ke buffer yang menyimpan hasil perhitungan
&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">// Mengalokasikan buffer sebagai variabel statis (untuk penyederhanaan)
&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">// Fungsi untuk melepaskan memori (jika diperlukan)
&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="kompilasi-dan-pemanggilan-dari-javascript">Kompilasi dan Pemanggilan dari JavaScript
&lt;/h3>&lt;p>Kita akan mengkompilasi kode ini menggunakan Emscripten.&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>Di sisi JavaScript, kita memuat glue code yang dihasilkan oleh Emscripten (&lt;code>mandelbrot.js&lt;/code>) dan memanggilnya menggunakan WebAssembly API seperti berikut.&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">// Memanggil fungsi C++ dan mendapatkan pointernya
&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">// Nama fungsi 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">// Tipe nilai kembalian (pointer adalah number)
&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">// Tipe argumen
&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">// Membaca data array secara langsung dari linear memory (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;Perhitungan selesai. Data piksel pertama: &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-pendekatan-dengan-rust-dan-wasm-pack">5. Pendekatan dengan Rust dan &lt;code>wasm-pack&lt;/code>
&lt;/h2>&lt;p>Rust menyediakan dukungan kelas satu untuk WebAssembly, dan menggunakan alat &lt;code>wasm-bindgen&lt;/code> serta &lt;code>wasm-pack&lt;/code> memungkinkan interaksi tingkat tinggi antara JavaScript dan Rust. Sementara pendekatan Emscripten &amp;ldquo;membawa runtime besar C/C++ ke browser,&amp;rdquo; pendekatan &lt;code>wasm-pack&lt;/code> dari Rust &amp;ldquo;hanya menghasilkan binding (JS glue code) minimal yang diperlukan.&amp;rdquo;&lt;/p>
&lt;h3 id="kode-implementasi-rust">Kode Implementasi Rust
&lt;/h3>&lt;p>Buat proyek Cargo, dan tentukan &lt;code>cdylib&lt;/code> dan &lt;code>wasm-bindgen&lt;/code> di &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>Selanjutnya, tulis implementasinya di &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="kompilasi-dan-pemanggilan-dari-javascript-1">Kompilasi dan Pemanggilan dari JavaScript
&lt;/h3>&lt;p>Build menggunakan perintah &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>Impor paket yang dihasilkan dari JavaScript. Berkat &lt;code>wasm-bindgen&lt;/code>, &lt;code>Vec&amp;lt;i32&amp;gt;&lt;/code> milik Rust secara otomatis dikonversi menjadi &lt;code>Int32Array&lt;/code> milik JavaScript (menyembunyikan manipulasi pointer).&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">// Inisialisasi modul 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">// Dapat menerima hasil langsung sebagai array 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;Perhitungan selesai. Data piksel pertama: &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-lebih-dalam-batas-memori-dan-melewatkan-tipe-data">6. Lebih Dalam: Batas Memori dan Melewatkan Tipe Data
&lt;/h2>&lt;p>Salah satu konsep paling penting dalam WebAssembly adalah &amp;ldquo;Memori Linear (Linear Memory)&amp;rdquo;. Kode Wasm tidak dapat mengakses ruang memori host (browser) secara langsung, melainkan dialokasikan sebuah &lt;code>ArrayBuffer&lt;/code> raksasa yang terisolasi. Inilah yang disebut memori linear.&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant JS as "Lingkungan JavaScript"
participant Wasm as "Runtime WebAssembly"
participant Mem as "Memori Linear (ArrayBuffer)"
JS->>Wasm: "Panggil calculate(10, 20)"
note over JS,Wasm: "Tipe Primitif (int, float) diteruskan langsung via Registers/Stack"
Wasm-->>JS: "Kembalikan 30"
note over JS, Mem: "Untuk data kompleks (Strings, Arrays)"
JS->>Mem: "Tulis String ke Memori"
JS->>Wasm: "Panggil process_string(pointer, length)"
Wasm->>Mem: "Baca dari pointer"
Wasm->>Mem: "Tulis hasil ke pointer baru"
Wasm-->>JS: "Kembalikan pointer &amp; length baru"
JS->>Mem: "Baca data hasil dari memori"&lt;/div>
&lt;h3 id="cara-melewatkan-string-dan-array">Cara Melewatkan String dan Array
&lt;/h3>&lt;p>Bilangan bulat dan pecahan (floating point) (&lt;code>i32&lt;/code>, &lt;code>i64&lt;/code>, &lt;code>f32&lt;/code>, &lt;code>f64&lt;/code>) dapat diteruskan langsung sebagai nilai ke fungsi Wasm. Namun, tipe kompleks seperti string, array, atau struktur data tidak bisa dilewatkan secara langsung pada signatur fungsi Wasm.&lt;/p>
&lt;p>&lt;strong>Kasus Emscripten&lt;/strong>:&lt;/p>
&lt;ol>
&lt;li>Panggil &lt;code>Module._malloc&lt;/code> di sisi JS untuk mengalokasikan memori linear di sisi Wasm.&lt;/li>
&lt;li>JS menulis data ke alamat memori yang dialokasikan (pointer) menggunakan &lt;code>Module.HEAPU8.set()&lt;/code>, dll.&lt;/li>
&lt;li>Pointer dilewatkan ke fungsi C++.&lt;/li>
&lt;li>Setelah dihitung, JS membaca hasil dari pointer, dan akhirnya memanggil &lt;code>Module._free&lt;/code>.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Kasus wasm-bindgen (Rust)&lt;/strong>:
Alur manajemen memori yang rumit di atas disembunyikan sepenuhnya di dalam glue code (JS wrapper) yang dihasilkan secara otomatis. Ketika Anda melewatkan &lt;code>String&lt;/code> atau &lt;code>Array&lt;/code> sederhana dari sisi JS ke fungsi Rust, serangkaian proses seperti alokasi buffer (setara dengan &lt;code>malloc&lt;/code>), penyalinan, pengiriman pointer, dan pelepasan memori akan dilakukan secara otomatis di latar belakang.&lt;/p>
&lt;h2 id="7-overhead-performa-dan-optimasi">7. Overhead Performa dan Optimasi
&lt;/h2>&lt;p>WebAssembly dapat dieksekusi dengan kecepatan mendekati native, tetapi ada overhead pada &amp;ldquo;komunikasi (Interop) yang melintasi batas antara JavaScript dan WebAssembly&amp;rdquo;.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Overhead Pemanggilan&lt;/strong>: Biaya peralihan bagi engine JavaScript untuk memanggil fungsi Wasm. Meskipun saat ini telah banyak dioptimalkan, memanggil fungsi yang sangat ringan puluhan ribu kali per frame harus dihindari.&lt;/li>
&lt;li>&lt;strong>Biaya Salin Memori&lt;/strong>: Ketika melewatkan string atau array ke Wasm, data disalin dari memori yang dikelola oleh garbage collection JS ke memori linear Wasm (ArrayBuffer). Jika melewatkan data berukuran besar, diperlukan desain &amp;ldquo;zero-copy&amp;rdquo; di mana data dibangun dari awal di memori Wasm, dan sisi JS mengaksesnya melalui tampilan TypedArray (seperti &lt;code>Uint8Array&lt;/code>).&lt;/li>
&lt;/ul>
&lt;p>Misalnya, pada engine game atau engine fisika, arsitektur umum yang digunakan adalah menyimpan seluruh status (state) di dalam memori linear Wasm, dan JavaScript hanya menangani pemicu untuk &amp;ldquo;perbarui&amp;rdquo; pada tiap frame dan penggambaran layar (pemanggilan WebGL/WebGPU API).&lt;/p>
&lt;h2 id="8-anatomi-format-biner-webassembly-wasm">8. Anatomi Format Biner WebAssembly (.wasm)
&lt;/h2>&lt;p>Sekarang, mari kita lihat struktur internal dari file &lt;code>.wasm&lt;/code> yang dihasilkan oleh kompilator. Biner Wasm terdiri dari kumpulan blok logis yang disebut &amp;ldquo;section&amp;rdquo; yang dirancang untuk mementingkan ekstensibilitas dan kecepatan parsing.&lt;/p>
&lt;div class="mermaid">graph TD
Root["Biner Wasm (.wasm)"] --> Magic["Angka Ajaib: '\0asm' (0x00 0x61 0x73 0x6D)"]
Root --> Version["Versi: 1 (0x01 0x00 0x00 0x00)"]
Root --> Sections["Sections"]
Sections --> S1["1: Type Section (Signatur Fungsi)"]
Sections --> S2["2: Import Section (Fungsi JS untuk Diimpor)"]
Sections --> S3["3: Function Section (Deklarasi Fungsi)"]
Sections --> S4["4: Table Section (Pointer Fungsi)"]
Sections --> S5["5: Memory Section (Ukuran Memori Linear)"]
Sections --> S7["7: Export Section (Fungsi yang diekspos ke JS)"]
Sections --> S10["10: Code Section (Instruksi Bytecode Wasm)"]
Sections --> S11["11: Data Section (String/Konstanta Statis)"]&lt;/div>
&lt;p>Angka ajaib (magic number) file ini selalu dimulai dengan &lt;code>0x00 0x61 0x73 0x6D&lt;/code> (&lt;code>\0asm&lt;/code>). Setiap bagian (section) yang mengikutinya memiliki ID masing-masing.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Type Section&lt;/strong>: Mendefinisikan semua signatur fungsi (tipe argumen dan nilai kembalian) yang digunakan.&lt;/li>
&lt;li>&lt;strong>Import Section&lt;/strong>: Daftar fungsi dan memori yang disediakan dari lingkungan JavaScript ke Wasm. Misalnya, jika memanggil &lt;code>console.log&lt;/code> dari C++, deklarasinya ada di sini.&lt;/li>
&lt;li>&lt;strong>Code Section&lt;/strong>: Berisi instruksi bytecode aktual (seperti &lt;code>i32.add&lt;/code>, &lt;code>call&lt;/code>, dan &lt;code>loop&lt;/code>). Karena merupakan stack machine, formatnya adalah dengan menaruh operand di stack lalu memanggil instruksi operasi.&lt;/li>
&lt;li>&lt;strong>Data Section&lt;/strong>: Literal string statis dan data inisialisasi yang didefinisikan dalam kode C++ atau Rust dimuat ke dalam memori linear dari bagian (section) ini.&lt;/li>
&lt;/ul>
&lt;p>Engine Wasm pada browser dapat mencapai peningkatan kecepatan proses startup yang dramatis dengan mengkompilasi bagian-bagian ini secara streaming (menerjemahkan ke bahasa mesin secara paralel sambil mengunduhnya).&lt;/p>
&lt;h2 id="9-c-vs-rust-mana-yang-harus-dipilih">9. C++ vs Rust: Mana yang Harus Dipilih?
&lt;/h2>&lt;p>Dalam pembuatan WebAssembly, memilih antara C++ dan Rust sangat bergantung pada persyaratan proyek dan aset yang sudah ada.&lt;/p>
&lt;p>&lt;strong>Kasus memilih C++ / Emscripten&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>Ingin melakukan porting library C/C++ yang sudah ada (FFmpeg, OpenCV, SQLite, dll.) ke browser.&lt;/li>
&lt;li>Proyek porting game yang ingin menggunakan fungsi yang mengonversi API grafis seperti OpenGL ke WebGL (lapisan emulasi GL Emscripten) apa adanya.&lt;/li>
&lt;li>Membutuhkan fungsi OS yang divirtualisasi, seperti emulasi sistem file (MEMFS).&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Kasus memilih Rust / wasm-pack&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>Mengembangkan modul baru berperforma tinggi dari nol sebagai bagian dari aplikasi web.&lt;/li>
&lt;li>Menginginkan integrasi yang kuat dan aman tipe (type-safe) dengan ekosistem JavaScript (Modul NPM atau TypeScript).&lt;/li>
&lt;li>Menginginkan ukuran biner yang relatif lebih kecil dan manajemen memori yang aman (model kepemilikan Rust).&lt;/li>
&lt;li>Ingin menikmati toolchain modern seperti manajemen dependensi melalui Cargo.&lt;/li>
&lt;/ul>
&lt;h2 id="10-kesimpulan">10. Kesimpulan
&lt;/h2>&lt;p>WebAssembly adalah teknologi inovatif untuk menjalankan pemrosesan berat di dalam browser. Baik pendekatan porting full-stack menggunakan C++ dan Emscripten maupun pendekatan modular yang terikat kuat dengan JavaScript menggunakan Rust dan wasm-bindgen, masing-masing memiliki keunggulannya sendiri.&lt;/p>
&lt;p>Untuk perhitungan seperti Himpunan Mandelbrot, Wasm diharapkan dapat meningkatkan kecepatan berkali-kali lipat hingga puluhan kali lipat dibandingkan dengan JavaScript biasa. Namun, performa yang sebenarnya tidak dapat dicapai jika Anda tidak memahami mekanisme batas memori antara Wasm dan JS dengan benar serta merancang sistem untuk menghindari penyalinan memori yang tidak perlu.&lt;/p>
&lt;p>Melalui artikel ini, kami harap Anda dapat memahami alur kompilasi Wasm dari C++ dan Rust untuk dijalankan di browser, serta memahami arsitektur di baliknya. Dalam pengembangan aplikasi web generasi berikutnya, WebAssembly pastinya akan menjadi senjata yang sangat ampuh.&lt;/p></description></item></channel></rss>