Skip to content

[go1.20] Added support for unsafe.SliceData #1298

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

Merged
merged 4 commits into from
May 12, 2024

Conversation

grantnelson-wf
Copy link
Collaborator

@grantnelson-wf grantnelson-wf commented Apr 25, 2024

go1.20 added unsafe.SlideData, unsafe.String, and unsafe.StringData.

For the following reasons, this PR only adds unsafe.SliceData. The tests for this change are in the Go repo tests of this builtin function. This is part of #1270

SliceData

unsafe.SliceData is something that GopherJS can handle because of how, even when empty, GopherJS slices have an array that can be pointed to.

The only thing we can't handle is how using the "unspecified memory address" works right now, seen in this playground, but there are no promises for how that should work and no one should be using that pointer like that. In GopherJS assigning to the pointer of the empty slice simply writes to [0] on the empty slice which then isn't visible, always returns zero, and is a pointless, but doesn't break anything.

The Go compiler ensures that the argument into SliceData will be a slice.

String

unsafe.String may be possible to support with Buffer but would require copying the data into a string. We should probably override it where possible because the point of this function is to not require a copy to be faster than simply performing a conversion, string([]byte{...}).

We may need to we can add this later (with the copy) since it seams like some natives are using this instead of the cast to save memory and/or time. Instead of overriding each location, we could just stub out the cast (kind of like how we didn't override all the atomics but just stubbed out the atomic methods).

StringData

unsafe.StringData may be possible via a copy to a byte array first but is the same as above, doing the copy makes this no better than a conversion. Or we could make some JS code similar to $indexPtr that wraps a string into a byte pointer. Until then we should probably override them instead.

Also, this is super unsafe because in Go if you get the string data for a literal and attempt to modify it (despite the comment in the docs saying *byte should be treated as immutable) it causes a segmentation fault because you can't modify the literal stored in the memory with the opcode. The fault signal can not be recovered from. Here's a playground with that.

@nevkontakte
Copy link
Member

In general, I am in favor of implementing String() and StringData() through the usual type conversion. Although it will cause a copy, it will probably work in more cases than not.

@flimzy
Copy link
Member

flimzy commented May 1, 2024

I wonder if String() and StringData() might be the kinds of things we should support, but emit an optional warning when they are used.

This would allow GopherJS authors to run, say, gopherjs build -w (no idea if that flag is already used) to warn when such symbols are used. This could alert them to rewrite their code, but would allow it still to work (with worse performance) when dependencies beyond their control use them.

@nevkontakte
Copy link
Member

I wonder if String() and StringData() might be the kinds of things we should support, but emit an optional warning when they are used.

That sounds like a perfect use case for https://github.com/gopherjs/gopherjsvet 😉

@grantnelson-wf grantnelson-wf requested a review from nevkontakte May 2, 2024 18:41
@flimzy
Copy link
Member

flimzy commented May 3, 2024

That sounds like a perfect use case for https://github.com/gopherjs/gopherjsvet 😉

I hit a blocker with that project, with a lack of support for abritrary tags in the upstream tools. But I think we can work around it just by forking the upstream (as I've seen done in a few other projects)... so when I have time, I'll try to get that project back off life support.

@nevkontakte nevkontakte merged commit fc3ec56 into gopherjs:go1.20 May 12, 2024
1 of 4 checks passed
@grantnelson-wf grantnelson-wf deleted the addUnsafeSliceData branch May 13, 2024 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants