رفع باگ چندسالهٔ top-level await توی سافاری
خلاصهٔ کاملتر
تیم وبکیت اعلام کرده لودر ماژولهای جاوااسکریپت سافاری رو کاملاً از نو نوشته تا مشکل قدیمی top-level await (یعنی استفاده از await مستقیم توی سطح بالای ماژول، بدون تابع async) رو حل کنه. قبل از این، بعضی وقتها با خطای عجیب «accessed before initialization» مواجه میشدید که اصلاً ربطی به کد خودتون نداشت.
ریشهٔ مشکل به این برمیگشت که لودر قدیمی سافاری از یه پیشنویس منسوخ به اسم WHATWG Loader (آخرین آپدیتش سال ۲۰۱۶) پیروی میکرد، از دورانی که اجرای ماژولها کاملاً sync بود و اصلاً await در ماژولها وجود نداشت. وقتی بعدها ECMAScript 2022 رسماً top-level await رو معرفی کرد، وبکیت سعی کرد این قابلیت رو روی همون پایهٔ قدیمی پیاده کنه، در حالی که اون پایه اصلاً برای این طراحی نشده بود.
نتیجه این میشد که وقتی یه ماژول چند بار import میشد، ترتیب resolve شدن import ها به هم میریخت؛ مثلاً بهجای ترتیب ۱، ۲، ۳، خروجی میشد ۲، ۳، ۱، و دوتای اول قبل از تموم شدن evaluation ماژول به exportهاش دسترسی پیدا میکردن و ارور میگرفتن. توی نسخهٔ جدید، لودر منتظر میمونه evaluation واقعاً تموم بشه، بعد promise رو resolve میکنه، پس ترتیب همیشه درسته.
یه تصمیم فنی جالب دیگه اینه که لودر قدیمی self-hosted JavaScript بود، یعنی خود مرورگر با جاوااسکریپت نوشته شده بود، ولی نسخهٔ جدید کاملاً با C++ نیتیو نوشته شده. دلیلش هم استارتاپ کندتر جاوااسکریپت (چون باید موقع اجرا کامپایل بشه) و performance غیرقابلپیشبینیترش بود، در حالی که لودر ماژول اصلاً یه hot path هم نیست که از JIT سود زیادی ببره.
برای تست، تیم وبکیت از تستهای خود موتور Bun (که رو JavaScriptCore ساخته شده و همین باگ رو داشت)، یه fuzzer اختصاصی برای مقایسهٔ خروجی با موتورهای دیگه، و کل تستهای ماژولمحور test262 و WPT استفاده کرده. الان میشه این تغییر رو توی Safari Technology Preview 251 یا Safari 27 beta امتحان کرد.
نکات کلیدی:
- لودر ماژول جاوااسکریپت سافاری از صفر و با C++ نیتیو بازنویسی شده، نه دیگه self-hosted JS
- مشکل قدیمی از پیروی از یه پیشنویس منسوخ WHATWG (۲۰۱۶) میومد که اصلاً await رو در نظر نمیگرفت
- نتیجهٔ باگ: ترتیب اشتباه resolve شدن import ها و خطای دسترسی به مقدار مقداردهینشده
- تغییر توی Safari Technology Preview 251 و Safari 27 beta قابل تسته




