New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compile to WebAssembly #1177
Comments
I'm not familiar with WebAssembly yet but if it's similar enough to |
Another possibility here though would be to compile to |
I don't think there's much of a benefit until WebAssembly adds at least PTC and better tooling(?). WebAssembly is targeting C/C++ today, and they're still iterating over the design. Should be interesting to consider it in the future though, as they're planning to diverge from JS's semantics in order to be a better compilation target for languages that aren't close to JS semantically (though PureScript kinda is). As an additional note, compiling to WebAssembly would allow PS to control the memory layout, flow layout and allocations. This is good because we can get rid of a lot of overhead (intermediate data structures, native closure invocation, unnecessary wrapping, branching instead of jumping), but it's also quite a bit more of work. They'll also allow you to define how to deal with exceptions (so your language has access to the stack unwinding and introspection stuff), which should be cool if PS ever plans to provide its own tooling in the browser. And I'm not sure the FFI between this language and JS is clearly defined yet. At least you can't share objects from WebAssembly directly with JS right now. And in the future, I'm not sure how that would work, so that's something to consider as well. |
I don't think Web Assembly will be ready to use anytime soon. At least not until they implement some sort of garbage collection, which will only be worked on after the MVP is done (see design/GC.md). However, I think integrating asm.js is an interesting option. @freebroccolo, I haven't run any tests myself, but don't know why a VM would need to switch from asm.js to non-asm.js code. I'm thinking of implementing only some of the asm.js features, like the bit operations on integers for example. So purescript doesn't need to be 100% asm.js compliant, but would benefit from the increased performance nevertheless. |
@pierrebeaucamp it's been awhile since I messed with it so I don't fully recall the details but I believe it has to do with the way the So in order to get some actual benefit, you need to structure your code so that you have tasks that run long enough to outweigh the initial penalty or you need to have a compilation strategy that runs everything in Bit twiddling was one of the things I was actually interested in doing in It's possible the situation has improved depending on what has happened with VMs in the meantime so it might be worth another shot but I wouldn't expect much. |
Hm, wouldn't this be related to the asm validation? I.e. if you don't validate / flag the code as asm, the VM would just interpret it as normal code... |
@pierrebeaucamp well, sort of. You can write I suspect it's still the case that calling individual inexpensive functions written in Now, if an entire purescript program with all the dependencies were compiled to specialized But anyway this is just speculation based on what I observed before. |
@freebroccolo Let me know if you'd like to try out something with one of the C++ backends. Pure14 is faster, but doesn't support rank-N types and is less tested (and behind). Pure11 should support everything, but its use of a custom variant type has a performance cost (no benchmarks yet). |
@freebroccolo So I've done some reading and it turns out that So probably there will be only a small performance benefit (and, therefore, it's not really worth optimizing for). |
Came here hoping Purescript would be the first language outside Emscripten to use asm.js. Left hoping one day asm.js doesn't suck as a compile target period. |
Closing, since this should ideally be implemented using the output of |
What is the status of this? Are we tracking this issue somewhere else? |
Nobody is working on it that I'm aware of - it's not being tracked in this repo as it's not going to be implemented in the main compiler in the foreseeable future. Maybe one day 😄 |
Says here WASM aims to target mobile, IoT and 'non-browser embeddings'. I think purescript could benefit a lot from that in terms of portability. All major browsers now support the format so unless the API design or implementations are horrible, at some point people are going to be shipping WASM code instead of JS. There might be an opportunity to greatly influence the future of Web app development here. |
WASM will not be a viable compilation target until it gets a story for garbage collection. |
@kritzcreek Although I agree with you, I want to point out that it is possible to compile a garbage collector to WebAssembly and then use it. That's what many garbage collected languages do right now. The problem is with JavaScript interop, not with the garbage collector per se. |
Experimental gc object support is available in Firefox Nightly behind the javascript.options.wasm_gc flag in about:config. Set https://blog.benj.me/2018/07/04/mozilla-2018-faster-calls-and-anyref/ for more details. |
Relevant thread: WebAssembly/gc#36 |
Roadmap for GC: WebAssembly/gc#44 @Pauan what's exactly the problem with JS interop that is stopping from shipping a simple GC? Other languages like Idris also have wasm binding with GC ... i'm not sure how they solve it. But it's just strange that for purescript it's blocking and others just go ahead with it ... |
@flip111 One issue is that the PureScript GC would need to carefully interact with the JavaScript GC in order to avoid memory leaks (e.g. circular references between PureScript and JS). The PureScript compiler would also have to do some heroics to transform the CommonJS modules into something which can be imported and used by Wasm. This is possible, but it's definitely very tricky! To give an example of the sort of stuff PureScript would have to do: Wasm does not support JS objects at all, it only supports integers. So in order to communicate between PureScript and JS, everything must be converted into an integer. The way to do that is to create a heap in JS, and put JS objects into that heap. The index in the heap is the "pointer" to the object. Then JS sends that index to Wasm, and Wasm can use it (since it's just an integer). Then whenever Wasm wants to do something to the object, it has to send the index back to JS, JS then looks up the index in the heap, does the operation, and then sends the result back to Wasm. And when Wasm is done using the object, it has to send a message to JS telling JS to remove the object from the heap (so that way it doesn't cause a memory leak). This is complicated by the fact that PureScript would need its own GC to keep track of these pointers. All of this extra work means that interop between Wasm and JS is multiple orders of magnitude slower than just using JS directly. Which means that Wasm is best in situations where it doesn't need to communicate with JS, and can do everything purely in Wasm. Wasm will soon have I've worked on Rust + JS integration, so I have a good idea of how all this fits together. It's not that difficult, but it's very different from what PureScript currently does, so it would likely require major changes to the FFI system (or heroics on the part of the PureScript compiler). And it would require major changes to the PureScript compiler. And since PureScript has so much communication with JS, it's likely that a Wasm version of PureScript would actually be slower (and would have dramatically larger file sizes) compared to the JS version of PureScript. PureScript was designed around JS, so trying to move to Wasm is very complicated, and likely won't give any benefits (compared to the downsides). This is different from Idris, which was designed to be run natively (and so they have their own GC already), and their FFI with JS is very different from PureScript. |
https://brendaneich.com/2015/06/from-asm-js-to-webassembly/
Are there any benefits to doing so?
I guess we'd need this first:
https://github.com/WebAssembly/design/blob/master/FutureFeatures.md#gcdom-integration
The text was updated successfully, but these errors were encountered: