Skip to content

[wasm] R2R: 32-byte struct passed by value is corrupted (fields shifted by one word) #131639

Description

@pavelsavara

Description

On browser-wasm (CoreCLR) with PublishReadyToRun, a 32-byte struct (four 8-byte fields) passed by value to a method is corrupted: the callee reads it shifted up by one 8-byte word, so each field takes the value of the next and the following argument bleeds in. 16- and 24-byte structs pass correctly.

Repro

using System;

struct S32 { public long A, B, C, D; }

class Program
{
    static string E32(int x, S32 s, int y) => $"{x}|{s.A},{s.B},{s.C},{s.D}|{y}";

    static void Main()
    {
        Console.WriteLine(E32(1, new S32 { A = 31, B = 32, C = 33, D = 34 }, 2));
    }
}

E32 must be ReadyToRun-compiled. Interpreted execution is correct.

Expected

1|31,32,33,34|2

Actual

1|32,33,34,2|0

s.A reads the input B, s.B reads C, s.C reads D, s.D reads the trailing int y (2), and y reads garbage (0) — i.e. the struct argument is read one 8-byte word too high.

Notes

  • 16-byte ({ long, long }) and 24-byte ({ long, long, long }) structs pass correctly; only the 32-byte (four-word) struct is affected.
  • Reproduces with a direct call; reflection-invoking the same method corrupts it further.

Configuration

  • -os browser -a wasm, CoreCLR, PublishReadyToRun (crossgen2, --obj-format:wasm)
  • Reproduces in Node and in the browser.

Note

This issue was written with the assistance of GitHub Copilot.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions