WebAssembly Nedir? Tarayıcıda Wasm Rehberi

## WebAssembly Nedir? WebAssembly (kısaca Wasm), tarayıcıda ve tarayıcı dışında çalışabilen, düşük seviyeli, ikili bir komut seti formatıdır. C, C++,...

WebAssembly Nedir? Tarayıcıda Wasm Rehberi

WebAssembly Nedir?

WebAssembly (kısaca Wasm), tarayıcıda ve tarayıcı dışında çalışabilen, düşük seviyeli, ikili bir komut seti formatıdır. C, C++, Rust gibi dillerle yazılmış kodu derleyip bu formata dönüştürebilir, ardından bir sanal makinede çalıştırabilirsiniz. Amaç, JavaScript'in yerini almak değil; hesaplama yoğun işleri JavaScript'in yanında, öngörülebilir bir performansla yürütmektir.

Wasm bir programlama dili değildir. Sizin yazdığınız kod değil, derleyicinin ürettiği hedef formattır. Bu ayrımı baştan netleştirmek gerekir; çünkü "Wasm ile uygulama yazacağım" cümlesi, aslında "kodu Wasm'a derleyeceğim" anlamına gelir.

Neden Var?

Tarayıcıda yüksek performans gerektiren işler (görüntü işleme, oyun motorları, video kodlama, kriptografi, veri sıkıştırma) JavaScript ile yapılabilir ama belirli bir noktadan sonra yönetimi ve performansı zorlaşır. Wasm şu özellikleriyle bu boşluğu doldurur:

  • İkili format: Metin yerine bayt kodu olduğu için ayrıştırma hızlıdır ve dosya boyutu küçüktür.
  • Öngörülebilir çalışma: Bellek erişimi doğrusal bir bellek alanıyla sınırlıdır; bu, hem güvenliği hem de optimizasyonu kolaylaştırır.
  • Dil bağımsızlığı: Aynı .wasm çıktısı tarayıcıda, Node.js'te veya gömülü bir runtime'da çalışabilir.
  • Sandbox modeli: Modül, kendisine açıkça verilmeyen bir kaynağa (dosya, ağ, DOM) erişemez.

Bu son madde kritik: Wasm modülü tek başına "hiçbir şey yapamaz". Ona yetenekleri host ortamı (tarayıcı ya da runtime) verir. Güvenlik modelinin temeli budur.

Hedef Ortamlar

Wasm iki ana bağlamda karşımıza çıkar:

  1. Tarayıcı: JavaScript, WebAssembly API'si üzerinden modülü yükler ve çağırır. DOM'a doğrudan erişim yoktur; JavaScript köprüsü gerekir.
  2. Tarayıcı dışı: WASI (WebAssembly System Interface) ile dosya sistemi, saat, rastgele sayı gibi yetenekler tanımlanır. Sunucu tarafı, edge fonksiyonları, plugin sistemleri bu modeli kullanır.

WASI'nin sürümleri ve desteklenen yetenek kümeleri runtime'a göre değişir. Bir runtime'da çalışan modülün başka bir runtime'da çalışacağını varsaymayın; kullandığınız runtime'ın hangi WASI sürümünü desteklediğini belgelemesinden doğrulayın.

Önkoşullar

  • JavaScript ve tarayıcı çalışma modeline aşinalık.
  • En az bir sistem dili (Rust, C/C++) ile derleme araç zinciri kurabilme.
  • Tarayıcı geliştirici araçlarında Network ve Console sekmelerini okuma alışkanlığı.

Sürüm numarası vermiyorum; çünkü Wasm ekosistemi (WASI, bileşen modeli, runtime'lar) hızlı değişiyor ve burada sabit bir sürüm yazmak kısa sürede yanıltıcı olur. Kullandığınız aracın resmi dokümantasyonundaki sürüm bilgisini esas alın.

Adım Adım: Tarayıcıda Basit Bir Wasm Modülü

Aşağıdaki örnek, elle yazılmış minimal bir WAT (WebAssembly Text) parçasını .wasm'a çevirip JavaScript'ten çağırma akışını gösterir. WAT, Wasm'ın okunabilir metin gösterimidir; üretimde bunu elle yazmazsınız ama formatı anlamak için faydalıdır.

1. Modülü tanımla

topla.wat dosyası:

(module
  (func $topla (param $a i32) (param $b i32) (result i32)
    local.get $a
    local.get $b
    i32.add)
  (export "topla" (func $topla))
)

Bu modül iki i32 alıp toplamını döndüren tek bir fonksiyon dışa aktarır. Bellek, tablo veya içe aktarım yok; bu yüzden en sade örnektir.

2. .wasm'a derle

WAT'ı ikili formata çevirmek için wat2wasm aracını (WABT paketi içinde gelir) kullanabilirsiniz:

wat2wasm topla.wat -o topla.wasm

Komut başarılı olursa aynı dizinde topla.wasm oluşur. Aracın kurulum adımları için WABT projesinin kendi dokümantasyonuna bakın.

3. Tarayıcıda yükle ve çağır

<!doctype html>
<html lang="tr">
<body>
<script>
async function calistir() {
  const yanit = await fetch('topla.wasm');
  const baytlar = await yanit.arrayBuffer();
  const { instance } = await WebAssembly.instantiate(baytlar);
  const sonuc = instance.exports.topla(3, 4);
  console.log('Sonuç:', sonuc); // 7
}
calistir();
</script>
</body>
</html>

Beklenen davranış: Konsolda Sonuç: 7 görünür. WebAssembly.instantiate bir Promise döner; instance.exports üzerinden dışa aktarılan fonksiyona erişilir.

Dikkat: Bu dosyayı file:// üzerinden açarsanız fetch çoğu tarayıcıda engellenir. Basit bir yerel HTTP sunucusu üzerinden servis edin.

Yaygın Hatalar

  • DOM'a doğrudan erişmeye çalışmak. Wasm modülü DOM görmez. DOM işlemleri JavaScript'te yapılır; modül ile JS arasında veri alışverişi köprü üzerinden olur.
  • Sık sık sınır geçişi yapmak. Her JS↔Wasm çağrısı bir maliyet taşır. Küçük işlemleri tek tek çağırmak yerine, toplu iş yapan fonksiyonlar tasarlayın.
  • Belleği yönetmeyi unutmak. Modülün doğrusal belleğine yazdığınız veriyi, işi bitince serbest bırakmazsanız bellek şişer. Dilinizin (Rust/C++) bellek yönetim kuralları Wasm'da da geçerlidir.
  • Yanlış tipleri geçirmek. Wasm yalnızca i32, i64, f32, f64 gibi temel tipleri doğrudan tanır. String ve nesneler için serileştirme ve bellek üzerinden paylaşım gerekir.
  • Modülü her seferinde yeniden derlemek. WebAssembly.compile/instantiate pahalıdır; aynı modülü tekrar tekrar derlemek yerine önbelleğe alın.

Güvenlik Tarafı

Wasm'ın güvenlik vaadi "sandbox"tır; ama bu, otomatik güvenlik anlamına gelmez.

  • Yetenek modeli: Modül yalnızca host'un verdiği içe aktarımları kullanabilir. Gereksiz içe aktarım açmayın.
  • Bellek sınırı: Modül kendi doğrusal belleği dışına yazamaz; bu, klasik bellek bozulmalarını sınırlar. Ancak modül içindeki mantık hataları (örneğin yanlış indeksleme) hâlâ uygulama düzeyinde sorunlara yol açabilir.
  • Üçüncü taraf modüller: Dışarıdan aldığınız .wasm dosyasını, tıpkı bir bağımlılık gibi değerlendirin. Kaynağını, derleme zincirini ve ne istediğini (hangi içe aktarımları) bilmiyorsanız çalıştırmayın.
  • Tarayıcı tarafı: Wasm, tarayıcının aynı-köken (same-origin) ve CSP kurallarını atlamaz. Yine de modüle verdiğiniz JS köprüsü, dolaylı bir saldırı yüzeyi olabilir; köprüyü minimum tutun.

Ne Zaman Kullanmalı, Ne Zaman Kullanmamalı?

Uygun olduğu durumlar:

  • Hesaplama yoğun, sıcak döngüler (görüntü/ses işleme, fizik, kriptografi).
  • Mevcut C/C++/Rust kod tabanını tarayıcıda yeniden kullanmak.
  • Farklı dillerden gelen eklentileri izole biçimde çalıştırmak (plugin sistemleri).

Uygun olmadığı durumlar:

  • Basit DOM manipülasyonu ve form işlemleri (JavaScript yeterli ve daha basit).
  • Küçük, seyrek çalışan fonksiyonlar (köprü maliyeti kazancı yer bitirir).
  • Ekosistem olgunluğu kritikse: araç zincirleri ve standartlar hâlâ gelişiyor.

"Geleceğin Teknolojisi mi?"

Wasm bugünün teknolojisidir; tarayıcılarda yaygın desteklenir ve üretimde kullanılır. "Gelecek" tartışması daha çok iki eksende sürüyor: tarayıcı dışı kullanımın (WASI, edge, plugin) olgunlaşması ve bileşen modelinin (component model) dil arası entegrasyonu standartlaştırması. Bu alanlar aktif geliştiriliyor; kesin bir "şu tarihte şu olacak" demek doğru olmaz.

Pratik sonuç şu: Wasm'ı gümüş kurşun olarak değil, belirli problemler için elinizdeki araçlardan biri olarak değerlendirin. Ölçün, köprü maliyetini hesaba katın, güvenlik modelini anlayın ve gereksiz yere JavaScript'in yerine geçirmeye çalışmayın.

İLGİLİ İÇERİKLER

Bunları da Okumak İsteyebilirsiniz