WASM Instructions
webassembly.github.io
webassembly.github.io
> This book takes a hands-on, bottoms-up approach: you'll go from hand crafting bytecodes to writing a real compiler for a simple programming language.
disclaimer: I'm the co-author
Writing a Minimum Viable Cartridge for WASM4 (https://wasm4.org/) using WAT:
https://twitter.com/warianoguerra/status/1748382204508410149
Wasm compilers in a tweet:
https://twitter.com/warianoguerra/status/1576166873296941056
A WebAssembly compiler for a reverse polish notation calculator in 269 bytes of JavaScript:
https://twitter.com/warianoguerra/status/1677271664009138177
From the linked page.
> This book takes a hands-on, bottoms-up approach
I think you mean "bottom-up". "bottoms-up" is a toast.
I assume it was initially intended to be more like a "real" assembly language but then they realized how much more optimized things could be if they went with higher level constructs.
https://en.wikipedia.org/wiki/WebAssembly "the initial implementation was based on the feature set of asm.js." https://en.wikipedia.org/wiki/Asm.js
NaCL tried more to be a real assembly language but had cross-platform issues.
However: https://www.tomshardware.com/news/chrome-deprecates-pnacl-em...
Just mentions API concerns and: https://robert.ocallahan.org/2013/05/blink-pnacl-and-standar... " PNaCl and Pepper are not open standards, and there are not even any proposals on the table to standardize them in any forum. They have documentation, but for the details one must defer to the large bundle of Chrome code that implements them. "
and
"1. NaCl is CPU-specific. That's not suitable for the web.
2. PNaCl is in theory portable, so it is potentially worth considering.
3. However there is no spec for PNaCl, and standardizing it would take an extreme amount of effort: It means standardizing a subset of LLVM IR, which is quite rich and complex, as well as the Pepper plugin API. This is an enormous amount of work that has not even been begun by Google AFAIK."
But you're right, I don't see anyone mentioning any hardware complications.
Oh well. Moot point these days, and I think we're all better off that everyone else stood their ground, in terms of security, integration with JS APIs, and having a variety of WASM implementations.
WASM's 'loop' isn't really that high level, it's a backwards branch target with no built in bells or whistles. It's less powerful than 'while' in C.
Simply put, wasm is optimized to allow JITs to be simpler, at the expense of making it harder to write compilers for it.
If you're doing liveness analysis, you wouldn't have to first deduce which edges are unstructured jumps and which are loop edges. If you're trying to find more opportunities for if-conversion, you wouldn't have to first deduce which edges those are.
https://github.com/WebAssembly/design/issues/796#issuecommen...
AFAIK no other Wasm implementation has the same constraint - the rest generally tend to desugar everything to (potentially irreducible) CFG and then proceed from there. So this is, at least to some extent, yet another case of a large company effectively forcing an open standard to be more convenient for them specifically.
"A fast Pascal (Delphi) WebAssembly interpreter":
https://github.com/marat1961/wasm
"WASM-4":
https://github.com/aduros/wasm4
"Curated list of awesome things regarding WebAssembly (wasm) ecosystem":
https://github.com/mbasso/awesome-wasm
Google Chromium/Chrome V8 (JavaScript Engine) WASM Source Code branch:
https://github.com/v8/v8/tree/main/src/wasm
Also... it would be nice if there was a WASM software/soft CPU for QEMU, which (if it existed!) would go here:
I was looking for something exactly like that(!) to test running off-line (and out of the web browser) WASM code locally!
Thanks extremely much!
Couldn't they have an option like alt text where it shows something less pretty but useful before JS is on?
All that is left after that is for VMs to implement the standard, which is tracked here:
https://webassembly.org/features/
Most major VMs do support tail calls today, but not all.
> effect handlers as a unifying mechanism to enable efficient compilation of control idioms, such as async/await, generators/iterators, first-class continuations, etc.
You have to have some sort translation layer/virtual machine consuming the fake assembly and spitting out the real hardware assembly... which begs the question of why is that better than mapping stuff into intrinsics.
So far the only use case I can gather is obfuscation for content management a la tiktok, where as the people behind WASM seem to be going with the "super ~native performance" marketing angle.
- Adobe has a C-based codebase of Photoshop developed over decades for the desktop app
- Adobe wants to bring Photoshop to the web for easier distribution and tighter control
- Adobe engineers compile the existing C-based codebase to webassembly instead of rewriting it from scratch in javascript
- Photoshop for the Web is born
- ...
- Profit?That argument feels a bit academic.
Also Asm.JS (Wasm's predecessor) was born to port GAMES, games often have their own GL,etc UI's that they render themselves and then tons upon tons of gameplay logic code that runs in C/C++ (or whatever scripting language the engine supports like C#).
That was the most important part initially, even if people on the outside are starting to benefit like the Figma folks that uses Wasm, kinda like GPU's were for gaming and now power a ton of modern UI and AI workloads.
If you’re not writing a fully custom UI, you might choose something like Qt, which has wasm built in: https://www.qt.io/web-assembly-example-slate?hsCtaTracking=3...
Home computer emulators:
https://floooh.github.io/tiny8bit/
CPU simulators for Z80 and 6502 (based on the netlists from visual6502.org):
https://floooh.github.io/visualz80remix/
https://floooh.github.io/visual6502remix/
The shareware version of Doom:
https://floooh.github.io/doom-sokol/
A Pacman clone in C:
https://floooh.github.io/pacman.c/pacman.html
...and the same in Zig:
https://floooh.github.io/pacman.zig/pacman.html
This is all relatively small hobby stuff written just by me, but there's nothing that would prevent scaling to bigger projects.
Finally here are the examples for the cross-platform libraries this stuff is built on top:
https://floooh.github.io/sokol-html5/
Also specifically about Photoshop: since PS is already a cross-platform application I would expect that they abstracted their UI layer enough to be portable to other UI frameworks without too much hassle. Hybrid WASM/JS applications are in fact a pretty good idea for some use cases (e.g. compile the core logic written in C/C++/Rust/Zig... to WASM, but implement the UI layer via HTML+CSS).
https://github.com/SimHacker/MicropolisCore/blob/main/src/Mi...
////////////////////////////////////////////////////////////////////////
// This file uses emscripten's embind to bind C++ classes,
// C structures, functions, enums, and contents into JavaScript,
// so you can even subclass C++ classes in JavaScript,
// for implementing plugins and user interfaces.
//
// Wrapping the entire Micropolis class from the Micropolis (open-source
// version of SimCity) code into Emscripten for JavaScript access is a
// large and complex task, mainly due to the size and complexity of the
// class. The class encompasses almost every aspect of the simulation,
// including map generation, simulation logic, user interface
// interactions, and more.
//
// Strategy for Wrapping
//
// 1. Core Simulation Logic: Focus on the core simulation aspects, such
// as the methods to run the simulation, update game states, and handle
// user inputs (like building tools and disaster simulations). This is
// crucial for any gameplay functionality.
//
// 2. Memory and Performance Considerations: JavaScript and WebAssembly
// run in a browser context, which can have memory limitations and
// performance constraints. Carefully manage memory allocation,
// especially when dealing with the game's map and various buffers.
//
// 3. Direct Memory Access: Provide JavaScript access to critical game
// data structures like the map buffer for efficient reading and
// writing. This can be done using Emscripten's heap access functions
// (HEAP8, HEAP16, HEAP32, etc.).
//
// 4. User Interface and Rendering: This part might not be necessary to
// wrap, as modern web technologies (HTML, CSS, WebGL) can be used for
// UI. However, providing some hooks for game state (like score, budget,
// etc.) to JavaScript might be helpful.
//
// 5. Callbacks and Interactivity: Ensure that key game events and
// callbacks are exposed to JavaScript, allowing for interactive and
// responsive gameplay.
//
// 6. Optimizations: Where possible, optimize C++ code for WebAssembly,
// focusing on critical paths in the simulation loop.
//
// Decisions and Explanations
//
// - Excluded Elements:
//
// - Low-level rendering or platform-specific code, as this can be
// handled more efficiently with web technologies.
//
// - Parts of the code that handle file I/O directly, as file access
// in a web context is typically handled differently (e.g., using
// browser APIs or server-side support).
//
// - Any networking or multiplayer code, as web-based
// implementations would differ significantly from desktop-based
// network code.
//
// - Included Elements:
//
// - Core game mechanics, such as map generation, zone simulation
// (residential, commercial, industrial), disaster simulation, and
// basic utilities.
//
// - Game state management, including budgeting, scoring, and city
// evaluation.
//
// - Direct memory access to critical structures like the map
// buffer, allowing efficient manipulation from JavaScript.
//
// - Essential callbacks and event handling mechanisms to ensure
// interactivity.
//
// Conclusion
//
// Given the complexity and size of the Micropolis class, wrapping the
// entire class directly is impractical. However, focusing on key areas
// essential for gameplay and providing efficient interfaces for
// critical data structures can create a functional and interactive city
// simulation in a web context. Further optimizations and adjustments
// would likely be needed based on testing and specific requirements of
// the web implementation.There doesn't appear to be much evidence to support this claim. In fact, there are benchmarks where Javascript outperforms Wasm.
Picking the fastest JS and non-JS binary trees there, for example, the JS one relies on the garbage collector, which means that in practice it can bump allocate all of its temporary objects, and the GC will never run, so they will never be freed.
The Rust one in comparison is allocating a bunch of ref-counted handles. It is automatically going to lose.
EDIT: I dug around that site more and if you pull up 'JavaScript vs Rust' for the same benchmark, JS is still faster. So I don't understand why you're even using this for a 'JS is faster than WASM' argument if it appears to be saying that JS is also faster than Rust.
This doesn't appear to generally be the case and some outliers are to be expected in benchmarks.
>'JS is faster than WASM'
Was never the argument.
Source: I contribute a lot to wasmtime’s C API and build Redpanda’s Wasm Data Transforms using it
You can run wasm in k8s: https://krustlet.dev/
Docker itself can run wasm: https://wasmlabs.dev/articles/docker-without-containers/
There are a few serverless runtimes based on wasm: https://wasmcloud.com/
A lot of those are powered by wasmtime or WasmEdge.
If you’re wanting to be able to just pull down a random app and run it as wasm, that’s inherently harder with wasm, because you have to recompile, and amazing compiling stuff is always harder than it should be. For example I compiled jq to wasm to other day, so you dont have to worry (as much) about the CVEs that was issued recently. https://github.com/rockwotj/jq-wasi
1. More compact representation due to binary encoding compared to text
2. Improved compilation times, since WebAssembly is "lower-level" compared to JS and the engines can assume code has been already optimized and can skip a good chunk of the normal JIT optimization pipeline.
3. Improved runtime performance due to strict typing. No type-checks, no bailouts, etc
These come with their set of drawbacks, the main one being that WebAssembly cannot _really_ use the DOM or interact with JavaScript directly and is effectively just a computational engine. Any interaction with the outside word is abstracted to "imports": calls with arbitrary semantics come from outside of WebAssembly.At some point WebAssembly also had the advantage of predictable performance, with the idea being that code would be compiled once-and-for-all during module loading.
This promise was, as far as I understand, effectively abandoned first by the introduction of "Baseline" compilers (Liftoff, in V8 terminology) and in more recent times by the requirement of WasmGC, which (I think) has reintroduced the need for bailouts and dynamic recompilation.
1. Baseline compilers are generally 2x slower than optimizing ones. That's noticeable, but it is still a far smaller difference than JS has between its tiers.
2. Even WasmGC doesn't require bailouts - in fact no VM implements them for Wasm AFAIK. However WasmGC is often compiled by languages that do benefit significantly from dynamic inlining, which adds unpredictability, but again the effect (30% [0]) is far smaller than typical differences in JS.
This, I don't understand...
AFAICT the "baseline" compiler's entire job is to get pixels on the screen as fast as possible and then they use optimization strategies to recompile code sections or functions or whatever to speed it up based on $reasons.
WASM originally promised to be AOT compiled once, start to finish, with consistent performance. The design omitted some useful (perhaps essential) things in order to be able to provide this.
P.S. I assume JS has a GC and WASM does not.
Note that pauses _can_ happen in non-GC languages too, if you have to delete something that references a bunch of other stuff that you have to recursively delete as well, though in the real world this is not very common.
WASM now has GC, since a goal is to support alternative scripting environments and e.g. run a mixture of Rust and Python code in the browser.
Absolutely. E.g. JVM byte code
> why is that better
Portability and sandboxing
No ... it's a "bytecode."
A runtime for an interpreted languages like Javascript can operate directly on the code text and execute the source code. The runtime has to parse, lex, and interpret the code text into things that represent what the code should do - in realtime.
"Bytecode" is basically that parse/lex/interpretation step already done. The runtime that interprets bytecode (often called a JIT or jitter) is drastically simpler since it only has to know how to do the relatively simple bytecode operations, instead of complex high-level things like Javascript syntax and object moderling.
Benefits:
- multiple languages can be targeted to that bytecode (Microsoft does this with it's CIL/.NET)
- porting the JIT to different platforms is potentially easier and less error/security-issue prone than the runtime for a high-level langauge
- bytecode is easier to examine for security issues than high-level languages - if you want sandboxed code - a whole lot easier to do in a JIT than a full interpreter.
- if you design your bytecode right, the JIT could basically translate it to actual CPU assembly language fairly easily.
https://github.com/WebAssembly/spec/blob/main/document/core/...
That being said...https://pastebin.com/mhtgjSjZ
That is so informative.
Seriously though, wouldn't one expect the authors of this spec to be experts on web technologies who eat their own dog food (of web standards) instead of relying on a pale imitation of a dated typesetting technology like TeX?
FWIW, it works perfectly fine for me on Linux with both Chrome and Firefox, so I'd say probably something is wonky in your environment, or a temporary issue on the website.
It’s really a truly terrible spec site.
You seem to be confusing "mature" with "dated."
- despite the window dressing of LaTeX, it is ultimately presentation-oriented instead of structure-oriented; many widely-used forms of formatting markup rely on precise character dimensions and positioning; changing page dimensions may sometimes require fixes throughout the whole document
- bad character set support: things like \mathcal{3} displays the wrong character WITH ZERO WARNING: see https://tex.stackexchange.com/q/84041/ and duplicates
- parsing is undecidable; the parser can be arbitrarily reconfigured at runtime, and can perform Turing-complete computations, which means processing arbitrary TeX code in any other way than to execute it as written is next to impossible; even a 100% correct syntax highlighter is unachievable
MathJax fixes or ameliorates some of these flaws, but in trying to be compatible with TeX, it cannot avoid all of them; and in the meantime, it imposes its own syntax quirks and burdens the client with running bloated JavaScript, incurs significant pop-in latency, and leaves indecipherable mess of TeX code to clients which do not run JS. TeX is just PDF that's easier to edit, and MathJax is the Cufon of math markup. (Remember Cufon? Be thankful if you don't. Good riddance!)
And yet Knuth seems to regard Unicode not as a basic building block of interoperability, but as useless bells-and-whistles, judging by his satirical "iTeX" presentation.