هذه المشكلة مرافقة لمناقشة "WebAssembly و Unicode والنظام الأساسي للويب". تم تسجيل العرض التقديمي مسبقًا ، وهو ما قررنا تجربته في https://github.com/WebAssembly/meetings/pull/775 ، مع تحديد موعد المناقشة في اجتماع الفيديو CG في 22 يونيو .
يرجى ملاحظة أنني أذكر بعض المفاهيم التي أتوقع أن تكون معروفة جيدًا بين أعضاء CG ، لكنني قررت تضمينها مع ذلك لجعل العرض التقديمي مناسبًا لمن ليسوا على دراية بالموضوع. نرحب بالتعليقات!
القضايا ذات الصلة:
ربما بعض الحلول المحتملة التي جمعتها من التعليقات غير المتصلة بالإنترنت حتى الآن ، للنظر فيها:
في أنواع الواجهات ، حدد:
string := list char
string16 := list u16
تحديد إكراه يتم تطبيقه أثناء الربط ، في الحالات التالية:
| من | إلى | توقع
| ------------ | ------------ | -------------
| string
| string16
| أعد الترميز من UTF-8 إلى UTF-16
| string16
| string
| إعادة التشفير من WTF-16 إلى UTF-8 (خيار بديل)
يضمن الإكراه أن وحدة string16
تعمل على مضيف WASI ، على التوالي أن وحدة string
و string16
يمكن أن تتفاعل مع بعضها البعض ، حتى لو كان كلاهما string
و string16
حدة أو المضيف دعوة نفس string
أو string16
التصدير، التي من شأنها أن يكون الأمر خلاف ذلك غامضة.
يقدم هذا أيضًا غموضًا في تضمين الويب في أن تمرير list u16
إلى JS يمكن أن يصبح Uint16Array
أو DOMString
. يبدو الإكراه على مستوى JS من Uint16Array
إلى DOMString
غير مرغوب فيه ، ولكن يمكن التلميح إلى نوع JS بشكل صريح باستخدام الاسم المستعار string16
(مع المعرّف الثنائي الخاص به ، string16 :> list u16
معنويًا بحتًا عند الحاجة) بدلاً من list u16
في وحدة المحول. ومن هنا الاسم المستعار. في هذه الحالة ، سيصبح string16
DOMString
بينما list u16
سيصبح Uint16Array
.
أنا غير مرتبط بشكل خاص بالاسم string16
وسأكون مناسبًا لأي اسم آخر ، أو أي بديل لا يتطلب اسمًا / معرفًا لحل الغموض.
لا يلزم إجراء تحسين مشابه لـ list.is_canon
هنا ، حيث يمكن استخدام list.count
. أيضًا ، يمكن إبقاء الباب نحو UTF-any والتحسين المحتمل لـ Latin1 ، كما هو موضح أدناه ، مفتوحًا عن طريق حجز مساحة للمستقبل الفوري في list.*_canon
تعليمات المحول.
في أنواع الواجهة ، حدد:
list.lift_canon $unit [...]
list.is_canon $unit [...]
list.lower_canon $unit [...]
where the $unit immediate is
0: 8-bit (UTF-8, ASCII-compatible)
1: 16-bit (UTF-16)
2: 32-bit (UTF-32)
3: 8-bit (Latin1, narrow UTF-16)
يمكن النظر في هذا الحل المحتمل عندما يكون التكوين الجيد مطلوبًا. سوف يتجنب إعادة الترميز المزدوجة للتأثيرات العلوية وغير المباشرة على حجم الكود ، لكنه يترك المشكلة البديلة دون معالجة. لاحظ أنه يمكن إضافة $unit
1-3 بعد MVP كتحسينات إضافية ، أو قد نبدأ ببعض منها على الفور.
في أنواع الواجهة ، حدد:
list.lift_canon $unit [...]
list.is_canon $unit [...]
list.lower_canon $unit [...]
where the $unit immediate is
0: 8-bit (WTF-8, ASCII-compatible)
1: 16-bit (WTF-16)
2: 32-bit (Code points except surrogate pairs)
3: 8-bit (Latin1, narrow WTF-16)
سيتطلب هذا الحل المحتمل أيضًا إعادة تعريف char
من Unicode Scalar Values إلى Unicode Code Points ، مع تقييد قوائم char
لعدم احتواء أزواج بديلة (مع السماح بدائل معزولة) ، من المحتمل أن يتم فرضها عند الرفع. مرة أخرى ، يمكن الجدل حول $unit
s في MVP.
لا يقدم هذا الخيار فقدانًا من تلقاء نفسه ، لذا فإن كل شيء آخر يصبح بالفعل مجرد تحسين بعد MVP.
في أنواع الواجهة ، حدد:
passthrough
عند التخفيض للحصول على "قائمة نقاط رمز Unicode". هذه إضافة وظيفية تتيح عبورًا بلا خسارة.من خلال القيام بذلك نحقق:
IIUC ، المشكلة الأساسية هي أن قسم تكنولوجيا المعلومات يريد أن تكون السلاسل عبارة عن تسلسلات من نقاط الترميز الموحدة ، لكن بعض اللغات تعتبر السلاسل سلاسل من قيم i8 أو i16 التي قد تتوافق أو لا تتوافق مع سلاسل unicode جيدة التكوين. أحد الحلول البسيطة هو أن يكون لديك لغات / واجهات برمجة تطبيقات تقبل أو تنتج سلاسل Unicode غير صالحة تستخدم (list u8)
أو (list u16)
(ربما مع بعض الأسماء المستعارة اللطيفة مثل byte_string
للتواصل مع النية) بدلاً من النوع IT string
، وهو اسم مستعار لـ IIRC لـ (list char)
. هل تمت مناقشة مقايضات القيام بذلك في أي مكان حتى الآن؟
أعتقد أن المشكلة أكثر دقة بقليل ، حيث يريد قسم تكنولوجيا المعلومات تحديد char
كـ "Unicode Scalar Values" ، والتي تحتوي على فجوة حيث ستكون نقاط الكود البديلة ، وبالتالي لا يمكن أن تمثل بدائل معزولة . من ناحية أخرى ، WTF هي "نقاط رمز Unicode" بدون هذا التقييد ، ولكن يتم تقييد التسلسلات بحيث لا تحتوي على أزواج نقطة رمز بديلة (يمكن استبدالها بنقاط رمز تكميلية> U + FFFF ، في حين أن البدائل المعزولة لا بأس بها). هل هذا ما كنت تعني؟
بخلاف ذلك ، أعتقد أن سلاسل البايت التي تشبه C اعتبارًا من const char*
يمكن أن تكون أي شيء لم تتم مناقشته بعد. ربما فاتني ذلك ، رغم ذلك.
أحد الحلول البسيطة هو أن يكون لديك لغات / واجهات برمجة تطبيقات تقبل أو تنتج سلاسل Unicode غير صالحة تستخدم
(list u8)
أو(list u16)
(ربما مع بعض الأسماء المستعارة اللطيفة مثلbyte_string
للتواصل مع النية) بدلاً من النوع ITstring
، وهو اسم مستعار لـ IIRC لـ(list char)
.
هذا هو الحل المفضل لدي حاليًا أيضًا - سيكون النوع wtf16string
اسمًا مستعارًا لـ (list u16)
بنفس الطريقة التي يُعرّف بها string
حاليًا كاسم مستعار لـ (list char)
. قيمة الاسم المستعار ، IIUC ، هي أن نتيجة دالة تُرجع (list u16)
يُدعى بها (على سبيل المثال) JS ستظهر كقائمة JS (للأرقام) ، في حين أن نتيجة دالة تُرجع wtf16string
يمكن تحديد
يبدو أن إضافة اسم مستعار إضافي wtf16string
إلى مسودة ABI الأساسي غير منطقي نسبيًا.
من ناحية أخرى ، WTF هي "نقاط رمز Unicode" بدون هذا التقييد ، ولكن يتم تقييد التسلسلات بحيث لا تحتوي على أزواج نقطة رمز بديلة (يمكن استبدالها بنقاط رمز تكميلية> U + FFFF ، في حين أن البدائل المعزولة لا بأس بها).
آه ، هل هذا يعني أن WTF-8 ليس هو نفسه (list u16)
عادي لأنه يحتوي على قيود الإضافة هذه؟ لم أقدّر هذا الفارق الدقيق. حدسي هو أنه سيكون من المبالغة أن يكون لديك نوع string
يمثل متواليات من قيم unicode العددية جيدة التكوين بالإضافة إلى النوع wtf16string
الذي يكاد يكون (list u16)
لكن له قيود إضافية. هل استخدام اسم مستعار لـ (list u16)
غير المقيد سيعمل بشكل جيد بما فيه الكفاية للأنظمة التي لا تفرض تنسيق unicode الجيد؟ تشير هذه الملاحظة في مواصفات WTF-8 إلى أنها ستفعل ذلك.
آه ، هل هذا يعني أن WTF-8 ليس هو نفسه العادي (قائمة u16) لأنه يحتوي على قيود الإضافة هذه؟
تنص على "مثل UTF-8 مقيد بشكل مصطنع على نص Unicode لمطابقة UTF-16 ، فإن WTF-8 مقيد بشكل مصطنع لاستبعاد أزواج نقطة الرمز البديلة من أجل مطابقة UTF-16 التي قد تكون سيئة التكوين." Iiuc ، فهو يتعامل مع هذه الأمور بشكل مشابه لكيفية تعامل UTF-8 مع متواليات البايت الطويلة أو المقطوعة. يمكن أن يمثل WTF-8 أي (list u16)
، لكن ليس كل (list u8)
صالحًا لـ WTF-8.
هل استخدام اسم مستعار لـ غير مقيد (قائمة u16) يعمل بشكل جيد بما فيه الكفاية للأنظمة التي لا تفرض التنسيق الجيد لليونيكود؟
خرائط WTF-16 1: 1 لقيم u16
عشوائية وهي تعتمد فقط على كيفية تفسير هذه القيم ، لذا نعم ، (list u16)
سيعمل.
IIUC ، WTF-8 ليست تمامًا مثل التعسفي list u8
. على سبيل المثال ، يحظر "تسلسل زوج البايت البديل" (انظر هنا ).
ومع ذلك ، WTF-16 _is_ هو نفسه list u16
. من الغريب بعض الشيء أنهم يشاركون موضوع التسمية.
تحرير: يجب أن يتم التحديث :)
لقد نشرت أول سؤال / إجابة تركز فقط على مسألة البدائل في أنواع الواجهة / # 135 . أعتقد أن هذا هو الجزء الأعلى من الترتيب ، وإذا تمكنا من الاتفاق على ذلك ، فستكون المناقشة اللاحقة حول دعم تنسيق ترميز واحد أو أكثر أبسط.
شكرا لك يا لوك.
إذا كنت على استعداد لدعم "Separate WTF-16" كما هو مذكور أعلاه (الإكراه أمر بالغ الأهمية لتمكين الوصول إلى واجهات برمجة تطبيقات WASI وللتعامل مع JavaScript بدون رمز الغراء) ، سأشعر بالراحة مع char
المقترح مدى القيمة. عندئذٍ سيكون لدى لغات WTF-16 فتحة الهروب التي تحتاج إلى تكاملها كما تحصل مع الوحدات المكتوبة بنفس اللغة ، وجافا سكريبت وعن طريق الاستبدال بلغات UTF- *. سأشعر أيضًا بتحسن كبير تجاه WASI بالمناسبة ، حيث سيتم حل نقطة الألم الرئيسية الناتجة عن عدم تطابق ترميزات السلسلة مع الإكراه في المكان.
وجود نوع string16
منفصل كما تقترحه مع البدائل سيظل يواجه جميع المشاكل مع البدائل الموضحة في أنواع الواجهة / # 135 ، لذلك أعتقد أنه لن يكون من الأفضل أن يكون لديك نوعان من السلاسل مقابل . واحد (خاصة إذا كانت قابلة للتحويل ضمنيًا ؛ فهي ليست أنواعًا منفصلة بشكل مفيد). قد يؤدي وجود نوعين من السلاسل إلى جعل الأمور أكثر سوءًا بشكل ملموس من خلال فرض عبء ذهني على كل مصمم واجهة ومستهلك ("لماذا يوجد نوعان؟ ما الفرق؟ متى يمكنني استخدام أحدهما أو الآخر؟"). أخيرًا ، فإن إضافة دعم لـ WTF-16 سيتعارض عمومًا مع إرشادات تطوير المعايير المستقبلية Web / IETF المذكورة أيضًا في أنواع الواجهة / # 135 . وبالتالي ، لا أعتقد أننا يجب أن نفكر في إضافة أنواع بديلة ما لم يكن لدينا دليل ملموس فعلي على أن أنواع الواجهة غير قابلة للحياة بدونها.
بالنسبة لحالات الاستخدام الحصرية للويب ، أعتقد أنه سيكون من المنطقي حل المشكلة في JS أو Web APIs. على سبيل المثال ، من السهل تخيل واجهة برمجة تطبيقات JS لواردات وتصدير wasm "الملزمة". هذا هو النهج الذي يتم اتباعه بالفعل في واجهات برمجة تطبيقات JS الناشئة الأخرى ، مثل تبديل المكدس ، وكنت أتساءل عما إذا كان ما نذهب إليه هو "استيراد ربط" / "تصدير ربط" واجهات برمجة تطبيقات JS قادرة على التعامل مع الويب - حالات محددة من الوعود وسلاسل JS وطرق عرض الصفيف المكتوبة.
سيظل وجود نوع سلسلة 16 منفصل كما تقترح مع البدائل يواجه جميع المشكلات مع البدائل الموضحة في أنواع الواجهة / 135
صحيح من الناحية الفنية ، ولكنه أيضًا يخطئ أن السلاسل ستعمل دائمًا على الأقل دائمًا بين الوحدات المترجمة بشكل منفصل في نفس اللغة ، وأي لغة متوافقة ، وجافا سكريبت ، حتى بدون معرفة مسبقة بنوع الوحدة التي يتفاعل معها المرء. أعتقد أن هذا هو عادة غالبية الحالات. على هذا النحو يبدو لي كحل وسط معقول ، أيضًا لأنه يسمح بتخصيص نطاق القيمة char
المطلوب لسلاسل (USV) جيدة التشكيل.
قد يؤدي وجود نوعين من السلاسل إلى جعل الأمور أكثر سوءًا بشكل ملموس من خلال فرض عبء ذهني على كل مصمم واجهة ومستهلك ("لماذا يوجد نوعان؟ ما الفرق؟ متى يمكنني استخدام أحدهما أو الآخر؟")
يبدو أن بديل الكسر العرضي أسوأ بكثير بالنسبة لي ، لذلك إذا كان هذا هو ما يتطلبه الأمر ، أعتقد أن معظم الناس سيكونون على ما يرام معه. ربما يكون الاسم الجيد لنوع السلسلة الثاني ( domstring
؟) كافياً للتخفيف من هذه المشكلة البسيطة.
أخيرًا ، فإن إضافة الدعم لـ WTF-16 سيتعارض بشكل عام مع إرشادات تطوير المعايير المستقبلية Web / IETF
لسوء الحظ ، في حالة عدم وجود فتحة هروب للغات المتأثرة ، لا يهمني كثيرًا مدى صحة تفكير أي شخص في الاتجاه المزعوم ، طالما أن IT MVP سوف يكسر شيئًا ما في مكان ما لشخص ما ، وهو عديم الفائدة إلى حد كبير بالنسبة للغة الشبيهة بجافا سكريبت التي أعمل عليها ، يمكنني فقط معارضتها.
ومن ثم أحاول إيجاد حل معقول أو حل وسط يمكن للجميع التعايش معه ، وسيسعدني إذا تمكنا من التعاون.
لا أرى كيف يعالج ما تقوله المشكلات التي أثيرت في أنواع الواجهة / # 135 أو يقدم دليلًا مضادًا على أن تكنولوجيا المعلومات لن تكون قابلة للتطبيق بشكل عام بدون تضمين نوع domstring
. توفر واجهة برمجة تطبيقات JS الحالية بالفعل فتحة هروب للأغراض العامة لإجراء تحويلات تعسفية للقيمة عند الحدود ، لذلك لا أرى مدى الحاجة إلى فتحة هروب ثانية في هذه المرحلة المبكرة من الوقت. أعتقد أننا نحتاج ببساطة إلى المزيد من الأدلة المستندة إلى الخبرة لمواجهة التوجيه القوي الذي تلقيناه ضد المزيد من السلاسل التي تحتوي على بدائل.
(FWIW ، إذا تمكنا من الاتفاق على عدم وجود بدائل ، أعتقد أنه سيكون من المنطقي التحدث عن دعم U TF-16 كترميز إضافي في ABI الأساسي string
. لكن هذا موضوع منفصل تمامًا مع بعض الخيارات ، لذلك لا أريد أن أخلط ذلك مع دلالات السلسلة المجردة التي يجب فهمها أولاً.)
أقدر فقرتك الثانية لأنها ستحل بالفعل بعض المشاكل المزعجة للغاية. أوافق على أن دعم UTF-16 مفيد بشكل منفصل ، وسأكون ممتنًا لإضافته إلى الشرح / MVP. احسبها علي!
ومع ذلك ، أجد صعوبة في متابعة حججك الواردة في الفقرة الأولى. ربما إذا كنت لا تصدقني ، فإليك لينوس تورفالدس يشرح قاعدة مهمة جدًا أعتقد أنها تتجاوز نواة لينكس: لا تكسر مساحة المستخدمين . وها هو في نفس الحديث ، متمسكًا بحكمة المبرمج: إذا كان هذا خطأ يعتمد عليه الناس ، فهو ليس خطأ ، إنها ميزة ، فقط للمتابعة مع:
إنه لأمر محزن حقًا عندما تكون معظم المكتبات الأساسية في النظام بأكمله على ما يرام مع تحطيم الأشياء طالما أن الأشياء "تتحسن" وتقوم "بإصلاح" ABI.
وعدم الحاجة إلى القلق بشأن البدائل هو في الواقع نوع من الميزات ، حيث يمكن للمستخدمين القيام بـ substring(0, 1)
هنا أو هناك واستدعاء وظيفة مستوردة معها ، أو يمكنهم split("")
، تمرير و join()
مرة أخرى ، أو قم بإنشاء StringBuilder
كوحدة نمطية لا ينتج عنها أحيانًا استبدال أحرف مزدوجة كما لو كانت سحرية. أعني ، هناك سبب وراء اختيار مجموعة من اللغات المشهورة جدًا ضد فرض الصياغة الجيدة ، وعندما يريد Wasm دعم هذه اللغات ومستخدميها جيدًا ، فكلما أصبح Wasm نمطيًا ، زادت الحدود ، سيكون من الصعب معرفة الوحدة النمطية التي تعيش فيها الوظيفة ، وستصبح المشكلة أكثر وضوحًا.
لا أعرف حقًا مقدار الأدلة الإضافية التي أحتاجها لإثبات أن تصميم شيء ما بطريقة تتجاهل الواقع الحالي هو فكرة سيئة. في الواقع ، يبدو أن هذا لا بأس به في أنواع الواجهة فقط ، بينما نحافظ على كل اقتراح آخر وفقًا لمعايير عالية جدًا. وعلى الرغم من أنني لست خبيرًا في هذا الأمر ، أعتقد أن معيار Unicode نفسه ارتكب نفس الخطأ بالضبط فيما يتعلق باحتياجات لغات UCS-2 عن طريق الإصرار على USVs ، مما أدى إلى حوالي عقد من اليأس نفسه. المناقشات (يمكن أن توصي بسلسلة
لاحظ أن إصدار حرف بديل عند مواجهة أخطاء ترميز الأحرف في دفق البتات هو شكل معروف جيدًا من تلف البيانات الصامت الخطير والأنظمة التي تتطلب النزاهة تمنع القيام بذلك.
فيما يتعلق بذلك ، إذا كان codePointAt يطرح استثناءً عند ضرب بديل وحيد ، فقد ينتهي بك الأمر مع خطأ يكسر التطبيق بالكامل لأن شخصًا ما وضع بطريق الخطأ حرفًا تعبيريًا في موضع خاطئ في سلسلة في قاعدة بيانات
لسوء الحظ ، يجعل ecmascript من الصعب جدًا ضمان عدم إنشاء سلاسل بنقاط رمز بديلة غير مقترنة في مكان ما فيها ، فمن السهل أخذ وحدات الطول 157 الأولى من سلسلة وربما إلحاق "..." لاختصارها. وإنه لصدفة غريبة إذا حدث ذلك فعليًا في الواقع لأن الأحرف غير BMP نادرة. يجب أن نكون مترددين جدًا في إدخال المخاطر على أمل تحسين نظافة Unicode لدينا.
السبب وراء امتلاك JS و Java و C # للسلاسل التي يمتلكونها هو أنه بحلول الوقت الذي أدرك فيه Unicode أن 2 بايت لم تكن كافية وبالتالي لم يكن UCS-2 قابلاً للتطبيق ، تمت كتابة مجموعة من التعليمات البرمجية بالفعل ، لذلك لم تكن هذه اللغات ببساطة ليس لدي خيار. وبالمثل ، بالنسبة إلى أنظمة تشغيل Linux المكشوفة لمساحة المستخدمين. في المقابل ، لا يوجد رمز اليوم يستخدم واجهات برمجة التطبيقات المحددة في تكنولوجيا المعلومات ، لذلك ليس لدينا نفس متطلبات التوافق مع الإصدارات السابقة. لأسباب عديدة ، لا تسعى أنواع الوسم والواجهة عن قصد إلى محاكاة لغة واحدة موجودة أو syscall ABI. قد يكون هدفًا صالحًا ، ولكن سيكون مشروعًا / معيارًا / طبقة منفصلة عن نموذج المكون. هذه هي فائدة الطبقات وتحديد النطاق: لسنا بحاجة إلى شيء واحد يحقق جميع الأهداف الممكنة.
أريد أن أعيد التأكيد على أنه بالطبع داخل المكون ، يمكن تمثيل السلاسل بأي طريقة مناسبة للغة ، لذلك نحن نتحدث فقط عن دلالات واجهات برمجة التطبيقات . بالنسبة لواجهات برمجة تطبيقات الويب المحددة بالفعل:
وبالتالي ، ما زلت لا أعتقد أن لدينا أي دليل يشير إلى أن تكنولوجيا المعلومات لن تكون قابلة للتطبيق دون المضي قدمًا في دلالات سلسلة WTF-16 ، وهو ما أعتقد أنه السؤال المناسب لـ MVP.
نقطتان لا أتفق معها:
لا أرى كيف يعالج ما تقوله المشاكل التي أثيرت في أنواع الواجهات / # 135
هذه قضية منفصلة الآن ، وفي المنشور السابق كنت أتحدث عن ما أعتقد أنه حل وسط معقول لحل الضياع. على وجه الخصوص ، سأكون موافقًا على تفكيرك في المشكلة المنفصلة ، ولكن فقط عندما يكون هناك احتياطي غير ضياع متاح. هذا ليس إما / أو في رأيي. إذا لم يكن الأمر كذلك ، فسأظل مع الرأي القائل بأن WTF-8/16 هو الخيار الأكثر شمولاً والأقل تقييدًا ، وعلى هذا النحو هو الأفضل ، أيضًا لأن أحد أهداف Wasm عالية المستوى هو الاندماج بسلاسة مع النظام الأساسي للويب على التوالي الحفاظ على التراجع. - طبيعة الويب المتوافقة ، وهذا ينطبق أيضًا على أنواع الواجهة.
توفر واجهة برمجة تطبيقات JS الحالية بالفعل فتحة هروب للأغراض العامة لإجراء تحويلات تعسفية للقيمة عند الحدود ، لذلك لا أرى مدى الحاجة إلى فتحة هروب ثانية في هذه المرحلة المبكرة من الوقت.
هناك دائمًا فتحة هروب لاستخدام روابط JS API المخصصة
هذا للأسف لا يكفي في حالتنا ، حيث لدينا حاليًا كود لاصق مثل:
const STRING_SMALLSIZE = 192; // break-even point in V8
const STRING_CHUNKSIZE = 1024; // mitigate stack overflow
const utf16 = new TextDecoder("utf-16le", { fatal: true }); // != wtf16
/** Gets a string from memory. */
function getStringImpl(buffer, ptr) {
let len = new Uint32Array(buffer)[ptr + SIZE_OFFSET >>> 2] >>> 1;
const wtf16 = new Uint16Array(buffer, ptr, len);
if (len <= STRING_SMALLSIZE) return String.fromCharCode(...wtf16);
try {
return utf16.decode(wtf16);
} catch {
let str = "", off = 0;
while (len - off > STRING_CHUNKSIZE) {
str += String.fromCharCode(...wtf16.subarray(off, off += STRING_CHUNKSIZE));
}
return str + String.fromCharCode(...wtf16.subarray(off));
}
}
أولاً ، نظرًا لأننا نهتم كثيرًا بمتصفح Chrome و Node.js ، وجدنا أن محرك V8 TextDecoder
لـ UTF-16LE أبطأ بكثير من المحركات الأخرى (محركات SM سريعة حقًا) ، لذا فإن String.fromCharCode
هو في الواقع أسرع في V8 حتى نقطة تعادل معينة. لذلك قررنا تحسينه في الوقت الحالي. بعد ذلك ، لا يوجد TextDecoder
لـ WTF-16 (وهو أمر مزعج بشكل منفصل) ، لذلك نحاول أولاً فك ترميز UTF-16 المشكل جيدًا ، وإذا فشل ذلك ، فإننا نتركه يرمي ويعود إلى التقسيم أبطأ بكثير String.fromCharCode
. يعتبر التقسيم ضروريًا لأنه لا يمكن للمرء ببساطة تطبيق String.fromCharCode
على سلسلة طويلة ، حيث من المحتمل أن يتجاوز ذلك المكدس.
من ناحية أخرى ، لن يحتاج Rust على سبيل المثال إلى هذا ، وهو أحد الأسباب التي تجعلني أعتقد أن تكنولوجيا المعلومات ، في الوقت الحالي ، ليست محايدة كما ينبغي. بشكل عام ، أعتقد أن الهدف من IT string
s هو أن تكون قادرًا بالفعل على التفاعل مع JS جيدًا ، والذي لا يزال هدفنا الأساسي المتداخل.
لا يوجد رمز موجود اليوم يستخدم واجهات برمجة التطبيقات المحددة في تكنولوجيا المعلومات ، لذلك ليس لدينا نفس متطلبات التوافق مع الإصدارات السابقة
النصف الأول صحيح تقنيًا ، نظرًا لعدم وجود تكنولوجيا المعلومات بعد ، ولكن IIUC تتضمن متطلباتنا تحسين حالات الاستخدام الحالية ، على سبيل المثال حساب الجزء الخرقاء من كود الغراء أعلاه. من الناحية المثالية لأكبر عدد ممكن من اللغات ، لذا فإن ما بعد MVP يصبح بالفعل "مجرد تحسين" كما قلت في عرضك التقديمي. على العكس من ذلك ، في الوقت الحالي ، تبدأ تكنولوجيا المعلومات بشكل أساسي بما يعد بالفعل تحسينًا للغات التي يمكنها الاستفادة من وحدة فك التشفير / التشفير UTF-8 ، والتي أعتقد أنها ليست محايدة.
لا تسعى أنواع الواجهات والوسيط عن قصد إلى محاكاة لغة مفردة موجودة أو syscall ABI
قرأت هذا كما لو كنت من هذا الرأي ، وأنا لست كذلك. أنا على استعداد لإعطائك فائدة الشك هنا ، لكني أود أن أضيف أنه في رأيي ، فإن تكنولوجيا المعلومات حاليًا مقيدة بشكل غير ضروري ، وبالتالي فهي لا تخدم سوى مجموعة محددة جدًا من اللغات جيدًا. على العكس من ذلك ، فإن WTF-8/16 هو الترميز الأكثر شمولاً الذي كنت أتوقع أن يكون الافتراضي المنطقي ، أيضًا لأنه يقوم برحلات ذهابًا وإيابًا إلى سلاسل JS. نحن نختلف هنا ، ولكن فقط في حالة عدم وجود فتحة هروب مناسبة. إذا كان هناك بديل قابل للتطبيق وغير ضياع ، لذلك لا أحد مكسور أو محروم بلا داع ، سأكون على ما يرام مع منطقك لنوع السلسلة الافتراضية.
لدينا الكثير من الأسباب للاعتقاد بأنه ليس من الضروري (وغالبًا ما يكون غير ذي معنى) تمرير البدائل
نحن نختلف هنا. على وجه الخصوص ، أعتقد أن عرضي التقديمي وتعليقاتي تثير شكًا معقولاً في أنه قد يكون ، في بعض الحالات ، على الرغم من ندرته ، ذو مغزى كبير (لنقل حيث تكون النزاهة مطلوبة) ، وأنا أرى أنه "يجب أن نكون مترددين جدًا في تقديم المخاطر التي تأمل في تحسين نظافة Unicode لدينا. " هذا ، إذا استطعنا ، أعتقد أنه يجب علينا تصميم ABI الأساسي بطريقة مضمونة للعمل في الحالات المهمة التالية أيضًا: Java / C # / AS <-> JS ، Java / C # / AS <-> جافا / C # / AS. ربما يكون الاستبدال على مسارات أخرى أمرًا لا مفر منه ، ولكن على الأقل يكون لدى اللغات والمستخدمين خيار ، على التوالي ، لم يتم كسر الافتراضي بالفعل في حالات نادرة.
ما زلت لا أعتقد أن لدينا أي دليل يشير إلى أن تكنولوجيا المعلومات لن تكون قابلة للتطبيق دون المضي قدمًا في دلالات سلسلة WTF-16
في ظل وجود شك معقول وغياب الرغبة في استكشاف ما أعتقد أنه حل وسط معقول ، أتوقع أن عبء الإثبات يقع على عاتقك الآن. مرة أخرى ، أنا على استعداد لترك السلسلة الافتراضية لك وللمستقبل المصمم جيدًا ، ولكن ليس على حساب عدم احتساب المخاطر التي قد تكون نادرة ، ولكن لا تزال. يمكن أن تتأثر العديد من اللغات الشائعة بهذا الأمر ، وقد يصبح من الصعب حقًا تبرير ذلك في المستقبل بمجرد إدراكهم.
أوافق على أن كود الغراء JS ليس مثاليًا ، لكنني أعتقد أن الإصلاح الصحيح لذلك موجود في JS API أو في JS ، وليس عن طريق إضافة مفهوم wtf-16-string إلى النظام البيئي للمكون المستقبلي بأكمله. علاوة على ذلك ، لا أرى معلومات جديدة للرد عليها لم يتم الرد عليها بالفعل ؛ يبدو أننا نختلف في الغالب حول مسائل الأهداف / النطاق.
أتوقع أن يكون الشذوذ TextDecoder
أكثر صعوبة في الإصلاح في JS ، لأنه من الواضح أنه قرر بالفعل أن هذا خارج النطاق. ويمكن لـ JS فعل ذلك ، لأن TextDecoder
في JS ليس شيئًا يتم استدعاؤه بين استدعائين للوظائف ، ولكنه يستخدم في الغالب لاسترداد البيانات عبر الشبكة أو من التخزين.
الشذوذ حتى أكثر إثارة للاهتمام، هو، مع ذلك، أنه ليس هناك حتى TextEncoder
لUTF-16LE، لذلك يتعين على المرء القيام به:
/** Allocates a new string in the module's memory and returns its pointer. */
function __newString(str) {
if (str == null) return 0;
const length = str.length;
const ptr = __new(length << 1, STRING_ID);
const U16 = new Uint16Array(memory.buffer);
for (var i = 0, p = ptr >>> 1; i < length; ++i) U16[p + i] = str.charCodeAt(i);
return ptr;
}
كما ترى ، هذه نقطة ألم رئيسية لشيء مثل Java و C # و AS وغيرها ، وسيظل كلاهما ضروريًا عند تمرير list u16
. وفي سياق هذه المشكلة ، لا يقتصر الأمر على JS API ، حيث لا تختلف إعادة الترميز المزدوجة + فقدان البيانات بين وحدتين من نفس اللغة:
هناك مساحة كاملة من الخيارات تتجاوز TextEncoder
/ TextDecoder
لكيفية معالجة حالة الاستخدام هذه على الويب. آخر هو تمديد new WebAssembly.Function()
(والذي تم تنفيذه بالفعل في بعض المتصفحات) لإجراء تحويلات سلسلة عن طريق إضافة معلمات اختيارية إضافية إلى المنشئ. من شأن هذا النهج أيضًا أن يجعل الوظيفة متاحة للاستخدامات غير المكونة للوسم أيضًا (وربما في وقت أقرب بكثير) ، مما يعزز النقطة التي مفادها أن JS API سيكون المكان المناسب لمعالجة حالة الاستخدام هذه.
لمعلوماتك: تمت إضافة خيار "Integrated W / UTF-any" الذي ظهر في https://github.com/WebAssembly/interface-types/issues/135#issuecomment -863493832 إلى قائمة الاقتراحات أعلاه :)
التعليق الأكثر فائدة
هذا هو الحل المفضل لدي حاليًا أيضًا - سيكون النوع
wtf16string
اسمًا مستعارًا لـ(list u16)
بنفس الطريقة التي يُعرّف بهاstring
حاليًا كاسم مستعار لـ(list char)
. قيمة الاسم المستعار ، IIUC ، هي أن نتيجة دالة تُرجع(list u16)
يُدعى بها (على سبيل المثال) JS ستظهر كقائمة JS (للأرقام) ، في حين أن نتيجة دالة تُرجعwtf16string
يمكن تحديديبدو أن إضافة اسم مستعار إضافي
wtf16string
إلى مسودة ABI الأساسي غير منطقي نسبيًا.