Hacker News new | ask | show | jobs
Show HN: Life – A secure, blazing-fast, cross-platform WebAssembly VM in Go (github.com)
111 points by twokei 2878 days ago
15 comments

At first glance, this looks like an ordinary interpreter loop [1] using a large switch statement. I didn't think this was all that fast in Go, compared to C. And yet the JIT version isn't hugely faster and can be slower. Are there performance tricks I'm missing?

[1] https://github.com/perlin-network/life/blob/master/exec/vm.g...

Do you mean the JIT engine in this same codebase?

It looks like it generates C code and compiles it on the fly. The generated code seems to do manual stack operations, rather than assigning values to variables, and it’s compiled with -O1 so it won’t be heavily optimized. It will be a bit faster than the interpreter because it avoids the opcode dispatch overhead, but if I understand the code right it’s not surprising that it isn’t a ton faster.

This is off-topic, but I really wonder what happened to adverbs in English, and why. When I was a boy — not that long ago — it would have been 'blazingly fast.'

The project itself looks pretty cool, though. It's neat to see WebAssembly starting to take off. I'm eager to begin programming browser applications in a decent language …

American English abandoned them. They are still used in British English.
What happened is that they became progressively less common in informal/spoken American English, and then only very recently in a fairly sudden transition most commercial writing abruptly lost the attention to grammar, spelling, word choice, etc., that had been previously the norm for formal writing because who has time for that?
And the internet has made English American, newer generation in EU are now writing more American English than ever.
It's common to avoid adverbs in general when writing fiction IIRC.
Not by removing the ly though, but by choosing a more expressive verb.
I was taught in (american) school adverbs are a lazy and informal form of expression. While I didn't agree at the time, I use them now only vanishingly rarely. ;)
> I was taught in (american) school adverbs are a lazy and informal form of expression.

I've certainly (in the same place) heard that heavy adverb use is a “writing smell” in much that way, but the point of that was very much not to substitute the use of adjectives serving as if they were adverbs for actual adverbs.

Off-topic, but I love Stephen King's comments [1] regarding adverbs.

[1] https://www.brainpickings.org/2013/03/13/stephen-king-on-adv...

True. "blazing-fast" sounds almost like a pidgin variant to me.
>…faster than all other WebAssembly implementations tested (go-interpreter/wagon, paritytech/wasmi).

Isn't Mozilla's implementation the fastest and most mature of them all? How does it fare against it?

Note: benchmarks are comparing to other wasm interpreters (in Go and Rust), not browser implementations.
Yeah this claim:

> is faster than all other WebAssembly implementations tested

is pretty meaningless once you realize this.

I'd be really surprised if this outperformed V8 or SpiderMonkey, but I'd love to be proved wrong.

Looking at the benchmark results, it’s really not very fast. Over 3 seconds for fib(35)??
Saw this on /r/golang and made some comments there. Good work! Always happy to see more non-web uses of WASM. Here's to hoping some of those higher-level features come to WASM soon so that we can really start sharing code instead of in the primitive constructs we have to use now.
In short: a reasonably compliant, customizable VM without native dependencies, great for running code in cross-platform sandboxes.

A JIT is planned but not yet implemented.

> A JIT is planned but not yet implemented.

I see "Life (JIT)" in the benchmark plot. What is it?

Well, there’s one in the repo that generates C code from the bytecode, compiles it with cc, and dynamic-loads it.
It does in fact have a JIT, but just for (32 bit) x86.
How fast is this compared to browser javascript vm "implementations" of WebAssembly?
AFAICT WebAssembly VM is implemented in native code in the major browsers (Firefox, Chrome, Safari, Edge). It's pretty fast, and has a pretty limited interface to JS or DOM.
Native code or not shouldn't matter that much for a JIT. I've heard Cliff Click say in a talk that if he were to write another VM, it'd probably be in something like Java. The memory management of fairly arbitrary graphs like you get in a compiler really benefit from garbage collection, and it's nice to run the compiler sort of through itself to get dynamic profiling for optimization.
I mean, implementing a WebAssembly VM inside e.g. JVM is both possible and practical, but it's a very different approach from implementing it in native code, let alone any JIT approaches.
I mean, implementing a JIT is orthogonal to implementing it in another VM. See JITing meta circular evaluators like Jikes or Graal.
At least an order of magnitude slower, probably two. It doesn't even implement a JIT yet.
The point here is not speed (that will come), the hope is it will bring privacy to your computational needs along with cost reduction and a little reverse crowdfunding ... perlin is a new distributed computation platform to spread execution of your code across disparate VM running on non-traditional machines. Goal here is to compete with big boys who run cloud VPS hosting services such that folks with spare cycles rent their hardware so other folks can execute their code ... to quote :

"Researchers, developers, startups and enterprises incur excessive costs to power up the cloud machines/instances they rent from centralized cloud computing providers.

Perlin is creating a decentralized, trustless cloud computing marketplace which delivers massive computational throughput and power with the ability to attain high transaction volume and market activity, effectively reducing the cost of computing power."

https://www.perlin.net/

More to the point and I quote :

"Decentralized cloud computing.

Perlin’s compute layer is bootstrapped on top of it’s DAG-based ledger unlocking a plethora of underutilized compute resources from everyday devices, to form a decentralized cloud computing marketplace that combats the inflated pricing models set by the oligopolistic cloud computing market."

"Perlin is the first practical, trustless and decentralized cloud computing marketplace that leverages underutilized compute power in everyday smart-devices to make supercomputing economically viable and accessible globally. This is achieved via a DAG-based distributed ledger using Avalanche consensus."

https://www.reddit.com/r/perlin/comments/8vq0c1/the_perlin_n...

I understand the basics behind WASM. What does WebAssembly VM in Go mean?

Can I write Golang code and see it executed through Life? Or will it execute my WASM binaries, compiled through whatever?

If the later, how is Life VM meant to be integrated into a web browser (if this is a goal)?

- the VM is written in Go and can execute wasm binaries

- the next version of the Go toolchain (Go-1.11) will have a wasm target

Yes, WASM binaries from anything. The VM configures the available imports.
Can I write Golang code and see it executed through Life?

Is there a Life target for the Go compiler?

Is WebAssembly more secure than Javascript when it comes to escaping the sandbox? I see exploits every year in pwn2own for Javascript.
That question should be answered in future pwn2owns, probably :) but since it reuses JIT architecture in existing JS engines, my guess is that it will mostly benefit from previous security and sandboxing advances.
This is not about cellular automata? I feel misled.

Can it be renamed to something more indicative of virtualization?

Does the lack of OS dependencies mean that it can't present a graphical user interface? Isn't that the main intended usage of WebAssembly, providing a cross-platform user interface that usually runs in a browser?
Can CPU and memory limits be enforced? If so, how is it done?
It looks like this Life VM has a "RunWithGasLimit" function that can run WebAssembly for a limited number of steps. I'm not sure if it pauses or aborts the VM when the limit is reached.

On a related note: you can enforce a CPU limit on WebAssembly in any engine by using wasm-metering[0]. Note that if the WebAssembly hits the limit, it is entirely aborted, not paused. So wasm-metering is good for limiting the CPU usage of a WebAssembly binary that has short functions called regularly, but not capable of time-slicing a long-running WebAssembly function. I think you'll need custom support from a WebAssembly VM (or a much more extensive preprocessor) for that.

[0] https://github.com/ewasm/wasm-metering

It supports both a `DefaultMemoryPages` size, as well as a `MaxMemoryPages` in the vmconfig[0]. Only the `DefaultMemoryPages` is set when running through the cli (value of 128 pages, with a page size of 64KB), and there appear to be no flags to configure it at the moment.

[0] https://github.com/perlin-network/life/blob/master/exec/vm.g...

Can't immediately see any mention of of how to accommodate file access on local system (or permanent storage within sandbox) - any pointers?
WebAssembly has no native filesystem APIs or any built-in APIs to the outside world. A WebAssembly binary may specify that it wants to import functions by certain names, and it's up to the user of the WebAssembly to implement and provide the functions that the WebAssembly wants to import. You could make a WebAssembly binary that imports a "readFile" function, and then you could load the WebAssembly in Go with this Life VM (or in Javascript with the native WebAssembly APIs) and specify your implementation of the "readFile" function in the host environment. Your implementation of "readFile" can then impose whatever restrictions it wants.
I believe Import Resolvers[0] solve this issue.

[0] https://github.com/perlin-network/life#import-resolvers

It's secure if so was written in description.