Skip to content
New issue

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

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

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # 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