Wasmtime اجرای WebAssembly خارج از مرورگر!

شروع کار با WebAssembly راکت

WebAssembly به‌طور مستقیم کدنویسی نمی‌شه، بلکه از زبان‌هایی مثل C، ++C یا Rust استفاده می‌کنی و بعد کد رو به WebAssembly کامپایل می‌کنی. دنیا‌ی تکنولوژی همیشه در حال تغییر و پیشرفته و هر روز تکنولوژی‌های جدیدتری میاد. WebAssembly به خاطر ماهیت پویایی که داره، می‌تونه تو این مسیر همراه باشه. مثلاً تو حوزه‌هایی مثل واقعیت افزوده (AR)، واقعیت مجازی (VR)، یادگیری ماشین و اینترنت اشیاء (IoT)، Wasm می‌تونه به عنوان قلب این ادغام‌ها عمل کنه. احتمال داره به زودی شاهد اپلیکیشن‌های وب هوشمندتر، ابزارهای واقعیت افزوده و دستگاه‌های متصل به هم باشیم که همگی از قدرت و کارایی Wasm بهره می‌برن.

سی پلاس پلاس زبانی است که تقریبا در هر پلتفرمی می‌شود از آن استفاده کرد. حال با استفاده از وب اسمبلی، می‌توان از سی پلاس پلاس در دنیای وب نیز استفاده کرد. اسمبلی به صورت کلی‌تر به یکی از زبان‌های سطح پایین گفته می‌شود که نسبت به زبان ماشین خوانایی بالاتری دارد و همچنین بسیار سریع اجرا می‌شود. زبان ماشین چیزی‌ست که پردازنده ما از آن متوجه می‌شود و می‌تواند در نهایت آن را اجرا بکند. بعدش یک سری system call در اختیار وب اسمبلی قرار می‌ده و اونهم بر اساس نیازهای برنامه درحال اجرا اون توابع رو در اختیار برنامه قرار می‌ده. چرا بالا تر گفتم «محیط اجرا» و مستقیم نگفتم مرورگر؟ به خاطر اینکه؛ در هیچ کجا ذکر نشده که «باید حتما مرورگر باشه» و بلکه فکرهایی شده برای اینکه خارج از مرورگر هم بشه از وب اسمبلی استفاده کرد.

برنامه‌های Wasm نمی‌توانند مستقیماً به هیچ چیز خارج از سندباکس دسترسی داشته باشند، از جمله DOM web page که در آن اجرا می‌شوند. هر گونه تعامل با بقیه دستگاه ها باید از ABI مانند رابط سیستم WebAssembly (WASI) استفاده کند. WASI دسترسی کنترل شده ای به فایل ها، شبکه، ساعت سیستم و سایر سرویس های سیستمی که اغلب در برنامه ها مورد نیاز است را فراهم می کند. کد WebAssembly برای بارگذاری ، تجزیه و اجرا سریعتر از جاوا اسکریپت است. هنگامی که WebAssembly توسط یک مرورگر وب استفاده می شود ، هزینه ی بهینه سازی بارگیری ماژول Wasm و راه اندازی آن وجود دارد. برای پروژه‌های بزرگ‌تر Wasm ، این ماژول‌ها می‌توانند تا چندین مگابایت اجرا شوند، بنابراین این تاخیرها می‌توانند در سرعت لود قابل توجه باشند.

مثلا نمی‌تونه یه فایل روی سیستم رو بخونه یا کارای Network سطح پایین تر از Http مثلا TCP و UDP انجام بده. از این دلقک بازی ها که بگذریم یه موقع هایی هست واسه یه کار خاصی پرفورمنس بالایی روی وب می‌خواید و JS پاسخگوی شما نیست اینجا میتونید یه ماژول wasm با یه زبون سطح پایین بنویسید و از JS توابعش رو صدا کنید. حتی یه وقتایی شما فکر می‌کنید برای مرورگرتون JS کد می‌زنید ولی بازم اونو می‌دید به یه کامپایلر تبدیلش می‌کنه به JS و نتیجه رو روی مرورگر اجرا می‌کنید. حالا که برنامه ساده C رو داریم, باید اون رو به wasm کامپایل کنیم. همچنین باید کد JavaScript glue رو تولید کنیم تا برای اجرایش کمکمون کنه. اکثر افراد ماژول های WebAssembly رو در C می نویسند و اونها رو به فایل های wasm.

