WebAssembly(wasm), wasi, wat, vb teknolojilere, assembly ve makine kodu perspektifinden biraz daha derinlemesine etüt ettim.
Bir kaç yanlış bildiğim nokta varmış onları sizinle paylaşmak istedim;
Yanlış Anlama: Business Logic Gizleme
Wasm’in beni en heyecanlandıran özelliklerinden bir tanesi, business-logic’i gizlemesi olarak düşünüyordum. Ama maalesef gerçekler biraz farklı.
Efendim wasm’in amacı, platform bağımsız, taşınabilir, ve diller arası komponentleri kolayca birbirine bağlamanızı sağlayacak bir arayüz oluşturmak. (bilgisayar dünyasının kronik problemini çözmek için çıkmış yani)
Gerçek Amaç: Platform Bağımsızlık
Kendi kodu aslında assembly mantığı gibi olsa da, stack olarak kurgulandığı için, insan gözüyle okunması ve geri çevrilmesi (reverse) edilmesi, klasik bir makine kodundan çok daha kolay. Hatta nerdeyse bazı noktalarda birebir çevirebiliyorsunuz.
Yani wasm aslında, dil-agnostik bir sistem arayüzü (interface definition layer) olarak geçiyor. Bytecode olarak tanımlansa da, JVM ve benzerleri gibi değil, yani warming-up problemleri yok.
Özetle: Wasm modüllerinin birbiriyle tür güvenli, bağımlılıksız, şekilde etkileşim kurmasına olanak tanıyan bir teknoloji.
Yani daha önce bir toy-proje paylaşmıştım, tüm dilleri destekleyen online editor, ve orada “Belki dilleri birbirleri ile haberleştirebilirim”, demiştim. Hah olayda bu yani.
WASI: Sistem Arayüzü Katmanı
WASI dediğimiz şeyde aslında JVM’deki sanal OS gibi bişey, şöyle ki, mesela sizin bir C kodunuz var ve bu sistem çağrıları yapıyor, libc, pthread, fd_read, fd_write vs.
WASI bunları köprü yapıp heryer de çalışmasını sağlayacak bir arayüz oluşturuyor ve simüle ediyor. Çok mantıksız değil. Şöyle düşünebilirsiniz, e ben zaten aynı kodu, BSD için, Linux için, Windows için derliyorum, ama işte bunda bir kere derleyip her yerde çalıştırıyorsunuz :D
Tanıdık geldi değil mi? Aslında JVM kafasında ama dili Java değil. İstediğiniz dille JVM olmadan aynı zamanda tarayıcılarda çalışan, dil bağımsız taşınabilir bir teknoloji. Bence güzel!
Güvenlik: Sandbox Modeli
WASI’nin en büyük farkı:
Bir Wasm modülü sadece açıkça erişmesine izin verilen dosyalara erişebilir.
E buda web için biçilmiş kaftan. Sandbox çok güzel bir teknoloji ya.
Interface Types (WIT)
Interface Types (WIT) nedir? Bu bizi çok ilgilendirmeyen, Wasm modüllerinin farklı dillerle iletişim kurmasını sağlayan şematik tanım biçimi.
WebAssembly Ekosistemi
Ekosistemin kuşbakışı resmini çekmek istersek şöyle birşey çıkıyor ortaya:
- Wasm (core bytecode)
- WASI (sistem arayüzü)
- Interface Types (WIT)
- Component Model (modül mimarisi)
- GC Support (managed diller için)
- Threads & Atomics
- JS APIs (tarayıcı köprüsü)
- Tooling (emcc, rustc, swiftwasm, wasm-opt)
- Paket Biçimleri (.wasm, .wat, .wasm-component)
- Runtime’lar (wasmtime, wasmer, wasmEdge, V8…)
Basit Tanımlar:
- Wasm: kodu çalıştıran makine,
- WASI: sisteme erişimi yöneten katman,
- WIT: modüllerin arayüz sözleşmesi,
- Component Model: Lego gibi modül birleştirme sistemi.
Bunların toplamı, OS’ten bağımsız, dil bağımsız ve platform bağımsız bir evrensel çalışma ortamı oluşturuyor.
Assembly Perspektifi
Şimdi gelelim Assembly perspektifinden olaya bakmaya;
Mesela bir C kodunuz var;
int add(int a, int b) {
return a + b;
}
derlediniz ve wasm dosyasını aldınız, sonra
wasm2wat -o output.wat input.wasm
dediniz çıkan output;
(module
(func $add (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.add)
(export "add" (func $add)))
Aynı kodun WASM versiyonu (binary):
00 61 73 6d 01 00 00 00
. Aslında sadece binary kolay şekilde wat ve oradan geri koda döndürülebiliyor.
Bu, neredeyse yukarıdaki C kodunun aynısı.
Tersine Mühendislik Açısından
Yani: Wasm tersine mühendislik açısından neredeyse “düz metin gibidir.” denilebilir.
Hatta wasm-decompile
tool’u var ki, koda çeviriyor.
Klasik Assembly ile Karşılaştırma
Her neyse, peki klasik assembly’de bu nasıl oluyor;
GCC ile bir C dosyasını derlediğiniz zaman çıktı şöyle oluyor;
- Header (magic: 0x7fELF)
- Kod segmentleri (text, data)
- Symbol table (fonksiyon/isimler)
- Debug info (opsiyonel gcc)
text
Makine kodlarının olduğu yer. CPU tarafından çalıştırılır.
Wasm vs Assembly Farkları
Özetle;
- Wasm register kullanmaz.
mov eax, ebx
yok. - Wasm stack tabanlıdır. akış
local.get
,i32.add
gibi sıralıdır. - Wasm çok optimize edilmemiştir (kendi içinde biraz var, ama CPU düzeyinde değil).
- Wasm modülleri name section içerir. debug için isimler tutulabilir.
- Bazı derleyiciler (emcc, rustc) isimleri açık bırakır.
- Wasm formatı şeffaflık için tasarlanmıştır, tersine mühendislik engellemek için değil.
Performans Sorusu
Bunu araştırırken aklıma şöyle bir soru geldi;
“Madem kodlar sonunda Wasm tabanlı assembly diline dönüyor, o zaman dilleri eşitliyor ve performans açısından fark nasıl oluyor?”
Bu sorunun cevabı şöyle;
Native dillerde fark neredeyse yok denecek kadar az; Ama runtime-based diller için durum farklı, yani Python, Go gibi dillerin yanında en temel runtime da yüklendiği için, performans ciddi anlamda etkileniyor.
Benchmark Sonuçları
Şöyle küçük bir benchmark testi yaptım sonuçlar;
- C: 3,120 byte, Runtime Yok
- Rust: 3,244 byte, core Runtime, dil güvenliğini sağlayacak bir kaç kod koyuyor
- Zig: 3,388 byte, Runtime Yok
- Nim: 5,820 byte, minnak Garbage Collector
- Go: 9,360 byte, Garbage Collector
- Python: 2,450,000 byte, CPython VM Runtime
Sonuç
WebAssembly, business logic gizleme aracı değil, evrensel platform bağımsızlık çözümü. Stack tabanlı yapısı sayesinde tersine mühendislik klasik assembly’den çok daha kolay. Native dillerde performans farkı minimal, runtime’lı dillerde ise runtime overhead’i devam ediyor.
Kısaca: WASM = Write Once, Run Everywhere (ama şeffaf şekilde)
Tags
Uğur Toprakdeviren
Cryptographer, security researcher, and systems engineer with over two decades of experience building secure systems. Currently focused on Apple internals, decentralized messaging protocols, ARM64 architectures, and the philosophical implications of digital privacy.
Learn more about me