<?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/ar/tags/wasm/</link><description>Recent content in Wasm on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ar</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 10:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/ar/tags/wasm/index.xml" rel="self" type="application/rss+xml"/><item><title>إخراج WebAssembly (Wasm) من C++ و Rust وتشغيله في المتصفح</title><link>http://kenji.blog/ar/p/webassembly-wasm-from-cpp-and-rust/</link><pubDate>Sat, 12 Sep 2026 10:00:00 +0900</pubDate><guid>http://kenji.blog/ar/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 إخراج WebAssembly (Wasm) من C++ و Rust وتشغيله في المتصفح" />&lt;h2 id="1-مقدمة">1. مقدمة
&lt;/h2>&lt;p>في تطوير الويب الحديث، أثبتت JavaScript (و TypeScript) مكانتها لفترة طويلة باعتبارها لغة البرمجة الوحيدة التي تعمل في المتصفح. ومع ذلك، في السنوات الأخيرة، زاد الطلب على تنفيذ حسابات أكثر تقدمًا في المتصفح نفسه، مثل معالجة الصور، وترميز الفيديو، والألعاب ثلاثية الأبعاد، والمحاكاة الفيزيائية. وهنا ظهر &lt;strong>WebAssembly (المعروف باسم Wasm)&lt;/strong>.&lt;/p>
&lt;p>تبدأ هذه المقالة بأساسيات WebAssembly، وتشرح الإجراءات والهياكل الداخلية بالتفصيل لإخراج Wasm من لغتين قويتين لبرمجة النظم: C++ (باستخدام Emscripten) و Rust (باستخدام &lt;code>wasm-pack&lt;/code>)، وربطها ببيئة JavaScript. بالإضافة إلى ذلك، سنتعمق بشكل شامل في إدارة حدود الذاكرة، وطرق تمرير البيانات المعقدة مثل السلاسل النصية والمصفوفات، والأعباء الإضافية على الأداء، وصولاً إلى التنسيق الثنائي لـ Wasm (&lt;code>.wasm&lt;/code>).&lt;/p>
&lt;h2 id="2-نظرة-عامة-على-webassembly-wasm-وبنيته">2. نظرة عامة على WebAssembly (Wasm) وبنيته
&lt;/h2>&lt;p>WebAssembly هو تنسيق أوامر ثنائي لآلة افتراضية تعتمد على المكدس (Stack-based virtual machine). تم تصميمه كـ &amp;ldquo;هدف تجميع محمول&amp;rdquo; يمكن التحويل البرمجي إليه من لغات مثل C/C++، Rust، Go، و Zig، ويهدف إلى التنفيذ بسرعة تقترب من السرعة الأصلية على متصفحات الويب.&lt;/p>
&lt;p>يوضح الشكل التالي التدفق العام لسلسلة الأدوات (toolchain) بدءًا من توليد WebAssembly من C++ و Rust حتى تنفيذه في المتصفح.&lt;/p>
&lt;div class="mermaid">graph TD
A["كود المصدر C++ (.cpp)"] --> B["Emscripten (clang/LLVM)"]
B --> C["إخراج .wasm"]
B --> D["إخراج Glue JS"]
E["كود المصدر Rust (.rs)"] --> F["cargo / rustc / LLVM"]
F --> G["wasm-bindgen / wasm-pack"]
G --> H["إخراج .wasm"]
G --> I["إخراج JS Wrappers"]
C --> J["المتصفح (V8 / SpiderMonkey / JavaScriptCore)"]
D --> J
H --> J
I --> J&lt;/div>
&lt;p>Wasm ليس بديلاً عن JavaScript. تم تصميمه ليعمل جنبًا إلى جنب مع JavaScript، ويستفيد من نقاط قوة كليهما عن طريق تفريغ المهام ذات الحمل الحسابي الثقيل إلى Wasm.&lt;/p>
&lt;h2 id="3-تحدي-رياضي-حساب-مجموعة-ماندلبروت">3. تحدي رياضي: حساب مجموعة ماندلبروت
&lt;/h2>&lt;p>في هذه المقالة، سنقوم بالتنفيذ بلغة C++ و Rust باستخدام خوارزمية رسم &amp;ldquo;مجموعة ماندلبروت (Mandelbrot set)&amp;rdquo; التي تضع حملاً عاليًا على وحدة المعالجة المركزية (CPU).&lt;/p>
&lt;p>يتم تعريف مجموعة ماندلبروت بواسطة صيغة التكرار المعقدة التالية:&lt;/p>
$$ z_{n+1} = z_n^2 + c $$
&lt;p>حيث $z$ و $c$ أعداد مركبة، ويبدأ الحساب من $z_0 = 0$. بالنسبة لعدد مركب معين $c$، فإن مجموعة ماندلبروت هي مجموعة من $c$ حيث لا تتباعد القيمة المطلقة لـ $z_n$ عند تكرار الحساب بشكل لا نهائي. بشكل عام، عند الحساب على جهاز كمبيوتر، يعتبر متباعدًا تحت الشروط التالية:&lt;/p>
$$ |z_n| > 2 $$
&lt;p>بمعنى آخر، بالنسبة للجزء الحقيقي $x$ والجزء التخيلي $y$، يتم تحديد ما إذا كان يفي بالشرط التالي حتى أقصى عدد من الحلقات (على سبيل المثال $N = 1000$):&lt;/p>
$$ x^2 + y^2 > 4 $$
&lt;h2 id="4-النهج-باستخدام-c-و-emscripten">4. النهج باستخدام C++ و Emscripten
&lt;/h2>&lt;p>Emscripten هي سلسلة أدوات مترجم تعتمد على LLVM وهي المعيار الفعلي لتجميع كود C/C++ إلى WebAssembly. إنها توفر وقت تشغيل (runtime) قوي يحاكي مكالمات نظام POSIX باستخدام واجهات برمجة تطبيقات المتصفح (Web API).&lt;/p>
&lt;h3 id="كود-تنفيذ-c">كود تنفيذ C++
&lt;/h3>&lt;p>يقوم كود C++ التالي بحساب مجموعة ماندلبروت للعرض والارتفاع المحددين، ويخزن النتائج (عدد التكرارات لكل بكسل) في مصفوفة أحادية البعد.&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">// تحديد ارتباط C ليتم استدعاؤه من 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">// إرجاع مؤشر إلى المخزن المؤقت الذي يخزن نتائج الحساب
&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">// تأمين المخزن المؤقت كمتغير ثابت (للتبسيط)
&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">// وظيفة تحرير الذاكرة (عند الضرورة)
&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="الترجمة-والاستدعاء-من-javascript">الترجمة والاستدعاء من JavaScript
&lt;/h3>&lt;p>نستخدم 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>على جانب JavaScript، نقوم بتحميل كود الغراء (&lt;code>mandelbrot.js&lt;/code>) الذي تم إنشاؤه بواسطة Emscripten، واستدعائه باستخدام WebAssembly API على النحو التالي:&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">// استدعاء دالة C++ والحصول على المؤشر
&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">// اسم دالة 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">// نوع القيمة المرجعة (المؤشر هو رقم)
&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">// أنواع المتغيرات
&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">// قراءة بيانات المصفوفة مباشرة من الذاكرة الخطية (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;اكتمل الحساب. بيانات البكسل الأول: &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-النهج-باستخدام-rust-و-wasm-pack">5. النهج باستخدام Rust و &lt;code>wasm-pack&lt;/code>
&lt;/h2>&lt;p>توفر Rust دعمًا من الدرجة الأولى لـ WebAssembly، وباستخدام أدوات &lt;code>wasm-bindgen&lt;/code> و &lt;code>wasm-pack&lt;/code>، يمكن تحقيق تكامل متقدم بين JavaScript و Rust. في حين أن Emscripten يتبع نهج &amp;ldquo;إحضار وقت تشغيل C/C++ الضخم إلى المتصفح&amp;rdquo;، فإن &lt;code>wasm-pack&lt;/code> في Rust يتبع نهج &amp;ldquo;إنشاء الروابط الضرورية فقط (كود الغراء JS)&amp;rdquo;.&lt;/p>
&lt;h3 id="كود-تنفيذ-rust">كود تنفيذ Rust
&lt;/h3>&lt;p>قم بإنشاء مشروع Cargo وحدد &lt;code>cdylib&lt;/code> و &lt;code>wasm-bindgen&lt;/code> في &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>بعد ذلك، اكتب التنفيذ في &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="الترجمة-والاستدعاء-من-javascript-1">الترجمة والاستدعاء من JavaScript
&lt;/h3>&lt;p>قم بالبناء باستخدام أمر &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>استورد الحزمة التي تم إنشاؤها من JavaScript. بفضل &lt;code>wasm-bindgen&lt;/code>، يتم تحويل &lt;code>Vec&amp;lt;i32&amp;gt;&lt;/code> في Rust تلقائيًا إلى &lt;code>Int32Array&lt;/code> في JavaScript (إخفاء عمليات المؤشر).&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">// تهيئة وحدة 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">// يمكن استلام النتيجة مباشرة كمصفوفة 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;اكتمل الحساب. بيانات البكسل الأول: &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-الغوص-العميق-حدود-الذاكرة-وتمرير-أنواع-البيانات">6. الغوص العميق: حدود الذاكرة وتمرير أنواع البيانات
&lt;/h2>&lt;p>أحد أهم المفاهيم في WebAssembly هو &amp;ldquo;الذاكرة الخطية (Linear Memory)&amp;rdquo;. لا يمكن لكود Wasm الوصول المباشر إلى مساحة ذاكرة المضيف (المتصفح)، وبدلاً من ذلك يتم تخصيص &lt;code>ArrayBuffer&lt;/code> معزول وضخم. هذه هي الذاكرة الخطية.&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant JS as "بيئة JavaScript"
participant Wasm as "وقت تشغيل WebAssembly"
participant Mem as "الذاكرة الخطية (ArrayBuffer)"
JS->>Wasm: "استدعاء calculate(10, 20)"
note over JS,Wasm: "تُمرر الأوليات (int, float) مباشرة عبر السجلات/المكدس"
Wasm-->>JS: "إرجاع 30"
note over JS, Mem: "للبيانات المعقدة (السلاسل النصية، المصفوفات)"
JS->>Mem: "كتابة سلسلة نصية إلى الذاكرة"
JS->>Wasm: "استدعاء process_string(pointer, length)"
Wasm->>Mem: "القراءة من المؤشر"
Wasm->>Mem: "كتابة النتيجة إلى مؤشر جديد"
Wasm-->>JS: "إرجاع مؤشر جديد وطول"
JS->>Mem: "قراءة بيانات النتيجة من الذاكرة"&lt;/div>
&lt;h3 id="كيفية-تمرير-السلاسل-النصية-والمصفوفات">كيفية تمرير السلاسل النصية والمصفوفات
&lt;/h3>&lt;p>يمكن تمرير الأعداد الصحيحة وأرقام الفاصلة العائمة (&lt;code>i32&lt;/code>, &lt;code>i64&lt;/code>, &lt;code>f32&lt;/code>, &lt;code>f64&lt;/code>) مباشرة كقيم إلى وظائف Wasm. ومع ذلك، لا يمكن تمرير الأنواع المعقدة مثل السلاسل النصية، المصفوفات، والهياكل (structs) مباشرة كتوقيعات (signatures) لوظيفة Wasm.&lt;/p>
&lt;p>&lt;strong>في حالة Emscripten&lt;/strong>:&lt;/p>
&lt;ol>
&lt;li>يستدعي جانب JS &lt;code>Module._malloc&lt;/code> لتخصيص مساحة ذاكرة خطية في جانب Wasm.&lt;/li>
&lt;li>يكتب JS البيانات في عنوان الذاكرة المخصص (المؤشر) باستخدام أدوات مثل &lt;code>Module.HEAPU8.set()&lt;/code>.&lt;/li>
&lt;li>يُمرر المؤشر إلى وظيفة C++.&lt;/li>
&lt;li>بعد الحساب، يقرأ JS النتيجة من المؤشر، وأخيرًا يستدعي &lt;code>Module._free&lt;/code>.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>في حالة wasm-bindgen (Rust)&lt;/strong>:
يتم إخفاء سير عمل إدارة الذاكرة المعقد المذكور أعلاه بالكامل داخل كود الغراء (غلاف JS) الذي يتم إنشاؤه تلقائيًا. عندما تمرر مجرد &lt;code>String&lt;/code> أو &lt;code>Array&lt;/code> من JS إلى دالة Rust، يتم تلقائيًا في الخلفية تأمين المخزن المؤقت (ما يعادل &lt;code>malloc&lt;/code>)، النسخ، تمرير المؤشر، وتحرير الذاكرة.&lt;/p>
&lt;h2 id="7-الأعباء-الإضافية-على-الأداء-والتحسين">7. الأعباء الإضافية على الأداء والتحسين
&lt;/h2>&lt;p>يمكن تنفيذ WebAssembly بسرعة تقترب من السرعة الأصلية، ولكن يوجد عبء إضافي (overhead) في &amp;ldquo;الاتصال عبر الحدود بين JavaScript و WebAssembly (Interop)&amp;rdquo;.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>عبء الاستدعاء&lt;/strong>: تكلفة التبديل لمحرك JavaScript لاستدعاء وظيفة Wasm. على الرغم من أنه تم تحسينه بشكل كبير حاليًا، إلا أنه يجب تجنب تصميم يستدعي وظيفة خفيفة جدًا عشرات الآلاف من المرات في كل إطار.&lt;/li>
&lt;li>&lt;strong>تكلفة نسخ الذاكرة&lt;/strong>: عند تمرير السلاسل النصية أو المصفوفات إلى Wasm، يحدث نسخ للبيانات من الذاكرة المُدارة بواسطة جمع القمامة (Garbage Collection) في JS إلى الذاكرة الخطية لـ Wasm (ArrayBuffer). عند تمرير كميات كبيرة من البيانات، يتطلب الأمر تصميمًا &amp;ldquo;خاليًا من النسخ (zero-copy)&amp;rdquo; حيث يتم بناء البيانات في ذاكرة Wasm منذ البداية، ويصل إليها جانب JS من خلال عرض TypedArray (مثل &lt;code>Uint8Array&lt;/code>).&lt;/li>
&lt;/ul>
&lt;p>على سبيل المثال، في محركات الألعاب ومحركات الفيزياء، من الشائع الاحتفاظ بكل الحالة (state) داخل الذاكرة الخطية لـ Wasm، بينما تكون JavaScript مسؤولة فقط عن مُشغل &amp;ldquo;التحديث&amp;rdquo; لكل إطار ورسم الشاشة (استدعاء WebGL/WebGPU API).&lt;/p>
&lt;h2 id="8-تشريح-التنسيق-الثنائي-لـ-webassembly-wasm">8. تشريح التنسيق الثنائي لـ WebAssembly (.wasm)
&lt;/h2>&lt;p>دعونا الآن نلقي نظرة على البنية الداخلية لملف &lt;code>.wasm&lt;/code> الذي ينتجه المترجم. يتكون الملف الثنائي لـ Wasm من مجموعة من الكتل المنطقية تسمى &amp;ldquo;أقسام (Sections)&amp;rdquo; مع التركيز على قابلية التوسعة وسرعة التحليل.&lt;/p>
&lt;div class="mermaid">graph TD
Root["الملف الثنائي لـ Wasm (.wasm)"] --> Magic["الرقم السحري: '\0asm' (0x00 0x61 0x73 0x6D)"]
Root --> Version["الإصدار: 1 (0x01 0x00 0x00 0x00)"]
Root --> Sections["الأقسام"]
Sections --> S1["1: قسم النوع (توقيعات الوظائف)"]
Sections --> S2["2: قسم الاستيراد (وظائف JS المراد استيرادها)"]
Sections --> S3["3: قسم الوظيفة (إعلانات الوظائف)"]
Sections --> S4["4: قسم الجدول (مؤشرات الوظائف)"]
Sections --> S5["5: قسم الذاكرة (حجم الذاكرة الخطية)"]
Sections --> S7["7: قسم التصدير (الوظائف المكشوفة لـ JS)"]
Sections --> S10["10: قسم الكود (تعليمات الكود البايتي لـ Wasm)"]
Sections --> S11["11: قسم البيانات (السلاسل النصية/الثوابت الثابتة)"]&lt;/div>
&lt;p>يبدأ الرقم السحري للملف دائمًا بـ &lt;code>0x00 0x61 0x73 0x6D&lt;/code> (&lt;code>\0asm&lt;/code>). كل قسم يليه له معرّف (ID) خاص به.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>قسم النوع (Type Section)&lt;/strong>: يُعرف جميع توقيعات الوظائف المستخدمة (أنواع الوسائط والقيم المرجعة).&lt;/li>
&lt;li>&lt;strong>قسم الاستيراد (Import Section)&lt;/strong>: قائمة بالوظائف والذاكرة المقدمة لـ Wasm من بيئة JavaScript. على سبيل المثال، إذا تم استدعاء &lt;code>console.log&lt;/code> من C++، فسيتم الإعلان عنه هنا.&lt;/li>
&lt;li>&lt;strong>قسم الكود (Code Section)&lt;/strong>: يخزن تعليمات الكود البايتي الفعلية (مثل &lt;code>i32.add&lt;/code>، &lt;code>call&lt;/code>، &lt;code>loop&lt;/code>). نظرًا لأنه آلة تعتمد على المكدس، فإنه يضع المعاملات على المكدس ويستدعي تعليمات العملية.&lt;/li>
&lt;li>&lt;strong>قسم البيانات (Data Section)&lt;/strong>: يتم تحميل القيم الحرفية للسلاسل الثابتة أو بيانات التهيئة المحددة في كود C++ أو Rust إلى الذاكرة الخطية من هذا القسم.&lt;/li>
&lt;/ul>
&lt;p>من خلال البث والترجمة (Streaming Compilation) (الترجمة إلى لغة الآلة بالتوازي أثناء التنزيل) لهذه الأقسام، تحقق محركات Wasm في المتصفح سرعة تشغيل أسرع بشكل كبير.&lt;/p>
&lt;h2 id="9-c-مقابل-rust-أيهما-يجب-أن-تختار">9. C++ مقابل Rust: أيهما يجب أن تختار؟
&lt;/h2>&lt;p>عند إنشاء WebAssembly، يعتمد الاختيار بين C++ و Rust بشكل كبير على متطلبات المشروع والأصول الحالية.&lt;/p>
&lt;p>&lt;strong>الحالات التي يجب فيها اختيار C++ / Emscripten&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>عندما تريد ترحيل (porting) مكتبات C/C++ الحالية (مثل FFmpeg، OpenCV، SQLite) إلى المتصفح.&lt;/li>
&lt;li>مشاريع ترحيل الألعاب التي تريد فيها استخدام القدرة على تحويل واجهات برمجة تطبيقات الرسومات مثل OpenGL إلى WebGL (طبقة محاكاة GL في Emscripten) كما هي.&lt;/li>
&lt;li>عندما تكون ميزات نظام التشغيل الافتراضية ضرورية، مثل محاكاة نظام الملفات (MEMFS).&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>الحالات التي يجب فيها اختيار Rust / wasm-pack&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>عند تطوير وحدة نمطية جديدة عالية الأداء من الصفر كجزء من تطبيق ويب.&lt;/li>
&lt;li>عندما تريد تكاملًا قويًا وآمنًا من حيث النوع مع نظام JavaScript البيئي (وحدات NPM أو TypeScript).&lt;/li>
&lt;li>عندما تحتاج إلى حجم ثنائي صغير نسبيًا وإدارة ذاكرة آمنة (نموذج الملكية في Rust).&lt;/li>
&lt;li>عندما ترغب في الاستفادة من سلسلة الأدوات الحديثة مثل إدارة التبعيات بواسطة Cargo.&lt;/li>
&lt;/ul>
&lt;h2 id="10-الخلاصة">10. الخلاصة
&lt;/h2>&lt;p>يعد WebAssembly تقنية مبتكرة لتنفيذ العمليات الثقيلة حسابيًا داخل المتصفح. كلا النهجين - نهج الترحيل الكامل باستخدام C++ و Emscripten، والنهج المعياري المرتبط بإحكام بـ JavaScript باستخدام Rust و wasm-bindgen - لهما نقاط قوة خاصة بهما.&lt;/p>
&lt;p>في الحسابات مثل مجموعة ماندلبروت، يمكن أن يوفر Wasm زيادة في السرعة تتراوح من عدة أضعاف إلى عشرات الأضعاف مقارنة بـ JavaScript وحدها. ومع ذلك، لا يمكن استخراج الأداء الحقيقي إلا إذا تم فهم آلية حدود الذاكرة بين Wasm و JS بشكل صحيح، وتم تصميم النظام لتجنب النسخ غير الضروري للذاكرة.&lt;/p>
&lt;p>نأمل أن تعمق هذه المقالة فهمك للتدفق الشامل لإخراج Wasm من C++ و Rust وتشغيله في المتصفح، والبنية الكامنة وراءه. في تطوير تطبيقات الويب من الجيل التالي، سيكون WebAssembly بلا شك سلاحًا قويًا.&lt;/p></description></item></channel></rss>