Implement Chicory WASM backend for the Ruby API#4017
Implement Chicory WASM backend for the Ruby API#4017
Conversation
|
This depends upon changes in #3944 and will be rebased once that merges to main. |
|
I wonder if it'd make sense to support the WASM case in |
Yes, that's why it's a draft. |
afd64c3 to
1b02ef4
Compare
Rather than templating two versions of sources with and without non-semantic fields, we can make that determination at build time. Passing -DPRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS=1 to `make` will force that variable to be literally true, and the compiler will eliminate `if` blocks that use it to conditionally serialize non- semantic data. This simplifies the templates by removing that variation and allows building both forms of the library from a single generated set of sources.
|
Most recent commit is an attempt to move the The JVM WASM builds need to take two forms:
These two artifacts should be sibling modules under
But because the templated sources must be generated twice, once for semantic-only and again for non-semantic, the build process ends up being much more complicated:
By moving the semantic-only flag into a C macro, a single set of sources can be generated and customized at C compile time, allowing a single make target to build both WASM forms. Ideally the other two major C templating flags could also move into build-time macros:
Really, the only tricky part is for the Java API that has two forms: with node ID and without node ID, and I think we can handle that a different way (perhaps by adding another flag to the serialization header?) |
| private Nodes.Node loadNode() { | ||
| int type = buffer.get() & 0xFF; | ||
| <%- if Prism::Template::INCLUDE_NODE_ID -%> | ||
| <%- unless Prism::Template::OMIT_NODE_ID -%> |
There was a problem hiding this comment.
Could you keep the constant as Prism::Template::INCLUDE_NODE_ID?
That way:
- The diff is much smaller and focused on the semantic fields change
- There is no double negation (
unless ... OMIT)
The ENV var can be either.
| JAVA_BACKEND = ENV["PRISM_JAVA_BACKEND"] || "default" | ||
| JAVA_IDENTIFIER_TYPE = JAVA_BACKEND == "truffleruby" ? "String" : "byte[]" | ||
| INCLUDE_NODE_ID = !SERIALIZE_ONLY_SEMANTICS_FIELDS || JAVA_BACKEND == "jruby" | ||
| OMIT_NODE_ID = ENV.fetch("PRISM_OMIT_NODE_ID", false) |
There was a problem hiding this comment.
| OMIT_NODE_ID = ENV.fetch("PRISM_OMIT_NODE_ID", false) | |
| INCLUDE_NODE_ID = ENV.fetch("PRISM_INCLUDE_NODE_ID", "true") != "false" |
(mentioned on Slack)
| <%- if node.flags -%> | ||
| pm_buffer_append_varuint(buffer, (uint32_t) node->flags); | ||
| <%- else -%> | ||
| if (!PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS) { |
There was a problem hiding this comment.
| if (!PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS) { | |
| #ifndef PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS |
would be better because it then goes away during preprocessing vs later in the compiler, which could potentially make a difference e.g. in inlining due to the function being bigger.
It's also clearer this is not a runtime check, and setting it must be done with -D.
That would mean PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS must not be defined by default.
This PR will provide a new Ruby API backend (in addition to the C extension and the FFI wrapper) based on the Chicory WASM runtime for the JVM.
This version of the gem will be published for JRuby users as the default cross-platform gem. Future gems will make platform-specific binary builds available for users that desire the additional performance.
The goal here is to get a native-code free version of the prism gem released for JRuby users.