Rust: اجعل الصدأ يعمل مع emscripten

تم إنشاؤها على ١٨ أبريل ٢٠١٢  ·  30تعليقات  ·  مصدر: rust-lang/rust

لقد أمضيت بعض الوقت في البحث عن هذه المشكلة و rustc الآن يولد رمزًا يمكن أن يترجمه emscripten ، لكن جافا سكريبت المترجم يفشل عندما يصل إلى وظيفة وقت التشغيل. الخطوة التالية هي البدء في إنشاء وقت التشغيل باستخدام emcc كمترجم. أخرج كل الأشياء التي لا يتم إنشاؤها خلف ifdefs EMSCRIPTEN .

يضيف Emscripten طريقة لمعاملة التجميع المضمن على أنه جافا سكريبت ، لذلك يمكن تنفيذ جميع أجزاء وقت التشغيل التي لا يتم إنشاؤها باستخدام emscripten في إطار جافا سكريبت.

بالتناوب ، يمكننا إعادة تنفيذ وقت التشغيل الجزئي في جافا سكريبت وعدم تكلف نفسه عناء تجميعه من C ++ على الإطلاق. لا ينصح بهذا الأسلوب.

A-runtime E-hard

التعليق الأكثر فائدة

إنني أبذل جهدًا هائلاً في عملية الفرز حتى نكون مستعدين لـ 1.0. كجزء من هذا ، أقوم بنقل الأشياء التي تشبه قائمة الرغبات إلى RFCs repo ، حيث يجب مناقشة / تحديد أولويات الأشياء الجديدة الرئيسية.

تم نقل هذه المشكلة إلى RFCs repo: rust-lang / rfcs # 604

ال 30 كومينتر

راجع أيضًا # 3608.

لا يزال لطيفا ليس في أي مرحلة استحقاق.

لا يزال سيكون لطيفًا ، لكنه ليس مهمًا جدًا. يجب أن يصبح هذا أسهل ، حيث تتم إعادة كتابة الكثير من وقت التشغيل في الصدأ.

الآن بعد أن تمت كتابة وقت التشغيل بلغة Rust ، كيف يغير ذلك احتمالات هذا الخطأ؟ ما مدى صعوبة تشغيل برنامج مرحبًا بلا حدود من خلال برنامج emscripten؟

لا ينبغي أن يكون من الصعب بشكل خاص إضافة دعم رائع حقًا لـ emscripten الآن. إنه يعمل بالفعل إلى حد كبير مع قلب الصدأ. في برنامج التحويل البرمجي ، نحتاج إلى إضافة دعم للهدف الثلاثي الصحيح ، وإعداد سمات الهدف المختلفة بشكل صحيح ، ثم عزل الأجزاء القليلة من وقت التشغيل التي لا تعمل حاليًا في js ، والترابط وتبديل السياق.

بمجرد أن ينضج وضع الجدولة 1: 1 أكثر قليلاً ، قد نتمكن حتى من إضافة دعم للمهام عبر العاملين على الويب ، على الرغم من أنه في الوقت الحالي يتطلب حلاً مختلفًا لتمرير الرسائل. اعتمادًا على دعم التوازي الذي تمت إضافته إلى js / emscripten ، قد نتمكن في النهاية من دعم رسالة الصدأ التي تمر عبر الدلالات بدقة.

brson : أعتقد أن # 10780 سيكون أكبر مانع في الوقت الحالي. سيخرج Rust منصات هبوط مع مكالمات لتحديث الحجم المستخدم للقيام بسلامة المكدس عبر دعم المكدس المقسم في LLVM.

بفضل -Z no-landing-pads هذا يعمل الآن بشكل جيد! من الممكن إضافة دعم صريح لهذا إلى المكتبة القياسية ، لكن معظمها لن يعمل على أي حال (ملفات ، tcp ، udp ، إلخ) لذلك لا أعتقد أنه ضروري. إذا وعندما تلتقط المكتبة القياسية دعمًا قائمًا بذاته ، فستبدأ في العمل ويمكننا فتح المزيد من المشكلات بناءً على الوظائف التي يمكننا تعيينها إلى JavaScript.