یعنی شما همون فایل wasm که توی IOS با پردازنده ARM اجرا می‌کنید رو می‌تونید ببرید روی Linux با پردازنده ی X86 هم اجرا کنید. و ماشین مجازی بین wasm و سخت افزار قرار میگیره و ترجمه ها و بهینه سازی های لازم رو انجام میده. فقط فرق wasm و بایت کد Java اینه که Wasm روی مرورگر هم قابل اجرا هست و فقط مخصوص یه زبان طراحی نشده و سازگاری زیادی با انواع زبان های برنامه نویسی با انواع مدل مدیریت حافظه و... مثلا Kotlin قابلیت Multi Threading داره ولی وقتی بخواید برنامه ی multi thread رو که با Kotlin نوشته شده رو به JS کامپایل کنید کامپایلر بهتون خطا میده چون اصلاً JS این موضوع رو ساپورت نمی‌کنه. به‌طور مثال، فرض کن یه برنامه‌نویس یه تابع رو با زبان C++ بنویسه و اون رو با استفاده از ابزاری مثل Emscripten کامپایل کنه.

این حالت در قالب باینری سطح پایین ارائه می‌شود به همین دلیل بسیار اندازه کمی دارد و در اجرا و بارگذاری بسیار سریع است. شما نیازی ندارید که WebAssembly بنویسید بلکه زبان‌های برنامه‌نویسی سطح بالایی را به WebAssembly کامپایل می‌کنید. WebAssembly تو محیط ایزوله (sandbox) مرورگر اجرا می‌شه، ولی این به این معنا نیست که از مشکلات امنیتی به‌طور کامل مصون باشه. به خاطر سطح پایین بودن کدها، ممکنه با نوع جدیدی از حملات سایبری مثل سرریز بافر یا سرریز اعداد صحیح مواجه بشی، که تو زبان‌های سطح بالا مثل جاوااسکریپت کمتر رخ می‌ده. یکی از مشکلات اصلی Wasm اینه که مثل زبان‌هایی مثل جاوااسکریپت، جاوا یا پایتون، سیستم جمع‌آوری خودکار حافظه نداره.

WebAssembly به کد ماشین تبدیل می‌شه که تقریباً به‌طور مستقیم روی سخت‌افزار سیستم اجرا می‌شه و این یعنی عملکرد بهتر و مصرف حافظه کمتر. به‌علاوه، حتی با وجود اینکه به کدهای سطح پایین تبدیل می‌شه، یه فرمت متنی هم تولید می‌شه که دیباگ کردن رو خیلی راحت‌تر می‌کنه. WebAssembly (Wasm) خودش یه زبان برنامه‌نویسی نیست و قرار هم نیست جاوااسکریپت رو کنار بزنه. برنامه‌نویس‌ها می‌تونن کدهای Wasm رو با استفاده از زبان‌های مختلفی بنویسن. این یعنی تو می‌تونی از زبان برنامه‌نویسی مورد علاقت استفاده کنی، بعد اون رو به فرمت Wasm تبدیل کنی تا مرورگر بتونه اجراش کنه. برای استفاده از Wasm، مرورگر باید هم از جاوااسکریپت و هم از Wasm پشتیبانی کنه.

وب اسمبلی سریع تره ولی دوتا ماشینه رو یادتونه؟ حالا فرض کنید اونی که سریع ترین سرعت رو داره مسیر رو بلد نیست ولی اونی که سرعتش کمتره بلده از یه راه کوتاه‌تر بره و مجبور نیست کل آزادراه رو طی کنه. فرض کنیم 0x6a یک دستور بایت‌کد در این زبان هست که معادل متنی اون می‌شه add (تابع جمع). حالا شما این امکان رو دارید که به زبان‌های مختلف (Rust, Go, C, CPP ...) کد بنویسید و اون رو تبدیل کنید به WASM (بخونید وزم - مخفف وب اسمبلی). موتورهای جستجو، مثل گوگل، بیشتر برای ایندکس کردن محتوای متنی مثل HTML، CSS و جاوااسکریپت طراحی شدن. اما WebAssembly به‌دلیل فرمت باینریش، با روش‌های رایج بهینه‌سازی برای موتورهای جستجو (SEO) سازگار نیست.

خب خوشبختانه مرورگرها خیلی زحمت می‌کشن که یه محیط ایمن و Sandbox ایجاد کنن که این اتفاق‌ها خیلی کم رخ بده و کدها فقط به اون چیزی که اجازه دارن دسترسی پیدا کنن ... پس بحث همینه؛ وقتی وب اسمبلی رو به چشم یک Sandbox نگاه کنیم استفاده ازش خارج از مرورگر می‌تونه خیلی پر کاربرد باشه. این شکل از نوشتن، به اندازه کافی انتزاعی هست که یک انسان بتونه بخونه و بنویسه و در عین حال یک ماشین با کمترین هزینه ترجمه کنه . شما می‌تونید به جای Rust یا Go مستقیم توی WAST کد بزنید و کامپایل کنید به WASM. این کار رو کسی نمی‌کنه بجز کسانی که می‌خوان به خود وب اسمبلی یه چیزی اضافه کنن. چون، همه چیز سطح پایین و در کنترل شماست و تقریبا چیزی جلودار خرابکاری‌ها نیست.

درحال حاضر, WebAssembly میتونه روی Chrome و Firefox اجرا بشه, درمورد Edge و Safari هم تقریبا کامل پشتیبانی میشه. این یعنی به زودی شما میتونید wasm رو روی هر مرورگر محبوبی اجرا کنید. هر سایتی را که در آن یک بازی یونیتی را اجرا می کند قطعا از WebAssembly استفاده می کند. WebAssembly همچنین کاملاً قادر به ساخت برنامه های مبتنی بر وب برای پردازش کلمه ، صفحات گسترده ، اسلایدها ، ویرایش عکس/فیلم و موارد دیگر است. و اگرچه WebAssembly ممکن است در حال حاضر پرکاربردترین فناوری نباشد ، اما روز به روز محبوبیت و کاربرد آن در حال افزایش است.

یک فایل پایه index.html می سازیم که شامل کد glue جاوا اسکریپت در یک تگ اسکریپت هست. ما می خواهیم هروقت لازم بشه تابع roll_dice در جاوا اسکریپت موجود باشه, پس برای این کار باید EMSCRIPTEN_KEEPALIVE رو اضافه کنیم. اساسی ترین کاربرد برای WebAssembly به عنوان هدفی برای نوشتن browser software است. اجزایی که در WebAssembly کامپایل می شوند را می توان به هر یک از زبان ها نوشت. سپس payload  WebAssembly از طریق جاوا اسکریپت به سمت کلاینت داده می شود. توسعه دهندگان باید WebAssembly را برای موارد استفاده فشرده مانند بازی ها، پخش موسیقی، ویرایش ویدیو و برنامه های CAD در نظر بگیرند.

اما حال با تغییر به سمت WebAssembly زمان بارگذاری آن‌ها تا سه برابر پیشرفت داشته است. از سال قبل تا به الان، اکثر مرورگرهای مدرن وب فرایند پشتیبانی از WebAssembly را شروع کرده‌اند. حتی به عنوان یک fallback، یک کتابخانه جاوااسکریپتی با نام asm.js ایجاد شده که Emscripten کد نوشته شده در C را به آن تبدیل می‌کند. در حال حاضر وبسایتی مانند فیسبوک برای فشرده‌سازی تصاویر و وبسایت Adobe Lightroom برای نسخه تحت وب خود از این تکنولوژی استفاده می‌کند. روی خیلی از سیستم‌ها یک زبان برنامه نویسی به طور مستقیم به شبکه، حافظه، سیستم‌فایل و غیره دسترسی نداره. چرا؟ چون اگه برنامه‌ها حق داشته باشن آزادانه از تمام منابع استفاده کنن بالاخره چه عمدی یا غیر عمدی سو استفاده رخ می‌ده.

البته باید گفت که جاوااسکریپت هنوز هم در بسیاری از استفاده‌ها کاربردی خواهد بود اما برای زمانی که بخواهید منحصرا روی یک موضوع تمرکز کنید و آن را بهتر نمایید، وب اسمبلی می‌تواند انتخاب خوبی باشد. قسمت‌هایی مانند رابط کاربری و App Logic را باید با جاوااسکریپت نوشت اما فانکشنالیتی اصلی در وب اپلیکیشن‌ها را می‌توان در وب اسمبلی همراه با کارایی بسیار بالاتری توسعه داد. WebAssembly یا همون Wasm یه استاندارد متن‌بازه که بهت اجازه می‌ده کدهای باینری رو توی وب اجرا کنی. به زبون ساده‌تر، WebAssembly کمک می‌کنه که برنامه‌نویس‌ها بتونن از زبان‌های سنگین و قوی مثل C، ++C و Rust تو توسعه وب استفاده کنن و کارهایی که نیاز به قدرت پردازش بالا دارن رو مستقیم تو مرورگر انجام بدن. خیلی ها معتقد اند که WASM داره دقیقا همون ایده ی JAVA رو ادامه میده. دقیقا مثل جاوا WASM هم یه زبون میانیه که مستقل از پلتفرم/سیستم عامل و معماری پردازنده هست.

این کار می‌تونه زمان‌بر و سخت باشه چون ابزارهای موجود محدود هستن. مثلاً تنظیم نقاط توقف (breakpoints) یا مشاهده متغیرها توی این سیستم به راحتی انجام نمی‌شه. خیلی از سازمان‌ها از راهکارهای خاص خودشون برای بهینه کردن کارها استفاده می‌کنن. از ابزارهای ساده مثل ویرایشگر فایل DOCX یا تبدیل‌کننده فرمت‌های تصویری گرفته تا موتورهای رندرینگ پیچیده، Wasm می‌تونه همه این‌ها رو با سرعت بالا و امنیت تضمین‌ شده فراهم کنه. یکی دیگه از قابلیت‌های جالب Wasm، سیستم WebAssembly System Interface (WASI) هست که مرزها رو جابه‌جا کرده و اجازه می‌ده برنامه‌های سمت سرور رو هم با Wasm اجرا کنی.

پس WASM یه استاندارد در حال توسعه هست که در آینده ی نزدیک قرار خیلی بیشتر اسمش رو بشنویم و ازش استفاده کنیم. واسه همین به نظرم رسید که چیزایی که ازش خونده بودم رو یه جا جمع کنم و تبدیلش کنم به این مطلبی که الان خوندید. در واقع WASM هم مثل JS وقتی داخل Sandbox مرورگر اجرا میشه دسترسی های محدودی داره. موتور بازی سازی Unity کد های #C شما رو به WASM تبدیل می‌کنه و بازی های تحت وب اکثرا با WASM کار می‌کنن. می‌خوام بگم توی دنیای امروز JS بیشتر از اینکه یه زبان برنامه‌نویسی باشه یه Compilation target هه.

یعنی بر اساس کدی که بهینه شده باید درباره «قدم‌های بعدی» اون همزمان با اجرا؛ تصمیم گرفت. فرض کنید 100 تا Object دارین که 99 تاش بهینه شدن ولی موقع اجرا مشخص می‌شه که Object آخر بهینه نیست. اینجا اون «انتظار» که از اجرای کد داشتیم براورده نشده و دوباره باید بهینه سازی انجام بشه ... پروژه‌هایی مثل WASI در حال توسعه هستن که به Wasm اجازه می‌دن روی سرورها و حتی دستگاه‌های لبه‌ای (Edge Devices) اجرا بشه. این یعنی Wasm می‌تونه به‌ عنوان یه راه‌حل همه‌کاره هم در سمت کاربر (کلاینت) و هم در سمت سرور استفاده بشه. حالا که با WebAssembly (Wasm) آشنا شدی، بیا چندتا مثال ساده از نحوه کار این تکنولوژی رو با هم بررسی کنیم تا بهتر با روش کدنویسی و اجرای کدها آشنا بشی.

تمام این موارد باعث می‌شود که کارایی بالاتری داشته باشیم و کدها در زمان سریع‌تری اجرا شوند. زمان اجرا شدن باینری‌های WASM تنها ۲۰ درصد کندر از اجرای همان کدها در حالت نیتیو است. در نهایت می‌توانید این ماژول را در وب اپلیکیشن‌تان قرار داده و آن را توسط جاوااسکریپت فراخوانی کنید. این موضوع می‌تونه برای برنامه‌نویس‌هایی که تجربه کار با سیستم‌های سطح پایین رو ندارن، چالش‌برانگیز باشه. علاوه بر این، مستندات و منابع آموزشی برای WebAssembly هنوز به اندازه زبان‌های قدیمی‌تر مثل جاوااسکریپت گسترده نیستن، که می‌تونه یادگیری و کار با این تکنولوژی رو برای تازه‌کارها سخت‌تر کنه. این موضوع به‌خصوص توی اپلیکیشن‌هایی که نیاز به تعامل لحظه‌ای با محیط وب دارن، مثل بازی‌های آنلاین یا شبیه‌سازی‌های تعاملی، مشکل‌ساز می‌شه.

