Giter VIP home page Giter VIP logo

wasm-golang-inline's Introduction

wasm-golang-inline

WARNING THIS EXAMPLE ONLY WORKS WITH THE CHROME BROWSER DUE TO ITS USE OF Atomics.waitAsync() for SYNCHRONIZATION.

Example WebAssembly (wasm) program in golang that can be loaded from local file system.

I wanted to experiment with WebAssembly, I have an application in python that I am trying to convert to javascript. I was thinking about rewriting my application in golang and then using the majority of the same code via a web browser.

Every example that I found of WebAssembly starts by requiring a local web server. Due to security concerns it is not possible to load WebAssembly code from the file system using fetch(), even if all files are local. The reasoning is that if a bad actor sends you a HTML attachment that you put in your download directory and then open with your browser fetch() could access all the files in that directory including your downloaded bank statements. The examples then go on to show how to run a simple local web server. I have no interest in running a local web server to work on local files. While looking around for a way around the problem, I came across the gem 1 that I used. The trick is to base64 encode the wasm then hand a data URL to fetch(). The Makefile creates a file assets/wasm.js that assigns a single variable wasm that can be loaded in the standard way.

Lessons

  • Run WebAssembly directly from a local file (i.e. without a web server)
  • Using Promises and Atomics (mutexes) to synchronize the loading of golang functions.
  • Loading WebAssembly/golang function into Javascript
  • Calling WebAssembly/golang function from Javascript.
  • Calling Javascript function from WebAssembly/golang

Requirements

  • GNU make
  • golang 1.20 (is known to work)

Installation

$ git clone https://github.com/gatanu/wasm-golang-inline.git
$ gmake

Run

Open the file wasm.html with your web browser. Open the javascript console and then reload the web page. You should see all the log messages.

Portability

The code was originally developed on a Chromebook in a Linux container. The original code in the Makefile was below.

	echo "// Generated by $(MAKEFILE_LIST) $(shell date +%Y-%m-%d)" > $(JS)
	/bin/echo -n "wasm= '" >> $(JS)
	base64 -w 0 < main.wasm >> $(JS)
	/bin/echo -n "'" >> $(JS)

It turned out that under MacOS gmake uses /bin/sh not /bin/bash so the "-n" flag to echo doesn't work. Also the program base64 always puts a newline at the end of the file, which is a disaster.

Tested

Linux

  • Chrome

MacOS

  • Chrome
  • Safari doesn't work: Atomics
  • Firefox doesn't work

Known issue Atomics.waitAsync

TODO

  • [] Replace the use of Atomics.waitAsync(), with something more portable
  • [] If an error occurs in the golang function when called from Javascript generate an idiomatic error (exception?).
  • [] Add an example to manipulate the DOM from golang

Note

It is worth looking at the wasm_exec.js to see how the Javascript golang binding is done, as well as syscall/js.

Conclusion

Although WebAssembly has been around for a few years I found documentation and tools to be a little alpha, for example wabt 2 could not disassemble the goland generated WebAssembly. In fact golang generated an opcode 3 that I could not find in the latest spec?

In my opinion Mozilla provides the best documentation for web related topics. I guess for obvious reasons they do not document how to work with WebAssembly/golang. Last time I looked the WebAssembly file was 2M, which is an artifact of having a garbage collector and having a massive runtime. I suspect that going forward I will use rust or C/C++ no runtime or garbage collector.

References

Footnotes

Footnotes

  1. How to load wasm locally

  2. WebAssembly tool kit

  3. WebAssembly opcodes

wasm-golang-inline's People

Contributors

gatanu avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.