Skip to content

[go1.20] Temporarily overriding generics for go1.20 #1309

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
May 25, 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
40 changes: 40 additions & 0 deletions compiler/natives/src/encoding/gob/gob.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//go:build js
// +build js

package gob

import (
"reflect"
"sync"
)

type typeInfo struct {
id typeId
encInit sync.Mutex

// temporarily replacement of atomic.Pointer[encEngine] for go1.20 without generics.
encoder atomicEncEnginePointer
wire *wireType
}

type atomicEncEnginePointer struct {
v *encEngine
}

func (x *atomicEncEnginePointer) Load() *encEngine { return x.v }
func (x *atomicEncEnginePointer) Store(val *encEngine) { x.v = val }

// temporarily replacement of growSlice[E any] for go1.20 without generics.
func growSlice(v reflect.Value, ps any, length int) {
vps := reflect.ValueOf(ps)
vs := vps.Elem()
zero := reflect.Zero(vs.Elem().Type())
vs.Set(reflect.Append(vs, zero))
cp := vs.Cap()
if cp > length {
cp = length
}
vs.Set(vs.Slice(0, cp))
v.Set(vs)
vps.Set(vs.Addr())
}
8 changes: 8 additions & 0 deletions compiler/natives/src/go/token/position.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,11 @@ type atomicFilePointer struct {

func (x *atomicFilePointer) Load() *File { return x.v }
func (x *atomicFilePointer) Store(val *File) { x.v = val }

func (x *atomicFilePointer) CompareAndSwap(old, new *File) bool {
if x.v == old {
x.v = new
return true
}
return false
}
83 changes: 83 additions & 0 deletions compiler/natives/src/internal/godebug/godebug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//go:build js
// +build js

package godebug

import (
"sync"
)

type Setting struct {
name string
once sync.Once

// temporarily replacement of atomic.Pointer[string] for go1.20 without generics.
value *atomicStringPointer
}

type atomicStringPointer struct {
v *string
}

func (x *atomicStringPointer) Load() *string { return x.v }
func (x *atomicStringPointer) Store(val *string) { x.v = val }

func (s *Setting) Value() string {
s.once.Do(func() {
v, ok := cache.Load(s.name)
if !ok {
// temporarily replacement of atomic.Pointer[string] for go1.20 without generics.
p := new(atomicStringPointer)
p.Store(&empty)
v, _ = cache.LoadOrStore(s.name, p)
}
// temporarily replacement of atomic.Pointer[string] for go1.20 without generics.
s.value = v.(*atomicStringPointer)
})
return *s.value.Load()
}

func update(def, env string) {
updateMu.Lock()
defer updateMu.Unlock()

did := make(map[string]bool)
parse(did, env)
parse(did, def)

cache.Range(func(name, v any) bool {
if !did[name.(string)] {
// temporarily replacement of atomic.Pointer[string] for go1.20 without generics.
v.(*atomicStringPointer).Store(&empty)
}
return true
})
}

func parse(did map[string]bool, s string) {
end := len(s)
eq := -1
for i := end - 1; i >= -1; i-- {
if i == -1 || s[i] == ',' {
if eq >= 0 {
name, value := s[i+1:eq], s[eq+1:end]
if !did[name] {
did[name] = true
v, ok := cache.Load(name)
if !ok {
// temporarily replacement of atomic.Pointer[string] for go1.20 without generics.
p := new(atomicStringPointer)
p.Store(&empty)
v, _ = cache.LoadOrStore(name, p)
}
// temporarily replacement of atomic.Pointer[string] for go1.20 without generics.
v.(*atomicStringPointer).Store(&value)
}
}
eq = -1
end = i
} else if s[i] == '=' {
eq = i
}
}
}
32 changes: 32 additions & 0 deletions compiler/natives/src/net/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ package http
import (
"bufio"
"bytes"
"context"
"crypto/tls"
"errors"
"io"
"net"
"net/textproto"
"strconv"
"sync"
"sync/atomic"

"github.com/gopherjs/gopherjs/js"
)
Expand Down Expand Up @@ -113,3 +118,30 @@ func (t *XHRTransport) CancelRequest(req *Request) {
xhr.Call("abort")
}
}

type conn struct {
server *Server
cancelCtx context.CancelFunc
rwc net.Conn
remoteAddr string
tlsState *tls.ConnectionState
werr error
r *connReader
bufr *bufio.Reader
bufw *bufio.Writer
lastMethod string

// temporarily replacement of `atomic.Pointer[response]` for go1.20 without generics.
curReq atomicResponsePointer

curState atomic.Uint64
mu sync.Mutex
hijackedv bool
}

type atomicResponsePointer struct {
v *response
}

func (x *atomicResponsePointer) Load() *response { return x.v }
func (x *atomicResponsePointer) Store(val *response) { x.v = val }
16 changes: 15 additions & 1 deletion compiler/natives/src/sync/atomic/atomic.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,5 +221,19 @@ func sameType(x, y interface{}) bool {
return js.InternalObject(x).Get("constructor") == js.InternalObject(y).Get("constructor")
}

//gopherjs:purge for go1.19 without generics
// Override pointer so that the type check in the source code is satisfied
// but remove the fields and methods for go1.20 without generics.
// See https://cs.opensource.google/go/go/+/refs/tags/go1.20.14:src/sync/atomic/type.go;l=40
type Pointer[T any] struct{}

//gopherjs:purge for go1.20 without generics
func (x *Pointer[T]) Load() *T

//gopherjs:purge for go1.20 without generics
func (x *Pointer[T]) Store(val *T)

//gopherjs:purge for go1.20 without generics
func (x *Pointer[T]) Swap(new *T) (old *T)

//gopherjs:purge for go1.20 without generics
func (x *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool)
9 changes: 9 additions & 0 deletions compiler/natives/src/time/export_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//go:build js
// +build js

package time

// replaced `parseRFC3339[string]` for go1.20 temporarily without generics.
var ParseRFC3339 = func(s string, local *Location) (Time, bool) {
return parseRFC3339(s, local)
}
Loading