توانایی فراهم کردن چنین سطحی از کارایی، فعالیتی‌ است که WebAssembly آن را برای ما فراهم می‌کند. از جهت «بهینه شدن کد و اجرای سریعتر» هم راه‌ حل‌های جالبی ارائه شده مثل Streaming compilation و Tiering compiler که یعنی به محض رسیدن یک قسمت از کد به کامپیوتر؛ همزمان یه مرحله کامپایل می‌شه. البته این یه مثال فرضی هست، کامپایلر هیچوقت برای مقادیر ثابت مثل 1 و 2 استک در نظر نمی‌گیره چون خروجی همون لحظه می‌تونه تشخیص داده بشه که 3 هست ... ولی منظور من اینه که دقیقا مثل یک استک دستورات Push و Pop می‌شه پس شما «باید» بلد باشین با «کمترین» حرکت ممکن دستور یا عملیات خاصی رو پیاده سازی کنید. یه آزادراه رو در نظر بگیرید که دوتا ماشین دارن توش حرکت می‌کنن؛ یکی شون پول عوارضی رو آنلاین پرداخت کرده و دیگه نیاز نیست همش وایسه و پول بده اما اون یکی باید دم هر عوارضی توقف کامل کنه و پول بده ...

شما کدتون رو توی یکی از زبانهایی که وب اسمبلی پشتیبانی می‌کنه می‌نویسید. بعد یک «تفسیر» از اون کد تولید می‌شه که کامپایلر وب اسمبلی از اون استفاده می‌کنه تا با دیتا تایپ‌های خودش تطابق بده و بایت‌کد تولید کنه. مثلا چیزی تحت عنوان Struct توی وب اسمبلی نیست این باید تبدیل بشه به چی؟ کار IR تفسیر همچین شرایطی هست. WebAssembly یه تکنولوژی نسبتاً جدید اما بسیار قوی و جذابه که آینده وب رو تغییر می‌ده. با سرعت و کارایی بالایی که داره، می‌تونه سنگین‌ترین اپلیکیشن‌ها رو توی مرورگرها اجرا کنه، بدون اینکه نیاز به نصب نرم‌افزارهای جانبی داشته باشیم.

WebAssembly جایگزین جاوا اسکریپت نمی شود بلکه آن را تکمیل می کند. می‌توانید بخش‌های پرفورمنس برنامه خود را در Wasm اجرا کنید در حالی که برای بقیه از جاوا اسکریپت استفاده می‌کنید. در این آموزش ما می خواهیم نشان بدیم که چطور یک فایل ساده C رو در wasm کامپایل کنیم و اون رو در یک صفحه وب شامل کنیم. تنها با یک کلیک وب اپلیکیشن‌ها را می‌توانید دریافت و استفاده بکنید. این کار بسیار امن‌تر از آن است که پکیج‌های مختلف را دانلود کنید و آن‌ها را به صورت مستقل روی کامپیوترتان نصب نمایید.

همچنین این سطح دسترسی «از برنامه به برنامه دیگه» فرق می‌کنه و یکسان نیست. اصطلاحا به این میگن یک برنامه user space که توی حلقه 3 اجرا می‌شه. درواقع سیستم‌عامل یک سری حلقه امنیتی داره و بحث ما مربوط میشه به حلقه سوم. حالا سیستم‌عامل یک سری توابع تحت عنوان System Call ارائه می‌کنه و هر قطعه کدی که به منابع سیستم نیاز داشته باشه باید اون توابع رو صدا بزنه و از اونها درخواست کنه. به همین دلیل، برنامه‌نویس‌ها باید دقت بیشتری در بررسی امنیت کدها داشته باشن و اقداماتی مثل اعتبارسنجی داده‌ها و تمیز کردن ورودی‌ها رو با دقت انجام بدن. این اقدامات اضافی می‌تونه کدنویسی رو پیچیده‌تر کنه و به منابع بیشتری نیاز داشته باشه.


برنامه نویسی حدی