Project

General

Profile

Actions

Feature #18462

closed

Proposal to merge WASI based WebAssembly support

Added by katei (Yuta Saito) over 2 years ago. Updated over 1 year ago.

Status:
Closed
Target version:
-
[ruby-core:106994]

Description

Proposal to merge WASI based WebAssembly support

This is an initial port of WASI based WebAssembly support.
This enables a CRuby binary to be available on Web browser, Serverless Edge environment, and other WebAssembly/WASI embedders.
Currently this port passes basic and bootstrap test suites not using Thread API.

The upstreaming PR on ruby/ruby is here: https://github.com/ruby/ruby/pull/5407

Background

For example, CRuby already supports WebAssembly target by Emscripten, but Emscripten heavily depends on JavaScript to emulate some missing features in WebAssembly itself.

In short the WASI is an effort to define a standard set of syscalls for WebAssembly modules, allowing WebAssembly modules to not only be portable across architectures but also be portable across environments implementing this standard set of system calls. The environments includes non JS environments, Edge Computing platforms, IoT devices, and so on.

This is a proposal ticket to support WASI based WebAssembly target.

This is a part of Ruby Association Grant project

Lexicon

  • WASI: A system call interface for WebAssembly
  • wasi-libc: A libc implementation for WebAssembly programs built on top of WASI system calls.

Current Limitation of WebAssembly and WASI

Threads

Currently WebAssembly has no threads, and WASI doesn't provide any API to create a thread, but they are on the roadmap. This means Thread.new doesn't work on this target, and it raises ENOSUP for now.

Register operations

Current WebAssembly doesn't allow to touch the program counter, but they are also on the roadmap.
This limitation makes it hard to implement setjmp/longjmp and context-switching on this target, and wasi-libc doesn't provide such implementations.

And also WebAssembly has function local infinite registers, but there is no way to scan the values in a call stack for now.
This limitation makes it unable to mark living objects by Conservative GC in a simple way.

Patch Overview

This patch is a set of minor changes:

Adapt to wasi-libc API

wasi-libc is almost compatible with other libc implementations, but it doesn't have some functions.
So this patch adds stub implementations for them.

Add no thread variant

As mentioned above, WebAssembly has no thread, so this patch adds a thread_none.c, which is a sibling of thread_win32.c and thread_pthread.c. This implementation does nothing around preemptive context switching because there is no native thread.

Emulate setjmp/longjmp, coroutine, and register scan by Asyncify

As mentioned above, WebAssembly has no context switching feature, but there is an userland technique to pause and resume a WebAssembly process by binary transformation.
This technique is called Asyncify.
This patch utilizes it to emulate setjmp/longjmp, coroutine, and register scan for GC.

Actions

Also available in: Atom PDF

Like1
Like0Like0Like0Like0Like0Like0Like0