Skip to content

proposal: make bulk-memory optional for GOARCH=wasm #62539

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

Closed
LiuJiazheng opened this issue Sep 8, 2023 · 7 comments
Closed

proposal: make bulk-memory optional for GOARCH=wasm #62539

LiuJiazheng opened this issue Sep 8, 2023 · 7 comments
Milestone

Comments

@LiuJiazheng
Copy link

Hi there,

We are working on compiling go to wasm and run them universally on browsers. And I noticed that newer WebAssembly features (like bulk memory operations) are not universally supported across all browsers and environments.

For compiler like tinygo, it has LLVM as backend. Hence we can control the target machine code by setting llvm features like "-mbulk-memory" or "-mno-bulk-memory" to control whether we want a 0xFC extension. It might not be only limited to 0xFC, I believes it could potentially apply to all "extensional" opcodes whose prefix is 0xF ( like 0xFD SIMD).

In principle it would be nice if users could decide whether to use extension opcodes, by providing a feature set like LLVM does. But I do understand golang directly reduces to SSA so it might be quite different. Meanwhile, I'd like to know where to control the codegen so it would be really appreciated if someone could show me some pointers about it, regardless whether you want to support it or not : )

@gopherbot gopherbot added this to the Proposal milestone Sep 8, 2023
@bcmills bcmills added the arch-wasm WebAssembly issues label Sep 8, 2023
@bcmills
Copy link
Contributor

bcmills commented Sep 8, 2023

(CC @golang/wasm)

@johanbrandhorst
Copy link
Member

I'm not sure exactly what's being proposed, could you elaborate on the state of the current implementation, what sort of knob you'd like to see, if any, and elaborate on the compatibility problems you're seeing? I don't know whether the existing implementation uses bulk memory or not but generally the intent is to be compatible with all modern browsers so if this is a compatibility issue we might have to change it altogether.

@mauri870
Copy link
Member

mauri870 commented Sep 8, 2023

FYI bulk memory operations were implemented in CL 444935

@LiuJiazheng
Copy link
Author

Thanks Johan,

The rationale is if we use libc like memcpy and memclr to manipulate a block of memory, we have two ways to do so in wasm,

  1. do a loop to iterate;
  2. use 0xFC extension opcodes operating bulk memory mentioned here https://webassembly.org/roadmap/

So the default behavior of golang right now is item 2, compound bulk memory operation to 0xFC extension opcodes. And in WAT you could see some opcodes like memory.copy or memory.fill. (For opcodes encoding, see https://pengowray.github.io/wasm-ops/#fc)

But we have a host env which is old and dislikes extensions at all (yes, that's painful). So instead of using memory.fill, it is more into a traditional way (loop-br).

So if I was able to design it I probably would go a way like go build -gcflags=all=-d=wasm-no-bulk-memory or GOFEATURE=no-bulk-memory; GOARCH=wasm; go buildsince it is only related to target wasm, nothing else.

I am not sure whether it is a proper request ---- modern browsers should be compatible with bulk-memory standard but I do notice quite a few emulators/runtime might not adopt that standard. This is a matter of compatibility.

@LiuJiazheng
Copy link
Author

Many thanks to @mauri870 pointing out bulk memory operation commit! At least we can revert it and play around.

@johanbrandhorst
Copy link
Member

Is this relating to GOOS=js or GOOS=wasip1? If the former, I'm tempted to say that our compatibility promise follows along the guidelines of #28360 and does not extend to older runtimes. If this is a wasip1 runtime, we might need to open a separate issue tracking any incompatibilities with it (similar to #60097 and #59907). I'm hesitant to introduce a knob for this as it seems to me it likely affects a very small part of the community. I'm happy to be proved wrong, of course.

In any case, it seems a workaround to me is to perform a wasm2wat followed by a substitution of the bulk memory operations with an old style loop and another compilation back to wasm. Is that practical?

@LiuJiazheng
Copy link
Author

Thanks Johan,

Yes I think it is doable. Either to use a transpiler to replace the bulk back to loop, which is quite risky, or do a revert on golang source code privately. Those two seem more practical rather than requesting a behavior change. And I fully understand your hesitation and it also makes sense to me. Getting a CL is good enough for me right now.

And hence I close the issue. And really appreciate your help.

@golang golang locked and limited conversation to collaborators Sep 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants