Category Archives: javascript

Assembler di browser berbasis Keystone dengan WebAssembly

Sebenarnya saat ini saya sedang sibuk dengan banyak hal, tapi karena sedang berduka, saya ingin melakukan sesuatu untuk mengalihkan pikiran. Bapak saya suka membongkar mobil untuk mengalihkan pikiran, sedangkan saya lebih suka memprogram sesuatu yang tidak berhubungan dengan pekerjaan. Hasilnya: hari ini saya mengkompilasi framework Keystone dengan target WebAssembly (Wasm) lalu memberi interface HTML dengan Preact (alternatif React yang ukurannya jauh lebih kecil).

Assembler ini bisa diakses online di https://asm.x32.dev dan sourcenya saya berikan di https://github.com/yohanes/online-assembler . Aplikasinya bisa diakses dengan semua browser modern (Safari, Chrome, Firefix, Edge), termasuk juga mobile browser (sudah ditest di iOS 13 dan Android 10).

WebAssembly (Wasam)

Supaya tidak bingung dengan penjelasan assembler dan webassembly, akan saya jelaskan apa itu WebAssembly (biasa disingkat dengan Wasm). WebAssembly adalah format instruksi biner untuk virtual machine (bisa dibayangkan seperti bytecode Java) . Saat ini target utamanya adalah web browser (saat ini sudah disupport di Firefox, Google Chrome, Safari dan Edge). Di masa depan web assembly ini dihrapkan akan bisa dipakai juga di aplikasi desktop maupun server.

Sekarang ini sudah ada compiler supaya kita bisa mengkompilasi bahasa C, C++, Rust, dsb ke kode WebAssembly. Setelah dikompilasi, kodenya bisa dijalankan di browser. Sayangnya API web browser tidak bisa diakses oleh kode web assembly, jadi diperlukan jembatan berupa kode JavaScript.

Keystone

Keystone merupakan library assembler untuk berbagai arsitektur. Diberikan teks assembly, kita bisa memakai library ini untuk mengubahnya menjadi bahasa mesin. Keystone ini sebenarnya memakai bagian dari libary LLVM, tapi diekstrak bagian assemblernya saja. LLVM sendiri merupakan proyek infrastruktur compiler yang memiliki banyak fitur (parser, optimizer, assembler, linker, debugger, dsb) tapi terlalu kompleks dan terlalu besar jika hanya ingin fitur assemblernya saja.

Untuk keperluan development program dalam assembly, Keystone ini belum terlalu layak pakai karena banyak bugnya dan tidak memiliki fitur macro yang ada di banyak assembler modern. Untuk development, sebaiknya pakai saja assembler dari berbagai compiler yang ada. Keystone ini lebih terpakai untuk riset security, patching program, dan berbagai fungsi kecil lain yang overkill jika memakai assembler lengkap dari sebuah compiler. Contoh pemakaian Keystone adalah untuk menyelesaikan soal CTF semacam yang saya selesaikan dua tahun yang lalu.

Jadi supaya jelas: assembly di WebAssembly tidak berhubungan dengan assembler di library Keystone (saat ini keystone belum mendukung web assembly).

EMSDK

Dengan menggunakan emscripten SDK (emsdk), sekarang kita bisa mengkompilasi banyak library dan program yang ditulis dalam bahasa C/C++ dengan target Web Assembly dengan relatif mudah. Jika program atau library memakai configure, kita bisa menjalankan emconfigure ./configure dan jika memakai cmake, kita bisa menjalankan emcmake cmake. Program emconfigure dan emcmake merupakan wrapper, agar ketika configure/cmake dijalankan, maka compiler dan library yang akan dipakai adalah untuk target WASM.

Tentunya tidak semua program dan library bisa dikompilasi dengan mudah. Contoh kode yang tidak bisa dicompile langsung: kode yang butuh library lain, kode yang butuh akses hardware, kode yang butuh akses layanan sistem operasi tertentu, kode yang memakai kode assembly dalam Intel x86 atau ARM, dan masih banyak lagi kasus khusus lain. Dalam kasus seperti ini, kita perlu melakukan porting manual.

