oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀
https://www.graalvm.org
Other
20.43k stars 1.64k forks source link

Wasm target architecture for native image #3391

Open jespertheend opened 3 years ago

jespertheend commented 3 years ago

Feature request

Is your feature request related to a problem? Please describe. I'm trying to port closure compiler to wasm so that it can run from within a browser.

Describe the solution you'd like. Closure compiler already has build support for native image. So I was hoping to be able to use the LLVM backend but it seems like adding a new target architecture is a lot more work than I had expected.

Describe who do you think will benefit the most. Anyone using GraalVM to build native image versions of their app would benefit from this, as they can now port their application to the web easily. Java developers who want to write a new application from the web could also benefit from this, they can now start developing in a language that they are already familiar with.

Describe alternatives you've considered. I have tried the following alternatives:

Additional context. The links in LLVM Backend for Native Image seem useful for implementing a new target.

Express whether you'd like to help contributing this feature I'd love to, though if this feature request requires a similar change to the changes in [AArch64][Statepoints] Statepoint support for AArch64., I don't think I'm the suitable person to do this. I was hoping it would only require a few flags to be set on llvm but it seems like that's not the case.

munishchouhan commented 3 years ago

@jespertheend thanks for the feature request, we are constantly adding new support to native-image and if we find it valuable to the community then surely we will add it in our future releases.

munishchouhan commented 3 years ago

@christianwimmer please advise

christianwimmer commented 3 years ago

We have thought about a WASM backend, but it is not on our list of features to implement in the near future. One of the biggest problems is the missing GC support in WASM: neither the GC of the underlying WASM/JS VM is exposed, nor stack walking is possible to include the existing SVM GC.

jespertheend commented 3 years ago

Ah yeah makes sense. Thanks for the info! Would the wasm gc proposal make this any easier?

christianwimmer commented 3 years ago

Would the wasm gc proposal make this any easier?

Yes, once WASM has a proper GC interface things are getting much more feasible.

jespertheend commented 3 years ago

Ah cool! I stay on the lookout for that then. Thanks for the info.

shafqatevo commented 2 years ago

Hi, now that there's an experimental WASI SDK for .net, can't such techniques be used to work around current Wasm limitations to run Substrate VM on Wasm?

Ref: https://www.fermyon.com/blog/dotnet-wasi

https://github.com/SteveSandersonMS/dotnet-wasi-sdk

https://www.youtube.com/watch?v=A0vz_BWxIMc

jimmywarting commented 2 years ago

Don't seem to be the only one wanting to port closure compiler to wasm 😉 subscribing to this issue.

ping me @jespertheend if you ever release a wasm version of closure compiler :)

jespertheend commented 2 years ago

@jimmywarting I'm actually about to ditch closure compiler in favour of terser to be honest. From my limited testing, builds seem to be slightly larger, but that seems worth it considering that it can run in a browser and generally seems to have less complexity. You might have some luck with https://github.com/mirkosertic/Bytecoder but some features seem to still be missing for it to successfully build closure compiler to wasm.

sdeleuze commented 2 years ago

@christianwimmer Potentially interesting related links:

VitGottwald commented 2 years ago

Another tool in this area is bck2brwsr.

mirkosertic commented 1 year ago

Hi!

Author of https://github.com/mirkosertic/Bytecoder here. I can confirm that native garbage collection support is an issue in WebAssembly. The current Wasm GC proposal is in "proposed" status, as seen here: https://chromestatus.com/feature/6062715726462976. However, Google's J2CL Wasm backend seems to rely on this proposal, so I am really not sure when we can expect the final release and support in Chromium at least. Till this point, every Wasm backend for JVM bytecode needs to provide its own implementation for garbage collection. And implementing a fast and reliable garbage collector can be really tricky, and it can become a nightmare and impossible if you want to prevent stop-the-world during GC runs in a Wasm in a single threaded environment. Maybe we can get around that with reference counting, but performance is a very important part of it. Good escape analysis will remove some of the heap allocations, but in most real life applications a lot of stack allocation will remain.

But when the time comes and the Wasm GC proposal is final, it would be good to know what might be a feasible way to use the Graal native image compiler with Wasm. The LLVM backend path might work, but it is for sure not the fastest way. So what I am searching is a kind of documentation about how to provide a custom backend to Graal, or a kind of "embedded" API to run Graal, retrieve the IR (Graphs) and use them for a custom backend for code generation. Something that can be completely based on JVM, without further toolchains like LLVM and co.

sdeleuze commented 1 year ago

GC proposal made a lot of progresses in 2022 and moved to phase 3. We can't be sure when it will move to phase 4 but could be possible in 2023.

Implementations in other browsers has started:

MTyson commented 1 year ago

Hello, I'm writing an article for InfoWorld about Java and WASM. native-image --features=wasm sure would be nice. Could anyone comment on the status or any thoughts?

tenaf0 commented 1 year ago

There has been quite a lot of movement around the WASM GC implementation, and it is available by default on chrome now, see https://developer.chrome.com/blog/wasmgc/

It might make sense to re-alive this issue.

Martin1994 commented 1 year ago

Why a Java AOT solution has to rely on the GC implementation of WASM? A Java GC should be runnable on WASM with low level memory management API, and on the other side using WASM's GC will most likely lose the GC related APIs on Java side.

tenaf0 commented 1 year ago

@Martin1994 From the article:

The C and Rust binaries could be anywhere from 6.1 K to 9.6 K depending on the various compiler flags, while the Java version is much smaller at only 2.3 K!

Compare it to the size of a C# application compiled to WASM, which is on the MB range, due to in part to having to also download on every site a complete GC/runtime implementation.

Given that Java can already be compiled to WASM (closure compiler, teawm), I believe that the WASM GC proposal’s API is more than fit for Java’s use case, and there are many advantages to using Graal, like polyglottism, size reduction (due to the closed world assumption, it can remove a bunch of classes that are never accessed), etc.

sgammon commented 1 year ago

In any case, this issue deserves a fresh look, because it opens GVM binaries up to new deployment targets, regardless of GC

(Consider users of --gc=epsilon, for example)

GC being shipped in several popular engines is a signal that WASM in general is maturing and stabilizing.

boonyasukd commented 1 year ago

FYI, Firefox 120 now enables Wasm GC by default (it was hidden under a flag for quite some time). I'd say the browser side is quite ready now. Kotlin team has been demoing/optimizing their work on Wasm GC since march, it'd be great if Graal supports it also.

https://www.mozilla.org/en-US/firefox/120.0/releasenotes/ https://twitter.com/bashorov/status/1716891482487988630

ericvergnaud commented 10 months ago

WASM GC is available in V8 (Chrome, Deno and soon Node). It'd be very disappointing to not see it rapidly coming to GraalVM

a-cosmic-jaw commented 8 months ago

Hello? Where are we on this?

axel22 commented 6 months ago

We are working on and have an in-progress implementation that outputs Wasm (with the WasmGC spec).

It would be really helpful for us if people could explain their use-cases for having a WasmGC backend. What sort of deployments scenarios do you foresee or have need for (e.g. do you need to target browser applications, or run Wasm modules in standalone mode with WASI)?

Thank you!

gocursor commented 6 months ago

It would be really helpful for us if people could explain their use-cases for having a WasmGC backend. What sort of deployments scenarios do you foresee or have need for (e.g. do you need to target browser applications, or run Wasm modules in standalone mode with WASI)?

Primarily browser apps (to share the code between frontend and backend and to leverage the existing Java skills).

CedNaru commented 6 months ago

Hello, I am one of the maintainers of the Kotlin-Java bindings for the Godot game engine (https://github.com/utopia-rise/godot-kotlin-jvm).

Godot supports exports for the main 3 desktop OS, Android, iOS and wasm. Wasm is currently the only export we don't support because we lack a simple way to run a JRE inside the browser. We already support the use of native images (our only way to run it on iOS currently) and a wasm target would be welcomed to complete our Godot support.

An alternative would be to use Kotlin/Native and Kotlin/Wasm instead of native images, but Godot being a C++ engine, we rely heavily on interop. Using different backends for Kotlin would require us to implement a specific interop layer for each of them. It would be much simpler for us if we could just keep using a regular JRE + JNI context for all of them.

agarciadom commented 6 months ago

I am one of the developers of the Eclipse Epsilon project. We provide a family of mini-languages for managing object-oriented system models (e.g. validating them, generating code from them, and so on). They are all interpreted languages, running on top of Java.

We started as being Eclipse-centric (it was the shiny new thing back in the mid 00s), but we are seeing more and more people interested in doing modelling from their browsers (e.g. from low-code development platforms). In fact, to make it easier for people to try out our languages, we've created a web-based Playground for the Epsilon languages.

The annoying part is that, since we can't run Java code on the browser, executing the code in the Playground involves spinning up a Google Cloud Function that runs the script, which is 1) costly and 2) slow. We'd very much like to use something like the Graal integration in Micronaut to package up our interpreter as a module that we could use from the Playground.

It'd also open other opportunities - for instance, we have the start of a language server for Epsilon, which is also written in Java. With a WasmGC export, we could look into running the language server from Node.js, which is one of the default runtimes supported by VS Code.

lemmy commented 6 months ago

The annoying part is that, since we can't run Java code on the browser, executing the code in the Playground involves spinning up a Google Cloud Function that runs the script, which is 1) costly and 2) slow. We'd very much like to use something like the Graal integration in Micronaut to package up our interpreter as a module that we could use from the Playground

https://github.com/tlaplus/tlaplus has a pretty similar use case.

gkresic commented 6 months ago

It would be really helpful for us if people could explain their use-cases for having a WasmGC backend.

Running Java code in browser environments would be our primary target, but WASI (although still in its infancy) shouldn't be ignored too. However, important feature in both cases would be as-good-as-possible support for integrations with JavaScript (in browser) and other WASM modules (especially ones written in languages other than Java).

simlei commented 6 months ago

Everything that has to do with compiling low-dependency Scala 3 programs to WASM, basically. It needs GC support for that.

On Wed, 8 May 2024, 10:10 Gordan Krešić @.***> wrote:

It would be really helpful for us if people could explain their use-cases for having a WasmGC backend.

Running Java code in browser environments would be our primary target, but WASI (although still in its infancy) should be ignored too. However, important feature in both cases would be as-good-as-possible support for integrations with JavaScript (in browser) and other WASM modules (especially ones written in languages other than Java).

— Reply to this email directly, view it on GitHub https://github.com/oracle/graal/issues/3391#issuecomment-2099998795, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHP224OX3SZ4NG7I4XEQCDZBHMWJAVCNFSM437LSQD2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TEMBZHE4TSOBXHE2Q . You are receiving this because you are subscribed to this thread.Message ID: @.***>

lisonge commented 6 months ago

It would be really helpful for us if people could explain their use-cases for having a WasmGC backend.

I need to run Java regular expressions in the browser with the same behavior as on the JVM. However, the native JavaScript RegExp and Java's Pattern exhibit inconsistent behavior. For example, JavaScript does not allow embedded flags in regular expressions, whereas Java does.

It seems the only solution is to compile Java's Pattern to WebAssembly (wasm) for JavaScript to call.

My current solution is to use Kotlin Multiplatform to compile Kotlin's kotlin.text.Regex to wasm for JavaScript to call.

https://github.com/gkd-kit/gkd/blob/v1.7.3/wasm_matches/src/commonMain/kotlin/li/songe/matches/toMatches.kt

https://github.com/gkd-kit/inspect/blob/f8b58ae6c34cf9559f148b566ddaadb0d3138cd4/src/utils/selector.ts#L14

if Graal could support compiling Java to WebAssembly (wasm) for JavaScript to call, then more Java libraries could be run directly in the browser, eliminating the need to manually re-implement them in JavaScript

For example, I recently wanted to port the functionality of converting SVG to XML from Android Studio to the browser. The source code is available at Svg2Vector.java. If these Java code could be directly compiled to WebAssembly (wasm), it would eliminate the need to manually re-implement it in JavaScript.

bashor commented 6 months ago

@lisonge, you can convert Svg2Vector.java to Kotlin 🫣 and continue using Kotlin Multiplatform 😉

lisonge commented 6 months ago

@lisonge, you can convert Svg2Vector.java to Kotlin 🫣 and continue using Kotlin Multiplatform 😉

@bashor The third-party library java.awt.* that it uses cannot be used with Kotlin Multiplatform

sgammon commented 6 months ago

@axel22 our use case is mostly server side, similar to Node. we want to support WASI as a server side target, especially on platforms like Cloudflare Workers.

many isolate-based hosting platforms can only accept WASM or JavaScript. compiling to WASM is therefore a fundamental need unless V8 begins accepting other binary types (unlikely).

this would also lower the cost floor for hosting a GraalVM application significantly. because WASM is not supported yet, one must resort to a container or a full VM, or even bare metal, all of which have much higher cost floors than isolate-based hosting.

rdobrik commented 5 months ago

We are working on Java stack for Internet Computer blockchain platform https://internetcomputer.org/. Currently developing Java Agent libraries but there is a demand for Java based backend smart contracts (canisters). Internet Computer backend is based on WASM and currently supports different languages like Rust, C++, Python and Javascript. While IO access will be quite restrictive, we will need to support Java reflections and annotations to be able serialize and deserialize Java types (like Jackson or Gson) to internal ICP data format. We already have code for that. Also support libraries like Bouncy Castle for encryption and decryption.

nilslice commented 5 months ago

This is really exciting! We'd love to be able to support a Java PDK for Extism, which would mean supporting a Java library that calls some external functions (some static, like wasip1), and some created by a Host environment, linking them dynamically.

Extism environments are embedded within other applications including things that run on the server, browser, IoT, and mobile.

ningpengtao-coder commented 5 months ago

I want to run my own swing application on wasm.

ceisserer commented 4 months ago

Is there any new regarding this topic? To me it seems all the required infrastructure is there (GC Proposal, Reference Types, Atomics). Regarding the use-case I guess I am not the only one with plenty of "legacy" Java desktop code which just needs a proper migration path to move on from JSE8.

wolonge95 commented 1 month ago

Target browser.

translatenix commented 1 month ago

My use case is to run the Pkl Truffle language in the browser (for educational purposes).

Sintrastes commented 2 weeks ago

Very interested in WASI / WIT support to be able have the graal ecosystem target a custom plugin ecosystem.

Basically the goal is to allow for third-parties to write a plugin in whatever language they want, so having the graal ecosystem as an option would be a huge win.

nilslice commented 2 weeks ago

@sintrastes - curious if you've come across https://extism.org, which makes all of that possible today across many more languages than WIT can generate.

we don't have support for GraalWasm yet, but would be open to collaborating!

we also have a similar binding generator toolchain with support for Go, Rust, TypeScript, Python, C#, C++ and Zig (with more coming!). we release all of this freely and under permissive licenses, learn more here: https://docs.xtp.dylibso.com/docs/concepts/xtp-schema

Sintrastes commented 2 weeks ago

@nilslice - Interesting! No, I was not familiar with this previously.

In terms of the IDL, are there plans to add support for things like sum types, like in WIT?

nilslice commented 2 weeks ago

@Sintrastes - great question, and probably not in the near term, but it's not out of the question.

XTP schema takes a very pragmatic approach to try and bring wasm to every app; vs try to make all apps wasm. So we take lots of care to not introduce features that are incompatible or create a non-idiomatic mess of generated code.

Sum types could be done, but they don't exist in all the languages we support - so we'd have to hand over a wonky Frankenstein combination of structs/methods/enums/states etc. to our users and we have a hard time shipping things that don't work great.

We also stick closely to OpenAPI spec, given that a local in-process plugin is basically just a bi-directional API call, and there's a LOT of OpenAPI based systems out there.

I don't mean to take over the discussion here, so please feel free to join us on Discord: https://extism.org/discord

ningpengtao-coder commented 4 days ago

https://github.com/stackblitz/bolt.new has opened a low-code tool for using llm. Using stackblitz's private webcontainer technology, it simulates the nodejs environment and runtime in the browser to support running front-end projects in the browser. bolt-new fork: https://github.com/coleam00/bolt.new-any-llm plans to use open source components instead of webcontainer. Open source components: https://github.com/wasmerio/wasmer https://github.com/Sandpack/nodebox-runtime https://github.com/leaningtech/webvm

issue: https://github.com/coleam00/bolt.new-any-llm/issues/229

can Graal introduce more runtime support?, such as GraalPython, GraalJS, Espresso (Java), etc., and convert these runtimes into wasm.

My personal experience using graal: I use graal to package swing programs into native and run them on desktop and mobile. But compared to browsers, it is very difficult to distribute programs on desktop and mobile. From practical experience, small programs, PWA and web are commonly used now, which are easier to distribute. These are areas where wasm is more likely to exert its strength.

And now is the era of AI, and entrepreneurial technology selection is more inclined to languages ​​such as JS and Python. If wasm can be supported, Graal can be more organically combined with AI, and Graal will have a wider range of usage scenarios.