إذا كان الأمر جيدًا ، أود فعلاً ترك هذا مفتوحًا الآن. أعتقد أن القيام بذلك سيكون خطوة جيدة للأمام نحو ضمان أن المكتبة القياسية قابلة للتوسيع وقادرة على العمل على أي عدد من الأنظمة الأساسية.

أوافق على أن معظم العمل قد تم إنجازه ، وسيحتاج هذا على الأرجح إلى libemscripten لتوفير إدخال / إخراج خاص بـ emscripten ، لكنني أعتقد أنه قد تكون هناك عقبات كافية على طول الطريق التي تستحق المغادرة القضية مفتوحة لـ (لا يزال مشروعًا مثيرًا للاهتمام!)

alexcrichton : لن يكون من الممكن توفير التزامن القياسي للمكتبة ودعم الإدخال / الإخراج لـ emscripten. في أحسن الأحوال ، يمكن إخراجها إلى وحدة التحكم لـ stdout / stderr. لا يمكنني التفكير في أي أشياء في المكتبة القياسية ستكون فكرة جيدة لهدف emscripten ولكن ليس هدفًا قائمًا بذاته ، بخلاف تطبيق المخصص الافتراضي.

تحديث الحالة:

alexcrichton أعاد تشكيل المكتبة القياسية إلى مجموعة من المكتبات الأصغر مع تبعيات أكثر قابلية للفهم. يجب أن يكون الحصول على المكتبات الأساسية والتخصيص والراند والمجموعات للترجمة إلى الويب الآن أمرًا تافهًا تقريبًا.

إليك كيف أقترح معالجة هذا:

  • قم ببعض التجارب مع سلاسل أدوات Rust و LLVM لفهم كيفية عمل codegen للترجمة التبادلية إلى asm.js.
  • قم ببناء libcore باستخدام emscripten يدويًا وإثبات أنه يعمل على الويب.
  • قم بتعديل rustc و mk / platform.mk لفهم ثلاثية الهدف الخاصة بـ emscripten ، وإنتاج سلسلة أدوات متقاطعة لا تحتوي إلا على libcore.rlib
  • تعامل مع liballoc بالسماح له بالعمل مع النظام (في هذه الحالة المقدم من emscripten) malloc ، ثم الصناديق الأخرى الخالية من وقت التشغيل.

هذه بداية جيدة!

حسنًا ، لقد حاولت من خلال الخطوات الأولى ، ومن الواضح أنني واجهت مشاكل على الفور.

جمعت libcore إلى رمز البت باستخدام --emit bc ، وعند محاولة تجميعه باستخدام emcc -O0 ، أحصل على:

/Users/arcnor/emscripten-fastcomp/build/bin/llvm-nm: /tmp/tmpfTkmfj/core_0.o: Invalid CMPXCHG record.
/Users/arcnor/emscripten-fastcomp/build/bin/opt: /tmp/tmpfTkmfj/core.bc: error: Invalid CMPXCHG record
Traceback (most recent call last):
  File "/Users/arcnor/emscripten/emcc", line 1573, in <module>
    shared.Building.llvm_opt(final, link_opts)
  File "/Users/arcnor/emscripten/tools/shared.py", line 1335, in llvm_opt
    assert os.path.exists(target), 'Failed to run llvm optimizations: ' + output
AssertionError: Failed to run llvm optimizations:

لست متأكدًا مما إذا كان بإمكاني فعل أي شيء حيال هذا ، أم أنه لا يمكننا استخدام الناتج rustc --emit لهذا الغرض.

آسف إذا لم يكن هذا هو المكان المناسب للتعليق على هذا ...

لقد حاولت أيضًا باستخدام libnum ، وهو أبسط ، و bc يُنشئ بشكل صحيح ، لكني تلقيت تحذيرًا أثناء عملية emcc حول استخدام الثلاثي الخطأ والنتيجة. ليس لدى js أي من الوظائف داخل libnum ، لذلك أعتقد أنني ساذج جدًا هنا :)

