1 poin oleh GN⁺ 2025-04-14 | 1 komentar | Bagikan ke WhatsApp
  • rustc_codegen_clr adalah proyek yang menghasilkan kode Rust ke C dan .NET, dan sedang bersiap untuk presentasi Rust Week seiring peningkatan tingkat kelulusan tes
  • Tingkat kelulusan tes Rust core naik dari 92% dua bulan lalu menjadi 95,9%, dan sekitar 65 tes yang tersisa tampaknya memiliki penyebab yang saling mirip
  • Perbaikan terbaru berfokus pada intrinsic integer 128-bit, checked arithmetic, dan subslicing; sisi .NET juga kini dapat menjalankan 96,3% tes Rust core
  • Dengan target lebih banyak kompiler C, proyek ini bertujuan menghasilkan output yang mendekati C99 atau ANSI C serta menggunakan API POSIX standar; beberapa kompiler ANSI C berhasil menjalankan program Rust yang sangat sederhana
  • Optimasi untuk mengurangi ukuran file pada pembuatan kode C berskala besar dan refactoring IR internal juga berjalan bersamaan, menjadi fondasi untuk memperluas jangkauan eksekusi Rust ke platform lama atau khusus

Presentasi Rust Week dan status proyek

  • Presentasi proyek rustc_codegen_clr dijadwalkan di Rust Week yang digelar di Utrecht, Belanda
  • Presentasi ini berupaya menyeimbangkan aksesibilitas bagi pemula dengan topik tingkat lanjut, yaitu kompilasi Rust ke C
  • Dalam beberapa bulan terakhir, perbaikan tes, kompatibilitas kompiler C, peningkatan performa, dan refactoring internal berjalan bersamaan

Tingkat kelulusan tes Rust core meningkat

  • Tingkat kelulusan tes Rust core meningkat dari 92% dua bulan lalu menjadi 95,9%
  • Masih ada sekitar 65 tes yang tersisa, tetapi penyebabnya tampak saling mirip sehingga karakter perbaikan yang tersisa relatif sudah menyempit
  • Sisi .NET juga terdampak perbaikan yang sama dan kini dapat menjalankan 96,3% tes Rust core

Perbaikan integer 128-bit dan checked arithmetic

  • Sebagian besar peningkatan berasal dari perbaikan intrinsic 128-bit, checked arithmetic, dan subslicing
  • Intrinsic popcount di C terdiri dari tiga jenis: __builtin_popcount, __builtin_popcountl, dan __builtin_popcountll
    • Berbeda dari namanya, __builtin_popcountll bekerja pada unsigned long long, bukan __int128_t
    • Berdasarkan x86_64 Linux dan GCC, unsigned long maupun unsigned long long sama-sama 64-bit
  • Implementasi sebelumnya pada intrinsic bit counting diam-diam memotong integer 128-bit menjadi 64-bit saat menghitung, sehingga menghasilkan hasil yang salah
  • popcount 128-bit diemulasikan dengan menghitung jumlah set bit pada 64-bit bawah dan 64-bit atas secara terpisah, lalu menjumlahkannya
  • Overflow check untuk perkalian 128-bit ditangani dengan cara sederhana karena belum ditemukan metode yang efisien
    • Jika b bukan 0 dan (a * b) / b == a, maka dianggap tidak terjadi overflow
    • Ini bukan metode yang revolusioner, tetapi cukup untuk meloloskan beberapa tes tambahan

Bug subslicing dan intrinsic fallback

  • Bug subslicing disebabkan oleh sizeof yang hilang, sehingga pointer data slice di-offset dalam satuan byte, bukan satuan elemen
  • Bug ini hanya rusak saat melakukan subslicing dari akhir slice, bukan dari awal, dan karena pola ini terutama dipakai dalam pattern matching, bug tersebut lama tidak ditemukan
  • Pada byte slice dan string slice, ukuran byte dan UTF-8 code unit adalah 1 byte sehingga tes internalnya lolos, dan masalah baru terlihat di seluruh suite tes Rust compiler
  • Sebagian intrinsic dapat menggunakan implementasi fallback milik Rust compiler tanpa perlu diimplementasikan langsung
  • carrying_mul_add harus melakukan perkalian pada integer yang 2 kali lebih besar daripada input
    • Hingga 64-bit masih bisa ditangani, tetapi input 128-bit membutuhkan integer 256-bit
    • LLVM mendukung integer 256-bit, tetapi C dan .NET tidak
  • Implementasi fallback Rust compiler melakukan perkalian dan penjumlahan 256-bit dengan integer 128-bit, sehingga dapat dijadikan referensi untuk mengemulasikan operasi 128-bit hanya dengan integer 64-bit

