Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

strange memory layout for enums with repr in webassembly #76916

Closed
Freax13 opened this issue Sep 19, 2020 · 2 comments
Closed

strange memory layout for enums with repr in webassembly #76916

Freax13 opened this issue Sep 19, 2020 · 2 comments
Labels
A-layout Area: Memory layout of types C-bug Category: This is a bug. O-wasm Target: WASM (WebAssembly), http://webassembly.org/ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Freax13
Copy link
Contributor

Freax13 commented Sep 19, 2020

I tried this code:

#[repr(u8)]
pub enum DirectEnum {
    A(u32),
    B(u32),
}

#[repr(u8)]
pub enum IndirectEnum {
    A(Value),
    B(Value),
}

#[repr(C)]
pub struct Value {
    val: u32,
}

#[no_mangle]
pub extern "C" fn test_direct() {
    unsafe { call_with_direct(DirectEnum::B(0xFFF)) }
}

#[no_mangle]
pub extern "C" fn test_indirect() {
    unsafe { call_with_indirect(IndirectEnum::B(Value { val: 0xFFF })) }
}

#[link(wasm_import_module = "something")]
extern "C" {
    fn call_with_direct(a: DirectEnum);
    fn call_with_indirect(a: IndirectEnum);
}

and compiled it with -C opt-level=3 --target wasm32-unknown-unknown https://godbolt.org/z/cTqbMq

I expected to see this happen: The code should be the same for test_direct and test_indirect. It should push two i32 values: 1 and 4096.

Instead, this happened: test_indirect pushes 8 values instead of two: 1, 0, 0, 0, 255, 15, 0 and 0. The numbers pushed seem to depend on the bitsize of the repr meaning only 4 values get pushed for repr(u16)

@Freax13 Freax13 added the C-bug Category: This is a bug. label Sep 19, 2020
@jyn514 jyn514 added A-layout Area: Memory layout of types O-wasm Target: WASM (WebAssembly), http://webassembly.org/ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 19, 2020
@RalfJung
Copy link
Member

RalfJung commented Sep 7, 2023

I expected to see this happen: The code should be the same for test_direct and test_indirect.

You are using repr(C) on Value, so why do you expect that? If you want Value to be represented like a u32, you need to use repr(transparent).

Or does the C ABI for this target guarantee that single-field structs look like their field? On most targets, the C ABI does not have that property.

@Freax13
Copy link
Contributor Author

Freax13 commented Sep 7, 2023

I expected to see this happen: The code should be the same for test_direct and test_indirect.

You are using repr(C) on Value, so why do you expect that? If you want Value to be represented like a u32, you need to use repr(transparent).

Yup, you're right, I shouldn't be expecting that.

@Freax13 Freax13 closed this as completed Sep 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-layout Area: Memory layout of types C-bug Category: This is a bug. O-wasm Target: WASM (WebAssembly), http://webassembly.org/ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants