Skip to content

Prism parser crashes in WASM (wasm32-wasi): pm_parser_init out-of-bounds memory access #4065

@aim2bpg

Description

@aim2bpg

Summary

When Ruby 3.4 or 4.0 is compiled to WebAssembly (wasm32-wasi) with Prism as the default parser, string-based eval and class_eval calls crash with an out-of-bounds memory access in pm_parser_init.

Building with --with-parser=parse.y and overriding RB_DEFAULT_PARSER to RB_DEFAULT_PARSER_PARSE_Y avoids the crash.

This issue is filed to investigate whether pm_parser_init has a WASM-specific bug. The parse.y workaround is a temporary measure; ideally Prism should work correctly in WASM environments without requiring a parser downgrade.

Environment

  • Ruby: 3.4.8 / 4.0.2 (compiled to wasm32-unknown-wasip1 via ruby_wasm 2.9.0)
  • wasi_sdk: 24.0
  • WASM runtime: wasmtime

Steps to reproduce

  1. Build Ruby 3.4 or 4.0 for WASM with the default Prism parser
  2. Run wasmtime run ruby-core.wasm -e 'eval("puts \"hello\"")'

Observed behaviour

The process crashes with exit code 134 (SIGABRT):

Error: failed to run main module ruby-core.wasm
...
ruby!pm_parser_init
ruby!pm_parse_string
ruby!eval_make_iseq
ruby!eval_string_with_cref
ruby!specific_eval
ruby!rb_mod_module_eval_internal
...
memory fault at wasm address 0xfffffffc in linear memory of size 0xffd30000
wasm trap: out of bounds memory access

The crash occurs in the call chain:
rb_mod_module_eval_internalspecific_evaleval_string_with_crefeval_make_iseqpm_parse_stringpm_parser_init.

Ruby 3.3 (which uses parse.y by default) does not exhibit this crash.
Note that puts "hello" without eval does not crash; the issue is specific to string-based eval paths that invoke Prism.

Workaround

Forcing the parse.y parser avoids the crash. Two changes are needed:

  1. Source patch (version.c): override RB_DEFAULT_PARSER to
    RB_DEFAULT_PARSER_PARSE_Y
  2. Build flag: pass --with-parser=parse.y to configure

Patch file:
https://github.com/aim2bpg/rubree/blob/main/ruby_wasm_patches/fix-default-parser-parse-y.patch

With this workaround applied, Ruby 3.4.8 and 4.0.2 boot and run successfully in WASM (verified with a Rails 8.1.3 application).

Note: this is a temporary workaround for WASM environments only and has no effect on native Ruby builds.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions