Stream: git-wasmtime

Topic: wasmtime / issue #1030 varargs support


view this post on Zulip Wasmtime GitHub notifications bot (Apr 17 2024 at 20:02):

Jakersnell commented on issue #1030:

Are there any updates with this? Implementing varargs as a frontend with Cranelift is extremely cumbersome.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 17 2024 at 20:22):

bjorn3 commented on issue #1030:

There hasn't been any change since the last comment here. Also do you need just support for calling variadic functions or also defining them? The former is a lot easier to support than the latter.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 17 2024 at 21:33):

Jakersnell commented on issue #1030:

Specifically calling them, although both would be nice.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 17 2024 at 21:49):

Jakersnell deleted a comment on issue #1030:

Specifically calling them, although both would be nice.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 17 2024 at 21:50):

Jakersnell commented on issue #1030:

Just calling them.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 08 2025 at 17:21):

rakivo commented on issue #1030:

Is this even possible to call vararg functions from Cranelift today? I've tried patching up the signature every call but without setting up al properly this won't work correctly.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 08 2025 at 18:46):

bjorn3 commented on issue #1030:

I believe al is an upper bound on the number of float args, so if you deny float args entirely, it shouldn't matter what value is in al.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 08 2025 at 19:23):

rakivo commented on issue #1030:

I am trying to integrate Cranelift as a backend to my language, and I've been trying all day to generate a simple printf call code using Cranelift but nothing works.

Here's for example an internal IR my compiler generates for some input:

printf :: (%1: string, ...) -> void;

main :: () -> i32 {
@entry (#0) preds=[] succs=[2, 3] params=[]
  %0 = alloca i32
  store %0 = 0_i32
  br 0_i32, block #1, block #2

@then (#1) preds=[0] succs=[4] params=[]
  %1 = 1_i32
  %2 = 2_i32
  br block #3 {params=[%1, %2]}

@else (#2) preds=[0] succs=[4] params=[]
  %3 = 3_i32
  %4 = 4_i32
  br block #3 {params=[%4, %3]}

@merge (#3) preds=[2, 3] succs=[4] params=[%5, %6]
  call printf("x = %d\n", %5)
  call printf("y = %d\n", %6)
  br block #4

@exit (#4) preds=[3] succs=[] params=[]
  ret
}

And this is the result of a Cranelift module translating the IR above:

function u0:0() -> i32 system_v {
    ss0 = explicit_slot 4
    gv0 = symbol colocated userextname1
    gv1 = symbol colocated userextname2
    sig0 = (i64) system_v
    sig1 = (i64, i32) system_v
    sig2 = (i64) system_v
    sig3 = (i64, i32) system_v
    fn0 = u0:0 sig1
    fn1 = u0:0 sig3

block0:
    v2 = iconst.i32 0
    v11 = stack_addr.i64 ss0
    store notrap v2, v11  ; v2 = 0
    brif v2, block2, block3  ; v2 = 0

block1:
    v4 = load.i32 notrap v11
    return v4

block2:
    v5 = iconst.i32 1
    v6 = iconst.i32 2
    jump block4(v5, v6)  ; v5 = 1, v6 = 2

block3:
    v8 = iconst.i32 4
    v7 = iconst.i32 3
    jump block4(v8, v7)  ; v8 = 4, v7 = 3

block4(v0: i32, v1: i32):
    v9 = symbol_value.i64 gv0
    call fn0(v9, v0)
    v10 = symbol_value.i64 gv1
    call fn1(v10, v1)
    jump block1
}

After linking it: clang -no-pie ./examples/simple-phi.o -o simple-phi, it prints this:

x = 4
y = 0
y = 3

Where's the y = 0 comming from?

objdump -d -M intel ./examples/simple-phi.o outputs this:

./examples/simple-phi.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <main>:
   0:   55                      push   rbp
   1:   48 89 e5                mov    rbp,rsp
   4:   48 83 ec 20             sub    rsp,0x20
   8:   48 89 5c 24 10          mov    QWORD PTR [rsp+0x10],rbx
   d:   4c 89 74 24 18          mov    QWORD PTR [rsp+0x18],r14
  12:   33 d2                   xor    edx,edx
  14:   4c 8d 34 24             lea    r14,[rsp]
  18:   41 c7 06 00 00 00 00    mov    DWORD PTR [r14],0x0
  1f:   85 d2                   test   edx,edx
  21:   0f 85 13 00 00 00       jne    3a <main+0x3a>
  27:   be 04 00 00 00          mov    esi,0x4
  2c:   41 bb 03 00 00 00       mov    r11d,0x3
  32:   4c 89 db                mov    rbx,r11
  35:   e9 0e 00 00 00          jmp    48 <main+0x48>
  3a:   be 01 00 00 00          mov    esi,0x1
  3f:   41 bb 02 00 00 00       mov    r11d,0x2
  45:   4c 89 db                mov    rbx,r11
  48:   48 8d 3d 00 00 00 00    lea    rdi,[rip+0x0]        # 4f <main+0x4f>
  4f:   48 b8 00 00 00 00 00    movabs rax,0x0
  56:   00 00 00
  59:   ff d0                   call   rax
  5b:   48 8d 3d 00 00 00 00    lea    rdi,[rip+0x0]        # 62 <main+0x62>
  62:   48 b8 00 00 00 00 00    movabs rax,0x0
  69:   00 00 00
  6c:   48 89 de                mov    rsi,rbx
  6f:   ff d0                   call   rax
  71:   41 8b 06                mov    eax,DWORD PTR [r14]
  74:   48 8b 5c 24 10          mov    rbx,QWORD PTR [rsp+0x10]
  79:   4c 8b 74 24 18          mov    r14,QWORD PTR [rsp+0x18]
  7e:   48 83 c4 20             add    rsp,0x20
  82:   48 89 ec                mov    rsp,rbp
  85:   5d                      pop    rbp
  86:   c3                      ret

I even tried calling a printf wrapper I wrote in gas that would xor al, but the output was still the same.

Am I missing something?

view this post on Zulip Wasmtime GitHub notifications bot (Jun 08 2025 at 19:51):

bjorn3 commented on issue #1030:

Did you make sure to nul-terminate your strings?

view this post on Zulip Wasmtime GitHub notifications bot (Jun 08 2025 at 19:56):

rakivo commented on issue #1030:

Ohhh man I completely forgot about that!!!! With nul-terminated strings it works fine, thank you sm!


Last updated: Dec 13 2025 at 19:03 UTC