Skip to content

cmd/compile: go:wasmimport allows pointers to pointers #59156

Closed
@johanbrandhorst

Description

@johanbrandhorst

Background

The go:wasmimport directive was added in #38248 and has since been used to implement the prototype implementation of the WASI port. It is currently limited to use in the runtime, syscall and syscall/js standard library packages. With #59149 we want to allow any Go user to write their own go:wasmimport statements to access functions implemented on the WASI host.

Wasm today uses 32 bit pointers, while internally in the Go Wasm implementation we use 64 bit pointers. When a function is decorated with the go:wasmimport directive, the compiler translates the arguments (including pointers) to Wasm types. However, pointers to structs containing pointers cannot have their pointer fields converted in the same way since the conversion would require copying the objects to new memory locations, including the conversion of pointer fields to 32 bits, and copying the data back into the objects when the call returns. The mechanism would have to recursively walk the objects, dealing with pointer cycles, and likely introduce a significant overhead when calling go:wasmimport functions.

What is the behaviour today?

The compiler does not error when compiling functions with arguments that point to pointers. At runtime, there is an ABI mismatch between the Go program and the Wasm host modules, the latter expecting pointers to be 32 bits, causing misalignment of fields in struct types passed by pointer to go:wasmimport functions.

What did I expect to see?

I expected the compiler to disallow functions using arguments that point to pointers so we prevent users of go:wasmimport from constructing programs with a memory layout that is incompatible with the Wasm host.

Discussion

The following should be allowed (no internal struct pointers):

//go:wasmimport module F1
func F1(p *byte)

//go:wasmimport module F2
func F2(p unsafe.Pointer)

type buffer struct {
  ptr uint32
  len uint32
}

//go:wasmimport module F3
func F3(b *buffer)

The following should not be allowed (types contain pointers to pointers):

type buffer struct {
  ptr *byte
  len uint32
}

//go:wasmimport module F4
func F4(b *buffer)

//go:wasmimport module F5
func F5(p **byte)

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.arch-wasmWebAssembly issuescompiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions