You can now run WebAssembly on Cloudflare Workers
blog.cloudflare.com
blog.cloudflare.com
tldr; Appears very much an in-joke between work colleagues at Cloudflare :)
Also, is there a badge or sash I can get somewhere saying "Not a Real C Programmer"?
// Really trivial malloc() implementation. We just allocate bytes sequentially from the start of
// the heap, and reset the whole heap to empty at the start of each request.
extern byte __heap_base; // Start of heap -- symbol provided by compiler.
byte* heap = NULL; // Current heap position.
void* last_malloc = NULL; // Last value returned by malloc(), for trivial optimizations.
void* malloc(size_t n) {
last_malloc = heap;
heap += n;
return last_malloc;
}
Am I missing something? How can this work? __heap_base is never used, so first malloc returns a pointer to (void * )NULL;Shouldn't it be:
byte *heap = &__heap_base;
or something to that effect?I haven't read the rest of the code, nor know how WebAssembly works, but I can't make sense of that snippet.
// init() is called from JS to allocate space for the image file.
byte* init(size_t image_size) {
// Reset the heap to empty. (See malloc() implementation in bootstrap.h.)
heap = &__heap_base;http://cs241.cs.illinois.edu/malloc.html
There is (or at least was) a score board you can compare against. By the end of the MP, there are usually handful beating libc.
The thing is.. libc is battle tested, so I'd always trust it over a hand rolled solution. It's always interesting to see improvements though (usually at a cost).
I'm confused; isn't libc an interface and not an implementation?
Traditionally, all WebAssembly modules are essentially eval()ed. You need JavaScript to download the module into an ArrayBuffer or the like, then pass that to the WebAssembly API to compile it.
However, in Cloudflare Workers, we didn't want you to have to fetch WebAssembly remotely at startup. Instead, you upload your WASM module to the Cloudflare configuration UI/API together with your JavaScript code. At startup, the WASM is compiled and the resulting `WebAssembly.Module` appears as a global variable in your script, which you can then instantiate.
Emscripten normally automatically generates JavaScript for you to load your WASM. But Emscripten's generated script doesn't understand this delivery model where the module shows up as a global variable. It should be trivial to add support, but it would be awkward for us to try to submit a patch upstream without the functionality being public yet.
Edit: Just tested this on https://public.tableau.com/vizql/v_public-release1809140800/...
runtimeweb.wasm 2,484,043
runtimewebwasm.b64 3,355,640
runtimwebwasm.hex 4,968,086
runtimewebwasm.b64.gz 974,065
runtimewebwasm.hex.gz 701,052
runtimewebwasm.b64.br 718,918
runtimewebwasm.hex.br 466,221
So with gzip -9, hex encoding is 72% of the size, with brotli (defaults) size is 65% of the size.* Security: In case of an attack we need to be able to call up the code to do forensics, which is hard if it was downloaded dynamically at runtime.
* Optimizations: We want to keep the ability to pre-compile code e.g. into V8 code cache format before distributing it to the edge.
which is hard if it was downloaded dynamically at runtime
Not sure if you mean something other than what this sounds like (I haven't used CF Workers), but just to clarify further, the option I mentioned causes emscripten to emit one single JS file with no external code downloaded at run time.
(In any case, that performance optimization alone certainly sounds like a good reason for the separation.)
Are there plans to change this? Or allow charging on higher use or something?
Node is not a cure all. It's for prototyping with wasm. You need significantly more integration with the execution environment to have DOS protection. How cloudflare does this I don't know. They'd have to remove features like multithreading and continually patch around v8 afaik. Even spidermonkies API is unuseable in a server context.
v8 and by extension isolated-vm by itself does not cover things like fetch if we're talking JS. https://github.com/laverdet/isolated-vm/issues/63 This is an immediete killer as js browser features are part of why a js engine is wanted.
Having node handling these things is a time bomb of debugging where instead of debugging v8 you're debugging node. There are node version problems with stability as mentioned on the isolate-vm readme.
DOS goes beyond just CPU time and memory. Wasm is being treated as an environment of its own with some lower level accessibility. Unless the API allows feature whitelisting - I can't find any docs relating to that - then I don't see anything stopping thread creation. I'd be interested to know how cloudflare prevents these features. isolate-vm doesn't appear to interact with the v8 api with options relating to this.
Fly.io has their fly engine meant for local development so you can deploy onto their servers. https://github.com/superfly/fly
Minimum size of wasm files generated by Go (so far) looks to be 2MB. That should improve over time.
Go wasm is currently hard coded to target browser environments too. Another thing which should improve down the track.