Selain mengkompilasi file C menjadi WASM, emsdk juga menghasilkan file Javascript yang gunanya menjadi jembatan antara Javascript dan WASM. Jembatan ini dua arah: kode C yang memanggil fungsi library standar seperti printf akan memanggil kode JavaScript (misalnya kita arahkan menjadi memanggil console.log), dan kita bisa memanggil kode C dari Javascript.

Optimasi ukuran

Saat ini kode yang dihasilkan dari EMSDK masih belum efisien. Library Keystone ketika dicompile dengan target Web Assembly, hasilnya menjadi file 9.7 megabyte. Saat ini ada proyek lain bernama binaryen yang merupakan infrastruktur compiler untuk WebAssembly. Salah satu toolnya adalah wasm-opt yang dapat digunakan untuk mengoptimasi bytecode WASM. Tool yang lain adalah disassembler Web Assembly (disassembler ini saya pakai untuk menyelesaikan soal CTF).

Setelah dioptimasi, library Keystone yang berukuran 9.7 megabyte berkurang menjadi 5.7 megabyte saja. Ketika didistribusikan, file ini masih akan dikompresi dengan gzip dan hasilnya menjadi 1.5 megabyte. Ukurannya memang tidak kecil, tapi kebanyakan foto dan video ukurannya juga sudah ratusan kilobyte.

User Interface

Bagian berikutnya yang perlu dilakukan adalah membuat user interface yang bagus untuk library yang kita compile tersebut. Untuk program yang memakai Simple DirectMedia Layer (SDL) dan OpenGL, kadang kita bisa langsung menjalankannya karena emsdk sudah menyediakan wrapper untuk API HTML Canvas dan WebGL. Sedangkan untuk aplikasi lain, kita perlu membuat interface HTML dan menggunakan JavaScript untuk memanggil kode C.

Alasan saya memporting Keystone agar bisa memakai assembler keystone terbaru dari browser. Sudah ada yang membuat keystone.js tapi sudah lama tidak diupdate.

Tadinya saya hanya ingin memakai HTML + Javascript murni saja untuk user interfacenya. Tapi setelah saya pertimbangkan lagi, memakai library Javascript akan membuat kodenya jadi lebih terstruktur. Tadinya saya akan memakai React, tapi aplikasi kecil dalam React butuh ratusan kilobyte (terutama karena bagian ReactDOM). Jadi saya memakai Preact yang memakai API yang (hampir) sama dengan React tapi ukurannya hanya 9 kilobyte saja (bahkan hanya 4 kilobyte setelah dikompres).

Development JavaScript Modern biasanya dilakukan dengan menggunakan build system, tapi sebenarnya tidak wajib. Karena program saya ini sangat kecil, saya putuskan untuk tidak memakai build system. Semua kode langsung masuk ke file HTML dan JS. Karena saya memakai WASM, browser harus cukup modern, jadi saya bisa memakai berbagai fitur HTML/JS terbaru tanpa butuh berbagai library polyfill.

Penutup

Salah satu cara belajar teknologi Web Assembly adalah dengan memporting berbagai library dan program ke browser dan membuat atau menyesuaikan user interface agar berjalan di browser. Bahasa C/C++ sudah ada sejak lama, dan sudah banyak hal menarik yang dibuat dalam C, berbagai kode yang sudah ada ini bisa dibawa ke browser dan dieksekusi langsung tanpa butuh server (server hanya sekedar untuk menyimpan file saja, tidak untuk eksekusinya).

Semoga artikel singkat ini berguna untuk memulai eksplorasi Web Assembly, dan semoga assembler onlinenya juga bisa terpakai di masa depan, baik untuk saya sendiri maupun orang lain.

Jangan Fanatik Teknologi Tertentu

Setiap waktu, selalu ada orang yang fanatik menggunakan teknologi tertentu untuk menyelesaikan semua masalah. Karena ini blog “Cinta Programming”, pembahasannya tentunya adalah teknologi pemrograman. Lebih spesifiknya lagi: bahasa tertentu. Sekarang ini aplikasi web sedang sangat populer, dan orang-orang pun ingin memanfaatkan 100% teknologi HTML dan JavaScript untuk melakukan semua hal. Bahkan bukan cuma aplikasi web, tapi aplikasi desktop dan mobile.

Screenshot_2016-06-07-19-19-09

Saya hanya ingin menunjukkan bahwa kadang tidak semuanya bisa dilakukan oleh satu teknologi seratus persen. Seperti Anda lihat di posting-posting sebelumnya, saya sudah membuat beberapa aplikasi dengan HTML5 (dan bahkan sudah ada yang saya jual), tapi meski demikian saya masih sering “gemes” dengan orang yang terpaku pada HTML dan JS dan menganggap itu teknologi terbaik untuk semua hal (termasuk juga aplikasi mobile).

Teknologi sering harus dicampur-campur untuk membuat aplikasi terbaik. Twitter dua tahun yang lalu (2010) yakin bahwa rendering di sisi client dengan JavaScript adalah cara terbaik. Baru-baru ini disadari bahwa HTML5 masih terlalu lambat dan Twitter kembali melakukan rendering di sisi server. Twitter tentunya tidak membuang 100% Javascript, tapi sebagian besar pemrosesan dipindahkan ke server.

Di sisi mobile, Facebook membuat aplikasi untuk iOS (iPhone/iPad) menggunakan HTML5 sejak bertahun-tahun yang lalu. Semua orang komplain: aplikasinya terlalu lambat. Akhirnya Facebook menulis ulang aplikasinya dalam native code (dalam kasus ini native adalah Objective C) supaya dua kali lebih cepat. Tapi Facebook juga tidak membuang HTML5 seluruhnya, sebagian aplikasinya masih memakai HTML5.

Pelajaran yang bisa dipetik dari dua hal tersebut adalah: belajarlah banyak teknologi, supaya bisa tahu teknologi yang terbaik, dan jika memang ada yang lebih baik: jangan takut berpindah dari satu teknologi ke teknologi yang lain. Sekali lagi: jangan terpaku pada satu teknologi saja:

if all you have is a hammer, everything looks like a nail

Sencha Touch di PlayBook

Ini catatan teknis mempackage aplikasi Sencha Touch menjadi file .bar PlayBook. Pertama download dulu Sencha Touch 2, dan Juga SDK Toolsnya.

Saya memakai Mac, tapi tutorial ini berlaku juga untuk OS Windows. Perhatikan bahwa Anda perlu punya web server terinstall. Di Mac, Apache sudah ada default. Di Windows, silakan install IIS atau Apache (misalnya dari Wamp).

Extract file sencha-touch-2.0.1.1-commercial.zip. Saya mengekstraknya di dalam ~/Sites/ , lalu saya rename jadi “sencha” saja, jadi file-file sencha-touch-all.js, sencha-touch.js dsb ada di ~/Sites/sencha/.

Berikutnya kita buat aplikasi hello world. Sekarang dari dalam ~/Sites/sencha kita bisa menjalankan perintah “sencha generate app” untuk membuat aplikasi:

$ cd ~/Sites/sencha/
$ sencha generate app --name=HelloWorld -p ~/Sites/helloworld

Aplikasinya bisa dites dengan mengakses di http://localhost/~yohanes/helloworld (atau tergantung setting web server Anda bagaimana).

Saya tidak akan mengubah file-filenya, jadi saya langsung package saja. Pertama buat dulu file config.xml. Saya memakai file template yang sudah biasa saya pakai. Sebenarnya baris-baris feature itu tidak diperlukan untuk ini, tapi karena saya sering lupa menambahkan baris tersebut ketika memakai API Blackberry, saya selalu menggunakan template ini.

Catatan: saya tidak menggunakan ikon untuk aplikasi ini (blank). Silakan ditambahkan sendiri jika dibutuhkan.

<?xml version="1.0" encoding="UTF-8"?>

<widget xmlns="http://www.w3.org/ns/widgets"
   xmlns:rim="http://www.blackberry.com/ns/widgets"
   version="1.0.0.0" id="helloworld" xml:lang="en">

   <name>Sencha Hello</name>
   <description>Sencha Hello.</description>
   <author rim:copyright="2012" email="[email protected]">Yohanes Nugroho</author>

   <rim:orientation mode="landscape" />

   <content src="index.html"/>
   <rim:category name="Games"/>

   <feature id="blackberry.app" required="true" version="1.0.0.0"/>
   <feature id="blackberry.app.event" required="true" version="1.0.0.0"/>
   <feature id="blackberry.system" required="true" version="1.0.0.0"/>
   <feature id="blackberry.system.event" required="true" version="1.0.0.0"/>
   <feature id="blackberry.ui.dialog" required="true" version="1.0.0.0"/>
   <feature id="blackberry.utils" required="true" version="1.0.0.0"/>
   <feature id="blackberry.invoke" required="true" version="1.0.0.0"/>
   <access subdomains="true" uri="*">
   </access>
</widget>

Sekarang kita bisa men-zip aplikasinya. Masalah utama adalah: tools webworks tidak suka dengan file yang memiliki nama dengan tilde (~) dan dengan at(@) (misalnya [email protected], ini untuk retina display). Ada beberapa file seperti ini, untungnya ini tidak diperlukan, jadi kita bisa kecualikan dari file zip

zip -r senchahello.zip config.xml app.js app.json index.html resources/ sdk/ app/ -x *2x* -x *~*

Kuncinya ada pada “-x *2x* -x *~*” untuk meng-exclude file yang tidak valid menurut webworks.

Berikutnya kita bisa mempaketkan file zip tersebut menjadi file bar. Untuk mempersingkat command line, saya menginstall SDK di home directory saya di direktori webworks-tablet.

~/webworks-tablet/bbwp/bbwp senchahello.zip -g password -v buildId 1

Catatan: jika versi tidak diubah, buildId perlu dinaikkan setiap kali build.

Sekarang file .bar akan tercipta dalam direktori ~/Sites/helloworld/bin siap untuk diinstall ke PlayBook.

Catatan Teknis – Baby Coloring Book

Setiap kali saya membuat aplikasi dengan teknologi yang baru, biasanya saya mendapati banyak tantangan teknis. Dalam konteks ini “baru” bisa berarti teknologinya benar-benar baru, atau saya yang baru saja mengenal teknologi tersebut. Kali ini saya ingin membahas mengenai aplikasi saya di appworld, Baby Coloring Book.

Ide dari aplikasi ini sangat sederhana: buku mewarnai untuk bayi (terutama di bawah 3 tahun), hanya perlu menyentuh saja untuk mewarnai, tidak perlu menggosok-gosok seperti memakai krayon. Jika saya menggunakan teknologi lain untuk membuat ini (misalnya flash atau C++), saya akan menggunakan pendekatan sederhana: buat gambar tidak berwarna, gunakan flood fill untuk mengisi area. Tapi saya menggunakan HTML5 untuk membuat aplikasi ini. Alasan utamanya adalah untuk belajar mengenal lebih jauh HTML5. Saya tidak menggunakan library selain selain JQuery.

Contoh Gambar

Di Stack Overflow sudah ada yang menjawab bagaimana mengimplementasikan flood fill dengan JavaScript menggunakan Canvas:

How can I perform flood fill with HTML Canvas?

Jadi saya coba itu di PC menggunakan browser Google Chrome. Manipulasi piksel di Google Chrome sangat cepat, tapi saya melihat ada sedikit delay. Saya langsung curiga: jangan-jangan jika saya coba di PlayBook akan sangat lambat. Ternyata benar: sangat lambat.

Ada beberapa pendekatan yang terpikir oleh saya supaya aplikasi ini bisa dibuat dengan HTML5 tapi tetap cepat, tapi saya memiliki beberapa requirement:

  1. Saya tidak ingin “membatik” mendefinisikan setiap area gambar yang bisa diwarnai. Jika saya punya gambar, saya ingin langsung bisa memakai gambar itu tanpa edit manual. Dengan pendekatan flood fill, algoritma tersebut bisa otomatis mewarnai sebuah area yang dibatasi pixel tertentu (seperti mewarnai dengan “ember” di Ms Paint).
  2. Saya ingin bisa membuat gambar yang warnanya seperti diwarnai dengan krayon, jadi tidak polos.

Continue reading

HTML5 Saat Ini

Akhir-akhir ini di waktu luang, saya sedang senang ngoprek HTML5. Kesimpulan sementara saat ini: HTML5 belum bisa memenuhi semua yang dijanjikannya terutama dalam hal portabilitas dan kecepatan. Sekarang ini lebih sering teknologi lain (misalnya Flash atau kode native) lebih cocok.

Tulisan ini berdasarkan pengalaman saya dan berlaku saat ini. Saya sendiri sudah mulai mengembangkan aplikasi dengan HTML5, bahkan sudah dijual di AppWorld (http://appworld.blackberry.com/webstore/vendor/9151/?lang=en, yang dibuat dengan HTML5 adalah MultiCounter, Four Colors, dan Baby Coloring Book), dan saya berharap dalam beberapa tahun ke depan HTML5 akan semakin baik.

HTML5 didengungkan sebagai sesuatu yang mudah, cepat dan portabel. Dalam kenyataannya, jika aplikasi kita sederhana (hanya memakai sebagian kecil fitur HTML5), maka hal itu benar, tapi jika aplikasi kita sudah mulai kompleks, maka hal-hal tersebut tidak lagi benar.

Continue reading

Catatan pengalaman development webworks untuk PlayBook

Sudah lama tidak posting dan belum semangat meneruskan tutorial manipulasi bit. Jadi untuk kali ini, saya akan cerita mengenai oprekan saya saat ini: memprogram playbook dengan webworkd (html5/javascript).

Saya ingat waktu pertama kali memprogram dalam bahasa BASIC, hal yang terpikir oleh saya adalah FUN. Menyenangkan sekali memprogram dengan BASIC, tidak perlu persiapan apa-apa, bisa langsung memprogram dan menjalankan programnya. Sekarang ini setiap kali memprogram sesuatu yang baru, rasanya ribet sekali, misalnya untuk memprogram Webworks Playbook: SDK harus diinstall (yang butuh AdobeAir SDK), signing key perlu disiapkan (walau cuma perlu sekali), Path perlu diset (supaya tidak perlu mengetik panjang), perlu tahu IP device, perlu mengaktifkan development mode, mengeset password, dsb. Walaupun cukup rumit, tapi sebenarnya webworks ini masih lebih sederhana dibandingkan aplikasi Adobe Air yang saya buat untuk playbook (LocalBar) yang memakai native extension dalam C++.

Untungnya setelah melewati semua langkah-langkah tersebut, sekarang saya bisa memprogram webworks dengan cukup nyaman. Bahkan ternyata setelah mengetahui langkah-langkahnya, itu bisa diulangi dengan cepat. Ketika saya sedang berlibur seperti ini, saya bisa mensetup development environment di pc adik saya dengan sangat cepat.

Memprogram dengan webworks ini cukup “fun”. Saya cuma perlu membuat file HTML dan Javascript, lalu saya test di komputer dengan Google Chrome. Library seperti jquery juga bisa saya gunakan.

Di PC development bisa dilakukan dengan cepat. Setelah semua algoritma selesai, halaman html yang sama tinggal dibuka dengan menggunakan browser playbook.
Browser playbook memiliki “Web Inspector” yang memungkinkan kita mendebug JavaScript di browser playbook menggunakan *browser* di desktop kita (ya benar, debuggernya diakses via *browser*).

Setelah itu saya bisa mensetup app “kosong” yang jika dibuka akan mengambil konten dari URL yang disediakan. Dengan cara ini, jika ada perubahan kode maka tidak perlu mempackage ulang file bar. Aplikasi juga bisa di debug tanpa tool khusus.

Baru setelah semua selesai, saya mempackage semua file menjadi sebuah file bar dan siap dikirimkan ke appworld.

Secara umum, development dengan webworks ini sangat mudah dan fun. Selain bagian packaging, semua development dan debugging bisa dilakukan dengan editor teks biasa dan web browser.