Stream: git-wasmtime

Topic: wasmtime / issue #9539 Introduce ArrayCall calling conven...


view this post on Zulip Wasmtime GitHub notifications bot (Nov 01 2024 at 06:29):

playX18 opened issue #9539:

Feature

What I am proposing is to introduce "array-call" calling convention, the name is just whatt I thought would fit it perfectly. The main goal of this feature is to allow implementing dynamically typed languages easier and making them more performant. The proposed feature should allow users of Cranelift to check argument count passed to a function on callee-side and fetch arguments dynamically akin accessing array. What it could look like is:

function u0:0(...) array_call {
    v0 = get_argument_count.i32
    v1 = icmp.lt v0, 2
    brif v1, block0, block1
    block0:
        v2 = get_argument.i64 0 // "constant" fetch of argument, index is know so we can just map it to `rdi` on x64 for example.
        v3 = iconst.i32 1
        v4 = get_argument.i64 v3 // also allow to fetch arguments dynamically
    block1:
        ...
}

Benefit

This allows for implementation of fast and efficient calls when compiling dynamically-typed languages where function arguments and function signature are not known in advance. One might argue that you can implement the same behavior by passing argc: usize, argv: *mut Value but it won't work in case of tail-calls and also is not as performant as directly passing arguments in register when opportunity presents itself.

One example where such calling convention can be used is Scheme compilers. There's many Scheme compilers in the wild which produce binaries and have to rely on their own backends simply because no other backend has "arraycall"-like calling-convention. In my own implementation I have to pass arguments on runstack which is stored in TLS state (uses pinned_reg feature to access the runstack though) and it's a huge performance hit compared to doing calls using arraycall-like calling convention in my baseline backend which compiles Scheme to assembly directly from bytecode.

Implementation

The implementation could be based on existing SystemV and TailCall calling conventions.
The following implementation is just an example and uses X64 as a base:

Alternatives


Last updated: Dec 23 2024 at 12:05 UTC