Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit daae650

Browse filesBrowse files
authored
Merge pull request #1043 from gopherjs/wip-go1.17
Go 1.17 support
2 parents eee08aa + 7fa979d commit daae650
Copy full SHA for daae650

File tree

122 files changed

+1615
-481
lines changed
Filter options

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner

122 files changed

+1615
-481
lines changed

‎.std_test_pkg_exclusions

Copy file name to clipboardExpand all lines: .std_test_pkg_exclusions
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ go/internal/gccgoimporter
77
go/internal/gcimporter
88
go/internal/srcimporter
99
go/types
10+
internal/abi
1011
internal/syscall/unix
1112
internal/syscall/windows
1213
internal/syscall/windows/registry

‎README.md

Copy file name to clipboardExpand all lines: README.md
+7-5Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ GopherJS compiles Go code ([golang.org](https://golang.org/)) to pure JavaScript
99

1010
### What's new?
1111

12+
- 2021-09-19: Go 1.17 support is available!
13+
- 2021-08-23: Go Modules are now fully supported.
1214
- 2021-06-19: Complete `syscall/js` package implementation compatible with the upstream Go 1.16.
1315
- 2021-04-04: **Go 1.16 is now officially supported!** 🎉 🎉 🎉
1416

@@ -22,7 +24,7 @@ Nearly everything, including Goroutines ([compatibility documentation](https://g
2224

2325
### Installation and Usage
2426

25-
GopherJS [requires Go 1.16 or newer](https://github.com/gopherjs/gopherjs/blob/master/doc/compatibility.md#go-version-compatibility). If you need an older Go
27+
GopherJS [requires Go 1.17 or newer](https://github.com/gopherjs/gopherjs/blob/master/doc/compatibility.md#go-version-compatibility). If you need an older Go
2628
version, you can use an [older Gopher release](https://github.com/gopherjs/gopherjs/releases).
2729

2830
Get or update GopherJS and dependencies with:
@@ -31,12 +33,12 @@ Get or update GopherJS and dependencies with:
3133
go get -u github.com/gopherjs/gopherjs
3234
```
3335

34-
If your local Go distribution as reported by `go version` is newer than Go 1.16, then you need to set the `GOPHERJS_GOROOT` environment variable to a directory that contains a Go 1.16 distribution. For example:
36+
If your local Go distribution as reported by `go version` is newer than Go 1.17, then you need to set the `GOPHERJS_GOROOT` environment variable to a directory that contains a Go 1.17 distribution. For example:
3537

3638
```
37-
go get golang.org/dl/go1.16.3
38-
go1.16.3 download
39-
export GOPHERJS_GOROOT="$(go1.16.3 env GOROOT)" # Also add this line to your .profile or equivalent.
39+
go get golang.org/dl/go1.17.1
40+
go1.17.1 download
41+
export GOPHERJS_GOROOT="$(go1.17.1 env GOROOT)" # Also add this line to your .profile or equivalent.
4042
```
4143

4244
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.

‎build/build.go

Copy file name to clipboardExpand all lines: build/build.go
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,11 @@ func (s *Session) InstallSuffix() string {
509509
return ""
510510
}
511511

512+
// GoRelease returns Go release version this session is building with.
513+
func (s *Session) GoRelease() string {
514+
return compiler.GoRelease(s.options.GOROOT)
515+
}
516+
512517
func (s *Session) BuildDir(packagePath string, importPath string, pkgObj string) error {
513518
if s.Watcher != nil {
514519
s.Watcher.Add(packagePath)
@@ -778,7 +783,7 @@ func (s *Session) WriteCommandPackage(archive *compiler.Archive, pkgObj string)
778783
if err != nil {
779784
return err
780785
}
781-
return compiler.WriteProgramCode(deps, sourceMapFilter)
786+
return compiler.WriteProgramCode(deps, sourceMapFilter, s.GoRelease())
782787
}
783788

784789
func NewMappingCallback(m *sourcemap.Map, goroot, gopath string, localMap bool) func(generatedLine, generatedColumn int, originalPos token.Position) {

‎build/cache.go

Copy file name to clipboardExpand all lines: build/cache.go
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
// cachePath is the base path for GopherJS's own build cache.
1212
//
1313
// It serves a similar function to the Go build cache, but is a lot more
14-
// simlistic and therefore not compatible with Go. We use this cache directory
14+
// simplistic and therefore not compatible with Go. We use this cache directory
1515
// to store build artifacts for packages loaded from a module, for which PkgObj
1616
// provided by go/build points inside the module source tree, which can cause
1717
// inconvenience with version control, etc.
@@ -28,7 +28,7 @@ var cachePath = func() string {
2828
// returned by go/build.
2929
func cachedPath(orig string) string {
3030
if orig == "" {
31-
panic(fmt.Errorf("CachedPath() must not be used with an empty string"))
31+
panic("CachedPath() must not be used with an empty string")
3232
}
3333
sum := fmt.Sprintf("%x", sha256.Sum256([]byte(orig)))
3434
return filepath.Join(cachePath, sum[0:2], sum)

‎build/versionhack/versionhack.go

Copy file name to clipboardExpand all lines: build/versionhack/versionhack.go
+6-2Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
// However, it naively assumes that the go tool version in the PATH matches the
1111
// version that was used to build GopherJS and disables module support whenever
1212
// ReleaseTags in the context are set to anything other than the default. This,
13-
// unfortunately, isn't very helpful since gopherjs may be build by a Go version
13+
// unfortunately, isn't very helpful since gopherjs may be built by a Go version
1414
// other than the PATH's default.
1515
//
16-
// Luckily, even if go tool version is mismatches, it's only used for discovery
16+
// Luckily, even if go tool version is mismatched, it's only used for discovery
1717
// of the package locations, and go/build evaluates build constraints on its own
1818
// with ReleaseTags we've passed.
1919
//
@@ -37,6 +37,10 @@ import (
3737
//go:linkname releaseTags go/build.defaultReleaseTags
3838
var releaseTags []string
3939

40+
//go:linkname toolTags go/build.defaultToolTags
41+
var toolTags []string
42+
4043
func init() {
4144
releaseTags = build.Default.ReleaseTags[:compiler.GoVersion]
45+
toolTags = []string{}
4246
}

‎circle.yml

Copy file name to clipboardExpand all lines: circle.yml
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ workflows:
4848
parameters:
4949
go_version:
5050
type: string
51-
default: "1.16.7"
51+
default: "1.17.1"
5252
nvm_version:
5353
type: string
5454
default: "0.38.0"

‎compiler/compiler.go

Copy file name to clipboardExpand all lines: compiler/compiler.go
+6-3Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ type dceInfo struct {
173173
methodFilter string
174174
}
175175

176-
func WriteProgramCode(pkgs []*Archive, w *SourceMapFilter) error {
176+
func WriteProgramCode(pkgs []*Archive, w *SourceMapFilter, goVersion string) error {
177177
mainPkg := pkgs[len(pkgs)-1]
178178
minify := mainPkg.Minified
179179

@@ -242,6 +242,10 @@ func WriteProgramCode(pkgs []*Archive, w *SourceMapFilter) error {
242242
if _, err := w.Write([]byte("\"use strict\";\n(function() {\n\n")); err != nil {
243243
return err
244244
}
245+
if _, err := w.Write([]byte(fmt.Sprintf("var $goVersion = %q;\n", goVersion))); err != nil {
246+
return err
247+
}
248+
245249
preludeJS := prelude.Prelude
246250
if minify {
247251
preludeJS = prelude.Minified
@@ -260,10 +264,9 @@ func WriteProgramCode(pkgs []*Archive, w *SourceMapFilter) error {
260264
}
261265
}
262266

263-
if _, err := w.Write([]byte("$synthesizeMethods();\n$initAllLinknames();var $mainPkg = $packages[\"" + string(mainPkg.ImportPath) + "\"];\n$packages[\"runtime\"].$init();\n$go($mainPkg.$init, []);\n$flushConsole();\n\n}).call(this);\n")); err != nil {
267+
if _, err := w.Write([]byte("$synthesizeMethods();\n$initAllLinknames();\nvar $mainPkg = $packages[\"" + string(mainPkg.ImportPath) + "\"];\n$packages[\"runtime\"].$init();\n$go($mainPkg.$init, []);\n$flushConsole();\n\n}).call(this);\n")); err != nil {
264268
return err
265269
}
266-
267270
return nil
268271
}
269272

‎compiler/expressions.go

Copy file name to clipboardExpand all lines: compiler/expressions.go
+28-12Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ func (fc *funcContext) translateExpr(expr ast.Expr) *expression {
199199

200200
switch t.Underlying().(type) {
201201
case *types.Struct, *types.Array:
202+
// JavaScript's pass-by-reference semantics makes passing array's or
203+
// struct's object semantically equivalent to passing a pointer
204+
// TODO(nevkontakte): Evaluate if performance gain justifies complexity
205+
// introduced by the special case.
202206
return fc.translateExpr(e.X)
203207
}
204208

@@ -426,10 +430,6 @@ func (fc *funcContext) translateExpr(expr ast.Expr) *expression {
426430
return fc.formatExpr("$equal(%e, %e, %s)", e.X, e.Y, fc.typeName(t))
427431
case *types.Interface:
428432
return fc.formatExpr("$interfaceIsEqual(%s, %s)", fc.translateImplicitConversion(e.X, t), fc.translateImplicitConversion(e.Y, t))
429-
case *types.Pointer:
430-
if _, ok := u.Elem().Underlying().(*types.Array); ok {
431-
return fc.formatExpr("$equal(%s, %s, %s)", fc.translateImplicitConversion(e.X, t), fc.translateImplicitConversion(e.Y, t), fc.typeName(u.Elem()))
432-
}
433433
case *types.Basic:
434434
if isBoolean(u) {
435435
if b, ok := analysis.BoolValue(e.X, fc.pkgCtx.Info.Info); ok && b {
@@ -450,11 +450,22 @@ func (fc *funcContext) translateExpr(expr ast.Expr) *expression {
450450

451451
case *ast.IndexExpr:
452452
switch t := fc.pkgCtx.TypeOf(e.X).Underlying().(type) {
453-
case *types.Array, *types.Pointer:
453+
case *types.Pointer:
454+
if _, ok := t.Elem().Underlying().(*types.Array); !ok {
455+
// Should never happen in type-checked code.
456+
panic(fmt.Errorf("non-array pointers can't be used with index expression"))
457+
}
458+
// Rewrite arrPtr[i] → (*arrPtr)[i] to concentrate array dereferencing
459+
// logic in one place.
460+
x := &ast.StarExpr{
461+
Star: e.X.Pos(),
462+
X: e.X,
463+
}
464+
astutil.SetType(fc.pkgCtx.Info.Info, t.Elem(), x)
465+
e.X = x
466+
return fc.translateExpr(e)
467+
case *types.Array:
454468
pattern := rangeCheck("%1e[%2f]", fc.pkgCtx.Types[e.Index].Value != nil, true)
455-
if _, ok := t.(*types.Pointer); ok { // check pointer for nix (attribute getter causes a panic)
456-
pattern = `(%1e.nilCheck, ` + pattern + `)`
457-
}
458469
return fc.formatExpr(pattern, e.X, e.Index)
459470
case *types.Slice:
460471
return fc.formatExpr(rangeCheck("%1e.$array[%1e.$offset + %2f]", fc.pkgCtx.Types[e.Index].Value != nil, false), e.X, e.Index)
@@ -823,6 +834,7 @@ func (fc *funcContext) makeReceiver(e *ast.SelectorExpr) *expression {
823834

824835
recv := fc.translateImplicitConversionWithCloning(x, methodsRecvType)
825836
if isWrapped(recvType) {
837+
// Wrap JS-native value to have access to the Go type's methods.
826838
recv = fc.formatExpr("new %s(%s)", fc.typeName(methodsRecvType), recv)
827839
}
828840
return recv
@@ -1031,7 +1043,7 @@ func (fc *funcContext) translateConversion(expr ast.Expr, desiredType types.Type
10311043
case t.Kind() == types.UnsafePointer:
10321044
if unary, isUnary := expr.(*ast.UnaryExpr); isUnary && unary.Op == token.AND {
10331045
if indexExpr, isIndexExpr := unary.X.(*ast.IndexExpr); isIndexExpr {
1034-
return fc.formatExpr("$sliceToArray(%s)", fc.translateConversionToSlice(indexExpr.X, types.NewSlice(types.Typ[types.Uint8])))
1046+
return fc.formatExpr("$sliceToNativeArray(%s)", fc.translateConversionToSlice(indexExpr.X, types.NewSlice(types.Typ[types.Uint8])))
10351047
}
10361048
if ident, isIdent := unary.X.(*ast.Ident); isIdent && ident.Name == "_zero" {
10371049
return fc.formatExpr("new Uint8Array(0)")
@@ -1075,8 +1087,12 @@ func (fc *funcContext) translateConversion(expr ast.Expr, desiredType types.Type
10751087
break
10761088
}
10771089

1078-
switch u := t.Elem().Underlying().(type) {
1090+
switch ptrElType := t.Elem().Underlying().(type) {
10791091
case *types.Array: // (*[N]T)(expr) — converting expr to a pointer to an array.
1092+
if _, ok := exprType.Underlying().(*types.Slice); ok {
1093+
return fc.formatExpr("$sliceToGoArray(%e, %s)", expr, fc.typeName(desiredType))
1094+
}
1095+
// TODO(nevkontakte): Is this just for aliased types (e.g. `type a [4]byte`)?
10801096
return fc.translateExpr(expr)
10811097
case *types.Struct: // (*StructT)(expr) — converting expr to a pointer to a struct.
10821098
if fc.pkgCtx.Pkg.Path() == "syscall" && types.Identical(exprType, types.Typ[types.UnsafePointer]) {
@@ -1086,7 +1102,7 @@ func (fc *funcContext) translateConversion(expr ast.Expr, desiredType types.Type
10861102
// indeed pointing at a byte array.
10871103
array := fc.newVariable("_array")
10881104
target := fc.newVariable("_struct")
1089-
return fc.formatExpr("(%s = %e, %s = %e, %s, %s)", array, expr, target, fc.zeroValue(t.Elem()), fc.loadStruct(array, target, u), target)
1105+
return fc.formatExpr("(%s = %e, %s = %e, %s, %s)", array, expr, target, fc.zeroValue(t.Elem()), fc.loadStruct(array, target, ptrElType), target)
10901106
}
10911107
// Convert between structs of different types but identical layouts,
10921108
// for example:
@@ -1152,7 +1168,7 @@ func (fc *funcContext) translateImplicitConversion(expr ast.Expr, desiredType ty
11521168

11531169
switch desiredType.Underlying().(type) {
11541170
case *types.Slice:
1155-
return fc.formatExpr("$subslice(new %1s(%2e.$array), %2e.$offset, %2e.$offset + %2e.$length)", fc.typeName(desiredType), expr)
1171+
return fc.formatExpr("$convertSliceType(%1e, %2s)", expr, fc.typeName(desiredType))
11561172

11571173
case *types.Interface:
11581174
if typesutil.IsJsObject(exprType) {

‎compiler/gopherjspkg/doc.go

Copy file name to clipboardExpand all lines: compiler/gopherjspkg/doc.go
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
package gopherjspkg
1111

1212
//go:generate vfsgendev -source="github.com/gopherjs/gopherjs/compiler/gopherjspkg".FS -tag=gopherjsdev
13+
//go:generate gofmt -w -s fs_vfsdata.go

‎compiler/gopherjspkg/fs.go

Copy file name to clipboardExpand all lines: compiler/gopherjspkg/fs.go
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//go:build gopherjsdev
12
// +build gopherjsdev
23

34
package gopherjspkg

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.