Stream: wasm

Topic: Creating small call indirect examples


view this post on Zulip Jannik Schütz (Jan 04 2024 at 23:11):

Hi, I am trying to understand why and where the compiler creates the specific patterns ahead of a call indirect, determining its index
I analyzed the WasmBench dataset and looked for pattern ahead of a call indirect and it turns out, that there are basically two patterns determining over 87% the index.
The first one is the Add Case and the second one the Load Offset Case:

ADD CASE
i32.add
i32.const
i32.and
i32.const
load offset
call_indirect (type x)
LOAD OFFSET CASE I
local.get
load offset
local.get
load offset
call_indirect (type x)
LOAD OFFSET CASE II
local.get
local.get
load offset
load offset
call_indirect (type x)

I mainly want to focus on C++ and Rust, as there these patterns occurred the most in the dataset, with the Add Case being dominant withing C++ and the Load Offset Case being dominant within Rust (but both cases occur in both languages).
I am trying to recreate those patterns by manually writing minimum viable programs. For example if you look at this small C Code. I do so, as i already know that a lot of call_indirects come from libraries, for example in Rust a program with a std lib creates over 76 call_indirects, whereas a #![no_std] program, doesn't.

int add(int a, int b) { return a+b; }
static int sub(int a, int b) { return a-b; }

int main(int argc) {
    int (*functionPtr)(int, int);
    if (argc)
        functionPtr = add;
    else
        functionPtr = sub;

    int a = functionPtr(2, 3);
    return a;
}

This creates a small wat File, that is still readable and has a call_indirect instruction in it, as i want. But it does not yet have one of the patterns above
It would be nice to know and thus i am asking if anyone knows the section, where the compiler creates these snippets?
Or could help me manually creating these patterns.

Thank you in advance, Jannik

A large dataset of real-world WebAssembly binaries, collected from the Web, GitHub, NPM and other sources. Useful as test data, to study WebAssembly, for training machine learning models, and much ...
int add(int a, int b) { return a+b; } static int sub(int a, int b) { return a-b; } int main(int argc) { int (*functionPtr)(int, int); if (argc) functionPtr = add; else functionPtr = sub; int a = functionPtr(2, 3); return a; }

Last updated: Dec 23 2024 at 12:05 UTC