Skip to content

[go1.20] Removing remaining uses of unsafeheader.Slice from reflect #1322

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 1 commit into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions compiler/natives/src/internal/unsafeheader/unsafeheader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//go:build js
// +build js

package unsafeheader

// Slice and String is Go's runtime representations which is different
// from GopherJS's runtime representations. By purging these types,
// it will prevent failures in JS where the code compiles fine but
// expects there to be a constructor which doesn't exist when casting
// from GopherJS's representation into Go's representation.

//gopherjs:purge
type Slice struct{}

//gopherjs:purge
type String struct{}
10 changes: 10 additions & 0 deletions compiler/natives/src/internal/unsafeheader/unsafeheader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ package unsafeheader_test

import "testing"

func TestTypeMatchesReflectType(t *testing.T) {
t.Skip("GopherJS uses different slice and string implementation than internal/unsafeheader.")
}

//gopherjs:purge
func testHeaderMatchesReflect()

//gopherjs:purge
func typeCompatible()

func TestWriteThroughHeader(t *testing.T) {
t.Skip("GopherJS uses different slice and string implementation than internal/unsafeheader.")
}
15 changes: 15 additions & 0 deletions compiler/natives/src/reflect/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,21 @@ func cvtSliceArrayPtr(v Value, t Type) Value {
return Value{t.common(), unsafe.Pointer(array.Unsafe()), v.flag&^(flagIndir|flagAddr|flagKindMask) | flag(Ptr)}
}

// convertOp: []T -> [N]T
func cvtSliceArray(v Value, t Type) Value {
n := t.Len()
if n > v.Len() {
panic("reflect: cannot convert slice with length " + itoa.Itoa(v.Len()) + " to array with length " + itoa.Itoa(n))
}

slice := v.object()
dst := MakeSlice(SliceOf(t.Elem()), n, n).object()
js.Global.Call("$copySlice", dst, slice)

arr := dst.Get("$array")
return Value{t.common(), unsafe.Pointer(arr.Unsafe()), v.flag&^(flagAddr|flagKindMask) | flag(Array)}
}

func Copy(dst, src Value) int {
dk := dst.kind()
if dk != Array && dk != Slice {
Expand Down
2 changes: 1 addition & 1 deletion compiler/prelude/prelude.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ var $sliceToNativeArray = slice => {
return slice.$array.slice(slice.$offset, slice.$offset + slice.$length);
};

// Convert Go slice to a pointer to an underlying Go array.
// Convert Go slice to a pointer to an underlying Go array, `[]T -> *[N]T`.
//
// Note that an array pointer can be represented by an "unwrapped" native array
// type, and it will be wrapped back into its Go type when necessary.
Expand Down
Loading