Dukungan untuk lebih banyak kompiler C

  • Proyek ini berupaya meningkatkan kemungkinan kode Rust berjalan di lebih banyak kompiler C khusus
  • Ada kasus ketika kode Rust berjalan di Game Boy, dikompilasi hanya dengan perintah move, atau dijalankan dengan Holly C dari Temple OS
  • Kompiler C proprietary yang tidak dapat diakses memang tidak bisa didukung secara langsung, tetapi dengan memperluas cakupan dukungan kompiler C obscure, peluang kode Rust berjalan di lingkungan seperti itu meningkat
  • Banyak platform tidak didukung karena kurangnya dokumentasi dan aksesibilitas
  • Terkait diskusi penulisan sebagian Git dengan Rust, platform proprietary seperti NonStop tidak mendukung Rust, LLVM, maupun GCC, sehingga bisa muncul masalah penurunan atau penghentian dukungan Git
  • Jika Rust dikompilasi ke C, secara teoretis Rust dapat dijalankan di mana pun C tersedia
    • Belum pasti apakah masalah di semua platform dapat diakali
    • Untuk memperoleh kompiler bagi platform tersebut secara legal, perlu membeli server, dan biayanya jauh melampaui anggaran
    • Kemungkinan Rust segera berjalan di platform semacam ini tampaknya kecil

Strategi output C saat ini

  • Rencana saat ini adalah menghasilkan kode yang sedapat mungkin mematuhi standar C99 atau mendekati ANSI C
  • Karena beberapa dukungan threading diperlukan untuk inisialisasi thread-local, arahnya adalah hanya menggunakan API POSIX standar
  • Proyek ini memiliki implementasi fallback sendiri untuk intrinsic tertentu, dan daftarnya ditambah secara bertahap
  • Beberapa kompiler ANSI C berhasil menjalankan program Rust yang sangat sederhana
  • Untuk saat ini, targetnya adalah membuat platform yang masih sulit didukung dapat ditambahkan dengan relatif mudah ketika kebutuhan muncul

Peningkatan kecil pada performa dan ukuran file

  • Output literal integer kini mencerminkan bahwa integer yang lebih kecil dari 2^32 sama panjang atau lebih pendek dalam decimal dibanding hexadecimal
    • 255 lebih pendek 1 byte daripada 0xFF
    • 65536 juga lebih pendek daripada 0xFFFF
    • Karena prefix 0x, representasi hexadecimal tidak menjadi lebih kecil sebelum 2^32
  • Dalam kasus ekstrem ketika seluruh Rust compiler dikonversi ke C, pernah dihasilkan C source file hingga 1GB, sehingga pengurangan ukuran file dalam persentase kecil pun berpengaruh
  • Directive #line yang digunakan untuk menyisipkan debug info juga dibuat lebih cerdas
    • Nama source file hanya disertakan ketika berubah
    • Saat debug info digunakan, ini dapat mengurangi ukuran file secara signifikan

Refactoring internal dan perapihan IR

  • Sebagian fungsi internal rustc_codegen_clr dipisahkan menjadi crate tersendiri untuk mempercepat incremental build
  • Pekerjaan untuk berpindah ke interned IR yang lebih efisien secara memori juga sedang berjalan
  • IR lama memiliki rvalue/lvalue yang tidak lazim dan sulit dipetakan ke C, dan masalahnya membesar pada fitur Rust seperti dynamically sized type
  • Sebagai contoh, pada custom dynamically sized type seperti MyStr, &self.s terlihat sederhana tetapi sebenarnya harus menangani metadata fat pointer
    • Dengan compound literal C99, struct FatPtr_str dapat dibuat dalam satu baris
    • Di ANSI C, data dan meta harus masing-masing dimasukkan ke variabel sementara lalu dikembalikan
  • Karena satu baris Rust dan MIR berkembang menjadi beberapa baris C, IR lama menanganinya dengan pendekatan scope internal yang memiliki temporary local dan sub-statement
  • Pendekatan baru memiliki tahap setup yang lebih kompleks, tetapi membuat keseluruhan IR lebih sederhana; setelah kasus sulit terakhir terselesaikan, fungsi terkait di IR lama dapat dihapus

Pekerjaan berikutnya

  • Masa pengerjaan proyek sudah sekitar 1,5 tahun, dan semakin sedikit bug, semakin banyak waktu yang diperlukan untuk menemukan bug yang tersisa
  • Bagian kedua “Rust panics under the hood” sedang dikerjakan, dengan tujuan menguraikan proses panic Rust langkah demi langkah
  • Penjelasan pembuatan panic message saja sudah berdurasi 10 menit, sehingga tulisan itu juga sedang dipertimbangkan untuk dibagi dua
  • Sebuah memory profiler kecil dan akurat untuk Rust juga sedang dikerjakan
    • Skala kodenya sekitar 2K LOC
    • Jadwalnya ketat, tetapi penulis ingin menulis artikel terkait dalam beberapa minggu

1 komentar

 
GN⁺ 2025-04-14
Komentar Hacker News
  • Masih menunggu salah satu frontend atau backend Rust alternatif yang memungkinkan Rust di-bootstrap di alpha, hppa, m68k, sh4
    Awalnya proyek rustc_codegen_gcc menjanjikan ini, tetapi pada akhirnya tidak memenuhinya
    • Saya penasaran apakah keempat platform itu benar-benar dipakai semuanya, atau hanya kriteria arbitrer untuk dianggap sebagai dukungan platform yang lengkap
    • Bukankah m68k-unknown-linux-gnu sudah digabungkan sebagai target Tier-3 Rust? [0]
      [0] https://github.com/rust-lang/compiler-team/issues/458
    • Apakah target itu sudah ditinggalkan? Terakhir saya dengar masih dalam pengembangan
    • Rust bahkan belum mendukung OpenBSD on x86_64 dengan baik
  • fractalfir benar-benar orang yang berbakat. Saya sering melihatnya di Rust Reddit; saya tidak terlalu paham soal compiler, tetapi sepertinya orang-orang cukup menyukai hasil kerjanya
    • Setahu saya dia masih cukup muda. Semoga masa depannya cerah
  • Dari kalimat “sebagian besar komponen std berfungsi sekitar 95% di .NET dan 80% di C”, judul HN melewatkan fakta bahwa tingkat kelulusan 95% hanya berlaku untuk .NET
    Untuk GCC/Clang, angkanya “hanya” 80%
    • README sudah ketinggalan zaman. Angka itu dari awal tahun ini, dan sekarang seperti ini
      | .NET Core tests | 1764 | 48 | 20 | 96.29% |
      | C Core tests | 1712 | 71 | 8 | 95.59% |
  • Ada banyak penggunaan menarik yang bisa dicoba dengan ini. Yang pertama terlintas adalah peningkatan interoperabilitas dengan bahasa lain seperti Python
    • Dengan PyO3, interoperabilitas sudah sangat bagus. Pengecualiannya adalah ketika orang ingin membangun bagian Rust dari source dan merasa repot harus memasang compiler Rust
      Hack ini adalah backend compiler Rust. Karena backend menerima instruksi spesifik platform sebagai input, kode C nontrivial yang dihasilkan tidak akan portabel
      Pengguna harus menerima source spesifik platform yang sudah dibuat sebelumnya, atau memasang compiler Rust dan backend ini lalu membuatnya sendiri
    • Apa manfaat baru yang diberikan ini yang belum bisa dilakukan dengan fungsi extern "c" di Rust?
  • Apakah ini dari LLVM IR ke C? Atau dari Rust AST ke C?
    • Saya menemukan jawabannya di README proyek
      “Representasi .NET IR saya terpetakan dengan baik ke C, dan berkat itu saya bisa menambahkan dukungan untuk mengompilasi Rust ke C hanya dengan 2–3 ribu baris kode. Hampir seluruh codebase digunakan kembali, dan kode khusus C maupun .NET hanya ada pada tahap paling akhir kompilasi”
    • Ini adalah backend rustc, yaitu alternatif untuk backend LLVM, GCC, dan Cranelift
      Awalnya dimulai sebagai backend .NET, tetapi kemudian diketahui bahwa pendekatannya juga bisa dengan mudah mendukung pembuatan kode C, jadi ditambahkan. Ia mengubah apa yang diberikan rustc menjadi intermediate representation (IR) miliknya sendiri lalu memprosesnya
  • Compiler dari Nim ke C memiliki tingkat kelulusan tes 100%
  • Tapi apakah jaminan ala Rust juga tetap dipertahankan?
    • Kalau transformasinya sendiri tidak punya bug, tidak ada alasan untuk tidak. Jaminan statis sudah diperiksa dan ada dengan asumsi kode Rust yang ditransformasikan adalah kode Rust yang sudah bisa dikompilasi oleh compiler Rust biasa
      Jaminan dinamis seperti pemeriksaan batas juga bisa diimplementasikan tanpa masalah di runtime C
    • Apakah ada alasan kenapa tidak bisa?
  • Sangat keren. Arah C ke Rust juga pasti bagus
    • Untuk program yang tidak trivial, kemungkinan seluruhnya harus dimasukkan ke dalam satu blok unsafe besar
      C tidak membawa semua informasi yang perlu diketahui secara eksplisit agar bisa dikompilasi di Rust
    • Mark Russinovich baru-baru ini memberi presentasi di konferensi Rust di Inggris yang menyebut upaya konversi C→Rust berskala besar di internal Microsoft
      https://www.youtube.com/watch?v=1VgptLwP588
    • Alat seperti itu sudah ada. Masalahnya, mereka banyak memakai blok unsafe, dan biasanya kode hasilnya tidak terasa Rust-idiomatis
      Misalnya, mengubah mesin status berbasis variabel global menjadi mesin status yang lebih Rust-idiomatis dengan enum bernama dan semacamnya akan sangat sulit
      Mungkin bisa dengan bantuan AI yang cukup kuat, tetapi AI masih jauh dari mampu benar-benar melakukan hal yang dimaksud, jadi sulit dibilang sudah siap. Dibutuhkan juga memori yang cukup untuk memasukkan seluruh codebase C dan Rust ke dalam context window; setelah kode melewati ukuran tertentu, ini cepat sekali membutuhkan hardware yang sangat mahal. Kalau tidak, seperti banyak LLM pendamping coding, ia akan menghasilkan kode-kode yang tidak saling kompatibel secara independen
      Meski begitu, jika ingin memperluas proyek C dengan Rust atau menulis ulang sedikit demi sedikit, https://c2rust.com/ sudah bisa langsung dipakai
    • Lihat https://github.com/immunant/c2rust
    • Manfaat apa yang diharapkan dari ini?
  • Rust ke C? Kenapa repot-repot begitu. Pakai C saja. Kalau bisa memahami Rust, pasti bisa memahami dan memakai C dengan mahir juga
    • Untuk mendapatkan keunggulan Rust sekaligus kompatibilitas dan dukungan arsitektur yang luas dari gcc/compiler C secara umum
      Rust adalah bahasa modern dengan manajemen paket, alat build/test terpadu yang lebih sederhana, beban warisan yang jauh lebih sedikit, serta fitur dan sintaks tingkat tinggi yang benar-benar disukai orang
      C juga bersih, tetapi codebase yang kompleks mendapat manfaat dari bahasa modern yang membantu membuat abstraksi yang kokoh sambil mempertahankan kecepatan C. Tentu saja borrow checker dan keamanan memori juga tidak boleh dilupakan
    • Untuk mendapatkan keunggulan Rust di platform yang tidak didukung rustc. Cukup intuitif
    • Tampaknya ada cukup banyak unsur “mencoba karena bisa”, tetapi juga karena ada banyak platform yang tidak didukung Rust
      Jika ada konverter Rust→C yang menghasilkan kode C yang cukup standar, itu bisa menjembatani celah tersebut