[HN Gopher] Show HN: Jaws - a JavaScript to WASM ahead-of-time c...
___________________________________________________________________
Show HN: Jaws - a JavaScript to WASM ahead-of-time compiler
I've open sourced a JavaScript to WASM compiler. It's an
experimental tool, but given the semantics I already implemented,
I'm fairly certain I am able to eventually cover 100% of JavaScript
spec. Any ideas, questions or critique welcomed! If you are
interested in WASM, especially with new proposals like WASM GC or
exception handling, it might be a good source of seeing these
features in action - the project has a few thousand lines of hand
written WAT so far.
Author : drogus
Score : 120 points
Date : 2024-11-09 18:14 UTC (4 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| samuelstros wrote:
| nice, "run JS without (browser) runtime" is coming. perforr,
| jaws, or another project will eventually succeed.
| jahewson wrote:
| bun?
| thrw42A8N wrote:
| Bun is a runtime.. If you're referring to the fact it can
| produce a single binary, Node.js can do that too.
| drogus wrote:
| Yeah, bun will still include V8 in the generated binary
| thrw42A8N wrote:
| Bun will include the Bun runtime with JavaScriptCore,
| Node.js will include the Node.js runtime with V8.
| drogus wrote:
| Oh, thanks for the clarification, I somehow thought Bun
| is also V8!
| thrw42A8N wrote:
| That would be Deno. It can also produce a single binary
| using the same principle.
| IggleSniggle wrote:
| Bun uses JavaScriptCore as its runtime, not V8
| codesnik wrote:
| also https://docs.docker.com/desktop/features/wasm/
| philipwhiuk wrote:
| You mean like Node?
| asabla wrote:
| Title might need to include "Show HN".
|
| Very cool and interesting project! How are build times? And how
| big are the artifacts?
|
| I'll for sure keep an eye on this, and add it to my ever
| expanding list of tech to explore.
|
| Thank you for sharing!
| drogus wrote:
| The binaries are a few KBs at the moment. I haven't measured
| the build times, cause it's too early for it to mean much. The
| amount of supported types and functions is very limited, so it
| will change a lot over time as I add more stuff.
|
| One interesting thing is that `eval()` support will require
| custom WebAssembly host functions, cause you can't do custom
| code generation in WASM. Thus by default the project will
| assume "no eval" compilation. In this mode it will be possible
| to do a lot of optimizations, like for example remove unused
| parts of the language/types, do certain optimiztions knowing
| exactly what types the script is dealing with etc. So a simple
| script that doesn't use a lot of the builtins should eventually
| result in a fairly small binary.
| lagrange77 wrote:
| Very cool!
|
| Does it support ArrayBuffers?
| drogus wrote:
| Not yet, it's very early stage where I'm mostly implementing
| full JavaScript semantics (and hopefully finding some
| funding/support for the project), but as soon as I'm done with
| async/await and a few simpler missing pieces, I will start
| implementing JS builtin types
| lagrange77 wrote:
| Cool, thanks and all the best with the project.
| OscarDC wrote:
| I read the README.md of the project but I'm still not sure:
| What's the expected usage of this? How does the outputed WASM
| code then interacts with a runtime (and with which, is it
| intended to be a tool compatible with browsers and other WASM
| runtimes or is it only compatible with a runtime linked to the
| project)?
|
| Somewhat linked questions: How does it react if it encounters
| e.g. web APIs inside the JavaScript code or other global
| identifiers only defined in some environment (e.g. a recent
| browser, Node.js etc.)? Or if it's not intended for those
| environments, how are you supposed to do I/O when using this?
| drogus wrote:
| These are very good questions, I'll respond here, but I'll also
| add more info to the README. This project is mainly targeting
| WebAssembly usage on the server, cause I think it makes little
| sense to run JavaScript in WebAssembly in JavaScript (although
| time will tell, maybe it will be useful for sandboxing frontend
| plugins?). Regardless if it's running in the browser or a
| backend runtime like WasmTime or WasmEdge, at the moment
| running JavaScript inside WebAssembly is not ideal. You either
| have to compile a JS engine like V8 or SpiderMonkey to WASM and
| then use it to run your script or you have to settle for an
| "almost JavaScript" language like AssemblyScript. This is a
| limiting factor for running server workloads. For example
| Fastly uses SpiderMonkey for their WASM workers, but it means
| that each instance uses 5-10MBs of memory even for a hello
| world. Shopify, on the other hand, uses WASM for customizing
| server side of their shops, and they decided they only allow
| WASM binaries up to 250KBs, which is a no-go for embedding any
| interpreter. Thus their "blessed" language is AssemblyScript.
| They outline reasons for that here:
| https://shopify.engineering/shopify-webassembly
|
| This is all due to a fact that historically WASM was a very
| simple runtime. It was relatively easy to compile C code to
| WASM, just like you compile C code to machine code, but even
| though a WebAssembly is a kind of interpreter by itself, it
| wasn't easy to interpret higher level languages on top of it.
|
| With new proposals being standardized, like garbage collection
| support or exception handling support, WebAssembly becomes much
| more powerful interpreter, with stuff like structs, arrays,
| function references etc.
|
| Jaws leverages that fact translating JS code to WASM code in a
| way that WASM interprets the resulting code, without the need
| of a JS engine like SpiderMonkey. In practice it mainly means
| that a binary generated by Jaws will be probably under 50KBs vs
| 10MBs when you compile SpiderMonkey to WASM and run your script
| on top of that. Memory usage will be also significantly lower.
| For companies like Fastly this would mean orders of magnitude
| lower memory usage and thus server costs. For companies like
| Shopify it would mean they could leverage JavaScript code
| already available (think NPM packkages) and JavaScript
| ecosystem for people writing plugins for Shopify's backend.
|
| > is it intended to be a tool compatible with browsers and
| other WASM runtimes or is it only compatible with a runtime
| linked to the project
|
| The only runtime the project uses is WebAssembly. The generated
| code is mostly 3k lines of WAT code form this file:
| https://github.com/drogus/jaws/blob/main/src/wat/template.wa...
| and whatever your JS code is translated to. For example for a
| very simple program like "console.log('foo')" the entire
| "generated" part is this: https://gist.github.com/drogus/1c49c2
| 5ed0b14804b2f27e10d2a79..., which more or less prepares an
| argument (with new_static_string) and then calls console.log.
| Right now I need a bit of glue code on the host, but eventually
| it will be possible to execute such a binary with any runtime
| that supports WASIp2, WASM GC and exception handling proposals.
|
| > Somewhat linked questions: How does it react if it encounters
| e.g. web APIs inside the JavaScript code or other global
| identifiers only defined in some environment (e.g. a recent
| browser, Node.js etc.)? Or if it's not intended for those
| environments, how are you supposed to do I/O when using this?
|
| None of this is implemented yet, but I can tell you how it will
| work. I plan to support Node.js APIs through WASI. WASI is a
| standard for communicating between WASM programs and the
| outside world. For example WASI defines a standard set of
| functions you can use to send an HTTP request, or write to
| STDOUT, or read/write to a file. So when I get to APIs like
| `fetch` or `fs`, it should work with any runtime that supports
| WASI preview2. Browsers could also be supported with polyfills,
| but in this case I/O support is more custom. Like, if you
| decide you allow WASM programs to write or read files, you
| would have to provide a mechanism to do that, for example save
| files to localStorage or an SQLite database compiled to WASM
| (or I guess even send them to S3 or something along the lines).
| Aldipower wrote:
| JAWS is a well-known screen reader for blind people with a more
| then 30 years history.
| refulgentis wrote:
| Even worse, JAWS is a well-known movie with a _49 year_
| history. I strongly believe the screen reader and the WASM
| compiler both knew this at the time, quite damning.
| drogus wrote:
| I am painfully aware the project will never be the first hit
| in Google by just typing it's name lol
|
| Btw, I am very bad at naming, I chose the name cause it has
| most of the letters that "JS-WASM" has (or all of them if you
| consider W is just inverted M)
| refulgentis wrote:
| Don't even think about it :) I'm just teasing the person
| I'm replying to, its a way of saying "yeah I don't think
| that name collision is significant" that A) assumes they
| desire conversation, so it's okay to reply B) engages
| without asserting C) expresses disagreement in a jovial
| matter, rather than confrontational
| benmccann wrote:
| JAWSM might be a more unique alternative if you're looking
| for any.
|
| Anyway, it's a cool project. Thanks for sharing!
| chamomeal wrote:
| I love the name!
| Aldipower wrote:
| Apples and peaches. Jaws the movie is another section, the
| movie section. Jaws and JAWS are both in the software
| section. There's the potential for conflicted naming. Sorry
| to be emotionless here, but at least you could respect the
| fact that there is a popular software with the same name,
| without making jokes about it.
| refulgentis wrote:
| There is no "software section" anymore, alas :( RIP
| Computer City.
|
| FWIW, for the audience, both you and I know the game here
| is "can we define a broad enough, yet narrow enough,
| category that someone could confuse the screenreader with
| the WASM compiler, such that it can be claimed to be
| 'emotionless' to say there's a significant collision and
| the WASM compiler needs a rename."
|
| First, there's certainly room for conversation, emotionless
| doesn't mean provably unambiguously correct and everyone
| else needs to agree and not reply. :)
|
| Second, it's clear you do have emotions, ex. see how you're
| policing whether its okay to "joke", where "joke" is me
| going to great lengths to indirectly indicate the
| possibility this is less than 100% unambiguously correct in
| as non-personal a way as possible. I did that because the
| initial curt, policing, tone indicated strongly that you
| would react poorly to any indication this was anything
| other than unambiguous. And here we are.
| drogus wrote:
| I know about Jaws as a screen reader, but I don't think it is
| much of a conflict. WebAssembly is a niche within a niche (like
| a tool in a WebAssembly ecosystem within a programming
| ecosystem), so it will probably never grow to a popularity
| where it's higher in search results making life of people using
| screen readers worse. But even now, when you enter Jaws into
| google now, the whole first page is about Jaws, the movie. So
| if anyone wants to find either of the projects by name they
| have to specify it more anyway, just like you often have to do
| with other projects (for example I always search for "phoenix
| elixir" instead of just Phoenix). My take is that with the
| amount of tools and programs there is no way to use simple
| names and not have a conflict here or there.
| IshKebab wrote:
| Yes. Well done. This is a different Jaws though.
| mmoskal wrote:
| Back in the day I did an almost-Typescript (though much closer
| than assembly script) to embedded ARM compiler. Some of the
| techniques may be useful.
|
| https://www.microsoft.com/en-us/research/uploads/prod/2019/0...
| drogus wrote:
| Nice! I'll definitely take a look!
| kengoa wrote:
| > I'm fairly certain I am able to eventually cover 100% of
| JavaScript spec. Any ideas, questions or critique welcomed!
|
| Do you have the results of test262_runner.rb? I came to know
| about test262 at a talk by the porffor's author and something
| like https://github.com/CanadaHonk/porffor?tab=readme-ov-
| file#tes... in README would be great to show this progress. Great
| project by the way!
| drogus wrote:
| Yeah, at the moment it's passing about 12% of tests, but there
| is a lot of low hanging fruits to implement, especially
| considering I started the project two weeks ago. This doesn't
| mean I will hit 100% in linear time, unfortunately, cause there
| is a long tail of builtin types and functions, but as I started
| by implementing the "hard parts" I left some easy parts not
| done. For example I implemented only enough syntax to allow
| running conditionals and a while loop cause it was needed for
| the test262 harness, but I left all the other loops (for, for
| in, for of, do while) and conditional expressions (switch)
| unimplemented. Implementing them will be more or less analogous
| to existing implementations for if/else and while.
|
| Once I finish implementing `await` and generators, which are
| the last hard to implement semantic concepts, I will be
| implementing those low hanging fruits. It's hard to say how
| much coverage that will give me, but just to give an example:
| currently 1200 tests fails, cause `object["foo"]` syntax is not
| implemented. Ie. `object.foo` works, but `object["foo"]` does
| not. It doesn't mean that those 1200 tests automatically will
| pass, cause they might be testing other stuff, but there is a
| lot of such relatively simple syntax ommissions that make
| hundreds of tests fail.
|
| And yes, I would love to have a nice graph like porffor has! :D
| philipwhiuk wrote:
| We're one step closer:
| https://www.destroyallsoftware.com/talks/the-birth-and-death...
| sedatk wrote:
| Off-topic, but, why does he pronounce JavaScript "YavaScript"?
| pvg wrote:
| Why do we say 'wat' instead of hwaet? Same thing.
| Kiro wrote:
| How else would you pronounce it?
| pvg wrote:
| J as in Jacques, 'script' like 'esprit'. Zhavascree, stress
| on final syllable.
| noman-land wrote:
| The joke is that he's speaking from the future where they
| inexplicably pronounce javascript "yavascript". This is how
| you know he's really from the future.
| sedatk wrote:
| Uh, okay, I must have missed that part :)
| noman-land wrote:
| He definitely never mentions it but the opening line of
| the presentation is "This talk is a 40 year history
| beginning in 1995 and going until 2035" and he speaks in
| the past tense so he sorta just launches into it without
| setting it up much.
| teaearlgraycold wrote:
| I get a build error where it can not find "prepend.js". Indeed it
| appears to not be in the repo.
| drogus wrote:
| thanks for reporting and sorry about that! I was prepending
| some JavaScript code to be compiled for test262 harness before,
| but at the moment it was just an empty file, so I removed it
| and pushed a fix. Please try again now and let me know if you
| run into any issues!
| andout_ wrote:
| Really clever use of the new WASM GC proposal. All the JS -> WASM
| compilers so far have basically just been shipping a whole JS
| engine - this is the first one I've seen that actually tries to
| map JS constructs directly to WASM primitives.
| drogus wrote:
| Thanks! Although, to be fair, it's a clever use mostly cause
| I'm too dumb to write the full interpreter on top of WASM lol
| tomcam wrote:
| Or, as some of us call it, a compiler. Nice work btw!
| drogus wrote:
| Haha, I haven't even noticed it doesn't make too much sense
| when I was writing the title :D
| huijzer wrote:
| Just when I was thinking: do we need more compilers or do they
| all exist already?
|
| Thank you for working on this! I think it's a great idea.
| drogus wrote:
| Just one more compiler, bro. Just one more, I promise. This is
| the last one, just one more
___________________________________________________________________
(page generated 2024-11-09 23:00 UTC)