Arcnor قد تسأل بعض أولئك الذين قاموا مسبقًا بتجميع اختبارات بسيطة باستخدام emscripten حول عمليتهم. لدي فقط القليل من الأفكار.

  • يتغير كود LLVM bitcode من إصدار إلى آخر ، والإصدار الذي يستخدمه Rust لا يكون دائمًا هو نفسه emscripten. يمكن أن يؤدي الحصول عليها باستخدام إصدار مماثل نسبيًا من LLVM إلى تحسين التوافق.
  • من رسالة الخطأ ، يبدو أنك تستخدم الواجهة الخلفية الجديدة "fastcomp" الخاصة بـ emscripten. قد يكون هذا أقل اختبارًا على أعباء العمل الصدئة من الخلفية القديمة. قد يؤدي اختيار الواجهة الخلفية القديمة يدويًا إلى نتائج مختلفة على الأقل.
  • يستخدم Emscripten بشكل عام الهدف الثلاثي الخاص به ، لذلك قد تحتاج إلى متابعة rustc لاستخدام نفس الهدف.

يبدو أن الخطأ الذي حدث عند محاولة تجميع libcore مرتبط بمشكلة emscripten هذه . يؤدي تجميع libcore إلى llvm bytecode إلى إنشاء تعليمات llvm الذرية ، لكن emscripten لا يدعم التعليمات الذرية.

قد تكون هناك طريقة للتغلب على هذا من جانب الصدأ ، ولكن استنادًا إلى التعليقات الواردة في قضية emscripten أعتقد أن الحصول على دعم الذرة في emscripten أمر منطقي للغاية.

إذا كان لدى emscripten النظام الأساسي الخاص به ، فربما يمكننا أن نتعامل مع جميع الذرات لمتغيراتها ذات الخيط الفردي ، لكنني أوافق على أنه سيكون من الأفضل الحصول على هذا في emscripten المنبع!

إذا لم أكن مخطئًا ، فإن الواجهة الخلفية الجديدة لـ "fastcomp" لـ emscripten هي شوكة لـ LLVM (بينما كانت الواجهة الخلفية السابقة مجرد طبقة فوق LLVM) ، لذلك من المحتمل أن يكون من الصعب ترقية إصدار LLVM من fastcomp ولن تتم ترقيته في كثير من الأحيان.

سيكون هذا مشكلة إذا كان يجب أن يكون متوافقًا مع إخراج الصدأ. على سبيل المثال ، الآن إصدار LLVM من fastcomp هو 3.3 ، بينما LLVM المستخدم بواسطة Rust هو 3.4.

تم إهمال الواجهة الخلفية القديمة لـ emscripten ويجب عدم استخدامها وفقًا للمستندات الرسمية ، لذلك ربما لا يكون خيارًا لاستخدامها.

يبدو أنني الشخص الوحيد الذي يحاول التجميع من أجل emscripten في الوقت الحالي.

للتسجيل ، إليك الأشياء التي جربتها:

  • التحويل البرمجي إلى رمز بايت (تم إنشاؤه بواسطة Rust's LLVM 3.4) وتمريره إلى fastcomp (تفرع من LLVM 3.3) ؛ يتسبب في تعطل fastcomp
  • التحويل البرمجي إلى IR وتحريره يدويًا حتى يصبح متوافقًا مع LLVM 3.3 وتمريره إلى fastcomp ؛ معقدة للغاية ، والعديد من الأشياء لتعديلها لأي كود غير تافه
  • يشير تجميع Rust stage1 باستخدام --llvm-root إلى fastcomp الخاص بـ emscripten ؛ هذا لم ينجح لأنهم أزالوا دعم ARM / MIPS / إلخ. في مفترقهم (أتلقى أخطاء من makefiles وأثناء الربط بسبب هذا)
  • تعديل الوحدة الفرعية git LLVM في كود مصدر Rust للإشارة إلى التزام قديم من عصر 3.3 ؛ الحصول على segfault في مرحلة ما في LLVM
  • يشير تجميع Rust باستخدام --llvm-root إلى LLVM 3.3 مُجمَّع مسبقًا (قادم من مستودع Uubuntu الرسمي) ؛ فشل الحصول على تأكيد في نهاية تجميع stage1 وثنائي rustc الناتج لا يعمل.

ما لم يكن لدى شخص ما فكرة ، استنتاجي هو أننا بحاجة إلى انتظار ترقية emscripten.

يبدو أن الروم يعمل ، نوعًا ما ؛ ربما هذا سوف يساعد

تحديث طفيف: تم تحديث emscripten-fastcomp إلى LLVM 3.4 ، وسيتم تحديثه إلى LLVM 3.5 لاحقًا.

tomaka هل حاولت فعل أي شيء مع الإصدار 3.4؟ لقد تمكنت من تجميع مثال الروم معه ، لكن أي شيء فشل أكثر مع وجود أخطاء غير مفهومة.

ibdknox 3.4 غير متوافق مع 3.5
حتى عالم الترحيب البسيط ينتج تأكيدًا فاشلاً: LLVM ERROR: 0 && "some i64 thing we can't legalize yet"

جلالة الملك. تمكنت من أخذ الناتج من rustc --emit ir foo.rust وتشغيله من خلال emscripten-Incoming. هل الصدأ موجود الآن على LLVM 3.5؟

يستخدم Rust LLVM 3.5 لفترة طويلة الآن. يمكنك أن تكون محظوظًا ولن يتم إنشاء أي شيء غير متوافق.
على سبيل المثال ، يتم تجميع هذا على ما يرام:

#[start]
fn main(_: int, _: *const *const u8) -> int {}

هذا ليس بسبب IR غير المتوافق:

fn main() { println!("hello world"); }

ibdknox http://www.reddit.com/r/rust_gamedev/comments/2n0x08/emscripten_experiments/
يبدو أن هناك حالات عدم توافق أقل مما كنت أعتقد.

كتحديث ، عندما أقوم بتجميع hello world باستخدام emscripten الذي تم تحديثه الآن إلى 3.5 ، أحصل على ما يلي:

Value:   %28 = call fastcc { i8, [0 x i8], [0 x i8] } @_ZN3fmt5write20h2c56fdda0b308d94DFAE({ i8*, void (i8*)** }* noalias nocapture dereferenceable(8) %arg.i, %"struct.core::fmt::Arguments[#3]"* noalias nocapture readonly dereferenceable(24) %__args31), !noalias !22
LLVM ERROR: Unrecognized struct value
Traceback (most recent call last):
  File "/Users/chris/Downloads/emsdk_portable/emscripten/incoming/emcc", line 1259, in <module>
    shared.Building.llvm_opt(final, link_opts)
  File "/Users/chris/Downloads/emsdk_portable/emscripten/incoming/tools/shared.py", line 1401, in llvm_opt
    assert os.path.exists(target), 'Failed to run llvm optimizations: ' + output
AssertionError: Failed to run llvm optimizations:

إليك كيف أقوم بالتجميع:

rustc --target i686-apple-darwin -C lto --emit ir foo.rust
emcc -v foo.ll -o test.html

يبدو أن الأشياء التي لا يبدو أنها تجلب fmt تعمل بشكل عام.

لقد كنت أقضي وقت فراغي الأسبوع الماضي في البحث في هذا الأمر. قرأت كتاب روست في وقت ما بين الصيف والآن وقد أحببت حقًا آليات اللغة ولكني بدأت مؤخرًا في تنفيذ شيء ما بها. أنا فقط على دراية بمجمع الصدأ فيما يتعلق بما تعلمته هذا الأسبوع ولكن آمل أن أتمكن من المساهمة.

لذا أعتقد أن أول شيء يجب ملاحظته بشأن ما تعلمته (لكن ذلك استغرق مني بعض الأمسيات لألاحظه) هو أن Rust انتقل إلى LLVM 3.6 في يوليو. لذا فإن الإصدارات الحالية من Rust و emscripten-fastcomp غير متوافقة.

حاولت تجميع الصدأ باستخدام --llvm-root للإشارة إلى emscripten-fastcomp 1.29.2 وحصلت على هذا الخطأ:

rustc: x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libcore
error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: http://doc.rust-lang.org/complement-bugreport.html
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'assertion failed: self.raw.hash != self.hashes_end', /Users/zen/Code/rust/src/libstd/collections/hash/table.rs:776


make: *** [x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/stamp.core] Error 101

للوصول إلى هذا الخطأ ، قمت بتكوين وإنشاء emscripten-fastcomp مع

../configure --enable-optimized --disable-assertions --enable-targets=host,js,arm,aarch64,mips

بدلاً من دليل emscripten الموصى به

../configure --enable-optimized --disable-assertions --enable-targets=host,js

على الرغم من أن Rust لا يحتاج إلى أن يتم تصميمه لجميع الأهداف ، إلا أنه يرتبط حاليًا دائمًا بـ LLVM مع دعم وحدة المعالجة المركزية المجمعة لجميع الأهداف. هذا حل بديل لمشكلة يمكن إصلاحها في المستقبل لذلك قد لا نحتاج دائمًا إلى ترجمة emscripten-fastcomp مع هذا التكوين.

بمجرد أن اكتشفت أن Rust قد انتقل إلى LLVM 3.6 ، بحثت عن آخر فرع على rust-lang / llvm كان LLVM 3.5. https://github.com/rust-lang/llvm/tree/rust-llvm-2014-07-24 جمعت مقابل ذلك بدلاً من emscripten-fastcomp ، فضولي لمعرفة ما سيحدث. لقد حصلت على نفس الخطأ بالضبط عند التجميع مقابل الانتقال الأخير لـ emscripton-fastcomp إلى LLVM 3.5. أعتقد أن هذا يعني أن Rust غير متوافق بطريقة ما مع LLVM 3.5 الآن ولا أتوقع خلاف ذلك حقًا.

لذا ننتظر الآن أو يتعين علينا الحصول على emscripten-fastcomp إلى LLVM 3.6: غمزة:

من الجدير بالذكر أنني قمت بتنزيل نسخة مؤرشفة 0.11 وتمكنت من إنتاج LLVM IR لـ hello world الذي يفهمه emcc ولكن بعد ذلك وصلت إلى مشكلة الربط. لقد كان من المثير جدًا رؤيتها تتخطى فهم كود البايت ولكن في الواقع ربطها سيحتاج إلى عمل في قاعدة كود الصدأ.

ألقيت نظرة خاطفة على دمج rust-lang / llvm في emscripten-fastcomp. في ذلك الوقت كان هناك 117 قسمًا متضاربًا على 43 ملفًا.

لقد ذكرت الحصول على Rust 0.11 و emcc 1.29.2 للوصول إلى مرحلة الربط. هذه هي النتيجة المحددة:

$ emcc -v hello.ll -o hello.js
INFO     root: (Emscripten: Running sanity checks)
WARNING: Linking two modules of different data layouts: '/Users/zen/.emscripten_cache/libc.bc' is 'e-p:32:32-i64:64-v128:32:128-n32-S128' whereas '/tmp/tmpv_yB8E/hello_0.o' is 'e-p:32:32-f64:32:64-f80:128-n8:16:32'
WARNING: Linking two modules of different target triples: /Users/zen/.emscripten_cache/libc.bc' is 'asmjs-unknown-emscripten' whereas '/tmp/tmpv_yB8E/hello_0.o' is 'i686-apple-darwin'
warning: incorrect target triple 'i686-apple-darwin' (did you use emcc/em++ on all source files and not clang directly?)
warning: unresolved symbol: _ZN2io5stdio12println_args20h0caae70b0e2eb347Iol7v0_11_0E
warning: unresolved symbol: _ZN10lang_start20h70f93b7d0a75f99atre7v0_11_0E

يبدو أن emcc / fastcomp يستبدل النقاط في الرموز بشرطة سفلية بينما يتوقع Rust البادئة بشرطة سفلية أخرى ولكني لست متأكدًا من ذلك. يظهر الرمز الأول الذي لم يتم حله بالشكل __ZN2io5stdio12println_args20h0caae70b0e2eb347Iol7v0.11.0E في libstd في بنية i686-apple-darwin. حتى لو كان بإمكاني الحصول على emcc لمعرفة كيفية العثور على هذا الرمز في المكتبات المبنية ، فأنا أعتقد أن libs تحتوي على رمز آلة بينما ستحتاج emcc إلى رموز بايت LLVM. أعتقد أنني أتذكر شخصًا ما ذكر أنه يحتاج إلى تجميع المكتبة القياسية لـ emscripten. سيكون هذا جزءًا من الحاجة لذلك.

إذن ، هذه هي الخطوات التالية التي أتطلع إلى تجربتها والعمل عليها إذا كان أي شخص يريد أن يأخذها بنفسه. (أو اسمحوا لي أن أعرف كم أنا على صواب أو خطأ).

  • دمج rust-lang / llvm في emscripten-fastcomp
  • قم ببناء الصدأ باستخدام fastcomp المدمج بدون دعم الواجهة الخلفية لـ JS
    على أمل أن يكون هذا اختبارًا جيدًا لسلامة عملية الدمج.
  • أضف ثلاثية emscripten إلى Rust وقم ببنائها
    من بين ما يمكنني قوله ، هناك عدد من الملفات التي أحتاج إلى تغييرها أو إضافتها.

    • عضو الكنيست / cfg / asmjs-unknown-emscripten.mk

    • rt / arch / asmjs / {morestack.S، record_sp.S} (قد يكون فارغًا؟)

      هذه الملفات مطلوبة لبناء morestack.a لكي يدعم Rust مكدس LLVM المقسم. إذا كنت أتذكر بشكل صحيح مكدس Emscripten هو الرأس أيضًا. يستخدم الطرف المقابل من الكومة باعتباره المكدس وبما أنه لا يمكنك تغيير حجم المصفوفة لإنشاء مقاطع مكدس جديدة بالنسبة لـ asmjs. لقد رأيت حقلاً في TargetOption في ملفات الهدف librustc_back التي نأمل أن تعطل هذا.

    • librustc_trans / trans / cabi_asmjs.rs

    • librustc_trans / عبر / cabi.rs

      لست متأكدًا مما إذا كانت هناك حاجة إلى هذه ، حاليًا مجرد تخمين.

    • librustc_back / target / asmjs_unknown_emscripten.rs

    • librustc_back / asmjs.rs

    • librustc_syntax / abi.rs

    • librustc_back / back / write.js configuration_llvm ()

    • librustc_llvm / lib.rs static_link_hack_this_sucks ()

  • تنفيذ واجهات النظام المفقودة
    رأيت في نوفمبر تمت إزالة libgreen. نظرًا لأن emscripten يحتاج إلى انتظار طريقة ما للمشاركة مع العاملين في المتصفحات ، إذا حدث ذلك ، فسيحتاج شيء مثل libgreen إلى استعادة أو تلميع pthread بطريقة معينة خصيصًا لـ emscripten مثل كيفية إنشاء الصدأ لـ pthreads أو windows سلاسل api.

أنا أيضا. ربما أجزاء أخرى لست على علم بها.

"دمج rust-lang / llvm في emscripten-fastcomp"

قد لا ترغب في القيام بذلك - يعتمد Emscripten على pnacl-llvm / pnacl-clang ، لذا فأنت تقوم بإنشاء شوكة بها رقع على بقع ، والتي من المحتمل أن تكون مؤلمة. إذا كنت مهتمًا ، يمكنك الاطلاع على بعض تفاصيل التفرع في التحقيق الذي أجريته لدمج Emscripten من r33 -> r34 على https://github.com/kripken/emscripten-fastcomp/issues/51#issuecomment -62323164 .

سمعت أن pnacl يخطط لتتبع المنبع أقرب قليلاً من ذي قبل ولكن لا يمكنني رؤية أي مشكلة ذات صلة في متعقب مشكلة pnacl للتحديث إلى 3.6 لذلك قد يستغرق الأمر بعض الوقت (خاصة بالنظر إلى 3.6 فقط المتفرعة منذ 5 أيام!). .. أعتقد أنه يمكنك إنشاء مشكلة؟ إذا قررت ضد مفترق Emscripten الخاص بك ، أرى خيارين - انتظار pnacl أو مساعدة Emscripten على الخروج من pnacl إلى المنبع.

تحرير: تصحيح "الآن" إلى "لا". فرق حاسم.

إنني أبذل جهدًا هائلاً في عملية الفرز حتى نكون مستعدين لـ 1.0. كجزء من هذا ، أقوم بنقل الأشياء التي تشبه قائمة الرغبات إلى RFCs repo ، حيث يجب مناقشة / تحديد أولويات الأشياء الجديدة الرئيسية.

تم نقل هذه المشكلة إلى RFCs repo: rust-lang / rfcs # 604

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات