aboutsummaryrefslogtreecommitdiff
path: root/_drafts/2020-02-11-on-webassembly-killing-javascript.md
diff options
context:
space:
mode:
Diffstat (limited to '_drafts/2020-02-11-on-webassembly-killing-javascript.md')
-rw-r--r--_drafts/2020-02-11-on-webassembly-killing-javascript.md205
1 files changed, 205 insertions, 0 deletions
diff --git a/_drafts/2020-02-11-on-webassembly-killing-javascript.md b/_drafts/2020-02-11-on-webassembly-killing-javascript.md
new file mode 100644
index 0000000..998c176
--- /dev/null
+++ b/_drafts/2020-02-11-on-webassembly-killing-javascript.md
@@ -0,0 +1,205 @@
+---
+title: On WebAssembly killing JavaScript
+date: 2020-02-11
+layout: post
+lang: en
+ref: on-webassembly-killing-javascript
+---
+When discussing WebAssembly (WASM), I often see people portraiting it too much
+as a JavaScript replacement, but I think this framing misses the point of some
+of the aspects on how WASM can be a great tool: being a portability oportunity,
+which means increasing the reach to code.
+
+If you think of WASM strictly as a optimization of JavaScript, that's where
+you'll end up: WASM is the same as JavaScript, but faster.
+
+But there's a more interesting aspect (to me) of it: portability. That means you
+can now write multiplatforme code that runs everywhere. I mean, everywhere, even
+in the browser. Let's imagine how you could write SQLite and mke it run on the Web.
+
+# SQLite
+
+If I were to create, say, SQLite today, I would consider adding web support for
+it. SQLite already is available almost everywhere[^1]. This is due to it having
+very so few dependencies,
+
+Imagine having writing SQLite today
+
+There are also other legimate uses of WASM, such as WASI and etc.
+
+Here's how I would start writing an application that could run on any POSIX
+system and, on top of that, could run on the browser:
+
+```
+// api.h
+
+extern void platformDependentPersistInt(int);
+extern int platformDependentRetrieveInt();
+
+
+// api-posix.c
+
+/* POSIX implementation of "api.h" interface to be used in non-web contexts */
+
+#include <stdio.h>
+
+void platformDependentPersistInt(int n) {
+ FILE* fp = fopen("/tmp/persisted.txt", "w+");
+ fprintf(fp, "%d", n);
+ fclose(fp);
+}
+
+int platformDependentRetrieveInt() {
+ FILE* fp = fopen("/tmp/persisted.txt", "r");
+ int persisted = fgetc(fp);
+ return persisted;
+}
+
+
+// api-wasm.js
+
+/* WASM implementation of "api.h" interface to be used in web contexts */
+
+export const platformDependentPersistInt = (n) =>
+ localStorage.setItem("persisted", n.toString());
+
+export const platformDependentRetrieveInt = () =>
+ parseInt(localStorage.getItem("persisted"));
+
+
+// add.h
+
+int add(int a, int b);
+void persistInt(int n);
+int retrieveInt();
+
+
+// add.c
+
+#include "api.h"
+
+int add(int a, int b) {
+ return a * a + b;
+}
+
+void persistInt(int n) {
+ platformDependentPersistInt(n);
+}
+
+int retrieveInt() {
+ return platformDependentRetrieveInt();
+}
+```
+
+```
+// main.c
+
+#include <stdio.h>
+#include "add.h"
+
+int main() {
+ int added = add(4, 5);
+ printf("Adding 4 and 5: %d\n", added);
+
+ persistInt(6);
+ int persisted = retrieveInt();
+ printf("Persisted number: %c\n", persisted);
+ return 0;
+}
+
+
+// index.html
+
+<script type="module">
+ import * as api from "./api-wasm.js";
+
+ WebAssembly
+ .instantiateStreaming(fetch("add.wasm"), { env: api })
+ .then(({instance: {exports}}) => {
+ const added = exports.add(4, 5);
+ console.log("Adding 4 and 5:", added);
+
+ exports.persistInt(6);
+ const persisted = exports.retrieveInt();
+ console.log("Persisted number:", persisted);
+ });
+</script>
+```
+
+In order to
+```
+// server.py
+
+#!/usr/bin/env python
+import SimpleHTTPServer
+import SocketServer
+
+PORT = 8001
+
+class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
+ pass
+
+Handler.extensions_map['.wasm'] = 'application/wasm'
+
+httpd = SocketServer.TCPServer(("", PORT), Handler)
+
+print "serving at port", PORT
+httpd.serve_forever()
+```
+
+Dependency graph:
+api-posix.c api-wasm.js
+api.h
+add.h
+add.c
+main.c index.html
+
+Compiling and running the POSIX code:
+```shell
+$ clang -o add main.c add.c api-posix.c
+$ ./add
+Adding 4 and 5: 21
+Persisted number: 6
+```
+
+Compiling and running the WASM
+```shell
+$ clang \
+ --target=wasm32 \
+ -nostdlib \
+ -Wl,--no-entry \
+ -Wl,--export-all \
+ -Wl,--allow-undefined \
+ -o add.wasm \
+ add.c
+$ ./server.py
+```
+
+After opening the browser, the console shows:
+```
+Adding 4 and 5: 21
+Persisted number: 6
+```
+
+Rust, C, Zig
+
+No Emscripten, no GC, no runtime
+
+Emscripten 11KB
+
+# Limitations
+
+"System call" cost in WebAssembly.
+
+WASM is very new, no flush guarantees.
+
+Confusing dependency tree
+
+AFAICT you can't package WASM with JavaScript.
+
+
+[^1]: [Platforms supported by SQLite are](https://sqlite.org/features.html):
+ "Android, *BSD, iOS, Linux, Mac, Solaris, VxWorks, and Windows (Win32,
+ WinCE, WinRT) are supported out of the box. Easy to port to other systems".
+
+https://sqlite.org/selfcontained.html