Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
3123941
Starting 1.20 updates
grantnelson-wf Mar 4, 2024
6b12471
Merge pull request #1273 from Workiva/startGo1.20
nevkontakte Mar 5, 2024
88d23fe
Updated for PkgObj no longer being set for Goroot
grantnelson-wf Mar 12, 2024
b9f08e3
Merge pull request #1277 from Workiva/contextUpdate1.20
nevkontakte Mar 19, 2024
25773b9
Added generics override for sync map
grantnelson-wf Mar 20, 2024
713ce26
Merge pull request #1278 from Workiva/syncMapUpdate
nevkontakte Mar 23, 2024
0df0881
Added native time overrides
grantnelson-wf Mar 26, 2024
a6a3edb
Added exit code param to runtime_beforeExit
grantnelson-wf Mar 26, 2024
32a8a96
Merge pull request #1280 from Workiva/tempTimeFix
nevkontakte Apr 1, 2024
0285af6
Merge pull request #1281 from Workiva/fixRuntimeBeforeExit
nevkontakte Apr 1, 2024
5c45b9a
Updated the linkname to handle new directives
grantnelson-wf Apr 2, 2024
a1c6032
Merge pull request #1282 from Workiva/updateLinkname
nevkontakte Apr 7, 2024
95f4bef
Updating crypto sublte xor overrides
grantnelson-wf Apr 3, 2024
c331582
Merge pull request #1284 from Workiva/subtleXor
nevkontakte Apr 11, 2024
2b0f3eb
Merge branch 'master' of github.com:gopherjs/gopherjs into mergeMaster
grantnelson-wf Apr 16, 2024
ac5011a
Added timeout flag handling
grantnelson-wf Apr 16, 2024
2b435e6
Merge pull request #1293 from Workiva/mergeMaster
nevkontakte Apr 17, 2024
0fcb7ec
Update test run example native override
grantnelson-wf Apr 19, 2024
4924340
Updating known fails for gorepo
grantnelson-wf Apr 18, 2024
70aef04
Merge pull request #1296 from Workiva/updateTestRunExample
nevkontakte Apr 21, 2024
7a7beaa
Merge pull request #1295 from Workiva/updateKnownFails
nevkontakte Apr 21, 2024
9b0362c
Updated known fails and fixed a test
grantnelson-wf Apr 23, 2024
d1eb76f
Added built-in support for unsafe.SliceData
grantnelson-wf Apr 25, 2024
bce1d3f
Merge pull request #1297 from Workiva/moreKnownFails
nevkontakte Apr 30, 2024
f657304
Merge branch 'go1.20' of github.com:gopherjs/gopherjs into addUnsafeS…
grantnelson-wf May 2, 2024
31a8063
Merge pull request #1304 from Workiva/gorepoTestTimeout
nevkontakte May 6, 2024
a19f8ed
Adding unsafe.SliceData
grantnelson-wf May 2, 2024
5b6ce8a
Merge branch 'go1.20' of github.com:gopherjs/gopherjs into addUnsafeS…
grantnelson-wf May 8, 2024
fc3ec56
Merge pull request #1298 from Workiva/addUnsafeSliceData
nevkontakte May 12, 2024
7f7a196
Merge branch 'master' of github.com:gopherjs/gopherjs into updateGo1.20
grantnelson-wf May 23, 2024
df7a1cb
Overriding generices for go1.20
grantnelson-wf May 23, 2024
b700426
Adding overrides for go1.20
grantnelson-wf May 23, 2024
73958a0
Merge pull request #1308 from Workiva/updateGo1.20
nevkontakte May 25, 2024
a5152c9
Merge pull request #1309 from Workiva/atomicPntrOverrides
nevkontakte May 25, 2024
5b0b675
Merge pull request #1310 from Workiva/g1.20overridesA
nevkontakte May 25, 2024
f9cbb03
Update to generics override for crypto
grantnelson-wf May 28, 2024
2b01410
Merge pull request #1312 from Workiva/updatingCrypto
nevkontakte May 28, 2024
3d13313
Updating anyOverlap
grantnelson-wf May 31, 2024
e518760
Merge pull request #1314 from Workiva/updateAnyOverlap
flimzy Jun 3, 2024
c849f60
Fixing env watcher for godebug
grantnelson-wf May 31, 2024
2dd555b
Merge pull request #1313 from Workiva/godebugUpdate
nevkontakte Jun 4, 2024
3e287f9
Adding reflect Grow
grantnelson-wf Jun 4, 2024
9fdcb64
Adding nil-check test
grantnelson-wf Jun 12, 2024
e7a03aa
Merge branch 'go1.20' of github.com:gopherjs/gopherjs into addReflect…
grantnelson-wf Jun 12, 2024
1e0d07b
add SemacquireRWMutex
grantnelson-wf Jul 2, 2024
165ce97
Made changes per suggestions and help
grantnelson-wf Jun 26, 2024
0a2738b
Merge pull request #1315 from Workiva/addReflectGrow
nevkontakte Jul 2, 2024
451b445
Merge pull request #1319 from Workiva/addSemacquireRWMutex
nevkontakte Jul 2, 2024
1a87608
Merge branch 'master' of github.com:gopherjs/gopherjs into HEAD
grantnelson-wf Jul 2, 2024
938fba2
Merge pull request #1320 from Workiva/bumpMaster
nevkontakte Jul 3, 2024
ba80a57
Adding some methods and fixing some of reflect
grantnelson-wf Jul 12, 2024
a6a3260
Fixing cvtSliceArray
grantnelson-wf Jul 12, 2024
92f71c0
Merge pull request #1321 from Workiva/add2Reflects
flimzy Jul 13, 2024
edeab09
Fixing mistake in encoding/gob
grantnelson-wf Jul 15, 2024
11d605d
Merge pull request #1323 from Workiva/fixGob
flimzy Jul 16, 2024
1a33e5a
Merge pull request #1322 from Workiva/add3Reflects
nevkontakte Jul 16, 2024
cf8ae57
Repeat go1.19 strings.Repeat for go1.20
grantnelson-wf Jul 17, 2024
1cf45be
Merge pull request #1324 from Workiva/repeatStringRepeat
nevkontakte Jul 17, 2024
0cf44a4
Adding overrides to two crypto tests
grantnelson-wf Jul 18, 2024
1982b78
Merge branch 'master' of github.com:gopherjs/gopherjs into bumpMaster3
grantnelson-wf Jul 18, 2024
6c00782
Bump version to go1.20
grantnelson-wf Jul 18, 2024
eacb580
Merge pull request #1326 from Workiva/bumpMaster3
flimzy Jul 19, 2024
956409c
Merge pull request #1325 from Workiva/fixCryptoCacheTests
flimzy Jul 19, 2024
1677ea2
Fixing measure-size.yml for go1.20
grantnelson-wf Jul 23, 2024
5a0e6a5
Merge pull request #1331 from Workiva/fixMeasureSizeCI
flimzy Jul 23, 2024
b6c2f3c
added copy from slice to array copy
grantnelson-wf Jul 23, 2024
5b2414c
Merge pull request #1332 from Workiva/sliceToArrayCast
flimzy Jul 24, 2024
1f83de8
Merge branch 'master' of github.com:gopherjs/gopherjs into bumpMaster4
grantnelson-wf Jul 24, 2024
8068eeb
Bumping go version to 1.20
grantnelson-wf Jul 24, 2024
eba1537
Merge pull request #1333 from Workiva/bumpMaster4
nevkontakte Jul 24, 2024
05dd05a
Merge branch 'master' of github.com:gopherjs/gopherjs into go120Update2
grantnelson-wf Aug 18, 2025
bca215b
Fixing merge conflicts
grantnelson-wf Aug 18, 2025
81cc1d7
Merge pull request #1388 from Workiva/go120Update2
grantnelson-wf Sep 10, 2025
c1962ab
Merge branch 'master' of github.com:gopherjs/gopherjs into go1.20update
grantnelson-wf Jan 5, 2026
7470df5
Fixing a merge conflict
grantnelson-wf Jan 5, 2026
33de2a5
Merge pull request #1397 from Workiva/go1.20update
grantnelson-wf Jan 6, 2026
1d47769
touchup of go1.20
grantnelson-wf Jan 9, 2026
2f63887
Merge pull request #1399 from Workiva/touchup120
grantnelson-wf Jan 12, 2026
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ concurrency:
cancel-in-progress: true

env:
GO_VERSION: 1.19.13
GO_VERSION: 1.20.14
NODE_VERSION: 18
GOLANGCI_VERSION: v1.53.3
SOURCE_MAP_SUPPORT: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/measure-size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Measure canonical app size
on: ['pull_request']

env:
GO_VERSION: '~1.19.13'
GO_VERSION: '~1.20.14'

jobs:
measure:
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ Nearly everything, including Goroutines ([compatibility documentation](https://g

### Installation and Usage

GopherJS [requires Go 1.19 or newer](https://github.com/gopherjs/gopherjs/blob/master/doc/compatibility.md#go-version-compatibility). If you need an older Go
GopherJS [requires Go 1.20 or newer](https://github.com/gopherjs/gopherjs/blob/master/doc/compatibility.md#go-version-compatibility). If you need an older Go
version, you can use an [older GopherJS release](https://github.com/gopherjs/gopherjs/releases).

Install GopherJS with `go install`:

```
go install github.com/gopherjs/gopherjs@v1.19.0-beta2 # Or replace 'v1.19.0-beta2' with another version.
go install github.com/gopherjs/gopherjs@v1.20.0-beta1 # Or replace 'v1.20.0-beta1' with another version.
```

If your local Go distribution as reported by `go version` is newer than Go 1.19, then you need to set the `GOPHERJS_GOROOT` environment variable to a directory that contains a Go 1.19 distribution. For example:
If your local Go distribution as reported by `go version` is newer than Go 1.20, then you need to set the `GOPHERJS_GOROOT` environment variable to a directory that contains a Go 1.20 distribution. For example:

```
go install golang.org/dl/go1.19.13@latest
go1.19.13 download
export GOPHERJS_GOROOT="$(go1.19.13 env GOROOT)" # Also add this line to your .profile or equivalent.
go install golang.org/dl/go1.20.14@latest
go1.20.14 download
export GOPHERJS_GOROOT="$(go1.20.14 env GOROOT)" # Also add this line to your .profile or equivalent.
```

Now you can use `gopherjs build [package]`, `gopherjs build [files]` or `gopherjs install [package]` which behave similar to the `go` tool. For `main` packages, these commands create a `.js` file and `.js.map` source map in the current directory or in `$GOPATH/bin`. The generated JavaScript file can be used as usual in a website. Use `gopherjs help [command]` to get a list of possible command line flags, e.g. for minification and automatically watching for changes.
Expand Down
28 changes: 21 additions & 7 deletions build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -725,19 +725,33 @@ func (p *PackageData) XTestPackage() *PackageData {

// InstallPath returns the path where "gopherjs install" command should place the
// generated output.
func (p *PackageData) InstallPath() string {
func (p *PackageData) InstallPath() (string, error) {
if p.IsCommand() {
name := filepath.Base(p.ImportPath) + ".js"

// For executable packages, mimic go tool behavior if possible.
if gobin := os.Getenv("GOBIN"); gobin != "" {
return filepath.Join(gobin, name)
} else if gopath := os.Getenv("GOPATH"); gopath != "" {
return filepath.Join(gopath, "bin", name)
} else if home, err := os.UserHomeDir(); err == nil {
return filepath.Join(home, "go", "bin", name)
return filepath.Join(gobin, name), nil
}

if gopath := os.Getenv("GOPATH"); gopath != "" {
return filepath.Join(gopath, "bin", name), nil
}

if home, err := os.UserHomeDir(); err == nil {
return filepath.Join(home, "go", "bin", name), nil
}
}
return p.PkgObj

if p.PkgObj != "" {
return p.PkgObj, nil
}

// The build.Context.Import method stopped populating build.Package.PkgObj
// in 1.20 for packages found in the Goroot. Currently we don't use the
// build.Package.PkgObj except for a fallback when no other locations
// can be found for command packages to install.
return "", fmt.Errorf(`no install location available for %q`, p.ImportPath)
}

// Session manages internal state GopherJS requires to perform a build.
Expand Down
15 changes: 11 additions & 4 deletions build/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,11 +368,18 @@ func (cc chainedCtx) Import(importPath string, srcDir string, mode build.ImportM
pkg, err := cc.primary.Import(importPath, srcDir, mode)
if err == nil {
return pkg, nil
} else if IsPkgNotFound(err) {
return cc.secondary.Import(importPath, srcDir, mode)
} else {
return nil, err
}

if IsPkgNotFound(err) {
if pkg, err2 := cc.secondary.Import(importPath, srcDir, mode); err2 == nil {
return pkg, nil
}
// if err2 != nil, return the original error that occurred in primary
// context since the secondary is for the virtual gopherjs context,
// meaning err2 will say that GOPATH is not set which is misleading.
}

return nil, err
}

func (cc chainedCtx) Env() Env { return cc.primary.Env() }
Expand Down
16 changes: 10 additions & 6 deletions build/context_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package build

import (
"fmt"
"go/build"
"net/http"
"path/filepath"
Expand Down Expand Up @@ -31,16 +30,19 @@ func TestSimpleCtx(t *testing.T) {

t.Run("exists", func(t *testing.T) {
tests := []struct {
name string
buildCtx XContext
wantPkg *PackageData
}{
{
name: `embeddedCtx`,
buildCtx: ec,
wantPkg: &PackageData{
Package: expectedPackage(&ec.bctx, "github.com/gopherjs/gopherjs/js", "wasm"),
IsVirtual: true,
},
}, {
name: `goCtx`,
buildCtx: gc,
wantPkg: &PackageData{
Package: expectedPackage(&gc.bctx, "fmt", "wasm"),
Expand All @@ -50,7 +52,7 @@ func TestSimpleCtx(t *testing.T) {
}

for _, test := range tests {
t.Run(fmt.Sprintf("%T", test.buildCtx), func(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
importPath := test.wantPkg.ImportPath
got, err := test.buildCtx.Import(importPath, "", build.FindOnly)
if err != nil {
Expand All @@ -65,25 +67,27 @@ func TestSimpleCtx(t *testing.T) {

t.Run("not found", func(t *testing.T) {
tests := []struct {
name string
buildCtx XContext
importPath string
}{
{
name: `embeddedCtx`,
buildCtx: ec,
importPath: "package/not/found",
}, {
// Outside of the main module.
name: `goCtx outside of the main module`,
buildCtx: gc,
importPath: "package/not/found",
}, {
// In the main module.
name: `goCtx in the main module`,
buildCtx: gc,
importPath: "github.com/gopherjs/gopherjs/not/found",
},
}

for _, test := range tests {
t.Run(fmt.Sprintf("%T", test.buildCtx), func(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
_, err := ec.Import(test.importPath, "", build.FindOnly)
want := "cannot find package"
if err == nil || !strings.Contains(err.Error(), want) {
Expand Down Expand Up @@ -210,6 +214,6 @@ func expectedPackage(bctx *build.Context, importPath string, goarch string) *bui
PkgTargetRoot: targetRoot,
BinDir: filepath.Join(bctx.GOROOT, "bin"),
Goroot: true,
PkgObj: filepath.Join(targetRoot, importPath+".a"),
PkgObj: ``, // not populated for Goroot packages since 1.20
}
}
3 changes: 3 additions & 0 deletions compiler/expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,9 @@ func (fc *funcContext) translateBuiltin(name string, sig *types.Signature, args
case "Offsetof":
sel, _ := fc.selectionOf(astutil.RemoveParens(args[0]).(*ast.SelectorExpr))
return fc.formatExpr("%d", typesutil.OffsetOf(sizes32, sel))
case "SliceData":
t := fc.typeOf(args[0]).Underlying().(*types.Slice)
return fc.formatExpr(`$sliceData(%e, %s)`, args[0], fc.typeName(t))
default:
panic(fmt.Sprintf("Unhandled builtin: %s\n", name))
}
Expand Down
122 changes: 87 additions & 35 deletions compiler/linkname/linkname.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,84 @@ type GoLinkname struct {
Reference symbol.Name
}

// ParseGoLinknames processed comments in a source file and extracts //go:linkname
// readLinknameFromComment reads the given comment to determine if it's a go:linkname
// directive then returns the linkname information, otherwise returns nil.
func readLinknameFromComment(pkgPath string, comment *ast.Comment) (*GoLinkname, error) {
if !strings.HasPrefix(comment.Text, `//go:linkname `) {
return nil, nil // Not a linkname compiler directive.
}

fields := strings.Fields(comment.Text)

// Check that the directive comment has both parts and is on the line by itself.
switch len(fields) {
case 2:
// Ignore one-argument form //go:linkname localName
// This is typically used with "insert"-style links to
// suppresses the usual error for a function that lacks a body.
// The "insert"-style links aren't supported by GopherJS so
// these bodiless functions have to be overridden in the natives anyway.
return nil, nil
case 3:
// Continue for two-argument form //go:linkname localName importPath.extName
break
default:
return nil, fmt.Errorf(`gopherjs: usage requires 2 arguments: //go:linkname localName importPath.extName`)
}

localPkg, localName := pkgPath, fields[1]
extPkg, extName := ``, fields[2]

if localName == extName {
// Ignore self referencing links, //go:linkname localName localName
// These function similar to one-argument links.
return nil, nil
}

pathOffset := 0
if pos := strings.LastIndexByte(extName, '/'); pos != -1 {
pathOffset = pos + 1
}

if idx := strings.IndexByte(extName[pathOffset:], '.'); idx != -1 {
extPkg, extName = extName[:pathOffset+idx], extName[pathOffset+idx+1:]
}

return &GoLinkname{
Reference: symbol.Name{PkgPath: localPkg, Name: localName},
Implementation: symbol.Name{PkgPath: extPkg, Name: extName},
}, nil
}

// isMitigatedVarLinkname checks if the given go:linkname directive on
// a variable, which GopherJS doesn't support, is known about.
// We silently ignore such directives, since it doesn't seem to cause any problems.
func isMitigatedVarLinkname(sym symbol.Name) bool {
mitigatedLinks := map[string]bool{
`reflect.zeroVal`: true,
`math/bits.overflowError`: true, // Defaults in bits_errors_bootstrap.go
`math/bits.divideError`: true, // Defaults in bits_errors_bootstrap.go
}
return mitigatedLinks[sym.String()]
}

// isMitigatedInsertLinkname checks if the given go:linkname directive
// on a function, where the function has a body, is known about.
// These are unsupported "insert"-style go:linkname directives,
// that we ignore as a link and handle case-by-case in native overrides.
func isMitigatedInsertLinkname(sym symbol.Name) bool {
mitigatedPkg := map[string]bool{
`runtime`: true, // Lots of "insert"-style links
`internal/fuzz`: true, // Defaults to no-op stubs
}
mitigatedLinks := map[string]bool{
`internal/bytealg.runtime_cmpstring`: true,
`os.net_newUnixFile`: true,
}
return mitigatedPkg[sym.PkgPath] || mitigatedLinks[sym.String()]
}

// parseGoLinknames processed comments in a source file and extracts //go:linkname
// compiler directive from the comments.
//
// The following directive format is supported:
Expand All @@ -45,63 +122,38 @@ func ParseGoLinknames(fset *token.FileSet, pkgPath string, file *ast.File) ([]Go
isUnsafe := astutil.ImportsUnsafe(file)

processComment := func(comment *ast.Comment) error {
if !strings.HasPrefix(comment.Text, "//go:linkname ") {
return nil // Not a linkname compiler directive.
link, err := readLinknameFromComment(pkgPath, comment)
if err != nil || link == nil {
return err
}

// TODO(nevkontakte): Ideally we should check that the directive comment
// is on a line by itself, line Go compiler does, but ast.Comment doesn't
// provide an easy way to find that out.

if !isUnsafe {
return fmt.Errorf(`//go:linkname is only allowed in Go files that import "unsafe"`)
}

fields := strings.Fields(comment.Text)
if len(fields) != 3 {
return fmt.Errorf(`usage (all fields required): //go:linkname localname importpath.extname`)
}

localPkg, localName := pkgPath, fields[1]
extPkg, extName := "", fields[2]
if pos := strings.LastIndexByte(extName, '/'); pos != -1 {
if idx := strings.IndexByte(extName[pos+1:], '.'); idx != -1 {
extPkg, extName = extName[0:pos+idx+1], extName[pos+idx+2:]
}
} else if idx := strings.IndexByte(extName, '.'); idx != -1 {
extPkg, extName = extName[0:idx], extName[idx+1:]
}

localName := link.Reference.Name
node := lookupTopNode(file, localName)
if node == nil {
return fmt.Errorf("//go:linkname local symbol %q is not found in the current source file", localName)
}

decl, isFunc := node.(*ast.FuncDecl)
if !isFunc {
if pkgPath == "math/bits" || pkgPath == "reflect" {
// These standard library packages are known to use go:linkname with
// variables, which GopherJS doesn't support. We silently ignore such
// directives, since it doesn't seem to cause any problems.
if isMitigatedVarLinkname(link.Reference) {
return nil
}
return fmt.Errorf("gopherjs: //go:linkname is only supported for functions, got %T", node)
}

if decl.Body != nil {
if pkgPath == "runtime" || pkgPath == "internal/bytealg" || pkgPath == "internal/fuzz" {
// These standard library packages are known to use unsupported
// "insert"-style go:linkname directives, which we ignore here and handle
// case-by-case in native overrides.
if isMitigatedInsertLinkname(link.Reference) {
return nil
}
return fmt.Errorf("gopherjs: //go:linkname can not insert local implementation into an external package %q", extPkg)
return fmt.Errorf("gopherjs: //go:linkname can not insert local implementation into an external package %q", link.Implementation.PkgPath)
}

// Local function has no body, treat it as a reference to an external implementation.
directives = append(directives, GoLinkname{
Reference: symbol.Name{PkgPath: localPkg, Name: localName},
Implementation: symbol.Name{PkgPath: extPkg, Name: extName},
})
directives = append(directives, *link)
return nil
}

Expand Down
Loading
Loading