Saya telah menghabiskan beberapa waktu untuk mengatasi masalah ini dan rustc sekarang menghasilkan kode yang dapat diterjemahkan oleh emscripten, tetapi javascript yang dikompilasi gagal ketika mencapai fungsi runtime. Langkah selanjutnya adalah mulai membangun runtime menggunakan emcc
sebagai compiler. Matikan semua hal yang tidak dibangun di belakang EMSCRIPTEN
ifdefs.
Emscripten menambahkan cara untuk memperlakukan perakitan sebaris sebagai javascript, sehingga semua bagian runtime yang tidak dibangun dengan emscripten dapat diimplementasikan sejalan dengan javascript.
Sebagai alternatif, kita dapat mengimplementasikan kembali runtime sedikit demi sedikit dalam javascript dan tidak perlu repot mengkompilasinya dari C++ sama sekali. Pendekatan ini tidak disarankan.
Lihat juga #3608.
Akan tetap menyenangkan; tidak pada tonggak kedewasaan apa pun.
Masih akan menyenangkan, tetapi tidak terlalu penting. Ini seharusnya menjadi lebih mudah, karena banyak runtime sedang ditulis ulang dengan karat.
Lihat juga https://github.com/mozilla/rust/issues/7282
Sekarang runtime ditulis dalam Rust, bagaimana hal itu mengubah prospek bug ini? Seberapa sulitkah menjalankan Hello World tanpa runtime melalui emscripten?
Seharusnya tidak terlalu sulit untuk menambahkan dukungan yang sangat bagus untuk emscripten sekarang. Ini sudah cukup banyak bekerja dengan rust-core. Di kompiler kita perlu menambahkan dukungan untuk triple target yang tepat, mengatur berbagai atribut target dengan benar, lalu menutup beberapa bagian runtime yang saat ini tidak dapat bekerja di js, threading, dan pengalihan konteks.
Setelah mode penjadwalan 1:1 menjadi lebih matang, kami bahkan mungkin dapat menambahkan dukungan untuk tugas melalui pekerja web, meskipun saat ini akan memerlukan solusi pengiriman pesan yang berbeda. Bergantung pada dukungan paralelisme apa yang ditambahkan ke js/emscripten, kami akhirnya dapat mendukung semantik penyampaian pesan rust dengan tepat.
@brson : Saya pikir #10780 akan menjadi pemblokir terbesar saat ini. Rust akan menampilkan bantalan pendaratan dengan panggilan untuk memperbarui ukuran yang digunakan untuk melakukan keamanan tumpukan melalui dukungan tumpukan tersegmentasi LLVM.
Berkat -Z no-landing-pads
ini sekarang berfungsi dengan baik! Menambahkan dukungan eksplisit untuk ini ke pustaka standar dimungkinkan, tetapi sebagian besar tetap tidak akan berfungsi (file, tcp, udp, dll.) jadi saya rasa itu tidak perlu. Jika dan ketika perpustakaan standar mengambil dukungan berdiri sendiri, itu akan mulai bekerja dan kami dapat membuka lebih banyak masalah berdasarkan fungsionalitas yang dapat kami petakan ke JavaScript.
Jika tidak apa-apa, saya sebenarnya ingin membiarkan ini terbuka untuk saat ini. Saya pikir melakukan ini akan menjadi langkah maju yang baik untuk memastikan perpustakaan standar dapat diperluas dan dapat berjalan di sejumlah platform.
Saya setuju bahwa sebagian besar pekerjaan mungkin sudah selesai, dan ini mungkin perlu libemscripten
untuk menyediakan I/O khusus emscripten, tetapi saya pikir mungkin ada cukup banyak hambatan yang terjadi sehingga ini layak untuk ditinggalkan masalah terbuka untuk (ini masih merupakan proyek yang menarik!)
@alexcrichton : Tidak mungkin menyediakan konkurensi perpustakaan standar dan dukungan I/O untuk emscripten. Paling-paling, itu bisa ditampilkan ke konsol untuk stdout/stderr. Saya tidak dapat memikirkan hal apa pun di perpustakaan standar yang akan menjadi ide bagus untuk target emscripten tetapi bukan yang berdiri sendiri, di luar implementasi pengalokasi default.
Pembaruan status:
@alexcrichton Telah
Inilah cara saya menyarankan untuk mengatasi ini:
Itu awal yang cukup bagus!
Oke, jadi saya mencoba dengan langkah pertama, dan jelas langsung mendapat masalah.
Saya mengkompilasi libcore
ke bitcode dengan --emit bc
, dan ketika mencoba mengompilasinya dengan emcc -O0
, saya mendapatkan:
/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:
Tidak yakin apakah saya dapat melakukan sesuatu tentang ini, atau karena kami tidak dapat menggunakan output rustc --emit
untuk ini.
Maaf jika ini bukan tempat untuk berkomentar tentang ini...
Saya juga mencoba dengan libnum
, yang lebih sederhana, dan bc
menghasilkan dengan benar, tetapi saya mendapat peringatan selama proses emcc
tentang menggunakan triple yang salah dan hasil . js tidak memiliki fungsi apa pun di dalam libnum
, jadi saya pikir saya terlalu naif di sini :)
@Arcnor Anda mungkin bertanya kepada beberapa dari mereka yang sebelumnya telah mengkompilasi tes sederhana dengan emscripten tentang prosesnya. Saya hanya punya beberapa ide.
Kesalahan saat mencoba mengkompilasi libcore
tampaknya terkait dengan masalah emscripten ini . Mengkompilasi libcore
ke llvm bytecode menghasilkan instruksi atom llvm, tetapi emscripten tidak mendukung instruksi atom.
Mungkin ada cara untuk mengatasi ini dari sisi karat, tetapi berdasarkan komentar di masalah emscripten, saya pikir mendapatkan dukungan untuk atom ke dalam emscripten paling masuk akal.
Jika emscripten memiliki platformnya sendiri, kami mungkin dapat melakukan cfg-out semua atom untuk varian utas tunggal mereka, tetapi saya setuju bahwa akan lebih baik untuk memiliki ini di emscripten hulu!
Jika saya tidak salah, backend "fastcomp" baru dari emscripten adalah cabang dari LLVM (sementara backend sebelumnya hanya satu lapisan di atas LLVM), jadi versi LLVM dari fastcomp mungkin sulit untuk ditingkatkan dan tidak akan ditingkatkan sering.
Ini akan bermasalah jika perlu kompatibel dengan output Rust. Misalnya saat ini versi LLVM dari fastcomp adalah 3.3, sedangkan LLVM yang digunakan oleh Rust adalah 3.4.
Backend emscripten lama sudah usang dan tidak boleh digunakan sesuai dengan dokumen resmi, jadi mungkin bukan pilihan untuk menggunakannya.
Sepertinya saya satu-satunya yang mencoba mengkompilasi untuk emscripten untuk saat ini.
Sebagai catatan, berikut adalah hal-hal yang saya coba:
--llvm-root
menunjuk ke fastcomp emscripten; itu tidak berhasil karena mereka menghapus dukungan untuk ARM/MIPS/dll. di garpu mereka (saya mendapatkan kesalahan dari makefile dan selama tautan karena ini)--llvm-root
menunjuk ke LLVM 3.3 yang telah dikompilasi sebelumnya (berasal dari repo ubuntu resmi); mendapatkan pernyataan gagal di akhir kompilasi stage1 dan biner rustc yang dihasilkan tidak berfungsi.Kecuali seseorang memiliki ide, kesimpulan saya adalah bahwa kita perlu menunggu emscripten untuk meningkatkan.
rum tampaknya berhasil, agak; mungkin ini akan membantu
Pembaruan kecil: emscripten-fastcomp telah diperbarui ke LLVM 3.4, dan akan diperbarui ke LLVM 3.5 nanti.
@tomaka sudahkah Anda mencoba melakukan sesuatu dengan versi 3.4? Saya bisa mendapatkan contoh rum yang dikompilasi dengannya, tetapi ada lagi yang gagal dengan kesalahan yang tidak dapat dipahami.
@ibdknox 3.4 tidak kompatibel dengan 3.5
Bahkan hello world yang sederhana menghasilkan pernyataan yang gagal: LLVM ERROR: 0 && "some i64 thing we can't legalize yet"
Hm. Saya dapat mengambil output dari rustc --emit ir foo.rust
dan menjalankannya melalui emscripten-incoming. Apakah karat sekarang di LLVM 3.5?
Rust telah menggunakan LLVM 3.5 sejak lama. Anda bisa beruntung dan tidak ada yang tidak kompatibel yang dihasilkan.
Misalnya ini mengkompilasi dengan baik:
#[start]
fn main(_: int, _: *const *const u8) -> int {}
Ini bukan karena IR yang tidak kompatibel:
fn main() { println!("hello world"); }
@ibdknox http://www.reddit.com/r/rust_gamedev/comments/2n0x08/emscripten_experiments/
Sepertinya ada lebih sedikit ketidakcocokan daripada yang saya kira.
Sebagai pembaruan, ketika saya mengkompilasi hello world dengan emscripten yang sekarang telah diperbarui ke 3.5, saya mendapatkan yang berikut:
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:
Inilah cara saya mengkompilasi:
rustc --target i686-apple-darwin -C lto --emit ir foo.rust
emcc -v foo.ll -o test.html
Namun, hal-hal yang tampaknya tidak berhasil pada umumnya tampaknya berhasil.
Saya telah menghabiskan waktu luang saya minggu lalu untuk melihat ini. Saya membaca buku rust antara musim panas dan sekarang dan sangat menyukai mekanika bahasanya tetapi baru-baru ini mulai menerapkan sesuatu dengannya. Saya hanya memiliki pengetahuan tentang kompiler karat tentang apa yang saya pelajari minggu ini tetapi berharap saya dapat berkontribusi.
Jadi saya kira hal pertama yang perlu diperhatikan dari apa yang saya pelajari (tetapi saya perlu beberapa malam untuk memperhatikannya) adalah bahwa Rust pindah ke LLVM 3.6 pada bulan Juli. Jadi versi Rust dan emscripten-fastcomp saat ini tidak kompatibel.
Saya mencoba mengkompilasi rust dengan --llvm-root
menunjuk ke emscripten-fastcomp 1.29.2 dan mendapatkan kesalahan ini:
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
Untuk mendapatkan kesalahan ini, saya mengonfigurasi dan membuat emscripten-fastcomp dengan
../configure --enable-optimized --disable-assertions --enable-targets=host,js,arm,aarch64,mips
Alih-alih panduan emscripten direkomendasikan
../configure --enable-optimized --disable-assertions --enable-targets=host,js
Meskipun Rust tidak perlu dibuat untuk semua target, saat ini Rust selalu terhubung dengan LLVM dengan dukungan CPU yang dikompilasi untuk semua target. Ini adalah solusi untuk masalah yang dapat diperbaiki di masa mendatang sehingga kami mungkin tidak perlu selalu mengkompilasi emscripten-fastcomp dengan konfigurasi tersebut.
Setelah saya menemukan bahwa Rust telah pindah ke LLVM 3.6, saya mencari cabang terakhir di rust-lang/llvm yaitu LLVM 3.5. https://github.com/rust-lang/llvm/tree/rust-llvm-2014-07-24 Saya mengkompilasinya alih-alih emscripten-fastcomp, penasaran ingin melihat apa yang akan terjadi. Saya mendapatkan kesalahan yang sama persis ketika mengkompilasi terhadap emscripton-fastcomp baru-baru ini pindah ke LLVM 3.5. Saya menganggap ini berarti bahwa Rust dalam beberapa hal tidak kompatibel dengan LLVM 3.5 sekarang dan saya tidak akan mengharapkan sebaliknya.
Jadi sekarang kita menunggu atau harus mendapatkan emscripten-fastcomp ke LLVM 3.6 :wink:
Patut disebutkan bahwa saya mengunduh salinan 0,11 yang diarsipkan dan mampu menghasilkan LLVM IR untuk hello world yang dipahami emcc
tetapi kemudian mencapai masalah penautan. Sangat menarik untuk melihatnya melewati pemahaman kode byte tetapi sebenarnya untuk menghubungkannya akan membutuhkan pekerjaan di basis kode karat.
Saya mengintip penggabungan rust-lang/llvm ke dalam emscripten-fastcomp. Pada saat itu ada 117 bagian yang saling bertentangan lebih dari 43 file.
Saya menyebutkan mendapatkan Rust 0.11 dan emcc 1.29.2 untuk sampai ke tahap penautan. Ini adalah hasil spesifiknya:
$ 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
Tampaknya emcc/fastcomp mengganti titik-titik dalam simbol dengan garis bawah sementara Rust mengharapkan awalan dengan garis bawah lain, tetapi saya tidak terlalu yakin tentang ini. Simbol unresolved pertama muncul sebagai __ZN2io5stdio12println_args20h0caae70b0e2eb347Iol7v0.11.0E
di libstd di i686-apple-darwin build. Bahkan jika saya bisa mendapatkan emcc untuk mengetahui bagaimana menemukan simbol ini di perpustakaan yang dibangun, saya menduga bahwa lib berisi kode mesin sementara emcc akan membutuhkan kode byte LLVM. Saya pikir saya ingat seseorang yang menyebutkan perlu mengkompilasi perpustakaan standar untuk emscripten. Ini akan menjadi bagian dari kebutuhan untuk itu.
Jadi, inilah langkah selanjutnya yang ingin saya coba dan kerjakan jika ada yang ingin mencobanya sendiri. (Atau dapat memberi tahu saya seberapa benar atau salah saya.)
IO juga. Mungkin bagian lain yang tidak saya ketahui.
"Gabungkan rust-lang/llvm ke dalam emscripten-fastcomp"
Anda mungkin tidak ingin melakukan ini - Emscripten didasarkan pada pnacl-llvm/pnacl-clang sehingga Anda membuat garpu dengan tambalan di tambalan, yang mungkin akan menyakitkan. Jika Anda tertarik, Anda dapat melihat beberapa detail percabangan dalam penyelidikan yang saya lakukan untuk penggabungan Emscripten dari r33 -> r34 di https://github.com/kripken/emscripten-fastcomp/issues/51#issuecomment -62323164 .
Saya mendengar bahwa pnacl berencana melacak upstream sedikit lebih dekat daripada sebelumnya, tetapi saya tidak dapat melihat masalah yang relevan di pelacak masalah pnacl untuk memperbarui ke 3.6 jadi mungkin perlu waktu (terutama mengingat 3.6 hanya bercabang 5 hari yang lalu!). ..Saya kira Anda bisa membuat masalah? Jika Anda memutuskan untuk tidak menggunakan garpu Emscripten Anda sendiri, saya melihat dua opsi - menunggu pnacl atau membantu Emscripten turun dari pnacl dan ke hulu.
Sunting: dikoreksi 'sekarang' menjadi 'tidak'. Perbedaan yang krusial.
Saya melakukan upaya triase besar-besaran untuk menyiapkan kita untuk 1.0. Sebagai bagian dari ini, saya memindahkan hal-hal yang seperti daftar keinginan ke repo RFC, karena di situlah hal-hal baru yang besar harus didiskusikan/diprioritaskan.
Masalah ini telah dipindahkan ke repo RFC: rust-lang/rfcs#604
Komentar yang paling membantu
Saya melakukan upaya triase besar-besaran untuk menyiapkan kita untuk 1.0. Sebagai bagian dari ini, saya memindahkan hal-hal yang seperti daftar keinginan ke repo RFC, karena di situlah hal-hal baru yang besar harus didiskusikan/diprioritaskan.
Masalah ini telah dipindahkan ke repo RFC: rust-lang/rfcs#604