gopherjs / gopherjs.github.io

GopherJS Playground
https://gopherjs.github.io/playground/
23 stars 12 forks source link

playground: Update for Go 1.9. #67

Closed dmitshur closed 7 years ago

dmitshur commented 7 years ago

This should be done with GopherJS version 1.9-1.

dmitshur commented 7 years ago

I'm investigating this right now.

Everything seems to work okay, except that something causes unsafe package to get loaded, and that fails, because it's not one of the installed packages:

https://github.com/gopherjs/gopherjs.github.io/blob/b7ffcc8bb375a70cc85b414ec55636f102fe68c8/playground/update.sh#L135-L138

I tried adding it to that list, and that fixes the problem:

diff --git a/playground/update.sh b/playground/update.sh
index 5d62c70..578a5fa 100755
--- a/playground/update.sh
+++ b/playground/update.sh
@@ -134,7 +135,8 @@ gopherjs install -m \
          time \
          unicode \
          unicode/utf16 \
-         unicode/utf8
+         unicode/utf8 \
+         unsafe

 cp -a "$GOROOT"/pkg/*_js_min/* pkg/
 cp -a "$GOROOT"/pkg/*_amd64_js_min/* pkg/

However, I want to look around first to see if there's a better fix, and whether this is indicative of a problem somewhere in GopherJS 1.9-1.

dmitshur commented 7 years ago

The "unsafe" package is special-cased here:

https://github.com/gopherjs/gopherjs/blob/95deb33d587c9f6e24b494ea9bdf9648c48f9a60/compiler/package.go#L105-L107

I want to see what changed related to that causing it to be included as part of a build, where previously it wasn't.

dmitshur commented 7 years ago

This is the generated code for the unsafe package:

$packages["unsafe"] = (function() {
    var $pkg = {}, $init;
    $init = function() {
        $pkg.$init = function() {};
        /* */ var $f, $c = false, $s = 0, $r; if (this !== undefined && this.$blk !== undefined) { $f = this; $c = true; $s = $f.$s; $r = $f.$r; } s: while (true) { switch ($s) { case 0:
        /* */ } return; } if ($f === undefined) { $f = { $blk: $init }; } $f.$s = $s; $f.$r = $r; return $f;
    };
    $pkg.$init = $init;
    return $pkg;
})();

It's basically empty (aside from bookkeeping related to goroutines and blocking calls). It contains an empty init function, and that's the only thing that gets called by other packages.

dmitshur commented 7 years ago

Figured it out. It's due to an API change in go/types package (https://github.com/golang/go/issues/21622).

"go/types".Package.Imports used to exclude package unsafe in Go 1.8, but no longer does in 1.9.

image

Compare https://gotools.org/go/types?rev=go1.8.3#package.go-L54-L55 vs https://gotools.org/go/types?rev=go1.9#package.go-L50-L51.

dmitshur commented 7 years ago

I might need to make additional changes, so I've undone the deploy of 8bcc3f3a576ba326bbd26a1d27f5de696b8cf9dd for now.