From e43635d0b95c464441c66cf07b4a5bbe6b7d3b54 Mon Sep 17 00:00:00 2001 From: Paul Jolly Date: Mon, 2 Jul 2018 19:00:51 +0100 Subject: [PATCH 01/10] ci: fix circle config for myitcv/gopherjs build (#1) --- circle.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/circle.yml b/circle.yml index 1a5f62651..e4f85ceae 100644 --- a/circle.yml +++ b/circle.yml @@ -5,13 +5,20 @@ machine: SOURCE_MAP_SUPPORT: false dependencies: - pre: + override: - cd /usr/local && sudo rm -rf go && curl https://storage.googleapis.com/golang/go1.10.1.linux-amd64.tar.gz | sudo tar -xz && sudo chmod a+w go/src/path/filepath - post: - - mv ./gopherjs $HOME/bin - npm install --global node-gyp - npm install # install our (dev) dependencies from package.json - cd node-syscall && node-gyp rebuild && mkdir -p ~/.node_libraries/ && cp build/Release/syscall.node ~/.node_libraries/syscall.node + - mkdir -p $HOME/.gopath/src/github.com/gopherjs + - mv $HOME/$CIRCLE_PROJECT_REPONAME $HOME/.gopath/src/github.com/gopherjs/gopherjs + - ln -s $HOME/.gopath/src/github.com/gopherjs/gopherjs $HOME/$CIRCLE_PROJECT_REPONAME + - | + echo 'export GOPATH=$HOME/.gopath:$GOPATH' >> ~/.circlerc + echo 'export PATH=$HOME/.gopath/bin:$PATH' >> ~/.circlerc + - go get -t -d -v github.com/gopherjs/gopherjs/... + - go install github.com/gopherjs/gopherjs + - which gopherjs test: override: From 51d17b27c7d7ef6336be4796295b2416aa360cb1 Mon Sep 17 00:00:00 2001 From: Paul Jolly Date: Mon, 2 Jul 2018 20:09:58 +0100 Subject: [PATCH 02/10] ci: upgrade to CircleCI 2 (#2) --- .circleci/config.yml | 84 +++++++++++++++++++++++ .std_test_pkg_exclusions | 81 ++++++++++++++++++++++ circle.yml | 144 --------------------------------------- 3 files changed, 165 insertions(+), 144 deletions(-) create mode 100644 .circleci/config.yml create mode 100644 .std_test_pkg_exclusions delete mode 100644 circle.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..ddd18653f --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,84 @@ +version: 2 +jobs: + build: + working_directory: /go/src/github.com/gopherjs/gopherjs + docker: + # We have a custom installation of Go below so this version is (largely) irrelevant. + - image: circleci/golang:1.10 + + environment: + SOURCE_MAP_SUPPORT: false + NVM_VERSION: v0.33.9 + GO_VERSION: 1.10.3 + NODE_VERSION: 10.0.0 + + steps: + - checkout + + - run: | + # Install nvm. + git clone https://github.com/creationix/nvm.git $HOME/.nvm + cd $HOME/.nvm && git checkout $NVM_VERSION + echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV + echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $BASH_ENV + + - run: | + # Install our own local Go version; we need src/path/filepath to be writable for certain tests. + mkdir $HOME/goroot + curl https://storage.googleapis.com/golang/go$GO_VERSION.linux-amd64.tar.gz | tar -C $HOME/goroot --strip-components=1 -xz + chmod a+w $HOME/goroot/src/path/filepath + echo 'export PATH="$HOME/goroot/bin:$PATH"' >> $BASH_ENV + + - run: | + # Per https://github.com/gopherjs/gopherjs/pull/687. + echo 'ulimit -s 10000' >> $BASH_ENV + + - run: | + # Setup our required Node version now that nvm is installed. + nvm install $NODE_VERSION node + nvm alias default $NODE_VERSION + + - run: | + # Verify our environment setup. + which node + which go + node --version + go version + go env + + - run: | + # Per https://github.com/gopherjs/gopherjs/blob/master/doc/syscalls.md. + npm install --global node-gyp + cd node-syscall && node-gyp rebuild && mkdir -p $HOME/.node_libraries/ && cp build/Release/syscall.node $HOME/.node_libraries/syscall.node + + - run: | + go get -t ./... + go install github.com/gopherjs/gopherjs + + - run: + # because this is a long-running test suite + no_output_timeout: 30m + command: | + echo ">> Ensure all go code is well formatted." + diff -u <(echo -n) <(gofmt -d .) + + echo ">> Vetting github.com/gopherjs/gopherjs" + go tool vet *.go + + echo ">> vet all subdirectories except tests and third_party." + for d in */; do echo $d; done | grep -v tests/ | grep -v third_party/ | xargs go tool vet + + echo ">> All those packages should have // +build js." + diff -u <(echo -n) <(go list ./compiler/natives/src/...) + + echo ">> Should build successfully (can't run tests, since only client is supported)." + gopherjs install -v net/http + + echo ">> Run the core gopherjs tests; exclusions take from .std_test_pkg_exclusions." + go list std | grep -v -x -f .std_test_pkg_exclusions | xargs gopherjs test --minify -v --short github.com/gopherjs/gopherjs/tests/... + + echo ">> Race tests." + go test -v -race ./... + + echo ">> Non-minified gopherjs tests should also work." + gopherjs test -v fmt diff --git a/.std_test_pkg_exclusions b/.std_test_pkg_exclusions new file mode 100644 index 000000000..474568539 --- /dev/null +++ b/.std_test_pkg_exclusions @@ -0,0 +1,81 @@ +# these are go list std packages we want to exclude from our tests +context +crypto +crypto/internal/cipherhw +crypto/tls +crypto/x509/pkix +debug/gosym +debug/plan9obj +encoding +go/build +go/importer +go/internal/gccgoimporter +go/internal/gcimporter +go/internal/srcimporter +go/types +hash +image/color/palette +image/internal/imageutil +internal/cpu +internal/nettrace +internal/poll +internal/race +internal/singleflight +internal/syscall/unix +internal/syscall/windows +internal/syscall/windows/registry +internal/syscall/windows/sysdll +internal/testenv +internal/testlog +internal/trace +log +log/syslog +net +net/http +net/http/cgi +net/http/httptest +net/http/httptrace +net/http/httputil +net/http/internal +net/http/pprof +net/internal/socktest +net/rpc +net/smtp +os +os/exec +os/signal +os/signal/internal/pty +os/user +plugin +runtime +runtime/cgo +runtime/debug +runtime/internal/atomic +runtime/internal/sys +runtime/pprof +runtime/pprof/internal/profile +runtime/race +runtime/trace +syscall +testing +testing/internal/testdeps +testing/iotest +unsafe +vendor/golang_org/x/crypto/chacha20poly1305 +vendor/golang_org/x/crypto/chacha20poly1305/internal/chacha20 +vendor/golang_org/x/crypto/cryptobyte +vendor/golang_org/x/crypto/cryptobyte/asn1 +vendor/golang_org/x/crypto/curve25519 +vendor/golang_org/x/crypto/poly1305 +vendor/golang_org/x/net/http2/hpack +vendor/golang_org/x/net/idna +vendor/golang_org/x/net/internal/nettest +vendor/golang_org/x/net/lex/httplex +vendor/golang_org/x/net/nettest +vendor/golang_org/x/net/proxy +vendor/golang_org/x/text/secure +vendor/golang_org/x/text/secure/bidirule +vendor/golang_org/x/text/transform +vendor/golang_org/x/text/unicode +vendor/golang_org/x/text/unicode/bidi +vendor/golang_org/x/text/unicode/norm diff --git a/circle.yml b/circle.yml deleted file mode 100644 index e4f85ceae..000000000 --- a/circle.yml +++ /dev/null @@ -1,144 +0,0 @@ -machine: - node: - version: 10.0.0 - environment: - SOURCE_MAP_SUPPORT: false - -dependencies: - override: - - cd /usr/local && sudo rm -rf go && curl https://storage.googleapis.com/golang/go1.10.1.linux-amd64.tar.gz | sudo tar -xz && sudo chmod a+w go/src/path/filepath - - npm install --global node-gyp - - npm install # install our (dev) dependencies from package.json - - cd node-syscall && node-gyp rebuild && mkdir -p ~/.node_libraries/ && cp build/Release/syscall.node ~/.node_libraries/syscall.node - - mkdir -p $HOME/.gopath/src/github.com/gopherjs - - mv $HOME/$CIRCLE_PROJECT_REPONAME $HOME/.gopath/src/github.com/gopherjs/gopherjs - - ln -s $HOME/.gopath/src/github.com/gopherjs/gopherjs $HOME/$CIRCLE_PROJECT_REPONAME - - | - echo 'export GOPATH=$HOME/.gopath:$GOPATH' >> ~/.circlerc - echo 'export PATH=$HOME/.gopath/bin:$PATH' >> ~/.circlerc - - go get -t -d -v github.com/gopherjs/gopherjs/... - - go install github.com/gopherjs/gopherjs - - which gopherjs - -test: - override: - - go generate github.com/gopherjs/gopherjs/compiler/prelude - - diff -u <(echo -n) <(git status --porcelain) - - diff -u <(echo -n) <(gofmt -d .) - - go tool vet *.go # Go package in root directory. - - for d in */; do echo $d; done | grep -v tests/ | grep -v third_party/ | xargs go tool vet # All subdirectories except "tests", "third_party". - - diff -u <(echo -n) <(go list ./compiler/natives/src/...) # All those packages should have // +build js. - - gopherjs install -v net/http # Should build successfully (can't run tests, since only client is supported). - - > - ulimit -s 10000 && gopherjs test --minify -v --short - github.com/gopherjs/gopherjs/tests - github.com/gopherjs/gopherjs/tests/main - github.com/gopherjs/gopherjs/js - archive/tar - archive/zip - bufio - bytes - compress/bzip2 - compress/flate - compress/gzip - compress/lzw - compress/zlib - container/heap - container/list - container/ring - crypto/aes - crypto/cipher - crypto/des - crypto/dsa - crypto/ecdsa - crypto/elliptic - crypto/hmac - crypto/md5 - crypto/rand - crypto/rc4 - crypto/rsa - crypto/sha1 - crypto/sha256 - crypto/sha512 - crypto/subtle - crypto/x509 - database/sql - database/sql/driver - debug/dwarf - debug/elf - debug/macho - debug/pe - encoding/ascii85 - encoding/asn1 - encoding/base32 - encoding/base64 - encoding/binary - encoding/csv - encoding/gob - encoding/hex - encoding/json - encoding/pem - encoding/xml - errors - expvar - flag - fmt - go/ast - go/constant - go/doc - go/format - go/parser - go/printer - go/scanner - go/token - hash/adler32 - hash/crc32 - hash/crc64 - hash/fnv - html - html/template - image - image/color - image/draw - image/gif - image/jpeg - image/png - index/suffixarray - io - io/ioutil - math - math/big - math/bits - math/cmplx - math/rand - mime - mime/multipart - mime/quotedprintable - net/http/cookiejar - net/http/fcgi - net/mail - net/rpc/jsonrpc - net/textproto - net/url - os/user - path - path/filepath - reflect - regexp - regexp/syntax - sort - strconv - strings - sync - sync/atomic - testing/quick - text/scanner - text/tabwriter - text/template - text/template/parse - time - unicode - unicode/utf16 - unicode/utf8 - - go test -v -race ./... - - gopherjs test -v fmt # No minification should work. From e8b02f446106adb2dafcc6f3721c6ac91aefe3a6 Mon Sep 17 00:00:00 2001 From: Paul Jolly Date: Mon, 2 Jul 2018 20:31:55 +0100 Subject: [PATCH 03/10] compiler/prelude: move prelude to separate .js files (#3) I've been working with the prelude quite a lot recently. One of the really painful things with the current implementation is that the JavaScript for the prelude exists as a const string in a .go file, which makes properly writing and formatting the JavaScript itself very difficult. This PR splits the prelude into separate .js files to make editing the JavaScript prelude more straightforward. genmin.go becomes genprelude.go where these .js files are catted together into a single prelude.go file. The minified prelude_min.go is as before. Automated formatting of these .js files will follow in a later PR. --- .circleci/config.yml | 9 + compiler/prelude/generate.go | 3 + compiler/prelude/genmin.go | 63 --- compiler/prelude/genprelude.go | 96 ++++ .../prelude/{goroutines.go => goroutines.js} | 4 - .../prelude/{jsmapping.go => jsmapping.js} | 4 - compiler/prelude/jspmapping.js | 0 compiler/prelude/{numeric.go => numeric.js} | 4 - compiler/prelude/prelude.go | 422 +----------------- compiler/prelude/prelude.js | 414 +++++++++++++++++ compiler/prelude/prelude_min.go | 2 +- compiler/prelude/{types.go => types.js} | 4 - 12 files changed, 526 insertions(+), 499 deletions(-) create mode 100644 compiler/prelude/generate.go delete mode 100644 compiler/prelude/genmin.go create mode 100644 compiler/prelude/genprelude.go rename compiler/prelude/{goroutines.go => goroutines.js} (99%) rename compiler/prelude/{jsmapping.go => jsmapping.js} (99%) create mode 100644 compiler/prelude/jspmapping.js rename compiler/prelude/{numeric.go => numeric.js} (99%) create mode 100644 compiler/prelude/prelude.js rename compiler/prelude/{types.go => types.js} (99%) diff --git a/.circleci/config.yml b/.circleci/config.yml index ddd18653f..00ebcae6a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -51,6 +51,9 @@ jobs: npm install --global node-gyp cd node-syscall && node-gyp rebuild && mkdir -p $HOME/.node_libraries/ && cp build/Release/syscall.node $HOME/.node_libraries/syscall.node + # this gives us the repo-local binaries we require + npm install + - run: | go get -t ./... go install github.com/gopherjs/gopherjs @@ -59,6 +62,12 @@ jobs: # because this is a long-running test suite no_output_timeout: 30m command: | + echo ">> Regenerate compiler/prelude" + go generate github.com/gopherjs/gopherjs/compiler/prelude + + echo ">> Ensure there are no variations from the git commit" + diff -u <(echo -n) <(git status --porcelain) + echo ">> Ensure all go code is well formatted." diff -u <(echo -n) <(gofmt -d .) diff --git a/compiler/prelude/generate.go b/compiler/prelude/generate.go new file mode 100644 index 000000000..bc4b2cea7 --- /dev/null +++ b/compiler/prelude/generate.go @@ -0,0 +1,3 @@ +package prelude + +//go:generate go run genprelude.go diff --git a/compiler/prelude/genmin.go b/compiler/prelude/genmin.go deleted file mode 100644 index 739dbf216..000000000 --- a/compiler/prelude/genmin.go +++ /dev/null @@ -1,63 +0,0 @@ -// +build ignore - -package main - -import ( - "bytes" - "fmt" - "go/build" - "io/ioutil" - "log" - "os/exec" - "path/filepath" - "strings" - - "github.com/gopherjs/gopherjs/compiler/prelude" -) - -func main() { - if err := run(); err != nil { - log.Fatalln(err) - } -} - -func run() error { - bpkg, err := build.Import("github.com/gopherjs/gopherjs", "", build.FindOnly) - if err != nil { - return fmt.Errorf("failed to locate path for github.com/gopherjs/gopherjs: %v", err) - } - - preludeDir := filepath.Join(bpkg.Dir, "compiler", "prelude") - - args := []string{ - filepath.Join(bpkg.Dir, "node_modules", ".bin", "uglifyjs"), - "--config-file", - filepath.Join(preludeDir, "uglifyjs_options.json"), - } - - stderr := new(bytes.Buffer) - cmd := exec.Command(args[0], args[1:]...) - cmd.Stdin = strings.NewReader(prelude.Prelude) - cmd.Stderr = stderr - - out, err := cmd.Output() - if err != nil { - return fmt.Errorf("failed to run %v: %v\n%s", strings.Join(args, " "), err, stderr.String()) - } - - fn := "prelude_min.go" - - outStr := fmt.Sprintf(`// Code generated by genmin; DO NOT EDIT. - -package prelude - -// Minified is an uglifyjs-minified version of Prelude. -const Minified = %q -`, out) - - if err := ioutil.WriteFile(fn, []byte(outStr), 0644); err != nil { - return fmt.Errorf("failed to write to %v: %v", fn, err) - } - - return nil -} diff --git a/compiler/prelude/genprelude.go b/compiler/prelude/genprelude.go new file mode 100644 index 000000000..05c241528 --- /dev/null +++ b/compiler/prelude/genprelude.go @@ -0,0 +1,96 @@ +// +build ignore + +package main + +import ( + "bytes" + "fmt" + "go/build" + "io/ioutil" + "log" + "os/exec" + "path/filepath" + "strings" +) + +const ( + fn = "prelude.go" + minFn = "prelude_min.go" +) + +func main() { + if err := run(); err != nil { + log.Fatalln(err) + } +} + +func run() error { + bpkg, err := build.Import("github.com/gopherjs/gopherjs", "", build.FindOnly) + if err != nil { + return fmt.Errorf("failed to locate path for github.com/gopherjs/gopherjs: %v", err) + } + + preludeDir := filepath.Join(bpkg.Dir, "compiler", "prelude") + + files := []string{ + "prelude.js", + "numeric.js", + "types.js", + "goroutines.js", + "jsmapping.js", + } + + prelude := new(bytes.Buffer) + + for _, f := range files { + p := filepath.Join(preludeDir, f) + out, err := ioutil.ReadFile(p) + if err != nil { + return fmt.Errorf("failed to read from %v: %v", p, err) + } + if _, err := prelude.Write(out); err != nil { + return fmt.Errorf("failed to append prelude: %v", err) + } + } + + args := append([]string{ + filepath.Join(bpkg.Dir, "node_modules", ".bin", "uglifyjs"), + "--config-file", + filepath.Join(preludeDir, "uglifyjs_options.json"), + }, files...) + + stderr := new(bytes.Buffer) + + cmd := exec.Command(args[0], args[1:]...) + cmd.Stderr = stderr + + minout, err := cmd.Output() + if err != nil { + return fmt.Errorf("failed to run %v: %v\n%s", strings.Join(args, " "), err, stderr.Bytes()) + } + + err = writeOutput("prelude.go", ""+ + "// Prelude is the GopherJS JavaScript interop layer.\n"+ + "const Prelude = %q", prelude.Bytes()) + + if err != nil { + return err + } + + err = writeOutput("prelude_min.go", ""+ + "// Minified is an uglifyjs-minified version of Prelude.\n"+ + "const Minified = %q", minout) + + return err +} + +func writeOutput(fn string, format string, byts []byte) error { + content := fmt.Sprintf("// Code generated by genprelude; DO NOT EDIT.\n\n"+ + "package prelude\n\n"+format+"\n", byts) + + if err := ioutil.WriteFile(fn, []byte(content), 0644); err != nil { + return fmt.Errorf("failed to write to %v: %v", fn, err) + } + + return nil +} diff --git a/compiler/prelude/goroutines.go b/compiler/prelude/goroutines.js similarity index 99% rename from compiler/prelude/goroutines.go rename to compiler/prelude/goroutines.js index d9780b65d..f1ae2d37e 100644 --- a/compiler/prelude/goroutines.go +++ b/compiler/prelude/goroutines.js @@ -1,6 +1,3 @@ -package prelude - -const goroutines = ` var $stackDepthOffset = 0; var $getStackDepth = function() { var err = new Error(); @@ -355,4 +352,3 @@ var $select = function(comms) { $block(); return f; }; -` diff --git a/compiler/prelude/jsmapping.go b/compiler/prelude/jsmapping.js similarity index 99% rename from compiler/prelude/jsmapping.go rename to compiler/prelude/jsmapping.js index dc29cba6b..44a2a96a4 100644 --- a/compiler/prelude/jsmapping.go +++ b/compiler/prelude/jsmapping.js @@ -1,6 +1,3 @@ -package prelude - -const jsmapping = ` var $jsObjectPtr, $jsErrorPtr; var $needsExternalization = function(t) { @@ -376,4 +373,3 @@ var $isASCII = function(s) { } return true; }; -` diff --git a/compiler/prelude/jspmapping.js b/compiler/prelude/jspmapping.js new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/prelude/numeric.go b/compiler/prelude/numeric.js similarity index 99% rename from compiler/prelude/numeric.go rename to compiler/prelude/numeric.js index 063d09f46..3064e33ab 100644 --- a/compiler/prelude/numeric.go +++ b/compiler/prelude/numeric.js @@ -1,6 +1,3 @@ -package prelude - -const numeric = ` var $min = Math.min; var $mod = function(x, y) { return x % y; }; var $parseInt = parseInt; @@ -193,4 +190,3 @@ var $divComplex = function(n, d) { var denom = d.$imag * ratio + d.$real; return new n.constructor((n.$imag * ratio + n.$real) / denom, (n.$imag - n.$real * ratio) / denom); }; -` diff --git a/compiler/prelude/prelude.go b/compiler/prelude/prelude.go index 1eed6c4dc..caa1d2ade 100644 --- a/compiler/prelude/prelude.go +++ b/compiler/prelude/prelude.go @@ -1,422 +1,6 @@ -package prelude +// Code generated by genprelude; DO NOT EDIT. -//go:generate go run genmin.go +package prelude // Prelude is the GopherJS JavaScript interop layer. -const Prelude = prelude + numeric + types + goroutines + jsmapping - -const prelude = `Error.stackTraceLimit = Infinity; - -var $global, $module; -if (typeof window !== "undefined") { /* web page */ - $global = window; -} else if (typeof self !== "undefined") { /* web worker */ - $global = self; -} else if (typeof global !== "undefined") { /* Node.js */ - $global = global; - $global.require = require; -} else { /* others (e.g. Nashorn) */ - $global = this; -} - -if ($global === undefined || $global.Array === undefined) { - throw new Error("no global object found"); -} -if (typeof module !== "undefined") { - $module = module; -} - -var $packages = {}, $idCounter = 0; -var $keys = function(m) { return m ? Object.keys(m) : []; }; -var $flushConsole = function() {}; -var $throwRuntimeError; /* set by package "runtime" */ -var $throwNilPointerError = function() { $throwRuntimeError("invalid memory address or nil pointer dereference"); }; -var $call = function(fn, rcvr, args) { return fn.apply(rcvr, args); }; -var $makeFunc = function(fn) { return function() { return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface); }; }; -var $unused = function(v) {}; - -var $mapArray = function(array, f) { - var newArray = new array.constructor(array.length); - for (var i = 0; i < array.length; i++) { - newArray[i] = f(array[i]); - } - return newArray; -}; - -var $methodVal = function(recv, name) { - var vals = recv.$methodVals || {}; - recv.$methodVals = vals; /* noop for primitives */ - var f = vals[name]; - if (f !== undefined) { - return f; - } - var method = recv[name]; - f = function() { - $stackDepthOffset--; - try { - return method.apply(recv, arguments); - } finally { - $stackDepthOffset++; - } - }; - vals[name] = f; - return f; -}; - -var $methodExpr = function(typ, name) { - var method = typ.prototype[name]; - if (method.$expr === undefined) { - method.$expr = function() { - $stackDepthOffset--; - try { - if (typ.wrapped) { - arguments[0] = new typ(arguments[0]); - } - return Function.call.apply(method, arguments); - } finally { - $stackDepthOffset++; - } - }; - } - return method.$expr; -}; - -var $ifaceMethodExprs = {}; -var $ifaceMethodExpr = function(name) { - var expr = $ifaceMethodExprs["$" + name]; - if (expr === undefined) { - expr = $ifaceMethodExprs["$" + name] = function() { - $stackDepthOffset--; - try { - return Function.call.apply(arguments[0][name], arguments); - } finally { - $stackDepthOffset++; - } - }; - } - return expr; -}; - -var $subslice = function(slice, low, high, max) { - if (high === undefined) { - high = slice.$length; - } - if (max === undefined) { - max = slice.$capacity; - } - if (low < 0 || high < low || max < high || high > slice.$capacity || max > slice.$capacity) { - $throwRuntimeError("slice bounds out of range"); - } - var s = new slice.constructor(slice.$array); - s.$offset = slice.$offset + low; - s.$length = high - low; - s.$capacity = max - low; - return s; -}; - -var $substring = function(str, low, high) { - if (low < 0 || high < low || high > str.length) { - $throwRuntimeError("slice bounds out of range"); - } - return str.substring(low, high); -}; - -var $sliceToArray = function(slice) { - if (slice.$array.constructor !== Array) { - return slice.$array.subarray(slice.$offset, slice.$offset + slice.$length); - } - return slice.$array.slice(slice.$offset, slice.$offset + slice.$length); -}; - -var $decodeRune = function(str, pos) { - var c0 = str.charCodeAt(pos); - - if (c0 < 0x80) { - return [c0, 1]; - } - - if (c0 !== c0 || c0 < 0xC0) { - return [0xFFFD, 1]; - } - - var c1 = str.charCodeAt(pos + 1); - if (c1 !== c1 || c1 < 0x80 || 0xC0 <= c1) { - return [0xFFFD, 1]; - } - - if (c0 < 0xE0) { - var r = (c0 & 0x1F) << 6 | (c1 & 0x3F); - if (r <= 0x7F) { - return [0xFFFD, 1]; - } - return [r, 2]; - } - - var c2 = str.charCodeAt(pos + 2); - if (c2 !== c2 || c2 < 0x80 || 0xC0 <= c2) { - return [0xFFFD, 1]; - } - - if (c0 < 0xF0) { - var r = (c0 & 0x0F) << 12 | (c1 & 0x3F) << 6 | (c2 & 0x3F); - if (r <= 0x7FF) { - return [0xFFFD, 1]; - } - if (0xD800 <= r && r <= 0xDFFF) { - return [0xFFFD, 1]; - } - return [r, 3]; - } - - var c3 = str.charCodeAt(pos + 3); - if (c3 !== c3 || c3 < 0x80 || 0xC0 <= c3) { - return [0xFFFD, 1]; - } - - if (c0 < 0xF8) { - var r = (c0 & 0x07) << 18 | (c1 & 0x3F) << 12 | (c2 & 0x3F) << 6 | (c3 & 0x3F); - if (r <= 0xFFFF || 0x10FFFF < r) { - return [0xFFFD, 1]; - } - return [r, 4]; - } - - return [0xFFFD, 1]; -}; - -var $encodeRune = function(r) { - if (r < 0 || r > 0x10FFFF || (0xD800 <= r && r <= 0xDFFF)) { - r = 0xFFFD; - } - if (r <= 0x7F) { - return String.fromCharCode(r); - } - if (r <= 0x7FF) { - return String.fromCharCode(0xC0 | r >> 6, 0x80 | (r & 0x3F)); - } - if (r <= 0xFFFF) { - return String.fromCharCode(0xE0 | r >> 12, 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F)); - } - return String.fromCharCode(0xF0 | r >> 18, 0x80 | (r >> 12 & 0x3F), 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F)); -}; - -var $stringToBytes = function(str) { - var array = new Uint8Array(str.length); - for (var i = 0; i < str.length; i++) { - array[i] = str.charCodeAt(i); - } - return array; -}; - -var $bytesToString = function(slice) { - if (slice.$length === 0) { - return ""; - } - var str = ""; - for (var i = 0; i < slice.$length; i += 10000) { - str += String.fromCharCode.apply(undefined, slice.$array.subarray(slice.$offset + i, slice.$offset + Math.min(slice.$length, i + 10000))); - } - return str; -}; - -var $stringToRunes = function(str) { - var array = new Int32Array(str.length); - var rune, j = 0; - for (var i = 0; i < str.length; i += rune[1], j++) { - rune = $decodeRune(str, i); - array[j] = rune[0]; - } - return array.subarray(0, j); -}; - -var $runesToString = function(slice) { - if (slice.$length === 0) { - return ""; - } - var str = ""; - for (var i = 0; i < slice.$length; i++) { - str += $encodeRune(slice.$array[slice.$offset + i]); - } - return str; -}; - -var $copyString = function(dst, src) { - var n = Math.min(src.length, dst.$length); - for (var i = 0; i < n; i++) { - dst.$array[dst.$offset + i] = src.charCodeAt(i); - } - return n; -}; - -var $copySlice = function(dst, src) { - var n = Math.min(src.$length, dst.$length); - $copyArray(dst.$array, src.$array, dst.$offset, src.$offset, n, dst.constructor.elem); - return n; -}; - -var $copyArray = function(dst, src, dstOffset, srcOffset, n, elem) { - if (n === 0 || (dst === src && dstOffset === srcOffset)) { - return; - } - - if (src.subarray) { - dst.set(src.subarray(srcOffset, srcOffset + n), dstOffset); - return; - } - - switch (elem.kind) { - case $kindArray: - case $kindStruct: - if (dst === src && dstOffset > srcOffset) { - for (var i = n - 1; i >= 0; i--) { - elem.copy(dst[dstOffset + i], src[srcOffset + i]); - } - return; - } - for (var i = 0; i < n; i++) { - elem.copy(dst[dstOffset + i], src[srcOffset + i]); - } - return; - } - - if (dst === src && dstOffset > srcOffset) { - for (var i = n - 1; i >= 0; i--) { - dst[dstOffset + i] = src[srcOffset + i]; - } - return; - } - for (var i = 0; i < n; i++) { - dst[dstOffset + i] = src[srcOffset + i]; - } -}; - -var $clone = function(src, type) { - var clone = type.zero(); - type.copy(clone, src); - return clone; -}; - -var $pointerOfStructConversion = function(obj, type) { - if(obj.$proxies === undefined) { - obj.$proxies = {}; - obj.$proxies[obj.constructor.string] = obj; - } - var proxy = obj.$proxies[type.string]; - if (proxy === undefined) { - var properties = {}; - for (var i = 0; i < type.elem.fields.length; i++) { - (function(fieldProp) { - properties[fieldProp] = { - get: function() { return obj[fieldProp]; }, - set: function(value) { obj[fieldProp] = value; } - }; - })(type.elem.fields[i].prop); - } - proxy = Object.create(type.prototype, properties); - proxy.$val = proxy; - obj.$proxies[type.string] = proxy; - proxy.$proxies = obj.$proxies; - } - return proxy; -}; - -var $append = function(slice) { - return $internalAppend(slice, arguments, 1, arguments.length - 1); -}; - -var $appendSlice = function(slice, toAppend) { - if (toAppend.constructor === String) { - var bytes = $stringToBytes(toAppend); - return $internalAppend(slice, bytes, 0, bytes.length); - } - return $internalAppend(slice, toAppend.$array, toAppend.$offset, toAppend.$length); -}; - -var $internalAppend = function(slice, array, offset, length) { - if (length === 0) { - return slice; - } - - var newArray = slice.$array; - var newOffset = slice.$offset; - var newLength = slice.$length + length; - var newCapacity = slice.$capacity; - - if (newLength > newCapacity) { - newOffset = 0; - newCapacity = Math.max(newLength, slice.$capacity < 1024 ? slice.$capacity * 2 : Math.floor(slice.$capacity * 5 / 4)); - - if (slice.$array.constructor === Array) { - newArray = slice.$array.slice(slice.$offset, slice.$offset + slice.$length); - newArray.length = newCapacity; - var zero = slice.constructor.elem.zero; - for (var i = slice.$length; i < newCapacity; i++) { - newArray[i] = zero(); - } - } else { - newArray = new slice.$array.constructor(newCapacity); - newArray.set(slice.$array.subarray(slice.$offset, slice.$offset + slice.$length)); - } - } - - $copyArray(newArray, array, newOffset + slice.$length, offset, length, slice.constructor.elem); - - var newSlice = new slice.constructor(newArray); - newSlice.$offset = newOffset; - newSlice.$length = newLength; - newSlice.$capacity = newCapacity; - return newSlice; -}; - -var $equal = function(a, b, type) { - if (type === $jsObjectPtr) { - return a === b; - } - switch (type.kind) { - case $kindComplex64: - case $kindComplex128: - return a.$real === b.$real && a.$imag === b.$imag; - case $kindInt64: - case $kindUint64: - return a.$high === b.$high && a.$low === b.$low; - case $kindArray: - if (a.length !== b.length) { - return false; - } - for (var i = 0; i < a.length; i++) { - if (!$equal(a[i], b[i], type.elem)) { - return false; - } - } - return true; - case $kindStruct: - for (var i = 0; i < type.fields.length; i++) { - var f = type.fields[i]; - if (!$equal(a[f.prop], b[f.prop], f.typ)) { - return false; - } - } - return true; - case $kindInterface: - return $interfaceIsEqual(a, b); - default: - return a === b; - } -}; - -var $interfaceIsEqual = function(a, b) { - if (a === $ifaceNil || b === $ifaceNil) { - return a === b; - } - if (a.constructor !== b.constructor) { - return false; - } - if (a.constructor === $jsObjectPtr) { - return a.object === b.object; - } - if (!a.constructor.comparable) { - $throwRuntimeError("comparing uncomparable type " + a.constructor.string); - } - return $equal(a.$val, b.$val, a.constructor); -}; -` +const Prelude = "Error.stackTraceLimit = Infinity;\n\nvar $global, $module;\nif (typeof window !== \"undefined\") { /* web page */\n $global = window;\n} else if (typeof self !== \"undefined\") { /* web worker */\n $global = self;\n} else if (typeof global !== \"undefined\") { /* Node.js */\n $global = global;\n $global.require = require;\n} else { /* others (e.g. Nashorn) */\n $global = this;\n}\n\nif ($global === undefined || $global.Array === undefined) {\n throw new Error(\"no global object found\");\n}\nif (typeof module !== \"undefined\") {\n $module = module;\n}\n\nvar $packages = {}, $idCounter = 0;\nvar $keys = function(m) { return m ? Object.keys(m) : []; };\nvar $flushConsole = function() {};\nvar $throwRuntimeError; /* set by package \"runtime\" */\nvar $throwNilPointerError = function() { $throwRuntimeError(\"invalid memory address or nil pointer dereference\"); };\nvar $call = function(fn, rcvr, args) { return fn.apply(rcvr, args); };\nvar $makeFunc = function(fn) { return function() { return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface); }; };\nvar $unused = function(v) {};\n\nvar $mapArray = function(array, f) {\n var newArray = new array.constructor(array.length);\n for (var i = 0; i < array.length; i++) {\n newArray[i] = f(array[i]);\n }\n return newArray;\n};\n\nvar $methodVal = function(recv, name) {\n var vals = recv.$methodVals || {};\n recv.$methodVals = vals; /* noop for primitives */\n var f = vals[name];\n if (f !== undefined) {\n return f;\n }\n var method = recv[name];\n f = function() {\n $stackDepthOffset--;\n try {\n return method.apply(recv, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n vals[name] = f;\n return f;\n};\n\nvar $methodExpr = function(typ, name) {\n var method = typ.prototype[name];\n if (method.$expr === undefined) {\n method.$expr = function() {\n $stackDepthOffset--;\n try {\n if (typ.wrapped) {\n arguments[0] = new typ(arguments[0]);\n }\n return Function.call.apply(method, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return method.$expr;\n};\n\nvar $ifaceMethodExprs = {};\nvar $ifaceMethodExpr = function(name) {\n var expr = $ifaceMethodExprs[\"$\" + name];\n if (expr === undefined) {\n expr = $ifaceMethodExprs[\"$\" + name] = function() {\n $stackDepthOffset--;\n try {\n return Function.call.apply(arguments[0][name], arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return expr;\n};\n\nvar $subslice = function(slice, low, high, max) {\n if (high === undefined) {\n high = slice.$length;\n }\n if (max === undefined) {\n max = slice.$capacity;\n }\n if (low < 0 || high < low || max < high || high > slice.$capacity || max > slice.$capacity) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n var s = new slice.constructor(slice.$array);\n s.$offset = slice.$offset + low;\n s.$length = high - low;\n s.$capacity = max - low;\n return s;\n};\n\nvar $substring = function(str, low, high) {\n if (low < 0 || high < low || high > str.length) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n return str.substring(low, high);\n};\n\nvar $sliceToArray = function(slice) {\n if (slice.$array.constructor !== Array) {\n return slice.$array.subarray(slice.$offset, slice.$offset + slice.$length);\n }\n return slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n};\n\nvar $decodeRune = function(str, pos) {\n var c0 = str.charCodeAt(pos);\n\n if (c0 < 0x80) {\n return [c0, 1];\n }\n\n if (c0 !== c0 || c0 < 0xC0) {\n return [0xFFFD, 1];\n }\n\n var c1 = str.charCodeAt(pos + 1);\n if (c1 !== c1 || c1 < 0x80 || 0xC0 <= c1) {\n return [0xFFFD, 1];\n }\n\n if (c0 < 0xE0) {\n var r = (c0 & 0x1F) << 6 | (c1 & 0x3F);\n if (r <= 0x7F) {\n return [0xFFFD, 1];\n }\n return [r, 2];\n }\n\n var c2 = str.charCodeAt(pos + 2);\n if (c2 !== c2 || c2 < 0x80 || 0xC0 <= c2) {\n return [0xFFFD, 1];\n }\n\n if (c0 < 0xF0) {\n var r = (c0 & 0x0F) << 12 | (c1 & 0x3F) << 6 | (c2 & 0x3F);\n if (r <= 0x7FF) {\n return [0xFFFD, 1];\n }\n if (0xD800 <= r && r <= 0xDFFF) {\n return [0xFFFD, 1];\n }\n return [r, 3];\n }\n\n var c3 = str.charCodeAt(pos + 3);\n if (c3 !== c3 || c3 < 0x80 || 0xC0 <= c3) {\n return [0xFFFD, 1];\n }\n\n if (c0 < 0xF8) {\n var r = (c0 & 0x07) << 18 | (c1 & 0x3F) << 12 | (c2 & 0x3F) << 6 | (c3 & 0x3F);\n if (r <= 0xFFFF || 0x10FFFF < r) {\n return [0xFFFD, 1];\n }\n return [r, 4];\n }\n\n return [0xFFFD, 1];\n};\n\nvar $encodeRune = function(r) {\n if (r < 0 || r > 0x10FFFF || (0xD800 <= r && r <= 0xDFFF)) {\n r = 0xFFFD;\n }\n if (r <= 0x7F) {\n return String.fromCharCode(r);\n }\n if (r <= 0x7FF) {\n return String.fromCharCode(0xC0 | r >> 6, 0x80 | (r & 0x3F));\n }\n if (r <= 0xFFFF) {\n return String.fromCharCode(0xE0 | r >> 12, 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F));\n }\n return String.fromCharCode(0xF0 | r >> 18, 0x80 | (r >> 12 & 0x3F), 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F));\n};\n\nvar $stringToBytes = function(str) {\n var array = new Uint8Array(str.length);\n for (var i = 0; i < str.length; i++) {\n array[i] = str.charCodeAt(i);\n }\n return array;\n};\n\nvar $bytesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i += 10000) {\n str += String.fromCharCode.apply(undefined, slice.$array.subarray(slice.$offset + i, slice.$offset + Math.min(slice.$length, i + 10000)));\n }\n return str;\n};\n\nvar $stringToRunes = function(str) {\n var array = new Int32Array(str.length);\n var rune, j = 0;\n for (var i = 0; i < str.length; i += rune[1], j++) {\n rune = $decodeRune(str, i);\n array[j] = rune[0];\n }\n return array.subarray(0, j);\n};\n\nvar $runesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i++) {\n str += $encodeRune(slice.$array[slice.$offset + i]);\n }\n return str;\n};\n\nvar $copyString = function(dst, src) {\n var n = Math.min(src.length, dst.$length);\n for (var i = 0; i < n; i++) {\n dst.$array[dst.$offset + i] = src.charCodeAt(i);\n }\n return n;\n};\n\nvar $copySlice = function(dst, src) {\n var n = Math.min(src.$length, dst.$length);\n $copyArray(dst.$array, src.$array, dst.$offset, src.$offset, n, dst.constructor.elem);\n return n;\n};\n\nvar $copyArray = function(dst, src, dstOffset, srcOffset, n, elem) {\n if (n === 0 || (dst === src && dstOffset === srcOffset)) {\n return;\n }\n\n if (src.subarray) {\n dst.set(src.subarray(srcOffset, srcOffset + n), dstOffset);\n return;\n }\n\n switch (elem.kind) {\n case $kindArray:\n case $kindStruct:\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n};\n\nvar $clone = function(src, type) {\n var clone = type.zero();\n type.copy(clone, src);\n return clone;\n};\n\nvar $pointerOfStructConversion = function(obj, type) {\n if(obj.$proxies === undefined) {\n obj.$proxies = {};\n obj.$proxies[obj.constructor.string] = obj;\n }\n var proxy = obj.$proxies[type.string];\n if (proxy === undefined) {\n var properties = {};\n for (var i = 0; i < type.elem.fields.length; i++) {\n (function(fieldProp) {\n properties[fieldProp] = {\n get: function() { return obj[fieldProp]; },\n set: function(value) { obj[fieldProp] = value; }\n };\n })(type.elem.fields[i].prop);\n }\n proxy = Object.create(type.prototype, properties);\n proxy.$val = proxy;\n obj.$proxies[type.string] = proxy;\n proxy.$proxies = obj.$proxies;\n }\n return proxy;\n};\n\nvar $append = function(slice) {\n return $internalAppend(slice, arguments, 1, arguments.length - 1);\n};\n\nvar $appendSlice = function(slice, toAppend) {\n if (toAppend.constructor === String) {\n var bytes = $stringToBytes(toAppend);\n return $internalAppend(slice, bytes, 0, bytes.length);\n }\n return $internalAppend(slice, toAppend.$array, toAppend.$offset, toAppend.$length);\n};\n\nvar $internalAppend = function(slice, array, offset, length) {\n if (length === 0) {\n return slice;\n }\n\n var newArray = slice.$array;\n var newOffset = slice.$offset;\n var newLength = slice.$length + length;\n var newCapacity = slice.$capacity;\n\n if (newLength > newCapacity) {\n newOffset = 0;\n newCapacity = Math.max(newLength, slice.$capacity < 1024 ? slice.$capacity * 2 : Math.floor(slice.$capacity * 5 / 4));\n\n if (slice.$array.constructor === Array) {\n newArray = slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n newArray.length = newCapacity;\n var zero = slice.constructor.elem.zero;\n for (var i = slice.$length; i < newCapacity; i++) {\n newArray[i] = zero();\n }\n } else {\n newArray = new slice.$array.constructor(newCapacity);\n newArray.set(slice.$array.subarray(slice.$offset, slice.$offset + slice.$length));\n }\n }\n\n $copyArray(newArray, array, newOffset + slice.$length, offset, length, slice.constructor.elem);\n\n var newSlice = new slice.constructor(newArray);\n newSlice.$offset = newOffset;\n newSlice.$length = newLength;\n newSlice.$capacity = newCapacity;\n return newSlice;\n};\n\nvar $equal = function(a, b, type) {\n if (type === $jsObjectPtr) {\n return a === b;\n }\n switch (type.kind) {\n case $kindComplex64:\n case $kindComplex128:\n return a.$real === b.$real && a.$imag === b.$imag;\n case $kindInt64:\n case $kindUint64:\n return a.$high === b.$high && a.$low === b.$low;\n case $kindArray:\n if (a.length !== b.length) {\n return false;\n }\n for (var i = 0; i < a.length; i++) {\n if (!$equal(a[i], b[i], type.elem)) {\n return false;\n }\n }\n return true;\n case $kindStruct:\n for (var i = 0; i < type.fields.length; i++) {\n var f = type.fields[i];\n if (!$equal(a[f.prop], b[f.prop], f.typ)) {\n return false;\n }\n }\n return true;\n case $kindInterface:\n return $interfaceIsEqual(a, b);\n default:\n return a === b;\n }\n};\n\nvar $interfaceIsEqual = function(a, b) {\n if (a === $ifaceNil || b === $ifaceNil) {\n return a === b;\n }\n if (a.constructor !== b.constructor) {\n return false;\n }\n if (a.constructor === $jsObjectPtr) {\n return a.object === b.object;\n }\n if (!a.constructor.comparable) {\n $throwRuntimeError(\"comparing uncomparable type \" + a.constructor.string);\n }\n return $equal(a.$val, b.$val, a.constructor);\n};\nvar $min = Math.min;\nvar $mod = function(x, y) { return x % y; };\nvar $parseInt = parseInt;\nvar $parseFloat = function(f) {\n if (f !== undefined && f !== null && f.constructor === Number) {\n return f;\n }\n return parseFloat(f);\n};\n\nvar $froundBuf = new Float32Array(1);\nvar $fround = Math.fround || function(f) {\n $froundBuf[0] = f;\n return $froundBuf[0];\n};\n\nvar $imul = Math.imul || function(a, b) {\n var ah = (a >>> 16) & 0xffff;\n var al = a & 0xffff;\n var bh = (b >>> 16) & 0xffff;\n var bl = b & 0xffff;\n return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0) >> 0);\n};\n\nvar $floatKey = function(f) {\n if (f !== f) {\n $idCounter++;\n return \"NaN$\" + $idCounter;\n }\n return String(f);\n};\n\nvar $flatten64 = function(x) {\n return x.$high * 4294967296 + x.$low;\n};\n\nvar $shiftLeft64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high << y | x.$low >>> (32 - y), (x.$low << y) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$low << (y - 32), 0);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightInt64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >> y, (x.$low >>> y | x.$high << (32 - y)) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$high >> 31, (x.$high >> (y - 32)) >>> 0);\n }\n if (x.$high < 0) {\n return new x.constructor(-1, 4294967295);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightUint64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >>> y, (x.$low >>> y | x.$high << (32 - y)) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(0, x.$high >>> (y - 32));\n }\n return new x.constructor(0, 0);\n};\n\nvar $mul64 = function(x, y) {\n var high = 0, low = 0;\n if ((y.$low & 1) !== 0) {\n high = x.$high;\n low = x.$low;\n }\n for (var i = 1; i < 32; i++) {\n if ((y.$low & 1<>> (32 - i);\n low += (x.$low << i) >>> 0;\n }\n }\n for (var i = 0; i < 32; i++) {\n if ((y.$high & 1< yHigh) || (xHigh === yHigh && xLow > yLow))) {\n yHigh = (yHigh << 1 | yLow >>> 31) >>> 0;\n yLow = (yLow << 1) >>> 0;\n n++;\n }\n for (var i = 0; i <= n; i++) {\n high = high << 1 | low >>> 31;\n low = (low << 1) >>> 0;\n if ((xHigh > yHigh) || (xHigh === yHigh && xLow >= yLow)) {\n xHigh = xHigh - yHigh;\n xLow = xLow - yLow;\n if (xLow < 0) {\n xHigh--;\n xLow += 4294967296;\n }\n low++;\n if (low === 4294967296) {\n high++;\n low = 0;\n }\n }\n yLow = (yLow >>> 1 | yHigh << (32 - 1)) >>> 0;\n yHigh = yHigh >>> 1;\n }\n\n if (returnRemainder) {\n return new x.constructor(xHigh * rs, xLow * rs);\n }\n return new x.constructor(high * s, low * s);\n};\n\nvar $divComplex = function(n, d) {\n var ninf = n.$real === Infinity || n.$real === -Infinity || n.$imag === Infinity || n.$imag === -Infinity;\n var dinf = d.$real === Infinity || d.$real === -Infinity || d.$imag === Infinity || d.$imag === -Infinity;\n var nnan = !ninf && (n.$real !== n.$real || n.$imag !== n.$imag);\n var dnan = !dinf && (d.$real !== d.$real || d.$imag !== d.$imag);\n if(nnan || dnan) {\n return new n.constructor(NaN, NaN);\n }\n if (ninf && !dinf) {\n return new n.constructor(Infinity, Infinity);\n }\n if (!ninf && dinf) {\n return new n.constructor(0, 0);\n }\n if (d.$real === 0 && d.$imag === 0) {\n if (n.$real === 0 && n.$imag === 0) {\n return new n.constructor(NaN, NaN);\n }\n return new n.constructor(Infinity, Infinity);\n }\n var a = Math.abs(d.$real);\n var b = Math.abs(d.$imag);\n if (a <= b) {\n var ratio = d.$real / d.$imag;\n var denom = d.$real * ratio + d.$imag;\n return new n.constructor((n.$real * ratio + n.$imag) / denom, (n.$imag * ratio - n.$real) / denom);\n }\n var ratio = d.$imag / d.$real;\n var denom = d.$imag * ratio + d.$real;\n return new n.constructor((n.$imag * ratio + n.$real) / denom, (n.$imag - n.$real * ratio) / denom);\n};\nvar $kindBool = 1;\nvar $kindInt = 2;\nvar $kindInt8 = 3;\nvar $kindInt16 = 4;\nvar $kindInt32 = 5;\nvar $kindInt64 = 6;\nvar $kindUint = 7;\nvar $kindUint8 = 8;\nvar $kindUint16 = 9;\nvar $kindUint32 = 10;\nvar $kindUint64 = 11;\nvar $kindUintptr = 12;\nvar $kindFloat32 = 13;\nvar $kindFloat64 = 14;\nvar $kindComplex64 = 15;\nvar $kindComplex128 = 16;\nvar $kindArray = 17;\nvar $kindChan = 18;\nvar $kindFunc = 19;\nvar $kindInterface = 20;\nvar $kindMap = 21;\nvar $kindPtr = 22;\nvar $kindSlice = 23;\nvar $kindString = 24;\nvar $kindStruct = 25;\nvar $kindUnsafePointer = 26;\n\nvar $methodSynthesizers = [];\nvar $addMethodSynthesizer = function(f) {\n if ($methodSynthesizers === null) {\n f();\n return;\n }\n $methodSynthesizers.push(f);\n};\nvar $synthesizeMethods = function() {\n $methodSynthesizers.forEach(function(f) { f(); });\n $methodSynthesizers = null;\n};\n\nvar $ifaceKeyFor = function(x) {\n if (x === $ifaceNil) {\n return 'nil';\n }\n var c = x.constructor;\n return c.string + '$' + c.keyFor(x.$val);\n};\n\nvar $identity = function(x) { return x; };\n\nvar $typeIDCounter = 0;\n\nvar $idKey = function(x) {\n if (x.$id === undefined) {\n $idCounter++;\n x.$id = $idCounter;\n }\n return String(x.$id);\n};\n\nvar $newType = function(size, kind, string, named, pkg, exported, constructor) {\n var typ;\n switch(kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.keyFor = $identity;\n break;\n\n case $kindString:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.keyFor = function(x) { return \"$\" + x; };\n break;\n\n case $kindFloat32:\n case $kindFloat64:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.keyFor = function(x) { return $floatKey(x); };\n break;\n\n case $kindInt64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) { return x.$high + \"$\" + x.$low; };\n break;\n\n case $kindUint64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >>> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) { return x.$high + \"$\" + x.$low; };\n break;\n\n case $kindComplex64:\n typ = function(real, imag) {\n this.$real = $fround(real);\n this.$imag = $fround(imag);\n this.$val = this;\n };\n typ.keyFor = function(x) { return x.$real + \"$\" + x.$imag; };\n break;\n\n case $kindComplex128:\n typ = function(real, imag) {\n this.$real = real;\n this.$imag = imag;\n this.$val = this;\n };\n typ.keyFor = function(x) { return x.$real + \"$\" + x.$imag; };\n break;\n\n case $kindArray:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, \"\", false, function(array) {\n this.$get = function() { return array; };\n this.$set = function(v) { typ.copy(this, v); };\n this.$val = array;\n });\n typ.init = function(elem, len) {\n typ.elem = elem;\n typ.len = len;\n typ.comparable = elem.comparable;\n typ.keyFor = function(x) {\n return Array.prototype.join.call($mapArray(x, function(e) {\n return String(elem.keyFor(e)).replace(/\\\\/g, \"\\\\\\\\\").replace(/\\$/g, \"\\\\$\");\n }), \"$\");\n };\n typ.copy = function(dst, src) {\n $copyArray(dst, src, 0, 0, src.length, elem);\n };\n typ.ptr.init(typ);\n Object.defineProperty(typ.ptr.nil, \"nilCheck\", { get: $throwNilPointerError });\n };\n break;\n\n case $kindChan:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.keyFor = $idKey;\n typ.init = function(elem, sendOnly, recvOnly) {\n typ.elem = elem;\n typ.sendOnly = sendOnly;\n typ.recvOnly = recvOnly;\n };\n break;\n\n case $kindFunc:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.init = function(params, results, variadic) {\n typ.params = params;\n typ.results = results;\n typ.variadic = variadic;\n typ.comparable = false;\n };\n break;\n\n case $kindInterface:\n typ = { implementedBy: {}, missingMethodFor: {} };\n typ.keyFor = $ifaceKeyFor;\n typ.init = function(methods) {\n typ.methods = methods;\n methods.forEach(function(m) {\n $ifaceNil[m.prop] = $throwNilPointerError;\n });\n };\n break;\n\n case $kindMap:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.init = function(key, elem) {\n typ.key = key;\n typ.elem = elem;\n typ.comparable = false;\n };\n break;\n\n case $kindPtr:\n typ = constructor || function(getter, setter, target) {\n this.$get = getter;\n this.$set = setter;\n this.$target = target;\n this.$val = this;\n };\n typ.keyFor = $idKey;\n typ.init = function(elem) {\n typ.elem = elem;\n typ.wrapped = (elem.kind === $kindArray);\n typ.nil = new typ($throwNilPointerError, $throwNilPointerError);\n };\n break;\n\n case $kindSlice:\n typ = function(array) {\n if (array.constructor !== typ.nativeArray) {\n array = new typ.nativeArray(array);\n }\n this.$array = array;\n this.$offset = 0;\n this.$length = array.length;\n this.$capacity = array.length;\n this.$val = this;\n };\n typ.init = function(elem) {\n typ.elem = elem;\n typ.comparable = false;\n typ.nativeArray = $nativeArray(elem.kind);\n typ.nil = new typ([]);\n };\n break;\n\n case $kindStruct:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, pkg, exported, constructor);\n typ.ptr.elem = typ;\n typ.ptr.prototype.$get = function() { return this; };\n typ.ptr.prototype.$set = function(v) { typ.copy(this, v); };\n typ.init = function(pkgPath, fields) {\n typ.pkgPath = pkgPath;\n typ.fields = fields;\n fields.forEach(function(f) {\n if (!f.typ.comparable) {\n typ.comparable = false;\n }\n });\n typ.keyFor = function(x) {\n var val = x.$val;\n return $mapArray(fields, function(f) {\n return String(f.typ.keyFor(val[f.prop])).replace(/\\\\/g, \"\\\\\\\\\").replace(/\\$/g, \"\\\\$\");\n }).join(\"$\");\n };\n typ.copy = function(dst, src) {\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n switch (f.typ.kind) {\n case $kindArray:\n case $kindStruct:\n f.typ.copy(dst[f.prop], src[f.prop]);\n continue;\n default:\n dst[f.prop] = src[f.prop];\n continue;\n }\n }\n };\n /* nil value */\n var properties = {};\n fields.forEach(function(f) {\n properties[f.prop] = { get: $throwNilPointerError, set: $throwNilPointerError };\n });\n typ.ptr.nil = Object.create(constructor.prototype, properties);\n typ.ptr.nil.$val = typ.ptr.nil;\n /* methods for embedded fields */\n $addMethodSynthesizer(function() {\n var synthesizeMethod = function(target, m, f) {\n if (target.prototype[m.prop] !== undefined) { return; }\n target.prototype[m.prop] = function() {\n var v = this.$val[f.prop];\n if (f.typ === $jsObjectPtr) {\n v = new $jsObjectPtr(v);\n }\n if (v.$val === undefined) {\n v = new f.typ(v);\n }\n return v[m.prop].apply(v, arguments);\n };\n };\n fields.forEach(function(f) {\n if (f.anonymous) {\n $methodSet(f.typ).forEach(function(m) {\n synthesizeMethod(typ, m, f);\n synthesizeMethod(typ.ptr, m, f);\n });\n $methodSet($ptrType(f.typ)).forEach(function(m) {\n synthesizeMethod(typ.ptr, m, f);\n });\n }\n });\n });\n };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n switch (kind) {\n case $kindBool:\n case $kindMap:\n typ.zero = function() { return false; };\n break;\n\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8 :\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n case $kindFloat32:\n case $kindFloat64:\n typ.zero = function() { return 0; };\n break;\n\n case $kindString:\n typ.zero = function() { return \"\"; };\n break;\n\n case $kindInt64:\n case $kindUint64:\n case $kindComplex64:\n case $kindComplex128:\n var zero = new typ(0, 0);\n typ.zero = function() { return zero; };\n break;\n\n case $kindPtr:\n case $kindSlice:\n typ.zero = function() { return typ.nil; };\n break;\n\n case $kindChan:\n typ.zero = function() { return $chanNil; };\n break;\n\n case $kindFunc:\n typ.zero = function() { return $throwNilPointerError; };\n break;\n\n case $kindInterface:\n typ.zero = function() { return $ifaceNil; };\n break;\n\n case $kindArray:\n typ.zero = function() {\n var arrayClass = $nativeArray(typ.elem.kind);\n if (arrayClass !== Array) {\n return new arrayClass(typ.len);\n }\n var array = new Array(typ.len);\n for (var i = 0; i < typ.len; i++) {\n array[i] = typ.elem.zero();\n }\n return array;\n };\n break;\n\n case $kindStruct:\n typ.zero = function() { return new typ.ptr(); };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n typ.id = $typeIDCounter;\n $typeIDCounter++;\n typ.size = size;\n typ.kind = kind;\n typ.string = string;\n typ.named = named;\n typ.pkg = pkg;\n typ.exported = exported;\n typ.methods = [];\n typ.methodSetCache = null;\n typ.comparable = true;\n return typ;\n};\n\nvar $methodSet = function(typ) {\n if (typ.methodSetCache !== null) {\n return typ.methodSetCache;\n }\n var base = {};\n\n var isPtr = (typ.kind === $kindPtr);\n if (isPtr && typ.elem.kind === $kindInterface) {\n typ.methodSetCache = [];\n return [];\n }\n\n var current = [{typ: isPtr ? typ.elem : typ, indirect: isPtr}];\n\n var seen = {};\n\n while (current.length > 0) {\n var next = [];\n var mset = [];\n\n current.forEach(function(e) {\n if (seen[e.typ.string]) {\n return;\n }\n seen[e.typ.string] = true;\n\n if (e.typ.named) {\n mset = mset.concat(e.typ.methods);\n if (e.indirect) {\n mset = mset.concat($ptrType(e.typ).methods);\n }\n }\n\n switch (e.typ.kind) {\n case $kindStruct:\n e.typ.fields.forEach(function(f) {\n if (f.anonymous) {\n var fTyp = f.typ;\n var fIsPtr = (fTyp.kind === $kindPtr);\n next.push({typ: fIsPtr ? fTyp.elem : fTyp, indirect: e.indirect || fIsPtr});\n }\n });\n break;\n\n case $kindInterface:\n mset = mset.concat(e.typ.methods);\n break;\n }\n });\n\n mset.forEach(function(m) {\n if (base[m.name] === undefined) {\n base[m.name] = m;\n }\n });\n\n current = next;\n }\n\n typ.methodSetCache = [];\n Object.keys(base).sort().forEach(function(name) {\n typ.methodSetCache.push(base[name]);\n });\n return typ.methodSetCache;\n};\n\nvar $Bool = $newType( 1, $kindBool, \"bool\", true, \"\", false, null);\nvar $Int = $newType( 4, $kindInt, \"int\", true, \"\", false, null);\nvar $Int8 = $newType( 1, $kindInt8, \"int8\", true, \"\", false, null);\nvar $Int16 = $newType( 2, $kindInt16, \"int16\", true, \"\", false, null);\nvar $Int32 = $newType( 4, $kindInt32, \"int32\", true, \"\", false, null);\nvar $Int64 = $newType( 8, $kindInt64, \"int64\", true, \"\", false, null);\nvar $Uint = $newType( 4, $kindUint, \"uint\", true, \"\", false, null);\nvar $Uint8 = $newType( 1, $kindUint8, \"uint8\", true, \"\", false, null);\nvar $Uint16 = $newType( 2, $kindUint16, \"uint16\", true, \"\", false, null);\nvar $Uint32 = $newType( 4, $kindUint32, \"uint32\", true, \"\", false, null);\nvar $Uint64 = $newType( 8, $kindUint64, \"uint64\", true, \"\", false, null);\nvar $Uintptr = $newType( 4, $kindUintptr, \"uintptr\", true, \"\", false, null);\nvar $Float32 = $newType( 4, $kindFloat32, \"float32\", true, \"\", false, null);\nvar $Float64 = $newType( 8, $kindFloat64, \"float64\", true, \"\", false, null);\nvar $Complex64 = $newType( 8, $kindComplex64, \"complex64\", true, \"\", false, null);\nvar $Complex128 = $newType(16, $kindComplex128, \"complex128\", true, \"\", false, null);\nvar $String = $newType( 8, $kindString, \"string\", true, \"\", false, null);\nvar $UnsafePointer = $newType( 4, $kindUnsafePointer, \"unsafe.Pointer\", true, \"\", false, null);\n\nvar $nativeArray = function(elemKind) {\n switch (elemKind) {\n case $kindInt:\n return Int32Array;\n case $kindInt8:\n return Int8Array;\n case $kindInt16:\n return Int16Array;\n case $kindInt32:\n return Int32Array;\n case $kindUint:\n return Uint32Array;\n case $kindUint8:\n return Uint8Array;\n case $kindUint16:\n return Uint16Array;\n case $kindUint32:\n return Uint32Array;\n case $kindUintptr:\n return Uint32Array;\n case $kindFloat32:\n return Float32Array;\n case $kindFloat64:\n return Float64Array;\n default:\n return Array;\n }\n};\nvar $toNativeArray = function(elemKind, array) {\n var nativeArray = $nativeArray(elemKind);\n if (nativeArray === Array) {\n return array;\n }\n return new nativeArray(array);\n};\nvar $arrayTypes = {};\nvar $arrayType = function(elem, len) {\n var typeKey = elem.id + \"$\" + len;\n var typ = $arrayTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(12, $kindArray, \"[\" + len + \"]\" + elem.string, false, \"\", false, null);\n $arrayTypes[typeKey] = typ;\n typ.init(elem, len);\n }\n return typ;\n};\n\nvar $chanType = function(elem, sendOnly, recvOnly) {\n var string = (recvOnly ? \"<-\" : \"\") + \"chan\" + (sendOnly ? \"<- \" : \" \") + elem.string;\n var field = sendOnly ? \"SendChan\" : (recvOnly ? \"RecvChan\" : \"Chan\");\n var typ = elem[field];\n if (typ === undefined) {\n typ = $newType(4, $kindChan, string, false, \"\", false, null);\n elem[field] = typ;\n typ.init(elem, sendOnly, recvOnly);\n }\n return typ;\n};\nvar $Chan = function(elem, capacity) {\n if (capacity < 0 || capacity > 2147483647) {\n $throwRuntimeError(\"makechan: size out of range\");\n }\n this.$elem = elem;\n this.$capacity = capacity;\n this.$buffer = [];\n this.$sendQueue = [];\n this.$recvQueue = [];\n this.$closed = false;\n};\nvar $chanNil = new $Chan(null, 0);\n$chanNil.$sendQueue = $chanNil.$recvQueue = { length: 0, push: function() {}, shift: function() { return undefined; }, indexOf: function() { return -1; } };\n\nvar $funcTypes = {};\nvar $funcType = function(params, results, variadic) {\n var typeKey = $mapArray(params, function(p) { return p.id; }).join(\",\") + \"$\" + $mapArray(results, function(r) { return r.id; }).join(\",\") + \"$\" + variadic;\n var typ = $funcTypes[typeKey];\n if (typ === undefined) {\n var paramTypes = $mapArray(params, function(p) { return p.string; });\n if (variadic) {\n paramTypes[paramTypes.length - 1] = \"...\" + paramTypes[paramTypes.length - 1].substr(2);\n }\n var string = \"func(\" + paramTypes.join(\", \") + \")\";\n if (results.length === 1) {\n string += \" \" + results[0].string;\n } else if (results.length > 1) {\n string += \" (\" + $mapArray(results, function(r) { return r.string; }).join(\", \") + \")\";\n }\n typ = $newType(4, $kindFunc, string, false, \"\", false, null);\n $funcTypes[typeKey] = typ;\n typ.init(params, results, variadic);\n }\n return typ;\n};\n\nvar $interfaceTypes = {};\nvar $interfaceType = function(methods) {\n var typeKey = $mapArray(methods, function(m) { return m.pkg + \",\" + m.name + \",\" + m.typ.id; }).join(\"$\");\n var typ = $interfaceTypes[typeKey];\n if (typ === undefined) {\n var string = \"interface {}\";\n if (methods.length !== 0) {\n string = \"interface { \" + $mapArray(methods, function(m) {\n return (m.pkg !== \"\" ? m.pkg + \".\" : \"\") + m.name + m.typ.string.substr(4);\n }).join(\"; \") + \" }\";\n }\n typ = $newType(8, $kindInterface, string, false, \"\", false, null);\n $interfaceTypes[typeKey] = typ;\n typ.init(methods);\n }\n return typ;\n};\nvar $emptyInterface = $interfaceType([]);\nvar $ifaceNil = {};\nvar $error = $newType(8, $kindInterface, \"error\", true, \"\", false, null);\n$error.init([{prop: \"Error\", name: \"Error\", pkg: \"\", typ: $funcType([], [$String], false)}]);\n\nvar $mapTypes = {};\nvar $mapType = function(key, elem) {\n var typeKey = key.id + \"$\" + elem.id;\n var typ = $mapTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(4, $kindMap, \"map[\" + key.string + \"]\" + elem.string, false, \"\", false, null);\n $mapTypes[typeKey] = typ;\n typ.init(key, elem);\n }\n return typ;\n};\nvar $makeMap = function(keyForFunc, entries) {\n var m = {};\n for (var i = 0; i < entries.length; i++) {\n var e = entries[i];\n m[keyForFunc(e.k)] = e;\n }\n return m;\n};\n\nvar $ptrType = function(elem) {\n var typ = elem.ptr;\n if (typ === undefined) {\n typ = $newType(4, $kindPtr, \"*\" + elem.string, false, \"\", elem.exported, null);\n elem.ptr = typ;\n typ.init(elem);\n }\n return typ;\n};\n\nvar $newDataPointer = function(data, constructor) {\n if (constructor.elem.kind === $kindStruct) {\n return data;\n }\n return new constructor(function() { return data; }, function(v) { data = v; });\n};\n\nvar $indexPtr = function(array, index, constructor) {\n array.$ptr = array.$ptr || {};\n return array.$ptr[index] || (array.$ptr[index] = new constructor(function() { return array[index]; }, function(v) { array[index] = v; }));\n};\n\nvar $sliceType = function(elem) {\n var typ = elem.slice;\n if (typ === undefined) {\n typ = $newType(12, $kindSlice, \"[]\" + elem.string, false, \"\", false, null);\n elem.slice = typ;\n typ.init(elem);\n }\n return typ;\n};\nvar $makeSlice = function(typ, length, capacity) {\n capacity = capacity || length;\n if (length < 0 || length > 2147483647) {\n $throwRuntimeError(\"makeslice: len out of range\");\n }\n if (capacity < 0 || capacity < length || capacity > 2147483647) {\n $throwRuntimeError(\"makeslice: cap out of range\");\n }\n var array = new typ.nativeArray(capacity);\n if (typ.nativeArray === Array) {\n for (var i = 0; i < capacity; i++) {\n array[i] = typ.elem.zero();\n }\n }\n var slice = new typ(array);\n slice.$length = length;\n return slice;\n};\n\nvar $structTypes = {};\nvar $structType = function(pkgPath, fields) {\n var typeKey = $mapArray(fields, function(f) { return f.name + \",\" + f.typ.id + \",\" + f.tag; }).join(\"$\");\n var typ = $structTypes[typeKey];\n if (typ === undefined) {\n var string = \"struct { \" + $mapArray(fields, function(f) {\n return f.name + \" \" + f.typ.string + (f.tag !== \"\" ? (\" \\\"\" + f.tag.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, \"\\\\\\\"\") + \"\\\"\") : \"\");\n }).join(\"; \") + \" }\";\n if (fields.length === 0) {\n string = \"struct {}\";\n }\n typ = $newType(0, $kindStruct, string, false, \"\", false, function() {\n this.$val = this;\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n var arg = arguments[i];\n this[f.prop] = arg !== undefined ? arg : f.typ.zero();\n }\n });\n $structTypes[typeKey] = typ;\n typ.init(pkgPath, fields);\n }\n return typ;\n};\n\nvar $assertType = function(value, type, returnTuple) {\n var isInterface = (type.kind === $kindInterface), ok, missingMethod = \"\";\n if (value === $ifaceNil) {\n ok = false;\n } else if (!isInterface) {\n ok = value.constructor === type;\n } else {\n var valueTypeString = value.constructor.string;\n ok = type.implementedBy[valueTypeString];\n if (ok === undefined) {\n ok = true;\n var valueMethodSet = $methodSet(value.constructor);\n var interfaceMethods = type.methods;\n for (var i = 0; i < interfaceMethods.length; i++) {\n var tm = interfaceMethods[i];\n var found = false;\n for (var j = 0; j < valueMethodSet.length; j++) {\n var vm = valueMethodSet[j];\n if (vm.name === tm.name && vm.pkg === tm.pkg && vm.typ === tm.typ) {\n found = true;\n break;\n }\n }\n if (!found) {\n ok = false;\n type.missingMethodFor[valueTypeString] = tm.name;\n break;\n }\n }\n type.implementedBy[valueTypeString] = ok;\n }\n if (!ok) {\n missingMethod = type.missingMethodFor[valueTypeString];\n }\n }\n\n if (!ok) {\n if (returnTuple) {\n return [type.zero(), false];\n }\n $panic(new $packages[\"runtime\"].TypeAssertionError.ptr(\"\", (value === $ifaceNil ? \"\" : value.constructor.string), type.string, missingMethod));\n }\n\n if (!isInterface) {\n value = value.$val;\n }\n if (type === $jsObjectPtr) {\n value = value.object;\n }\n return returnTuple ? [value, true] : value;\n};\nvar $stackDepthOffset = 0;\nvar $getStackDepth = function() {\n var err = new Error();\n if (err.stack === undefined) {\n return undefined;\n }\n return $stackDepthOffset + err.stack.split(\"\\n\").length;\n};\n\nvar $panicStackDepth = null, $panicValue;\nvar $callDeferred = function(deferred, jsErr, fromPanic) {\n if (!fromPanic && deferred !== null && deferred.index >= $curGoroutine.deferStack.length) {\n throw jsErr;\n }\n if (jsErr !== null) {\n var newErr = null;\n try {\n $curGoroutine.deferStack.push(deferred);\n $panic(new $jsErrorPtr(jsErr));\n } catch (err) {\n newErr = err;\n }\n $curGoroutine.deferStack.pop();\n $callDeferred(deferred, newErr);\n return;\n }\n if ($curGoroutine.asleep) {\n return;\n }\n\n $stackDepthOffset--;\n var outerPanicStackDepth = $panicStackDepth;\n var outerPanicValue = $panicValue;\n\n var localPanicValue = $curGoroutine.panicStack.pop();\n if (localPanicValue !== undefined) {\n $panicStackDepth = $getStackDepth();\n $panicValue = localPanicValue;\n }\n\n try {\n while (true) {\n if (deferred === null) {\n deferred = $curGoroutine.deferStack[$curGoroutine.deferStack.length - 1];\n if (deferred === undefined) {\n /* The panic reached the top of the stack. Clear it and throw it as a JavaScript error. */\n $panicStackDepth = null;\n if (localPanicValue.Object instanceof Error) {\n throw localPanicValue.Object;\n }\n var msg;\n if (localPanicValue.constructor === $String) {\n msg = localPanicValue.$val;\n } else if (localPanicValue.Error !== undefined) {\n msg = localPanicValue.Error();\n } else if (localPanicValue.String !== undefined) {\n msg = localPanicValue.String();\n } else {\n msg = localPanicValue;\n }\n throw new Error(msg);\n }\n }\n var call = deferred.pop();\n if (call === undefined) {\n $curGoroutine.deferStack.pop();\n if (localPanicValue !== undefined) {\n deferred = null;\n continue;\n }\n return;\n }\n var r = call[0].apply(call[2], call[1]);\n if (r && r.$blk !== undefined) {\n deferred.push([r.$blk, [], r]);\n if (fromPanic) {\n throw null;\n }\n return;\n }\n\n if (localPanicValue !== undefined && $panicStackDepth === null) {\n throw null; /* error was recovered */\n }\n }\n } finally {\n if (localPanicValue !== undefined) {\n if ($panicStackDepth !== null) {\n $curGoroutine.panicStack.push(localPanicValue);\n }\n $panicStackDepth = outerPanicStackDepth;\n $panicValue = outerPanicValue;\n }\n $stackDepthOffset++;\n }\n};\n\nvar $panic = function(value) {\n $curGoroutine.panicStack.push(value);\n $callDeferred(null, null, true);\n};\nvar $recover = function() {\n if ($panicStackDepth === null || ($panicStackDepth !== undefined && $panicStackDepth !== $getStackDepth() - 2)) {\n return $ifaceNil;\n }\n $panicStackDepth = null;\n return $panicValue;\n};\nvar $throw = function(err) { throw err; };\n\nvar $noGoroutine = { asleep: false, exit: false, deferStack: [], panicStack: [] };\nvar $curGoroutine = $noGoroutine, $totalGoroutines = 0, $awakeGoroutines = 0, $checkForDeadlock = true;\nvar $mainFinished = false;\nvar $go = function(fun, args) {\n $totalGoroutines++;\n $awakeGoroutines++;\n var $goroutine = function() {\n try {\n $curGoroutine = $goroutine;\n var r = fun.apply(undefined, args);\n if (r && r.$blk !== undefined) {\n fun = function() { return r.$blk(); };\n args = [];\n return;\n }\n $goroutine.exit = true;\n } catch (err) {\n if (!$goroutine.exit) {\n throw err;\n }\n } finally {\n $curGoroutine = $noGoroutine;\n if ($goroutine.exit) { /* also set by runtime.Goexit() */\n $totalGoroutines--;\n $goroutine.asleep = true;\n }\n if ($goroutine.asleep) {\n $awakeGoroutines--;\n if (!$mainFinished && $awakeGoroutines === 0 && $checkForDeadlock) {\n console.error(\"fatal error: all goroutines are asleep - deadlock!\");\n if ($global.process !== undefined) {\n $global.process.exit(2);\n }\n }\n }\n }\n };\n $goroutine.asleep = false;\n $goroutine.exit = false;\n $goroutine.deferStack = [];\n $goroutine.panicStack = [];\n $schedule($goroutine);\n};\n\nvar $scheduled = [];\nvar $runScheduled = function() {\n try {\n var r;\n while ((r = $scheduled.shift()) !== undefined) {\n r();\n }\n } finally {\n if ($scheduled.length > 0) {\n setTimeout($runScheduled, 0);\n }\n }\n};\n\nvar $schedule = function(goroutine) {\n if (goroutine.asleep) {\n goroutine.asleep = false;\n $awakeGoroutines++;\n }\n $scheduled.push(goroutine);\n if ($curGoroutine === $noGoroutine) {\n $runScheduled();\n }\n};\n\nvar $setTimeout = function(f, t) {\n $awakeGoroutines++;\n return setTimeout(function() {\n $awakeGoroutines--;\n f();\n }, t);\n};\n\nvar $block = function() {\n if ($curGoroutine === $noGoroutine) {\n $throwRuntimeError(\"cannot block in JavaScript callback, fix by wrapping code in goroutine\");\n }\n $curGoroutine.asleep = true;\n};\n\nvar $send = function(chan, value) {\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv !== undefined) {\n queuedRecv([value, true]);\n return;\n }\n if (chan.$buffer.length < chan.$capacity) {\n chan.$buffer.push(value);\n return;\n }\n\n var thisGoroutine = $curGoroutine;\n var closedDuringSend;\n chan.$sendQueue.push(function(closed) {\n closedDuringSend = closed;\n $schedule(thisGoroutine);\n return value;\n });\n $block();\n return {\n $blk: function() {\n if (closedDuringSend) {\n $throwRuntimeError(\"send on closed channel\");\n }\n }\n };\n};\nvar $recv = function(chan) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend !== undefined) {\n chan.$buffer.push(queuedSend(false));\n }\n var bufferedValue = chan.$buffer.shift();\n if (bufferedValue !== undefined) {\n return [bufferedValue, true];\n }\n if (chan.$closed) {\n return [chan.$elem.zero(), false];\n }\n\n var thisGoroutine = $curGoroutine;\n var f = { $blk: function() { return this.value; } };\n var queueEntry = function(v) {\n f.value = v;\n $schedule(thisGoroutine);\n };\n chan.$recvQueue.push(queueEntry);\n $block();\n return f;\n};\nvar $close = function(chan) {\n if (chan.$closed) {\n $throwRuntimeError(\"close of closed channel\");\n }\n chan.$closed = true;\n while (true) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend === undefined) {\n break;\n }\n queuedSend(true); /* will panic */\n }\n while (true) {\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv === undefined) {\n break;\n }\n queuedRecv([chan.$elem.zero(), false]);\n }\n};\nvar $select = function(comms) {\n var ready = [];\n var selection = -1;\n for (var i = 0; i < comms.length; i++) {\n var comm = comms[i];\n var chan = comm[0];\n switch (comm.length) {\n case 0: /* default */\n selection = i;\n break;\n case 1: /* recv */\n if (chan.$sendQueue.length !== 0 || chan.$buffer.length !== 0 || chan.$closed) {\n ready.push(i);\n }\n break;\n case 2: /* send */\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n if (chan.$recvQueue.length !== 0 || chan.$buffer.length < chan.$capacity) {\n ready.push(i);\n }\n break;\n }\n }\n\n if (ready.length !== 0) {\n selection = ready[Math.floor(Math.random() * ready.length)];\n }\n if (selection !== -1) {\n var comm = comms[selection];\n switch (comm.length) {\n case 0: /* default */\n return [selection];\n case 1: /* recv */\n return [selection, $recv(comm[0])];\n case 2: /* send */\n $send(comm[0], comm[1]);\n return [selection];\n }\n }\n\n var entries = [];\n var thisGoroutine = $curGoroutine;\n var f = { $blk: function() { return this.selection; } };\n var removeFromQueues = function() {\n for (var i = 0; i < entries.length; i++) {\n var entry = entries[i];\n var queue = entry[0];\n var index = queue.indexOf(entry[1]);\n if (index !== -1) {\n queue.splice(index, 1);\n }\n }\n };\n for (var i = 0; i < comms.length; i++) {\n (function(i) {\n var comm = comms[i];\n switch (comm.length) {\n case 1: /* recv */\n var queueEntry = function(value) {\n f.selection = [i, value];\n removeFromQueues();\n $schedule(thisGoroutine);\n };\n entries.push([comm[0].$recvQueue, queueEntry]);\n comm[0].$recvQueue.push(queueEntry);\n break;\n case 2: /* send */\n var queueEntry = function() {\n if (comm[0].$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n f.selection = [i];\n removeFromQueues();\n $schedule(thisGoroutine);\n return comm[1];\n };\n entries.push([comm[0].$sendQueue, queueEntry]);\n comm[0].$sendQueue.push(queueEntry);\n break;\n }\n })(i);\n }\n $block();\n return f;\n};\nvar $jsObjectPtr, $jsErrorPtr;\n\nvar $needsExternalization = function(t) {\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return false;\n default:\n return t !== $jsObjectPtr;\n }\n};\n\nvar $externalize = function(v, t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return v;\n case $kindInt64:\n case $kindUint64:\n return $flatten64(v);\n case $kindArray:\n if ($needsExternalization(t.elem)) {\n return $mapArray(v, function(e) { return $externalize(e, t.elem); });\n }\n return v;\n case $kindFunc:\n return $externalizeFunction(v, t, false);\n case $kindInterface:\n if (v === $ifaceNil) {\n return null;\n }\n if (v.constructor === $jsObjectPtr) {\n return v.$val.object;\n }\n return $externalize(v.$val, v.constructor);\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var entry = v[keys[i]];\n m[$externalize(entry.k, t.key)] = $externalize(entry.v, t.elem);\n }\n return m;\n case $kindPtr:\n if (v === t.nil) {\n return null;\n }\n return $externalize(v.$get(), t.elem);\n case $kindSlice:\n if ($needsExternalization(t.elem)) {\n return $mapArray($sliceToArray(v), function(e) { return $externalize(e, t.elem); });\n }\n return $sliceToArray(v);\n case $kindString:\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\", r;\n for (var i = 0; i < v.length; i += r[1]) {\n r = $decodeRune(v, i);\n var c = r[0];\n if (c > 0xFFFF) {\n var h = Math.floor((c - 0x10000) / 0x400) + 0xD800;\n var l = (c - 0x10000) % 0x400 + 0xDC00;\n s += String.fromCharCode(h, l);\n continue;\n }\n s += String.fromCharCode(c);\n }\n return s;\n case $kindStruct:\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && v.constructor === timePkg.Time.ptr) {\n var milli = $div64(v.UnixNano(), new $Int64(0, 1000000));\n return new Date($flatten64(milli));\n }\n\n var noJsObject = {};\n var searchJsObject = function(v, t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindPtr:\n if (v === t.nil) {\n return noJsObject;\n }\n return searchJsObject(v.$get(), t.elem);\n case $kindStruct:\n var f = t.fields[0];\n return searchJsObject(v[f.prop], f.typ);\n case $kindInterface:\n return searchJsObject(v.$val, v.constructor);\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(v, t);\n if (o !== noJsObject) {\n return o;\n }\n\n o = {};\n for (var i = 0; i < t.fields.length; i++) {\n var f = t.fields[i];\n if (!f.exported) {\n continue;\n }\n o[f.name] = $externalize(v[f.prop], f.typ);\n }\n return o;\n }\n $throwRuntimeError(\"cannot externalize \" + t.string);\n};\n\nvar $externalizeFunction = function(v, t, passThis) {\n if (v === $throwNilPointerError) {\n return null;\n }\n if (v.$externalizeWrapper === undefined) {\n $checkForDeadlock = false;\n v.$externalizeWrapper = function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem, varargs = [];\n for (var j = i; j < arguments.length; j++) {\n varargs.push($internalize(arguments[j], vt));\n }\n args.push(new (t.params[i])(varargs));\n break;\n }\n args.push($internalize(arguments[i], t.params[i]));\n }\n var result = v.apply(passThis ? this : undefined, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $externalize(result, t.results[0]);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $externalize(result[i], t.results[i]);\n }\n return result;\n }\n };\n }\n return v.$externalizeWrapper;\n};\n\nvar $internalize = function(v, t, recv) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n if (v && v.__internal_object__ !== undefined) {\n return $assertType(v.__internal_object__, t, false);\n }\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && t === timePkg.Time) {\n if (!(v !== null && v !== undefined && v.constructor === Date)) {\n $throwRuntimeError(\"cannot internalize time.Time from \" + typeof v + \", must be Date\");\n }\n return timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000));\n }\n switch (t.kind) {\n case $kindBool:\n return !!v;\n case $kindInt:\n return parseInt(v);\n case $kindInt8:\n return parseInt(v) << 24 >> 24;\n case $kindInt16:\n return parseInt(v) << 16 >> 16;\n case $kindInt32:\n return parseInt(v) >> 0;\n case $kindUint:\n return parseInt(v);\n case $kindUint8:\n return parseInt(v) << 24 >>> 24;\n case $kindUint16:\n return parseInt(v) << 16 >>> 16;\n case $kindUint32:\n case $kindUintptr:\n return parseInt(v) >>> 0;\n case $kindInt64:\n case $kindUint64:\n return new t(0, v);\n case $kindFloat32:\n case $kindFloat64:\n return parseFloat(v);\n case $kindArray:\n if (v.length !== t.len) {\n $throwRuntimeError(\"got array with wrong size from JavaScript native\");\n }\n return $mapArray(v, function(e) { return $internalize(e, t.elem); });\n case $kindFunc:\n return function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem, varargs = arguments[i];\n for (var j = 0; j < varargs.$length; j++) {\n args.push($externalize(varargs.$array[varargs.$offset + j], vt));\n }\n break;\n }\n args.push($externalize(arguments[i], t.params[i]));\n }\n var result = v.apply(recv, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $internalize(result, t.results[0]);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $internalize(result[i], t.results[i]);\n }\n return result;\n }\n };\n case $kindInterface:\n if (t.methods.length !== 0) {\n $throwRuntimeError(\"cannot internalize \" + t.string);\n }\n if (v === null) {\n return $ifaceNil;\n }\n if (v === undefined) {\n return new $jsObjectPtr(undefined);\n }\n switch (v.constructor) {\n case Int8Array:\n return new ($sliceType($Int8))(v);\n case Int16Array:\n return new ($sliceType($Int16))(v);\n case Int32Array:\n return new ($sliceType($Int))(v);\n case Uint8Array:\n return new ($sliceType($Uint8))(v);\n case Uint16Array:\n return new ($sliceType($Uint16))(v);\n case Uint32Array:\n return new ($sliceType($Uint))(v);\n case Float32Array:\n return new ($sliceType($Float32))(v);\n case Float64Array:\n return new ($sliceType($Float64))(v);\n case Array:\n return $internalize(v, $sliceType($emptyInterface));\n case Boolean:\n return new $Bool(!!v);\n case Date:\n if (timePkg === undefined) {\n /* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */\n return new $jsObjectPtr(v);\n }\n return new timePkg.Time($internalize(v, timePkg.Time));\n case Function:\n var funcType = $funcType([$sliceType($emptyInterface)], [$jsObjectPtr], true);\n return new funcType($internalize(v, funcType));\n case Number:\n return new $Float64(parseFloat(v));\n case String:\n return new $String($internalize(v, $String));\n default:\n if ($global.Node && v instanceof $global.Node) {\n return new $jsObjectPtr(v);\n }\n var mapType = $mapType($String, $emptyInterface);\n return new mapType($internalize(v, mapType));\n }\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var k = $internalize(keys[i], t.key);\n m[t.key.keyFor(k)] = { k: k, v: $internalize(v[keys[i]], t.elem) };\n }\n return m;\n case $kindPtr:\n if (t.elem.kind === $kindStruct) {\n return $internalize(v, t.elem);\n }\n case $kindSlice:\n return new t($mapArray(v, function(e) { return $internalize(e, t.elem); }));\n case $kindString:\n v = String(v);\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\";\n var i = 0;\n while (i < v.length) {\n var h = v.charCodeAt(i);\n if (0xD800 <= h && h <= 0xDBFF) {\n var l = v.charCodeAt(i + 1);\n var c = (h - 0xD800) * 0x400 + l - 0xDC00 + 0x10000;\n s += $encodeRune(c);\n i += 2;\n continue;\n }\n s += $encodeRune(h);\n i++;\n }\n return s;\n case $kindStruct:\n var noJsObject = {};\n var searchJsObject = function(t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n switch (t.kind) {\n case $kindPtr:\n return searchJsObject(t.elem);\n case $kindStruct:\n var f = t.fields[0];\n var o = searchJsObject(f.typ);\n if (o !== noJsObject) {\n var n = new t.ptr();\n n[f.prop] = o;\n return n;\n }\n return noJsObject;\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(t);\n if (o !== noJsObject) {\n return o;\n }\n }\n $throwRuntimeError(\"cannot internalize \" + t.string);\n};\n\n/* $isASCII reports whether string s contains only ASCII characters. */\nvar $isASCII = function(s) {\n for (var i = 0; i < s.length; i++) {\n if (s.charCodeAt(i) >= 128) {\n return false;\n }\n }\n return true;\n};\n" diff --git a/compiler/prelude/prelude.js b/compiler/prelude/prelude.js new file mode 100644 index 000000000..58ad4e0d3 --- /dev/null +++ b/compiler/prelude/prelude.js @@ -0,0 +1,414 @@ +Error.stackTraceLimit = Infinity; + +var $global, $module; +if (typeof window !== "undefined") { /* web page */ + $global = window; +} else if (typeof self !== "undefined") { /* web worker */ + $global = self; +} else if (typeof global !== "undefined") { /* Node.js */ + $global = global; + $global.require = require; +} else { /* others (e.g. Nashorn) */ + $global = this; +} + +if ($global === undefined || $global.Array === undefined) { + throw new Error("no global object found"); +} +if (typeof module !== "undefined") { + $module = module; +} + +var $packages = {}, $idCounter = 0; +var $keys = function(m) { return m ? Object.keys(m) : []; }; +var $flushConsole = function() {}; +var $throwRuntimeError; /* set by package "runtime" */ +var $throwNilPointerError = function() { $throwRuntimeError("invalid memory address or nil pointer dereference"); }; +var $call = function(fn, rcvr, args) { return fn.apply(rcvr, args); }; +var $makeFunc = function(fn) { return function() { return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface); }; }; +var $unused = function(v) {}; + +var $mapArray = function(array, f) { + var newArray = new array.constructor(array.length); + for (var i = 0; i < array.length; i++) { + newArray[i] = f(array[i]); + } + return newArray; +}; + +var $methodVal = function(recv, name) { + var vals = recv.$methodVals || {}; + recv.$methodVals = vals; /* noop for primitives */ + var f = vals[name]; + if (f !== undefined) { + return f; + } + var method = recv[name]; + f = function() { + $stackDepthOffset--; + try { + return method.apply(recv, arguments); + } finally { + $stackDepthOffset++; + } + }; + vals[name] = f; + return f; +}; + +var $methodExpr = function(typ, name) { + var method = typ.prototype[name]; + if (method.$expr === undefined) { + method.$expr = function() { + $stackDepthOffset--; + try { + if (typ.wrapped) { + arguments[0] = new typ(arguments[0]); + } + return Function.call.apply(method, arguments); + } finally { + $stackDepthOffset++; + } + }; + } + return method.$expr; +}; + +var $ifaceMethodExprs = {}; +var $ifaceMethodExpr = function(name) { + var expr = $ifaceMethodExprs["$" + name]; + if (expr === undefined) { + expr = $ifaceMethodExprs["$" + name] = function() { + $stackDepthOffset--; + try { + return Function.call.apply(arguments[0][name], arguments); + } finally { + $stackDepthOffset++; + } + }; + } + return expr; +}; + +var $subslice = function(slice, low, high, max) { + if (high === undefined) { + high = slice.$length; + } + if (max === undefined) { + max = slice.$capacity; + } + if (low < 0 || high < low || max < high || high > slice.$capacity || max > slice.$capacity) { + $throwRuntimeError("slice bounds out of range"); + } + var s = new slice.constructor(slice.$array); + s.$offset = slice.$offset + low; + s.$length = high - low; + s.$capacity = max - low; + return s; +}; + +var $substring = function(str, low, high) { + if (low < 0 || high < low || high > str.length) { + $throwRuntimeError("slice bounds out of range"); + } + return str.substring(low, high); +}; + +var $sliceToArray = function(slice) { + if (slice.$array.constructor !== Array) { + return slice.$array.subarray(slice.$offset, slice.$offset + slice.$length); + } + return slice.$array.slice(slice.$offset, slice.$offset + slice.$length); +}; + +var $decodeRune = function(str, pos) { + var c0 = str.charCodeAt(pos); + + if (c0 < 0x80) { + return [c0, 1]; + } + + if (c0 !== c0 || c0 < 0xC0) { + return [0xFFFD, 1]; + } + + var c1 = str.charCodeAt(pos + 1); + if (c1 !== c1 || c1 < 0x80 || 0xC0 <= c1) { + return [0xFFFD, 1]; + } + + if (c0 < 0xE0) { + var r = (c0 & 0x1F) << 6 | (c1 & 0x3F); + if (r <= 0x7F) { + return [0xFFFD, 1]; + } + return [r, 2]; + } + + var c2 = str.charCodeAt(pos + 2); + if (c2 !== c2 || c2 < 0x80 || 0xC0 <= c2) { + return [0xFFFD, 1]; + } + + if (c0 < 0xF0) { + var r = (c0 & 0x0F) << 12 | (c1 & 0x3F) << 6 | (c2 & 0x3F); + if (r <= 0x7FF) { + return [0xFFFD, 1]; + } + if (0xD800 <= r && r <= 0xDFFF) { + return [0xFFFD, 1]; + } + return [r, 3]; + } + + var c3 = str.charCodeAt(pos + 3); + if (c3 !== c3 || c3 < 0x80 || 0xC0 <= c3) { + return [0xFFFD, 1]; + } + + if (c0 < 0xF8) { + var r = (c0 & 0x07) << 18 | (c1 & 0x3F) << 12 | (c2 & 0x3F) << 6 | (c3 & 0x3F); + if (r <= 0xFFFF || 0x10FFFF < r) { + return [0xFFFD, 1]; + } + return [r, 4]; + } + + return [0xFFFD, 1]; +}; + +var $encodeRune = function(r) { + if (r < 0 || r > 0x10FFFF || (0xD800 <= r && r <= 0xDFFF)) { + r = 0xFFFD; + } + if (r <= 0x7F) { + return String.fromCharCode(r); + } + if (r <= 0x7FF) { + return String.fromCharCode(0xC0 | r >> 6, 0x80 | (r & 0x3F)); + } + if (r <= 0xFFFF) { + return String.fromCharCode(0xE0 | r >> 12, 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F)); + } + return String.fromCharCode(0xF0 | r >> 18, 0x80 | (r >> 12 & 0x3F), 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F)); +}; + +var $stringToBytes = function(str) { + var array = new Uint8Array(str.length); + for (var i = 0; i < str.length; i++) { + array[i] = str.charCodeAt(i); + } + return array; +}; + +var $bytesToString = function(slice) { + if (slice.$length === 0) { + return ""; + } + var str = ""; + for (var i = 0; i < slice.$length; i += 10000) { + str += String.fromCharCode.apply(undefined, slice.$array.subarray(slice.$offset + i, slice.$offset + Math.min(slice.$length, i + 10000))); + } + return str; +}; + +var $stringToRunes = function(str) { + var array = new Int32Array(str.length); + var rune, j = 0; + for (var i = 0; i < str.length; i += rune[1], j++) { + rune = $decodeRune(str, i); + array[j] = rune[0]; + } + return array.subarray(0, j); +}; + +var $runesToString = function(slice) { + if (slice.$length === 0) { + return ""; + } + var str = ""; + for (var i = 0; i < slice.$length; i++) { + str += $encodeRune(slice.$array[slice.$offset + i]); + } + return str; +}; + +var $copyString = function(dst, src) { + var n = Math.min(src.length, dst.$length); + for (var i = 0; i < n; i++) { + dst.$array[dst.$offset + i] = src.charCodeAt(i); + } + return n; +}; + +var $copySlice = function(dst, src) { + var n = Math.min(src.$length, dst.$length); + $copyArray(dst.$array, src.$array, dst.$offset, src.$offset, n, dst.constructor.elem); + return n; +}; + +var $copyArray = function(dst, src, dstOffset, srcOffset, n, elem) { + if (n === 0 || (dst === src && dstOffset === srcOffset)) { + return; + } + + if (src.subarray) { + dst.set(src.subarray(srcOffset, srcOffset + n), dstOffset); + return; + } + + switch (elem.kind) { + case $kindArray: + case $kindStruct: + if (dst === src && dstOffset > srcOffset) { + for (var i = n - 1; i >= 0; i--) { + elem.copy(dst[dstOffset + i], src[srcOffset + i]); + } + return; + } + for (var i = 0; i < n; i++) { + elem.copy(dst[dstOffset + i], src[srcOffset + i]); + } + return; + } + + if (dst === src && dstOffset > srcOffset) { + for (var i = n - 1; i >= 0; i--) { + dst[dstOffset + i] = src[srcOffset + i]; + } + return; + } + for (var i = 0; i < n; i++) { + dst[dstOffset + i] = src[srcOffset + i]; + } +}; + +var $clone = function(src, type) { + var clone = type.zero(); + type.copy(clone, src); + return clone; +}; + +var $pointerOfStructConversion = function(obj, type) { + if(obj.$proxies === undefined) { + obj.$proxies = {}; + obj.$proxies[obj.constructor.string] = obj; + } + var proxy = obj.$proxies[type.string]; + if (proxy === undefined) { + var properties = {}; + for (var i = 0; i < type.elem.fields.length; i++) { + (function(fieldProp) { + properties[fieldProp] = { + get: function() { return obj[fieldProp]; }, + set: function(value) { obj[fieldProp] = value; } + }; + })(type.elem.fields[i].prop); + } + proxy = Object.create(type.prototype, properties); + proxy.$val = proxy; + obj.$proxies[type.string] = proxy; + proxy.$proxies = obj.$proxies; + } + return proxy; +}; + +var $append = function(slice) { + return $internalAppend(slice, arguments, 1, arguments.length - 1); +}; + +var $appendSlice = function(slice, toAppend) { + if (toAppend.constructor === String) { + var bytes = $stringToBytes(toAppend); + return $internalAppend(slice, bytes, 0, bytes.length); + } + return $internalAppend(slice, toAppend.$array, toAppend.$offset, toAppend.$length); +}; + +var $internalAppend = function(slice, array, offset, length) { + if (length === 0) { + return slice; + } + + var newArray = slice.$array; + var newOffset = slice.$offset; + var newLength = slice.$length + length; + var newCapacity = slice.$capacity; + + if (newLength > newCapacity) { + newOffset = 0; + newCapacity = Math.max(newLength, slice.$capacity < 1024 ? slice.$capacity * 2 : Math.floor(slice.$capacity * 5 / 4)); + + if (slice.$array.constructor === Array) { + newArray = slice.$array.slice(slice.$offset, slice.$offset + slice.$length); + newArray.length = newCapacity; + var zero = slice.constructor.elem.zero; + for (var i = slice.$length; i < newCapacity; i++) { + newArray[i] = zero(); + } + } else { + newArray = new slice.$array.constructor(newCapacity); + newArray.set(slice.$array.subarray(slice.$offset, slice.$offset + slice.$length)); + } + } + + $copyArray(newArray, array, newOffset + slice.$length, offset, length, slice.constructor.elem); + + var newSlice = new slice.constructor(newArray); + newSlice.$offset = newOffset; + newSlice.$length = newLength; + newSlice.$capacity = newCapacity; + return newSlice; +}; + +var $equal = function(a, b, type) { + if (type === $jsObjectPtr) { + return a === b; + } + switch (type.kind) { + case $kindComplex64: + case $kindComplex128: + return a.$real === b.$real && a.$imag === b.$imag; + case $kindInt64: + case $kindUint64: + return a.$high === b.$high && a.$low === b.$low; + case $kindArray: + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!$equal(a[i], b[i], type.elem)) { + return false; + } + } + return true; + case $kindStruct: + for (var i = 0; i < type.fields.length; i++) { + var f = type.fields[i]; + if (!$equal(a[f.prop], b[f.prop], f.typ)) { + return false; + } + } + return true; + case $kindInterface: + return $interfaceIsEqual(a, b); + default: + return a === b; + } +}; + +var $interfaceIsEqual = function(a, b) { + if (a === $ifaceNil || b === $ifaceNil) { + return a === b; + } + if (a.constructor !== b.constructor) { + return false; + } + if (a.constructor === $jsObjectPtr) { + return a.object === b.object; + } + if (!a.constructor.comparable) { + $throwRuntimeError("comparing uncomparable type " + a.constructor.string); + } + return $equal(a.$val, b.$val, a.constructor); +}; diff --git a/compiler/prelude/prelude_min.go b/compiler/prelude/prelude_min.go index ed6fb09ba..5a14f94da 100644 --- a/compiler/prelude/prelude_min.go +++ b/compiler/prelude/prelude_min.go @@ -1,4 +1,4 @@ -// Code generated by genmin; DO NOT EDIT. +// Code generated by genprelude; DO NOT EDIT. package prelude diff --git a/compiler/prelude/types.go b/compiler/prelude/types.js similarity index 99% rename from compiler/prelude/types.go rename to compiler/prelude/types.js index a8c29d575..e645ab3f5 100644 --- a/compiler/prelude/types.go +++ b/compiler/prelude/types.js @@ -1,6 +1,3 @@ -package prelude - -const types = ` var $kindBool = 1; var $kindInt = 2; var $kindInt8 = 3; @@ -740,4 +737,3 @@ var $assertType = function(value, type, returnTuple) { } return returnTuple ? [value, true] : value; }; -` From 679d5dd9794219e8a910909e595694fe4b57d445 Mon Sep 17 00:00:00 2001 From: Paul Jolly Date: Mon, 2 Jul 2018 20:45:27 +0100 Subject: [PATCH 04/10] compiler/prelude: format .js files using prettier (#4) This PR introduces automatic formatting of the prelude's now separate .js files. Using prettier has the same argument as using gofmt on .go source code. As part of this we make the go generate step for the prelude include a formatpreludejs.go step. The resulting prelude_min.go file is slightly different now, but post https://github.com/gopherjs/gopherjs/pull/791 we can see these differences are entirely and solely attributable to prettier's adjusting of the .js files. --- compiler/prelude/formatpreludejs.go | 56 ++ compiler/prelude/generate.go | 1 + compiler/prelude/goroutines.js | 130 ++-- compiler/prelude/jsmapping.js | 549 +++++++-------- compiler/prelude/numeric.js | 61 +- compiler/prelude/prelude.go | 2 +- compiler/prelude/prelude.js | 176 ++--- compiler/prelude/prettier_options.json | 4 + compiler/prelude/types.js | 887 ++++++++++++++----------- package-lock.json | 12 +- package.json | 3 +- 11 files changed, 1069 insertions(+), 812 deletions(-) create mode 100644 compiler/prelude/formatpreludejs.go create mode 100644 compiler/prelude/prettier_options.json diff --git a/compiler/prelude/formatpreludejs.go b/compiler/prelude/formatpreludejs.go new file mode 100644 index 000000000..76b8484af --- /dev/null +++ b/compiler/prelude/formatpreludejs.go @@ -0,0 +1,56 @@ +// +build ignore + +package main + +import ( + "fmt" + "go/build" + "io/ioutil" + "log" + "os/exec" + "path/filepath" + "strings" +) + +func main() { + if err := run(); err != nil { + log.Fatalln(err) + } +} + +func run() error { + bpkg, err := build.Import("github.com/gopherjs/gopherjs", "", build.FindOnly) + if err != nil { + return fmt.Errorf("failed to locate path for github.com/gopherjs/gopherjs/compiler/prelude: %v", err) + } + + preludeDir := filepath.Join(bpkg.Dir, "compiler", "prelude") + + args := []string{ + filepath.Join(bpkg.Dir, "node_modules", ".bin", "prettier"), + "--config", + filepath.Join(preludeDir, "prettier_options.json"), + "--write", + } + + fis, err := ioutil.ReadDir(preludeDir) + if err != nil { + return fmt.Errorf("failed to list contents of %v: %v", preludeDir, err) + } + for _, fi := range fis { + fn := fi.Name() + if !strings.HasSuffix(fn, ".js") || strings.HasSuffix(fn, ".min.js") { + continue + } + args = append(args, fn) + } + + cmd := exec.Command(args[0], args[1:]...) + + out, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("failed to run %v: %v\n%s", strings.Join(args, " "), err, string(out)) + } + + return nil +} diff --git a/compiler/prelude/generate.go b/compiler/prelude/generate.go index bc4b2cea7..d320fd3bf 100644 --- a/compiler/prelude/generate.go +++ b/compiler/prelude/generate.go @@ -1,3 +1,4 @@ package prelude +//go:generate go run formatpreludejs.go //go:generate go run genprelude.go diff --git a/compiler/prelude/goroutines.js b/compiler/prelude/goroutines.js index f1ae2d37e..06c51b8f6 100644 --- a/compiler/prelude/goroutines.js +++ b/compiler/prelude/goroutines.js @@ -7,7 +7,8 @@ var $getStackDepth = function() { return $stackDepthOffset + err.stack.split("\n").length; }; -var $panicStackDepth = null, $panicValue; +var $panicStackDepth = null, + $panicValue; var $callDeferred = function(deferred, jsErr, fromPanic) { if (!fromPanic && deferred !== null && deferred.index >= $curGoroutine.deferStack.length) { throw jsErr; @@ -106,10 +107,20 @@ var $recover = function() { $panicStackDepth = null; return $panicValue; }; -var $throw = function(err) { throw err; }; +var $throw = function(err) { + throw err; +}; -var $noGoroutine = { asleep: false, exit: false, deferStack: [], panicStack: [] }; -var $curGoroutine = $noGoroutine, $totalGoroutines = 0, $awakeGoroutines = 0, $checkForDeadlock = true; +var $noGoroutine = { + asleep: false, + exit: false, + deferStack: [], + panicStack: [], +}; +var $curGoroutine = $noGoroutine, + $totalGoroutines = 0, + $awakeGoroutines = 0, + $checkForDeadlock = true; var $mainFinished = false; var $go = function(fun, args) { $totalGoroutines++; @@ -119,7 +130,9 @@ var $go = function(fun, args) { $curGoroutine = $goroutine; var r = fun.apply(undefined, args); if (r && r.$blk !== undefined) { - fun = function() { return r.$blk(); }; + fun = function() { + return r.$blk(); + }; args = []; return; } @@ -130,7 +143,8 @@ var $go = function(fun, args) { } } finally { $curGoroutine = $noGoroutine; - if ($goroutine.exit) { /* also set by runtime.Goexit() */ + if ($goroutine.exit) { + /* also set by runtime.Goexit() */ $totalGoroutines--; $goroutine.asleep = true; } @@ -219,7 +233,7 @@ var $send = function(chan, value) { if (closedDuringSend) { $throwRuntimeError("send on closed channel"); } - } + }, }; }; var $recv = function(chan) { @@ -236,7 +250,11 @@ var $recv = function(chan) { } var thisGoroutine = $curGoroutine; - var f = { $blk: function() { return this.value; } }; + var f = { + $blk: function() { + return this.value; + }, + }; var queueEntry = function(v) { f.value = v; $schedule(thisGoroutine); @@ -272,22 +290,22 @@ var $select = function(comms) { var comm = comms[i]; var chan = comm[0]; switch (comm.length) { - case 0: /* default */ - selection = i; - break; - case 1: /* recv */ - if (chan.$sendQueue.length !== 0 || chan.$buffer.length !== 0 || chan.$closed) { - ready.push(i); - } - break; - case 2: /* send */ - if (chan.$closed) { - $throwRuntimeError("send on closed channel"); - } - if (chan.$recvQueue.length !== 0 || chan.$buffer.length < chan.$capacity) { - ready.push(i); - } - break; + case 0 /* default */: + selection = i; + break; + case 1 /* recv */: + if (chan.$sendQueue.length !== 0 || chan.$buffer.length !== 0 || chan.$closed) { + ready.push(i); + } + break; + case 2 /* send */: + if (chan.$closed) { + $throwRuntimeError("send on closed channel"); + } + if (chan.$recvQueue.length !== 0 || chan.$buffer.length < chan.$capacity) { + ready.push(i); + } + break; } } @@ -297,19 +315,23 @@ var $select = function(comms) { if (selection !== -1) { var comm = comms[selection]; switch (comm.length) { - case 0: /* default */ - return [selection]; - case 1: /* recv */ - return [selection, $recv(comm[0])]; - case 2: /* send */ - $send(comm[0], comm[1]); - return [selection]; + case 0 /* default */: + return [selection]; + case 1 /* recv */: + return [selection, $recv(comm[0])]; + case 2 /* send */: + $send(comm[0], comm[1]); + return [selection]; } } var entries = []; var thisGoroutine = $curGoroutine; - var f = { $blk: function() { return this.selection; } }; + var f = { + $blk: function() { + return this.selection; + }, + }; var removeFromQueues = function() { for (var i = 0; i < entries.length; i++) { var entry = entries[i]; @@ -324,28 +346,28 @@ var $select = function(comms) { (function(i) { var comm = comms[i]; switch (comm.length) { - case 1: /* recv */ - var queueEntry = function(value) { - f.selection = [i, value]; - removeFromQueues(); - $schedule(thisGoroutine); - }; - entries.push([comm[0].$recvQueue, queueEntry]); - comm[0].$recvQueue.push(queueEntry); - break; - case 2: /* send */ - var queueEntry = function() { - if (comm[0].$closed) { - $throwRuntimeError("send on closed channel"); - } - f.selection = [i]; - removeFromQueues(); - $schedule(thisGoroutine); - return comm[1]; - }; - entries.push([comm[0].$sendQueue, queueEntry]); - comm[0].$sendQueue.push(queueEntry); - break; + case 1 /* recv */: + var queueEntry = function(value) { + f.selection = [i, value]; + removeFromQueues(); + $schedule(thisGoroutine); + }; + entries.push([comm[0].$recvQueue, queueEntry]); + comm[0].$recvQueue.push(queueEntry); + break; + case 2 /* send */: + var queueEntry = function() { + if (comm[0].$closed) { + $throwRuntimeError("send on closed channel"); + } + f.selection = [i]; + removeFromQueues(); + $schedule(thisGoroutine); + return comm[1]; + }; + entries.push([comm[0].$sendQueue, queueEntry]); + comm[0].$sendQueue.push(queueEntry); + break; } })(i); } diff --git a/compiler/prelude/jsmapping.js b/compiler/prelude/jsmapping.js index 44a2a96a4..0a16a8250 100644 --- a/compiler/prelude/jsmapping.js +++ b/compiler/prelude/jsmapping.js @@ -25,113 +25,118 @@ var $externalize = function(v, t) { return v; } switch (t.kind) { - case $kindBool: - case $kindInt: - case $kindInt8: - case $kindInt16: - case $kindInt32: - case $kindUint: - case $kindUint8: - case $kindUint16: - case $kindUint32: - case $kindUintptr: - case $kindFloat32: - case $kindFloat64: - return v; - case $kindInt64: - case $kindUint64: - return $flatten64(v); - case $kindArray: - if ($needsExternalization(t.elem)) { - return $mapArray(v, function(e) { return $externalize(e, t.elem); }); - } - return v; - case $kindFunc: - return $externalizeFunction(v, t, false); - case $kindInterface: - if (v === $ifaceNil) { - return null; - } - if (v.constructor === $jsObjectPtr) { - return v.$val.object; - } - return $externalize(v.$val, v.constructor); - case $kindMap: - var m = {}; - var keys = $keys(v); - for (var i = 0; i < keys.length; i++) { - var entry = v[keys[i]]; - m[$externalize(entry.k, t.key)] = $externalize(entry.v, t.elem); - } - return m; - case $kindPtr: - if (v === t.nil) { - return null; - } - return $externalize(v.$get(), t.elem); - case $kindSlice: - if ($needsExternalization(t.elem)) { - return $mapArray($sliceToArray(v), function(e) { return $externalize(e, t.elem); }); - } - return $sliceToArray(v); - case $kindString: - if ($isASCII(v)) { + case $kindBool: + case $kindInt: + case $kindInt8: + case $kindInt16: + case $kindInt32: + case $kindUint: + case $kindUint8: + case $kindUint16: + case $kindUint32: + case $kindUintptr: + case $kindFloat32: + case $kindFloat64: return v; - } - var s = "", r; - for (var i = 0; i < v.length; i += r[1]) { - r = $decodeRune(v, i); - var c = r[0]; - if (c > 0xFFFF) { - var h = Math.floor((c - 0x10000) / 0x400) + 0xD800; - var l = (c - 0x10000) % 0x400 + 0xDC00; - s += String.fromCharCode(h, l); - continue; + case $kindInt64: + case $kindUint64: + return $flatten64(v); + case $kindArray: + if ($needsExternalization(t.elem)) { + return $mapArray(v, function(e) { + return $externalize(e, t.elem); + }); } - s += String.fromCharCode(c); - } - return s; - case $kindStruct: - var timePkg = $packages["time"]; - if (timePkg !== undefined && v.constructor === timePkg.Time.ptr) { - var milli = $div64(v.UnixNano(), new $Int64(0, 1000000)); - return new Date($flatten64(milli)); - } - - var noJsObject = {}; - var searchJsObject = function(v, t) { - if (t === $jsObjectPtr) { + return v; + case $kindFunc: + return $externalizeFunction(v, t, false); + case $kindInterface: + if (v === $ifaceNil) { + return null; + } + if (v.constructor === $jsObjectPtr) { + return v.$val.object; + } + return $externalize(v.$val, v.constructor); + case $kindMap: + var m = {}; + var keys = $keys(v); + for (var i = 0; i < keys.length; i++) { + var entry = v[keys[i]]; + m[$externalize(entry.k, t.key)] = $externalize(entry.v, t.elem); + } + return m; + case $kindPtr: + if (v === t.nil) { + return null; + } + return $externalize(v.$get(), t.elem); + case $kindSlice: + if ($needsExternalization(t.elem)) { + return $mapArray($sliceToArray(v), function(e) { + return $externalize(e, t.elem); + }); + } + return $sliceToArray(v); + case $kindString: + if ($isASCII(v)) { return v; } - switch (t.kind) { - case $kindPtr: - if (v === t.nil) { - return noJsObject; + var s = "", + r; + for (var i = 0; i < v.length; i += r[1]) { + r = $decodeRune(v, i); + var c = r[0]; + if (c > 0xffff) { + var h = Math.floor((c - 0x10000) / 0x400) + 0xd800; + var l = (c - 0x10000) % 0x400 + 0xdc00; + s += String.fromCharCode(h, l); + continue; } - return searchJsObject(v.$get(), t.elem); - case $kindStruct: - var f = t.fields[0]; - return searchJsObject(v[f.prop], f.typ); - case $kindInterface: - return searchJsObject(v.$val, v.constructor); - default: - return noJsObject; + s += String.fromCharCode(c); + } + return s; + case $kindStruct: + var timePkg = $packages["time"]; + if (timePkg !== undefined && v.constructor === timePkg.Time.ptr) { + var milli = $div64(v.UnixNano(), new $Int64(0, 1000000)); + return new Date($flatten64(milli)); } - }; - var o = searchJsObject(v, t); - if (o !== noJsObject) { - return o; - } - o = {}; - for (var i = 0; i < t.fields.length; i++) { - var f = t.fields[i]; - if (!f.exported) { - continue; + var noJsObject = {}; + var searchJsObject = function(v, t) { + if (t === $jsObjectPtr) { + return v; + } + switch (t.kind) { + case $kindPtr: + if (v === t.nil) { + return noJsObject; + } + return searchJsObject(v.$get(), t.elem); + case $kindStruct: + var f = t.fields[0]; + return searchJsObject(v[f.prop], f.typ); + case $kindInterface: + return searchJsObject(v.$val, v.constructor); + default: + return noJsObject; + } + }; + var o = searchJsObject(v, t); + if (o !== noJsObject) { + return o; } - o[f.name] = $externalize(v[f.prop], f.typ); - } - return o; + + o = {}; + for (var i = 0; i < t.fields.length; i++) { + var f = t.fields[i]; + if (!f.exported) { + continue; + } + o[f.name] = $externalize(v[f.prop], f.typ); + } + return o; } $throwRuntimeError("cannot externalize " + t.string); }; @@ -146,26 +151,27 @@ var $externalizeFunction = function(v, t, passThis) { var args = []; for (var i = 0; i < t.params.length; i++) { if (t.variadic && i === t.params.length - 1) { - var vt = t.params[i].elem, varargs = []; + var vt = t.params[i].elem, + varargs = []; for (var j = i; j < arguments.length; j++) { varargs.push($internalize(arguments[j], vt)); } - args.push(new (t.params[i])(varargs)); + args.push(new t.params[i](varargs)); break; } args.push($internalize(arguments[i], t.params[i])); } var result = v.apply(passThis ? this : undefined, args); switch (t.results.length) { - case 0: - return; - case 1: - return $externalize(result, t.results[0]); - default: - for (var i = 0; i < t.results.length; i++) { - result[i] = $externalize(result[i], t.results[i]); - } - return result; + case 0: + return; + case 1: + return $externalize(result, t.results[0]); + default: + for (var i = 0; i < t.results.length; i++) { + result[i] = $externalize(result[i], t.results[i]); + } + return result; } }; } @@ -190,176 +196,183 @@ var $internalize = function(v, t, recv) { return timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000)); } switch (t.kind) { - case $kindBool: - return !!v; - case $kindInt: - return parseInt(v); - case $kindInt8: - return parseInt(v) << 24 >> 24; - case $kindInt16: - return parseInt(v) << 16 >> 16; - case $kindInt32: - return parseInt(v) >> 0; - case $kindUint: - return parseInt(v); - case $kindUint8: - return parseInt(v) << 24 >>> 24; - case $kindUint16: - return parseInt(v) << 16 >>> 16; - case $kindUint32: - case $kindUintptr: - return parseInt(v) >>> 0; - case $kindInt64: - case $kindUint64: - return new t(0, v); - case $kindFloat32: - case $kindFloat64: - return parseFloat(v); - case $kindArray: - if (v.length !== t.len) { - $throwRuntimeError("got array with wrong size from JavaScript native"); - } - return $mapArray(v, function(e) { return $internalize(e, t.elem); }); - case $kindFunc: - return function() { - var args = []; - for (var i = 0; i < t.params.length; i++) { - if (t.variadic && i === t.params.length - 1) { - var vt = t.params[i].elem, varargs = arguments[i]; - for (var j = 0; j < varargs.$length; j++) { - args.push($externalize(varargs.$array[varargs.$offset + j], vt)); + case $kindBool: + return !!v; + case $kindInt: + return parseInt(v); + case $kindInt8: + return (parseInt(v) << 24) >> 24; + case $kindInt16: + return (parseInt(v) << 16) >> 16; + case $kindInt32: + return parseInt(v) >> 0; + case $kindUint: + return parseInt(v); + case $kindUint8: + return (parseInt(v) << 24) >>> 24; + case $kindUint16: + return (parseInt(v) << 16) >>> 16; + case $kindUint32: + case $kindUintptr: + return parseInt(v) >>> 0; + case $kindInt64: + case $kindUint64: + return new t(0, v); + case $kindFloat32: + case $kindFloat64: + return parseFloat(v); + case $kindArray: + if (v.length !== t.len) { + $throwRuntimeError("got array with wrong size from JavaScript native"); + } + return $mapArray(v, function(e) { + return $internalize(e, t.elem); + }); + case $kindFunc: + return function() { + var args = []; + for (var i = 0; i < t.params.length; i++) { + if (t.variadic && i === t.params.length - 1) { + var vt = t.params[i].elem, + varargs = arguments[i]; + for (var j = 0; j < varargs.$length; j++) { + args.push($externalize(varargs.$array[varargs.$offset + j], vt)); + } + break; } - break; + args.push($externalize(arguments[i], t.params[i])); } - args.push($externalize(arguments[i], t.params[i])); - } - var result = v.apply(recv, args); - switch (t.results.length) { - case 0: - return; - case 1: - return $internalize(result, t.results[0]); - default: - for (var i = 0; i < t.results.length; i++) { - result[i] = $internalize(result[i], t.results[i]); + var result = v.apply(recv, args); + switch (t.results.length) { + case 0: + return; + case 1: + return $internalize(result, t.results[0]); + default: + for (var i = 0; i < t.results.length; i++) { + result[i] = $internalize(result[i], t.results[i]); + } + return result; } - return result; + }; + case $kindInterface: + if (t.methods.length !== 0) { + $throwRuntimeError("cannot internalize " + t.string); } - }; - case $kindInterface: - if (t.methods.length !== 0) { - $throwRuntimeError("cannot internalize " + t.string); - } - if (v === null) { - return $ifaceNil; - } - if (v === undefined) { - return new $jsObjectPtr(undefined); - } - switch (v.constructor) { - case Int8Array: - return new ($sliceType($Int8))(v); - case Int16Array: - return new ($sliceType($Int16))(v); - case Int32Array: - return new ($sliceType($Int))(v); - case Uint8Array: - return new ($sliceType($Uint8))(v); - case Uint16Array: - return new ($sliceType($Uint16))(v); - case Uint32Array: - return new ($sliceType($Uint))(v); - case Float32Array: - return new ($sliceType($Float32))(v); - case Float64Array: - return new ($sliceType($Float64))(v); - case Array: - return $internalize(v, $sliceType($emptyInterface)); - case Boolean: - return new $Bool(!!v); - case Date: - if (timePkg === undefined) { - /* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */ - return new $jsObjectPtr(v); + if (v === null) { + return $ifaceNil; } - return new timePkg.Time($internalize(v, timePkg.Time)); - case Function: - var funcType = $funcType([$sliceType($emptyInterface)], [$jsObjectPtr], true); - return new funcType($internalize(v, funcType)); - case Number: - return new $Float64(parseFloat(v)); - case String: - return new $String($internalize(v, $String)); - default: - if ($global.Node && v instanceof $global.Node) { - return new $jsObjectPtr(v); + if (v === undefined) { + return new $jsObjectPtr(undefined); } - var mapType = $mapType($String, $emptyInterface); - return new mapType($internalize(v, mapType)); - } - case $kindMap: - var m = {}; - var keys = $keys(v); - for (var i = 0; i < keys.length; i++) { - var k = $internalize(keys[i], t.key); - m[t.key.keyFor(k)] = { k: k, v: $internalize(v[keys[i]], t.elem) }; - } - return m; - case $kindPtr: - if (t.elem.kind === $kindStruct) { - return $internalize(v, t.elem); - } - case $kindSlice: - return new t($mapArray(v, function(e) { return $internalize(e, t.elem); })); - case $kindString: - v = String(v); - if ($isASCII(v)) { - return v; - } - var s = ""; - var i = 0; - while (i < v.length) { - var h = v.charCodeAt(i); - if (0xD800 <= h && h <= 0xDBFF) { - var l = v.charCodeAt(i + 1); - var c = (h - 0xD800) * 0x400 + l - 0xDC00 + 0x10000; - s += $encodeRune(c); - i += 2; - continue; + switch (v.constructor) { + case Int8Array: + return new ($sliceType($Int8))(v); + case Int16Array: + return new ($sliceType($Int16))(v); + case Int32Array: + return new ($sliceType($Int))(v); + case Uint8Array: + return new ($sliceType($Uint8))(v); + case Uint16Array: + return new ($sliceType($Uint16))(v); + case Uint32Array: + return new ($sliceType($Uint))(v); + case Float32Array: + return new ($sliceType($Float32))(v); + case Float64Array: + return new ($sliceType($Float64))(v); + case Array: + return $internalize(v, $sliceType($emptyInterface)); + case Boolean: + return new $Bool(!!v); + case Date: + if (timePkg === undefined) { + /* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */ + return new $jsObjectPtr(v); + } + return new timePkg.Time($internalize(v, timePkg.Time)); + case Function: + var funcType = $funcType([$sliceType($emptyInterface)], [$jsObjectPtr], true); + return new funcType($internalize(v, funcType)); + case Number: + return new $Float64(parseFloat(v)); + case String: + return new $String($internalize(v, $String)); + default: + if ($global.Node && v instanceof $global.Node) { + return new $jsObjectPtr(v); + } + var mapType = $mapType($String, $emptyInterface); + return new mapType($internalize(v, mapType)); } - s += $encodeRune(h); - i++; - } - return s; - case $kindStruct: - var noJsObject = {}; - var searchJsObject = function(t) { - if (t === $jsObjectPtr) { + case $kindMap: + var m = {}; + var keys = $keys(v); + for (var i = 0; i < keys.length; i++) { + var k = $internalize(keys[i], t.key); + m[t.key.keyFor(k)] = { k: k, v: $internalize(v[keys[i]], t.elem) }; + } + return m; + case $kindPtr: + if (t.elem.kind === $kindStruct) { + return $internalize(v, t.elem); + } + case $kindSlice: + return new t( + $mapArray(v, function(e) { + return $internalize(e, t.elem); + }) + ); + case $kindString: + v = String(v); + if ($isASCII(v)) { return v; } - if (t === $jsObjectPtr.elem) { - $throwRuntimeError("cannot internalize js.Object, use *js.Object instead"); + var s = ""; + var i = 0; + while (i < v.length) { + var h = v.charCodeAt(i); + if (0xd800 <= h && h <= 0xdbff) { + var l = v.charCodeAt(i + 1); + var c = (h - 0xd800) * 0x400 + l - 0xdc00 + 0x10000; + s += $encodeRune(c); + i += 2; + continue; + } + s += $encodeRune(h); + i++; } - switch (t.kind) { - case $kindPtr: - return searchJsObject(t.elem); - case $kindStruct: - var f = t.fields[0]; - var o = searchJsObject(f.typ); - if (o !== noJsObject) { - var n = new t.ptr(); - n[f.prop] = o; - return n; + return s; + case $kindStruct: + var noJsObject = {}; + var searchJsObject = function(t) { + if (t === $jsObjectPtr) { + return v; } - return noJsObject; - default: - return noJsObject; + if (t === $jsObjectPtr.elem) { + $throwRuntimeError("cannot internalize js.Object, use *js.Object instead"); + } + switch (t.kind) { + case $kindPtr: + return searchJsObject(t.elem); + case $kindStruct: + var f = t.fields[0]; + var o = searchJsObject(f.typ); + if (o !== noJsObject) { + var n = new t.ptr(); + n[f.prop] = o; + return n; + } + return noJsObject; + default: + return noJsObject; + } + }; + var o = searchJsObject(t); + if (o !== noJsObject) { + return o; } - }; - var o = searchJsObject(t); - if (o !== noJsObject) { - return o; - } } $throwRuntimeError("cannot internalize " + t.string); }; diff --git a/compiler/prelude/numeric.js b/compiler/prelude/numeric.js index 3064e33ab..3d40deec0 100644 --- a/compiler/prelude/numeric.js +++ b/compiler/prelude/numeric.js @@ -1,5 +1,7 @@ var $min = Math.min; -var $mod = function(x, y) { return x % y; }; +var $mod = function(x, y) { + return x % y; +}; var $parseInt = parseInt; var $parseFloat = function(f) { if (f !== undefined && f !== null && f.constructor === Number) { @@ -9,18 +11,22 @@ var $parseFloat = function(f) { }; var $froundBuf = new Float32Array(1); -var $fround = Math.fround || function(f) { - $froundBuf[0] = f; - return $froundBuf[0]; -}; +var $fround = + Math.fround || + function(f) { + $froundBuf[0] = f; + return $froundBuf[0]; + }; -var $imul = Math.imul || function(a, b) { - var ah = (a >>> 16) & 0xffff; - var al = a & 0xffff; - var bh = (b >>> 16) & 0xffff; - var bl = b & 0xffff; - return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0) >> 0); -}; +var $imul = + Math.imul || + function(a, b) { + var ah = (a >>> 16) & 0xffff; + var al = a & 0xffff; + var bh = (b >>> 16) & 0xffff; + var bl = b & 0xffff; + return (al * bl + (((ah * bl + al * bh) << 16) >>> 0)) >> 0; + }; var $floatKey = function(f) { if (f !== f) { @@ -39,7 +45,7 @@ var $shiftLeft64 = function(x, y) { return x; } if (y < 32) { - return new x.constructor(x.$high << y | x.$low >>> (32 - y), (x.$low << y) >>> 0); + return new x.constructor((x.$high << y) | (x.$low >>> (32 - y)), (x.$low << y) >>> 0); } if (y < 64) { return new x.constructor(x.$low << (y - 32), 0); @@ -52,7 +58,7 @@ var $shiftRightInt64 = function(x, y) { return x; } if (y < 32) { - return new x.constructor(x.$high >> y, (x.$low >>> y | x.$high << (32 - y)) >>> 0); + return new x.constructor(x.$high >> y, ((x.$low >>> y) | (x.$high << (32 - y))) >>> 0); } if (y < 64) { return new x.constructor(x.$high >> 31, (x.$high >> (y - 32)) >>> 0); @@ -68,7 +74,7 @@ var $shiftRightUint64 = function(x, y) { return x; } if (y < 32) { - return new x.constructor(x.$high >>> y, (x.$low >>> y | x.$high << (32 - y)) >>> 0); + return new x.constructor(x.$high >>> y, ((x.$low >>> y) | (x.$high << (32 - y))) >>> 0); } if (y < 64) { return new x.constructor(0, x.$high >>> (y - 32)); @@ -77,19 +83,20 @@ var $shiftRightUint64 = function(x, y) { }; var $mul64 = function(x, y) { - var high = 0, low = 0; + var high = 0, + low = 0; if ((y.$low & 1) !== 0) { high = x.$high; low = x.$low; } for (var i = 1; i < 32; i++) { - if ((y.$low & 1<>> (32 - i); + if ((y.$low & (1 << i)) !== 0) { + high += (x.$high << i) | (x.$low >>> (32 - i)); low += (x.$low << i) >>> 0; } } for (var i = 0; i < 32; i++) { - if ((y.$high & 1< yHigh) || (xHigh === yHigh && xLow > yLow))) { - yHigh = (yHigh << 1 | yLow >>> 31) >>> 0; + var high = 0, + low = 0, + n = 0; + while (yHigh < 2147483648 && (xHigh > yHigh || (xHigh === yHigh && xLow > yLow))) { + yHigh = ((yHigh << 1) | (yLow >>> 31)) >>> 0; yLow = (yLow << 1) >>> 0; n++; } for (var i = 0; i <= n; i++) { - high = high << 1 | low >>> 31; + high = (high << 1) | (low >>> 31); low = (low << 1) >>> 0; - if ((xHigh > yHigh) || (xHigh === yHigh && xLow >= yLow)) { + if (xHigh > yHigh || (xHigh === yHigh && xLow >= yLow)) { xHigh = xHigh - yHigh; xLow = xLow - yLow; if (xLow < 0) { @@ -149,7 +158,7 @@ var $div64 = function(x, y, returnRemainder) { low = 0; } } - yLow = (yLow >>> 1 | yHigh << (32 - 1)) >>> 0; + yLow = ((yLow >>> 1) | (yHigh << (32 - 1))) >>> 0; yHigh = yHigh >>> 1; } @@ -164,7 +173,7 @@ var $divComplex = function(n, d) { var dinf = d.$real === Infinity || d.$real === -Infinity || d.$imag === Infinity || d.$imag === -Infinity; var nnan = !ninf && (n.$real !== n.$real || n.$imag !== n.$imag); var dnan = !dinf && (d.$real !== d.$real || d.$imag !== d.$imag); - if(nnan || dnan) { + if (nnan || dnan) { return new n.constructor(NaN, NaN); } if (ninf && !dinf) { diff --git a/compiler/prelude/prelude.go b/compiler/prelude/prelude.go index caa1d2ade..f28837e7d 100644 --- a/compiler/prelude/prelude.go +++ b/compiler/prelude/prelude.go @@ -3,4 +3,4 @@ package prelude // Prelude is the GopherJS JavaScript interop layer. -const Prelude = "Error.stackTraceLimit = Infinity;\n\nvar $global, $module;\nif (typeof window !== \"undefined\") { /* web page */\n $global = window;\n} else if (typeof self !== \"undefined\") { /* web worker */\n $global = self;\n} else if (typeof global !== \"undefined\") { /* Node.js */\n $global = global;\n $global.require = require;\n} else { /* others (e.g. Nashorn) */\n $global = this;\n}\n\nif ($global === undefined || $global.Array === undefined) {\n throw new Error(\"no global object found\");\n}\nif (typeof module !== \"undefined\") {\n $module = module;\n}\n\nvar $packages = {}, $idCounter = 0;\nvar $keys = function(m) { return m ? Object.keys(m) : []; };\nvar $flushConsole = function() {};\nvar $throwRuntimeError; /* set by package \"runtime\" */\nvar $throwNilPointerError = function() { $throwRuntimeError(\"invalid memory address or nil pointer dereference\"); };\nvar $call = function(fn, rcvr, args) { return fn.apply(rcvr, args); };\nvar $makeFunc = function(fn) { return function() { return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface); }; };\nvar $unused = function(v) {};\n\nvar $mapArray = function(array, f) {\n var newArray = new array.constructor(array.length);\n for (var i = 0; i < array.length; i++) {\n newArray[i] = f(array[i]);\n }\n return newArray;\n};\n\nvar $methodVal = function(recv, name) {\n var vals = recv.$methodVals || {};\n recv.$methodVals = vals; /* noop for primitives */\n var f = vals[name];\n if (f !== undefined) {\n return f;\n }\n var method = recv[name];\n f = function() {\n $stackDepthOffset--;\n try {\n return method.apply(recv, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n vals[name] = f;\n return f;\n};\n\nvar $methodExpr = function(typ, name) {\n var method = typ.prototype[name];\n if (method.$expr === undefined) {\n method.$expr = function() {\n $stackDepthOffset--;\n try {\n if (typ.wrapped) {\n arguments[0] = new typ(arguments[0]);\n }\n return Function.call.apply(method, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return method.$expr;\n};\n\nvar $ifaceMethodExprs = {};\nvar $ifaceMethodExpr = function(name) {\n var expr = $ifaceMethodExprs[\"$\" + name];\n if (expr === undefined) {\n expr = $ifaceMethodExprs[\"$\" + name] = function() {\n $stackDepthOffset--;\n try {\n return Function.call.apply(arguments[0][name], arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return expr;\n};\n\nvar $subslice = function(slice, low, high, max) {\n if (high === undefined) {\n high = slice.$length;\n }\n if (max === undefined) {\n max = slice.$capacity;\n }\n if (low < 0 || high < low || max < high || high > slice.$capacity || max > slice.$capacity) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n var s = new slice.constructor(slice.$array);\n s.$offset = slice.$offset + low;\n s.$length = high - low;\n s.$capacity = max - low;\n return s;\n};\n\nvar $substring = function(str, low, high) {\n if (low < 0 || high < low || high > str.length) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n return str.substring(low, high);\n};\n\nvar $sliceToArray = function(slice) {\n if (slice.$array.constructor !== Array) {\n return slice.$array.subarray(slice.$offset, slice.$offset + slice.$length);\n }\n return slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n};\n\nvar $decodeRune = function(str, pos) {\n var c0 = str.charCodeAt(pos);\n\n if (c0 < 0x80) {\n return [c0, 1];\n }\n\n if (c0 !== c0 || c0 < 0xC0) {\n return [0xFFFD, 1];\n }\n\n var c1 = str.charCodeAt(pos + 1);\n if (c1 !== c1 || c1 < 0x80 || 0xC0 <= c1) {\n return [0xFFFD, 1];\n }\n\n if (c0 < 0xE0) {\n var r = (c0 & 0x1F) << 6 | (c1 & 0x3F);\n if (r <= 0x7F) {\n return [0xFFFD, 1];\n }\n return [r, 2];\n }\n\n var c2 = str.charCodeAt(pos + 2);\n if (c2 !== c2 || c2 < 0x80 || 0xC0 <= c2) {\n return [0xFFFD, 1];\n }\n\n if (c0 < 0xF0) {\n var r = (c0 & 0x0F) << 12 | (c1 & 0x3F) << 6 | (c2 & 0x3F);\n if (r <= 0x7FF) {\n return [0xFFFD, 1];\n }\n if (0xD800 <= r && r <= 0xDFFF) {\n return [0xFFFD, 1];\n }\n return [r, 3];\n }\n\n var c3 = str.charCodeAt(pos + 3);\n if (c3 !== c3 || c3 < 0x80 || 0xC0 <= c3) {\n return [0xFFFD, 1];\n }\n\n if (c0 < 0xF8) {\n var r = (c0 & 0x07) << 18 | (c1 & 0x3F) << 12 | (c2 & 0x3F) << 6 | (c3 & 0x3F);\n if (r <= 0xFFFF || 0x10FFFF < r) {\n return [0xFFFD, 1];\n }\n return [r, 4];\n }\n\n return [0xFFFD, 1];\n};\n\nvar $encodeRune = function(r) {\n if (r < 0 || r > 0x10FFFF || (0xD800 <= r && r <= 0xDFFF)) {\n r = 0xFFFD;\n }\n if (r <= 0x7F) {\n return String.fromCharCode(r);\n }\n if (r <= 0x7FF) {\n return String.fromCharCode(0xC0 | r >> 6, 0x80 | (r & 0x3F));\n }\n if (r <= 0xFFFF) {\n return String.fromCharCode(0xE0 | r >> 12, 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F));\n }\n return String.fromCharCode(0xF0 | r >> 18, 0x80 | (r >> 12 & 0x3F), 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F));\n};\n\nvar $stringToBytes = function(str) {\n var array = new Uint8Array(str.length);\n for (var i = 0; i < str.length; i++) {\n array[i] = str.charCodeAt(i);\n }\n return array;\n};\n\nvar $bytesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i += 10000) {\n str += String.fromCharCode.apply(undefined, slice.$array.subarray(slice.$offset + i, slice.$offset + Math.min(slice.$length, i + 10000)));\n }\n return str;\n};\n\nvar $stringToRunes = function(str) {\n var array = new Int32Array(str.length);\n var rune, j = 0;\n for (var i = 0; i < str.length; i += rune[1], j++) {\n rune = $decodeRune(str, i);\n array[j] = rune[0];\n }\n return array.subarray(0, j);\n};\n\nvar $runesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i++) {\n str += $encodeRune(slice.$array[slice.$offset + i]);\n }\n return str;\n};\n\nvar $copyString = function(dst, src) {\n var n = Math.min(src.length, dst.$length);\n for (var i = 0; i < n; i++) {\n dst.$array[dst.$offset + i] = src.charCodeAt(i);\n }\n return n;\n};\n\nvar $copySlice = function(dst, src) {\n var n = Math.min(src.$length, dst.$length);\n $copyArray(dst.$array, src.$array, dst.$offset, src.$offset, n, dst.constructor.elem);\n return n;\n};\n\nvar $copyArray = function(dst, src, dstOffset, srcOffset, n, elem) {\n if (n === 0 || (dst === src && dstOffset === srcOffset)) {\n return;\n }\n\n if (src.subarray) {\n dst.set(src.subarray(srcOffset, srcOffset + n), dstOffset);\n return;\n }\n\n switch (elem.kind) {\n case $kindArray:\n case $kindStruct:\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n};\n\nvar $clone = function(src, type) {\n var clone = type.zero();\n type.copy(clone, src);\n return clone;\n};\n\nvar $pointerOfStructConversion = function(obj, type) {\n if(obj.$proxies === undefined) {\n obj.$proxies = {};\n obj.$proxies[obj.constructor.string] = obj;\n }\n var proxy = obj.$proxies[type.string];\n if (proxy === undefined) {\n var properties = {};\n for (var i = 0; i < type.elem.fields.length; i++) {\n (function(fieldProp) {\n properties[fieldProp] = {\n get: function() { return obj[fieldProp]; },\n set: function(value) { obj[fieldProp] = value; }\n };\n })(type.elem.fields[i].prop);\n }\n proxy = Object.create(type.prototype, properties);\n proxy.$val = proxy;\n obj.$proxies[type.string] = proxy;\n proxy.$proxies = obj.$proxies;\n }\n return proxy;\n};\n\nvar $append = function(slice) {\n return $internalAppend(slice, arguments, 1, arguments.length - 1);\n};\n\nvar $appendSlice = function(slice, toAppend) {\n if (toAppend.constructor === String) {\n var bytes = $stringToBytes(toAppend);\n return $internalAppend(slice, bytes, 0, bytes.length);\n }\n return $internalAppend(slice, toAppend.$array, toAppend.$offset, toAppend.$length);\n};\n\nvar $internalAppend = function(slice, array, offset, length) {\n if (length === 0) {\n return slice;\n }\n\n var newArray = slice.$array;\n var newOffset = slice.$offset;\n var newLength = slice.$length + length;\n var newCapacity = slice.$capacity;\n\n if (newLength > newCapacity) {\n newOffset = 0;\n newCapacity = Math.max(newLength, slice.$capacity < 1024 ? slice.$capacity * 2 : Math.floor(slice.$capacity * 5 / 4));\n\n if (slice.$array.constructor === Array) {\n newArray = slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n newArray.length = newCapacity;\n var zero = slice.constructor.elem.zero;\n for (var i = slice.$length; i < newCapacity; i++) {\n newArray[i] = zero();\n }\n } else {\n newArray = new slice.$array.constructor(newCapacity);\n newArray.set(slice.$array.subarray(slice.$offset, slice.$offset + slice.$length));\n }\n }\n\n $copyArray(newArray, array, newOffset + slice.$length, offset, length, slice.constructor.elem);\n\n var newSlice = new slice.constructor(newArray);\n newSlice.$offset = newOffset;\n newSlice.$length = newLength;\n newSlice.$capacity = newCapacity;\n return newSlice;\n};\n\nvar $equal = function(a, b, type) {\n if (type === $jsObjectPtr) {\n return a === b;\n }\n switch (type.kind) {\n case $kindComplex64:\n case $kindComplex128:\n return a.$real === b.$real && a.$imag === b.$imag;\n case $kindInt64:\n case $kindUint64:\n return a.$high === b.$high && a.$low === b.$low;\n case $kindArray:\n if (a.length !== b.length) {\n return false;\n }\n for (var i = 0; i < a.length; i++) {\n if (!$equal(a[i], b[i], type.elem)) {\n return false;\n }\n }\n return true;\n case $kindStruct:\n for (var i = 0; i < type.fields.length; i++) {\n var f = type.fields[i];\n if (!$equal(a[f.prop], b[f.prop], f.typ)) {\n return false;\n }\n }\n return true;\n case $kindInterface:\n return $interfaceIsEqual(a, b);\n default:\n return a === b;\n }\n};\n\nvar $interfaceIsEqual = function(a, b) {\n if (a === $ifaceNil || b === $ifaceNil) {\n return a === b;\n }\n if (a.constructor !== b.constructor) {\n return false;\n }\n if (a.constructor === $jsObjectPtr) {\n return a.object === b.object;\n }\n if (!a.constructor.comparable) {\n $throwRuntimeError(\"comparing uncomparable type \" + a.constructor.string);\n }\n return $equal(a.$val, b.$val, a.constructor);\n};\nvar $min = Math.min;\nvar $mod = function(x, y) { return x % y; };\nvar $parseInt = parseInt;\nvar $parseFloat = function(f) {\n if (f !== undefined && f !== null && f.constructor === Number) {\n return f;\n }\n return parseFloat(f);\n};\n\nvar $froundBuf = new Float32Array(1);\nvar $fround = Math.fround || function(f) {\n $froundBuf[0] = f;\n return $froundBuf[0];\n};\n\nvar $imul = Math.imul || function(a, b) {\n var ah = (a >>> 16) & 0xffff;\n var al = a & 0xffff;\n var bh = (b >>> 16) & 0xffff;\n var bl = b & 0xffff;\n return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0) >> 0);\n};\n\nvar $floatKey = function(f) {\n if (f !== f) {\n $idCounter++;\n return \"NaN$\" + $idCounter;\n }\n return String(f);\n};\n\nvar $flatten64 = function(x) {\n return x.$high * 4294967296 + x.$low;\n};\n\nvar $shiftLeft64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high << y | x.$low >>> (32 - y), (x.$low << y) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$low << (y - 32), 0);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightInt64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >> y, (x.$low >>> y | x.$high << (32 - y)) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$high >> 31, (x.$high >> (y - 32)) >>> 0);\n }\n if (x.$high < 0) {\n return new x.constructor(-1, 4294967295);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightUint64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >>> y, (x.$low >>> y | x.$high << (32 - y)) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(0, x.$high >>> (y - 32));\n }\n return new x.constructor(0, 0);\n};\n\nvar $mul64 = function(x, y) {\n var high = 0, low = 0;\n if ((y.$low & 1) !== 0) {\n high = x.$high;\n low = x.$low;\n }\n for (var i = 1; i < 32; i++) {\n if ((y.$low & 1<>> (32 - i);\n low += (x.$low << i) >>> 0;\n }\n }\n for (var i = 0; i < 32; i++) {\n if ((y.$high & 1< yHigh) || (xHigh === yHigh && xLow > yLow))) {\n yHigh = (yHigh << 1 | yLow >>> 31) >>> 0;\n yLow = (yLow << 1) >>> 0;\n n++;\n }\n for (var i = 0; i <= n; i++) {\n high = high << 1 | low >>> 31;\n low = (low << 1) >>> 0;\n if ((xHigh > yHigh) || (xHigh === yHigh && xLow >= yLow)) {\n xHigh = xHigh - yHigh;\n xLow = xLow - yLow;\n if (xLow < 0) {\n xHigh--;\n xLow += 4294967296;\n }\n low++;\n if (low === 4294967296) {\n high++;\n low = 0;\n }\n }\n yLow = (yLow >>> 1 | yHigh << (32 - 1)) >>> 0;\n yHigh = yHigh >>> 1;\n }\n\n if (returnRemainder) {\n return new x.constructor(xHigh * rs, xLow * rs);\n }\n return new x.constructor(high * s, low * s);\n};\n\nvar $divComplex = function(n, d) {\n var ninf = n.$real === Infinity || n.$real === -Infinity || n.$imag === Infinity || n.$imag === -Infinity;\n var dinf = d.$real === Infinity || d.$real === -Infinity || d.$imag === Infinity || d.$imag === -Infinity;\n var nnan = !ninf && (n.$real !== n.$real || n.$imag !== n.$imag);\n var dnan = !dinf && (d.$real !== d.$real || d.$imag !== d.$imag);\n if(nnan || dnan) {\n return new n.constructor(NaN, NaN);\n }\n if (ninf && !dinf) {\n return new n.constructor(Infinity, Infinity);\n }\n if (!ninf && dinf) {\n return new n.constructor(0, 0);\n }\n if (d.$real === 0 && d.$imag === 0) {\n if (n.$real === 0 && n.$imag === 0) {\n return new n.constructor(NaN, NaN);\n }\n return new n.constructor(Infinity, Infinity);\n }\n var a = Math.abs(d.$real);\n var b = Math.abs(d.$imag);\n if (a <= b) {\n var ratio = d.$real / d.$imag;\n var denom = d.$real * ratio + d.$imag;\n return new n.constructor((n.$real * ratio + n.$imag) / denom, (n.$imag * ratio - n.$real) / denom);\n }\n var ratio = d.$imag / d.$real;\n var denom = d.$imag * ratio + d.$real;\n return new n.constructor((n.$imag * ratio + n.$real) / denom, (n.$imag - n.$real * ratio) / denom);\n};\nvar $kindBool = 1;\nvar $kindInt = 2;\nvar $kindInt8 = 3;\nvar $kindInt16 = 4;\nvar $kindInt32 = 5;\nvar $kindInt64 = 6;\nvar $kindUint = 7;\nvar $kindUint8 = 8;\nvar $kindUint16 = 9;\nvar $kindUint32 = 10;\nvar $kindUint64 = 11;\nvar $kindUintptr = 12;\nvar $kindFloat32 = 13;\nvar $kindFloat64 = 14;\nvar $kindComplex64 = 15;\nvar $kindComplex128 = 16;\nvar $kindArray = 17;\nvar $kindChan = 18;\nvar $kindFunc = 19;\nvar $kindInterface = 20;\nvar $kindMap = 21;\nvar $kindPtr = 22;\nvar $kindSlice = 23;\nvar $kindString = 24;\nvar $kindStruct = 25;\nvar $kindUnsafePointer = 26;\n\nvar $methodSynthesizers = [];\nvar $addMethodSynthesizer = function(f) {\n if ($methodSynthesizers === null) {\n f();\n return;\n }\n $methodSynthesizers.push(f);\n};\nvar $synthesizeMethods = function() {\n $methodSynthesizers.forEach(function(f) { f(); });\n $methodSynthesizers = null;\n};\n\nvar $ifaceKeyFor = function(x) {\n if (x === $ifaceNil) {\n return 'nil';\n }\n var c = x.constructor;\n return c.string + '$' + c.keyFor(x.$val);\n};\n\nvar $identity = function(x) { return x; };\n\nvar $typeIDCounter = 0;\n\nvar $idKey = function(x) {\n if (x.$id === undefined) {\n $idCounter++;\n x.$id = $idCounter;\n }\n return String(x.$id);\n};\n\nvar $newType = function(size, kind, string, named, pkg, exported, constructor) {\n var typ;\n switch(kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.keyFor = $identity;\n break;\n\n case $kindString:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.keyFor = function(x) { return \"$\" + x; };\n break;\n\n case $kindFloat32:\n case $kindFloat64:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.keyFor = function(x) { return $floatKey(x); };\n break;\n\n case $kindInt64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) { return x.$high + \"$\" + x.$low; };\n break;\n\n case $kindUint64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >>> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) { return x.$high + \"$\" + x.$low; };\n break;\n\n case $kindComplex64:\n typ = function(real, imag) {\n this.$real = $fround(real);\n this.$imag = $fround(imag);\n this.$val = this;\n };\n typ.keyFor = function(x) { return x.$real + \"$\" + x.$imag; };\n break;\n\n case $kindComplex128:\n typ = function(real, imag) {\n this.$real = real;\n this.$imag = imag;\n this.$val = this;\n };\n typ.keyFor = function(x) { return x.$real + \"$\" + x.$imag; };\n break;\n\n case $kindArray:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, \"\", false, function(array) {\n this.$get = function() { return array; };\n this.$set = function(v) { typ.copy(this, v); };\n this.$val = array;\n });\n typ.init = function(elem, len) {\n typ.elem = elem;\n typ.len = len;\n typ.comparable = elem.comparable;\n typ.keyFor = function(x) {\n return Array.prototype.join.call($mapArray(x, function(e) {\n return String(elem.keyFor(e)).replace(/\\\\/g, \"\\\\\\\\\").replace(/\\$/g, \"\\\\$\");\n }), \"$\");\n };\n typ.copy = function(dst, src) {\n $copyArray(dst, src, 0, 0, src.length, elem);\n };\n typ.ptr.init(typ);\n Object.defineProperty(typ.ptr.nil, \"nilCheck\", { get: $throwNilPointerError });\n };\n break;\n\n case $kindChan:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.keyFor = $idKey;\n typ.init = function(elem, sendOnly, recvOnly) {\n typ.elem = elem;\n typ.sendOnly = sendOnly;\n typ.recvOnly = recvOnly;\n };\n break;\n\n case $kindFunc:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.init = function(params, results, variadic) {\n typ.params = params;\n typ.results = results;\n typ.variadic = variadic;\n typ.comparable = false;\n };\n break;\n\n case $kindInterface:\n typ = { implementedBy: {}, missingMethodFor: {} };\n typ.keyFor = $ifaceKeyFor;\n typ.init = function(methods) {\n typ.methods = methods;\n methods.forEach(function(m) {\n $ifaceNil[m.prop] = $throwNilPointerError;\n });\n };\n break;\n\n case $kindMap:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.init = function(key, elem) {\n typ.key = key;\n typ.elem = elem;\n typ.comparable = false;\n };\n break;\n\n case $kindPtr:\n typ = constructor || function(getter, setter, target) {\n this.$get = getter;\n this.$set = setter;\n this.$target = target;\n this.$val = this;\n };\n typ.keyFor = $idKey;\n typ.init = function(elem) {\n typ.elem = elem;\n typ.wrapped = (elem.kind === $kindArray);\n typ.nil = new typ($throwNilPointerError, $throwNilPointerError);\n };\n break;\n\n case $kindSlice:\n typ = function(array) {\n if (array.constructor !== typ.nativeArray) {\n array = new typ.nativeArray(array);\n }\n this.$array = array;\n this.$offset = 0;\n this.$length = array.length;\n this.$capacity = array.length;\n this.$val = this;\n };\n typ.init = function(elem) {\n typ.elem = elem;\n typ.comparable = false;\n typ.nativeArray = $nativeArray(elem.kind);\n typ.nil = new typ([]);\n };\n break;\n\n case $kindStruct:\n typ = function(v) { this.$val = v; };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, pkg, exported, constructor);\n typ.ptr.elem = typ;\n typ.ptr.prototype.$get = function() { return this; };\n typ.ptr.prototype.$set = function(v) { typ.copy(this, v); };\n typ.init = function(pkgPath, fields) {\n typ.pkgPath = pkgPath;\n typ.fields = fields;\n fields.forEach(function(f) {\n if (!f.typ.comparable) {\n typ.comparable = false;\n }\n });\n typ.keyFor = function(x) {\n var val = x.$val;\n return $mapArray(fields, function(f) {\n return String(f.typ.keyFor(val[f.prop])).replace(/\\\\/g, \"\\\\\\\\\").replace(/\\$/g, \"\\\\$\");\n }).join(\"$\");\n };\n typ.copy = function(dst, src) {\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n switch (f.typ.kind) {\n case $kindArray:\n case $kindStruct:\n f.typ.copy(dst[f.prop], src[f.prop]);\n continue;\n default:\n dst[f.prop] = src[f.prop];\n continue;\n }\n }\n };\n /* nil value */\n var properties = {};\n fields.forEach(function(f) {\n properties[f.prop] = { get: $throwNilPointerError, set: $throwNilPointerError };\n });\n typ.ptr.nil = Object.create(constructor.prototype, properties);\n typ.ptr.nil.$val = typ.ptr.nil;\n /* methods for embedded fields */\n $addMethodSynthesizer(function() {\n var synthesizeMethod = function(target, m, f) {\n if (target.prototype[m.prop] !== undefined) { return; }\n target.prototype[m.prop] = function() {\n var v = this.$val[f.prop];\n if (f.typ === $jsObjectPtr) {\n v = new $jsObjectPtr(v);\n }\n if (v.$val === undefined) {\n v = new f.typ(v);\n }\n return v[m.prop].apply(v, arguments);\n };\n };\n fields.forEach(function(f) {\n if (f.anonymous) {\n $methodSet(f.typ).forEach(function(m) {\n synthesizeMethod(typ, m, f);\n synthesizeMethod(typ.ptr, m, f);\n });\n $methodSet($ptrType(f.typ)).forEach(function(m) {\n synthesizeMethod(typ.ptr, m, f);\n });\n }\n });\n });\n };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n switch (kind) {\n case $kindBool:\n case $kindMap:\n typ.zero = function() { return false; };\n break;\n\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8 :\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n case $kindFloat32:\n case $kindFloat64:\n typ.zero = function() { return 0; };\n break;\n\n case $kindString:\n typ.zero = function() { return \"\"; };\n break;\n\n case $kindInt64:\n case $kindUint64:\n case $kindComplex64:\n case $kindComplex128:\n var zero = new typ(0, 0);\n typ.zero = function() { return zero; };\n break;\n\n case $kindPtr:\n case $kindSlice:\n typ.zero = function() { return typ.nil; };\n break;\n\n case $kindChan:\n typ.zero = function() { return $chanNil; };\n break;\n\n case $kindFunc:\n typ.zero = function() { return $throwNilPointerError; };\n break;\n\n case $kindInterface:\n typ.zero = function() { return $ifaceNil; };\n break;\n\n case $kindArray:\n typ.zero = function() {\n var arrayClass = $nativeArray(typ.elem.kind);\n if (arrayClass !== Array) {\n return new arrayClass(typ.len);\n }\n var array = new Array(typ.len);\n for (var i = 0; i < typ.len; i++) {\n array[i] = typ.elem.zero();\n }\n return array;\n };\n break;\n\n case $kindStruct:\n typ.zero = function() { return new typ.ptr(); };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n typ.id = $typeIDCounter;\n $typeIDCounter++;\n typ.size = size;\n typ.kind = kind;\n typ.string = string;\n typ.named = named;\n typ.pkg = pkg;\n typ.exported = exported;\n typ.methods = [];\n typ.methodSetCache = null;\n typ.comparable = true;\n return typ;\n};\n\nvar $methodSet = function(typ) {\n if (typ.methodSetCache !== null) {\n return typ.methodSetCache;\n }\n var base = {};\n\n var isPtr = (typ.kind === $kindPtr);\n if (isPtr && typ.elem.kind === $kindInterface) {\n typ.methodSetCache = [];\n return [];\n }\n\n var current = [{typ: isPtr ? typ.elem : typ, indirect: isPtr}];\n\n var seen = {};\n\n while (current.length > 0) {\n var next = [];\n var mset = [];\n\n current.forEach(function(e) {\n if (seen[e.typ.string]) {\n return;\n }\n seen[e.typ.string] = true;\n\n if (e.typ.named) {\n mset = mset.concat(e.typ.methods);\n if (e.indirect) {\n mset = mset.concat($ptrType(e.typ).methods);\n }\n }\n\n switch (e.typ.kind) {\n case $kindStruct:\n e.typ.fields.forEach(function(f) {\n if (f.anonymous) {\n var fTyp = f.typ;\n var fIsPtr = (fTyp.kind === $kindPtr);\n next.push({typ: fIsPtr ? fTyp.elem : fTyp, indirect: e.indirect || fIsPtr});\n }\n });\n break;\n\n case $kindInterface:\n mset = mset.concat(e.typ.methods);\n break;\n }\n });\n\n mset.forEach(function(m) {\n if (base[m.name] === undefined) {\n base[m.name] = m;\n }\n });\n\n current = next;\n }\n\n typ.methodSetCache = [];\n Object.keys(base).sort().forEach(function(name) {\n typ.methodSetCache.push(base[name]);\n });\n return typ.methodSetCache;\n};\n\nvar $Bool = $newType( 1, $kindBool, \"bool\", true, \"\", false, null);\nvar $Int = $newType( 4, $kindInt, \"int\", true, \"\", false, null);\nvar $Int8 = $newType( 1, $kindInt8, \"int8\", true, \"\", false, null);\nvar $Int16 = $newType( 2, $kindInt16, \"int16\", true, \"\", false, null);\nvar $Int32 = $newType( 4, $kindInt32, \"int32\", true, \"\", false, null);\nvar $Int64 = $newType( 8, $kindInt64, \"int64\", true, \"\", false, null);\nvar $Uint = $newType( 4, $kindUint, \"uint\", true, \"\", false, null);\nvar $Uint8 = $newType( 1, $kindUint8, \"uint8\", true, \"\", false, null);\nvar $Uint16 = $newType( 2, $kindUint16, \"uint16\", true, \"\", false, null);\nvar $Uint32 = $newType( 4, $kindUint32, \"uint32\", true, \"\", false, null);\nvar $Uint64 = $newType( 8, $kindUint64, \"uint64\", true, \"\", false, null);\nvar $Uintptr = $newType( 4, $kindUintptr, \"uintptr\", true, \"\", false, null);\nvar $Float32 = $newType( 4, $kindFloat32, \"float32\", true, \"\", false, null);\nvar $Float64 = $newType( 8, $kindFloat64, \"float64\", true, \"\", false, null);\nvar $Complex64 = $newType( 8, $kindComplex64, \"complex64\", true, \"\", false, null);\nvar $Complex128 = $newType(16, $kindComplex128, \"complex128\", true, \"\", false, null);\nvar $String = $newType( 8, $kindString, \"string\", true, \"\", false, null);\nvar $UnsafePointer = $newType( 4, $kindUnsafePointer, \"unsafe.Pointer\", true, \"\", false, null);\n\nvar $nativeArray = function(elemKind) {\n switch (elemKind) {\n case $kindInt:\n return Int32Array;\n case $kindInt8:\n return Int8Array;\n case $kindInt16:\n return Int16Array;\n case $kindInt32:\n return Int32Array;\n case $kindUint:\n return Uint32Array;\n case $kindUint8:\n return Uint8Array;\n case $kindUint16:\n return Uint16Array;\n case $kindUint32:\n return Uint32Array;\n case $kindUintptr:\n return Uint32Array;\n case $kindFloat32:\n return Float32Array;\n case $kindFloat64:\n return Float64Array;\n default:\n return Array;\n }\n};\nvar $toNativeArray = function(elemKind, array) {\n var nativeArray = $nativeArray(elemKind);\n if (nativeArray === Array) {\n return array;\n }\n return new nativeArray(array);\n};\nvar $arrayTypes = {};\nvar $arrayType = function(elem, len) {\n var typeKey = elem.id + \"$\" + len;\n var typ = $arrayTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(12, $kindArray, \"[\" + len + \"]\" + elem.string, false, \"\", false, null);\n $arrayTypes[typeKey] = typ;\n typ.init(elem, len);\n }\n return typ;\n};\n\nvar $chanType = function(elem, sendOnly, recvOnly) {\n var string = (recvOnly ? \"<-\" : \"\") + \"chan\" + (sendOnly ? \"<- \" : \" \") + elem.string;\n var field = sendOnly ? \"SendChan\" : (recvOnly ? \"RecvChan\" : \"Chan\");\n var typ = elem[field];\n if (typ === undefined) {\n typ = $newType(4, $kindChan, string, false, \"\", false, null);\n elem[field] = typ;\n typ.init(elem, sendOnly, recvOnly);\n }\n return typ;\n};\nvar $Chan = function(elem, capacity) {\n if (capacity < 0 || capacity > 2147483647) {\n $throwRuntimeError(\"makechan: size out of range\");\n }\n this.$elem = elem;\n this.$capacity = capacity;\n this.$buffer = [];\n this.$sendQueue = [];\n this.$recvQueue = [];\n this.$closed = false;\n};\nvar $chanNil = new $Chan(null, 0);\n$chanNil.$sendQueue = $chanNil.$recvQueue = { length: 0, push: function() {}, shift: function() { return undefined; }, indexOf: function() { return -1; } };\n\nvar $funcTypes = {};\nvar $funcType = function(params, results, variadic) {\n var typeKey = $mapArray(params, function(p) { return p.id; }).join(\",\") + \"$\" + $mapArray(results, function(r) { return r.id; }).join(\",\") + \"$\" + variadic;\n var typ = $funcTypes[typeKey];\n if (typ === undefined) {\n var paramTypes = $mapArray(params, function(p) { return p.string; });\n if (variadic) {\n paramTypes[paramTypes.length - 1] = \"...\" + paramTypes[paramTypes.length - 1].substr(2);\n }\n var string = \"func(\" + paramTypes.join(\", \") + \")\";\n if (results.length === 1) {\n string += \" \" + results[0].string;\n } else if (results.length > 1) {\n string += \" (\" + $mapArray(results, function(r) { return r.string; }).join(\", \") + \")\";\n }\n typ = $newType(4, $kindFunc, string, false, \"\", false, null);\n $funcTypes[typeKey] = typ;\n typ.init(params, results, variadic);\n }\n return typ;\n};\n\nvar $interfaceTypes = {};\nvar $interfaceType = function(methods) {\n var typeKey = $mapArray(methods, function(m) { return m.pkg + \",\" + m.name + \",\" + m.typ.id; }).join(\"$\");\n var typ = $interfaceTypes[typeKey];\n if (typ === undefined) {\n var string = \"interface {}\";\n if (methods.length !== 0) {\n string = \"interface { \" + $mapArray(methods, function(m) {\n return (m.pkg !== \"\" ? m.pkg + \".\" : \"\") + m.name + m.typ.string.substr(4);\n }).join(\"; \") + \" }\";\n }\n typ = $newType(8, $kindInterface, string, false, \"\", false, null);\n $interfaceTypes[typeKey] = typ;\n typ.init(methods);\n }\n return typ;\n};\nvar $emptyInterface = $interfaceType([]);\nvar $ifaceNil = {};\nvar $error = $newType(8, $kindInterface, \"error\", true, \"\", false, null);\n$error.init([{prop: \"Error\", name: \"Error\", pkg: \"\", typ: $funcType([], [$String], false)}]);\n\nvar $mapTypes = {};\nvar $mapType = function(key, elem) {\n var typeKey = key.id + \"$\" + elem.id;\n var typ = $mapTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(4, $kindMap, \"map[\" + key.string + \"]\" + elem.string, false, \"\", false, null);\n $mapTypes[typeKey] = typ;\n typ.init(key, elem);\n }\n return typ;\n};\nvar $makeMap = function(keyForFunc, entries) {\n var m = {};\n for (var i = 0; i < entries.length; i++) {\n var e = entries[i];\n m[keyForFunc(e.k)] = e;\n }\n return m;\n};\n\nvar $ptrType = function(elem) {\n var typ = elem.ptr;\n if (typ === undefined) {\n typ = $newType(4, $kindPtr, \"*\" + elem.string, false, \"\", elem.exported, null);\n elem.ptr = typ;\n typ.init(elem);\n }\n return typ;\n};\n\nvar $newDataPointer = function(data, constructor) {\n if (constructor.elem.kind === $kindStruct) {\n return data;\n }\n return new constructor(function() { return data; }, function(v) { data = v; });\n};\n\nvar $indexPtr = function(array, index, constructor) {\n array.$ptr = array.$ptr || {};\n return array.$ptr[index] || (array.$ptr[index] = new constructor(function() { return array[index]; }, function(v) { array[index] = v; }));\n};\n\nvar $sliceType = function(elem) {\n var typ = elem.slice;\n if (typ === undefined) {\n typ = $newType(12, $kindSlice, \"[]\" + elem.string, false, \"\", false, null);\n elem.slice = typ;\n typ.init(elem);\n }\n return typ;\n};\nvar $makeSlice = function(typ, length, capacity) {\n capacity = capacity || length;\n if (length < 0 || length > 2147483647) {\n $throwRuntimeError(\"makeslice: len out of range\");\n }\n if (capacity < 0 || capacity < length || capacity > 2147483647) {\n $throwRuntimeError(\"makeslice: cap out of range\");\n }\n var array = new typ.nativeArray(capacity);\n if (typ.nativeArray === Array) {\n for (var i = 0; i < capacity; i++) {\n array[i] = typ.elem.zero();\n }\n }\n var slice = new typ(array);\n slice.$length = length;\n return slice;\n};\n\nvar $structTypes = {};\nvar $structType = function(pkgPath, fields) {\n var typeKey = $mapArray(fields, function(f) { return f.name + \",\" + f.typ.id + \",\" + f.tag; }).join(\"$\");\n var typ = $structTypes[typeKey];\n if (typ === undefined) {\n var string = \"struct { \" + $mapArray(fields, function(f) {\n return f.name + \" \" + f.typ.string + (f.tag !== \"\" ? (\" \\\"\" + f.tag.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, \"\\\\\\\"\") + \"\\\"\") : \"\");\n }).join(\"; \") + \" }\";\n if (fields.length === 0) {\n string = \"struct {}\";\n }\n typ = $newType(0, $kindStruct, string, false, \"\", false, function() {\n this.$val = this;\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n var arg = arguments[i];\n this[f.prop] = arg !== undefined ? arg : f.typ.zero();\n }\n });\n $structTypes[typeKey] = typ;\n typ.init(pkgPath, fields);\n }\n return typ;\n};\n\nvar $assertType = function(value, type, returnTuple) {\n var isInterface = (type.kind === $kindInterface), ok, missingMethod = \"\";\n if (value === $ifaceNil) {\n ok = false;\n } else if (!isInterface) {\n ok = value.constructor === type;\n } else {\n var valueTypeString = value.constructor.string;\n ok = type.implementedBy[valueTypeString];\n if (ok === undefined) {\n ok = true;\n var valueMethodSet = $methodSet(value.constructor);\n var interfaceMethods = type.methods;\n for (var i = 0; i < interfaceMethods.length; i++) {\n var tm = interfaceMethods[i];\n var found = false;\n for (var j = 0; j < valueMethodSet.length; j++) {\n var vm = valueMethodSet[j];\n if (vm.name === tm.name && vm.pkg === tm.pkg && vm.typ === tm.typ) {\n found = true;\n break;\n }\n }\n if (!found) {\n ok = false;\n type.missingMethodFor[valueTypeString] = tm.name;\n break;\n }\n }\n type.implementedBy[valueTypeString] = ok;\n }\n if (!ok) {\n missingMethod = type.missingMethodFor[valueTypeString];\n }\n }\n\n if (!ok) {\n if (returnTuple) {\n return [type.zero(), false];\n }\n $panic(new $packages[\"runtime\"].TypeAssertionError.ptr(\"\", (value === $ifaceNil ? \"\" : value.constructor.string), type.string, missingMethod));\n }\n\n if (!isInterface) {\n value = value.$val;\n }\n if (type === $jsObjectPtr) {\n value = value.object;\n }\n return returnTuple ? [value, true] : value;\n};\nvar $stackDepthOffset = 0;\nvar $getStackDepth = function() {\n var err = new Error();\n if (err.stack === undefined) {\n return undefined;\n }\n return $stackDepthOffset + err.stack.split(\"\\n\").length;\n};\n\nvar $panicStackDepth = null, $panicValue;\nvar $callDeferred = function(deferred, jsErr, fromPanic) {\n if (!fromPanic && deferred !== null && deferred.index >= $curGoroutine.deferStack.length) {\n throw jsErr;\n }\n if (jsErr !== null) {\n var newErr = null;\n try {\n $curGoroutine.deferStack.push(deferred);\n $panic(new $jsErrorPtr(jsErr));\n } catch (err) {\n newErr = err;\n }\n $curGoroutine.deferStack.pop();\n $callDeferred(deferred, newErr);\n return;\n }\n if ($curGoroutine.asleep) {\n return;\n }\n\n $stackDepthOffset--;\n var outerPanicStackDepth = $panicStackDepth;\n var outerPanicValue = $panicValue;\n\n var localPanicValue = $curGoroutine.panicStack.pop();\n if (localPanicValue !== undefined) {\n $panicStackDepth = $getStackDepth();\n $panicValue = localPanicValue;\n }\n\n try {\n while (true) {\n if (deferred === null) {\n deferred = $curGoroutine.deferStack[$curGoroutine.deferStack.length - 1];\n if (deferred === undefined) {\n /* The panic reached the top of the stack. Clear it and throw it as a JavaScript error. */\n $panicStackDepth = null;\n if (localPanicValue.Object instanceof Error) {\n throw localPanicValue.Object;\n }\n var msg;\n if (localPanicValue.constructor === $String) {\n msg = localPanicValue.$val;\n } else if (localPanicValue.Error !== undefined) {\n msg = localPanicValue.Error();\n } else if (localPanicValue.String !== undefined) {\n msg = localPanicValue.String();\n } else {\n msg = localPanicValue;\n }\n throw new Error(msg);\n }\n }\n var call = deferred.pop();\n if (call === undefined) {\n $curGoroutine.deferStack.pop();\n if (localPanicValue !== undefined) {\n deferred = null;\n continue;\n }\n return;\n }\n var r = call[0].apply(call[2], call[1]);\n if (r && r.$blk !== undefined) {\n deferred.push([r.$blk, [], r]);\n if (fromPanic) {\n throw null;\n }\n return;\n }\n\n if (localPanicValue !== undefined && $panicStackDepth === null) {\n throw null; /* error was recovered */\n }\n }\n } finally {\n if (localPanicValue !== undefined) {\n if ($panicStackDepth !== null) {\n $curGoroutine.panicStack.push(localPanicValue);\n }\n $panicStackDepth = outerPanicStackDepth;\n $panicValue = outerPanicValue;\n }\n $stackDepthOffset++;\n }\n};\n\nvar $panic = function(value) {\n $curGoroutine.panicStack.push(value);\n $callDeferred(null, null, true);\n};\nvar $recover = function() {\n if ($panicStackDepth === null || ($panicStackDepth !== undefined && $panicStackDepth !== $getStackDepth() - 2)) {\n return $ifaceNil;\n }\n $panicStackDepth = null;\n return $panicValue;\n};\nvar $throw = function(err) { throw err; };\n\nvar $noGoroutine = { asleep: false, exit: false, deferStack: [], panicStack: [] };\nvar $curGoroutine = $noGoroutine, $totalGoroutines = 0, $awakeGoroutines = 0, $checkForDeadlock = true;\nvar $mainFinished = false;\nvar $go = function(fun, args) {\n $totalGoroutines++;\n $awakeGoroutines++;\n var $goroutine = function() {\n try {\n $curGoroutine = $goroutine;\n var r = fun.apply(undefined, args);\n if (r && r.$blk !== undefined) {\n fun = function() { return r.$blk(); };\n args = [];\n return;\n }\n $goroutine.exit = true;\n } catch (err) {\n if (!$goroutine.exit) {\n throw err;\n }\n } finally {\n $curGoroutine = $noGoroutine;\n if ($goroutine.exit) { /* also set by runtime.Goexit() */\n $totalGoroutines--;\n $goroutine.asleep = true;\n }\n if ($goroutine.asleep) {\n $awakeGoroutines--;\n if (!$mainFinished && $awakeGoroutines === 0 && $checkForDeadlock) {\n console.error(\"fatal error: all goroutines are asleep - deadlock!\");\n if ($global.process !== undefined) {\n $global.process.exit(2);\n }\n }\n }\n }\n };\n $goroutine.asleep = false;\n $goroutine.exit = false;\n $goroutine.deferStack = [];\n $goroutine.panicStack = [];\n $schedule($goroutine);\n};\n\nvar $scheduled = [];\nvar $runScheduled = function() {\n try {\n var r;\n while ((r = $scheduled.shift()) !== undefined) {\n r();\n }\n } finally {\n if ($scheduled.length > 0) {\n setTimeout($runScheduled, 0);\n }\n }\n};\n\nvar $schedule = function(goroutine) {\n if (goroutine.asleep) {\n goroutine.asleep = false;\n $awakeGoroutines++;\n }\n $scheduled.push(goroutine);\n if ($curGoroutine === $noGoroutine) {\n $runScheduled();\n }\n};\n\nvar $setTimeout = function(f, t) {\n $awakeGoroutines++;\n return setTimeout(function() {\n $awakeGoroutines--;\n f();\n }, t);\n};\n\nvar $block = function() {\n if ($curGoroutine === $noGoroutine) {\n $throwRuntimeError(\"cannot block in JavaScript callback, fix by wrapping code in goroutine\");\n }\n $curGoroutine.asleep = true;\n};\n\nvar $send = function(chan, value) {\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv !== undefined) {\n queuedRecv([value, true]);\n return;\n }\n if (chan.$buffer.length < chan.$capacity) {\n chan.$buffer.push(value);\n return;\n }\n\n var thisGoroutine = $curGoroutine;\n var closedDuringSend;\n chan.$sendQueue.push(function(closed) {\n closedDuringSend = closed;\n $schedule(thisGoroutine);\n return value;\n });\n $block();\n return {\n $blk: function() {\n if (closedDuringSend) {\n $throwRuntimeError(\"send on closed channel\");\n }\n }\n };\n};\nvar $recv = function(chan) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend !== undefined) {\n chan.$buffer.push(queuedSend(false));\n }\n var bufferedValue = chan.$buffer.shift();\n if (bufferedValue !== undefined) {\n return [bufferedValue, true];\n }\n if (chan.$closed) {\n return [chan.$elem.zero(), false];\n }\n\n var thisGoroutine = $curGoroutine;\n var f = { $blk: function() { return this.value; } };\n var queueEntry = function(v) {\n f.value = v;\n $schedule(thisGoroutine);\n };\n chan.$recvQueue.push(queueEntry);\n $block();\n return f;\n};\nvar $close = function(chan) {\n if (chan.$closed) {\n $throwRuntimeError(\"close of closed channel\");\n }\n chan.$closed = true;\n while (true) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend === undefined) {\n break;\n }\n queuedSend(true); /* will panic */\n }\n while (true) {\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv === undefined) {\n break;\n }\n queuedRecv([chan.$elem.zero(), false]);\n }\n};\nvar $select = function(comms) {\n var ready = [];\n var selection = -1;\n for (var i = 0; i < comms.length; i++) {\n var comm = comms[i];\n var chan = comm[0];\n switch (comm.length) {\n case 0: /* default */\n selection = i;\n break;\n case 1: /* recv */\n if (chan.$sendQueue.length !== 0 || chan.$buffer.length !== 0 || chan.$closed) {\n ready.push(i);\n }\n break;\n case 2: /* send */\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n if (chan.$recvQueue.length !== 0 || chan.$buffer.length < chan.$capacity) {\n ready.push(i);\n }\n break;\n }\n }\n\n if (ready.length !== 0) {\n selection = ready[Math.floor(Math.random() * ready.length)];\n }\n if (selection !== -1) {\n var comm = comms[selection];\n switch (comm.length) {\n case 0: /* default */\n return [selection];\n case 1: /* recv */\n return [selection, $recv(comm[0])];\n case 2: /* send */\n $send(comm[0], comm[1]);\n return [selection];\n }\n }\n\n var entries = [];\n var thisGoroutine = $curGoroutine;\n var f = { $blk: function() { return this.selection; } };\n var removeFromQueues = function() {\n for (var i = 0; i < entries.length; i++) {\n var entry = entries[i];\n var queue = entry[0];\n var index = queue.indexOf(entry[1]);\n if (index !== -1) {\n queue.splice(index, 1);\n }\n }\n };\n for (var i = 0; i < comms.length; i++) {\n (function(i) {\n var comm = comms[i];\n switch (comm.length) {\n case 1: /* recv */\n var queueEntry = function(value) {\n f.selection = [i, value];\n removeFromQueues();\n $schedule(thisGoroutine);\n };\n entries.push([comm[0].$recvQueue, queueEntry]);\n comm[0].$recvQueue.push(queueEntry);\n break;\n case 2: /* send */\n var queueEntry = function() {\n if (comm[0].$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n f.selection = [i];\n removeFromQueues();\n $schedule(thisGoroutine);\n return comm[1];\n };\n entries.push([comm[0].$sendQueue, queueEntry]);\n comm[0].$sendQueue.push(queueEntry);\n break;\n }\n })(i);\n }\n $block();\n return f;\n};\nvar $jsObjectPtr, $jsErrorPtr;\n\nvar $needsExternalization = function(t) {\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return false;\n default:\n return t !== $jsObjectPtr;\n }\n};\n\nvar $externalize = function(v, t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return v;\n case $kindInt64:\n case $kindUint64:\n return $flatten64(v);\n case $kindArray:\n if ($needsExternalization(t.elem)) {\n return $mapArray(v, function(e) { return $externalize(e, t.elem); });\n }\n return v;\n case $kindFunc:\n return $externalizeFunction(v, t, false);\n case $kindInterface:\n if (v === $ifaceNil) {\n return null;\n }\n if (v.constructor === $jsObjectPtr) {\n return v.$val.object;\n }\n return $externalize(v.$val, v.constructor);\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var entry = v[keys[i]];\n m[$externalize(entry.k, t.key)] = $externalize(entry.v, t.elem);\n }\n return m;\n case $kindPtr:\n if (v === t.nil) {\n return null;\n }\n return $externalize(v.$get(), t.elem);\n case $kindSlice:\n if ($needsExternalization(t.elem)) {\n return $mapArray($sliceToArray(v), function(e) { return $externalize(e, t.elem); });\n }\n return $sliceToArray(v);\n case $kindString:\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\", r;\n for (var i = 0; i < v.length; i += r[1]) {\n r = $decodeRune(v, i);\n var c = r[0];\n if (c > 0xFFFF) {\n var h = Math.floor((c - 0x10000) / 0x400) + 0xD800;\n var l = (c - 0x10000) % 0x400 + 0xDC00;\n s += String.fromCharCode(h, l);\n continue;\n }\n s += String.fromCharCode(c);\n }\n return s;\n case $kindStruct:\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && v.constructor === timePkg.Time.ptr) {\n var milli = $div64(v.UnixNano(), new $Int64(0, 1000000));\n return new Date($flatten64(milli));\n }\n\n var noJsObject = {};\n var searchJsObject = function(v, t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindPtr:\n if (v === t.nil) {\n return noJsObject;\n }\n return searchJsObject(v.$get(), t.elem);\n case $kindStruct:\n var f = t.fields[0];\n return searchJsObject(v[f.prop], f.typ);\n case $kindInterface:\n return searchJsObject(v.$val, v.constructor);\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(v, t);\n if (o !== noJsObject) {\n return o;\n }\n\n o = {};\n for (var i = 0; i < t.fields.length; i++) {\n var f = t.fields[i];\n if (!f.exported) {\n continue;\n }\n o[f.name] = $externalize(v[f.prop], f.typ);\n }\n return o;\n }\n $throwRuntimeError(\"cannot externalize \" + t.string);\n};\n\nvar $externalizeFunction = function(v, t, passThis) {\n if (v === $throwNilPointerError) {\n return null;\n }\n if (v.$externalizeWrapper === undefined) {\n $checkForDeadlock = false;\n v.$externalizeWrapper = function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem, varargs = [];\n for (var j = i; j < arguments.length; j++) {\n varargs.push($internalize(arguments[j], vt));\n }\n args.push(new (t.params[i])(varargs));\n break;\n }\n args.push($internalize(arguments[i], t.params[i]));\n }\n var result = v.apply(passThis ? this : undefined, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $externalize(result, t.results[0]);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $externalize(result[i], t.results[i]);\n }\n return result;\n }\n };\n }\n return v.$externalizeWrapper;\n};\n\nvar $internalize = function(v, t, recv) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n if (v && v.__internal_object__ !== undefined) {\n return $assertType(v.__internal_object__, t, false);\n }\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && t === timePkg.Time) {\n if (!(v !== null && v !== undefined && v.constructor === Date)) {\n $throwRuntimeError(\"cannot internalize time.Time from \" + typeof v + \", must be Date\");\n }\n return timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000));\n }\n switch (t.kind) {\n case $kindBool:\n return !!v;\n case $kindInt:\n return parseInt(v);\n case $kindInt8:\n return parseInt(v) << 24 >> 24;\n case $kindInt16:\n return parseInt(v) << 16 >> 16;\n case $kindInt32:\n return parseInt(v) >> 0;\n case $kindUint:\n return parseInt(v);\n case $kindUint8:\n return parseInt(v) << 24 >>> 24;\n case $kindUint16:\n return parseInt(v) << 16 >>> 16;\n case $kindUint32:\n case $kindUintptr:\n return parseInt(v) >>> 0;\n case $kindInt64:\n case $kindUint64:\n return new t(0, v);\n case $kindFloat32:\n case $kindFloat64:\n return parseFloat(v);\n case $kindArray:\n if (v.length !== t.len) {\n $throwRuntimeError(\"got array with wrong size from JavaScript native\");\n }\n return $mapArray(v, function(e) { return $internalize(e, t.elem); });\n case $kindFunc:\n return function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem, varargs = arguments[i];\n for (var j = 0; j < varargs.$length; j++) {\n args.push($externalize(varargs.$array[varargs.$offset + j], vt));\n }\n break;\n }\n args.push($externalize(arguments[i], t.params[i]));\n }\n var result = v.apply(recv, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $internalize(result, t.results[0]);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $internalize(result[i], t.results[i]);\n }\n return result;\n }\n };\n case $kindInterface:\n if (t.methods.length !== 0) {\n $throwRuntimeError(\"cannot internalize \" + t.string);\n }\n if (v === null) {\n return $ifaceNil;\n }\n if (v === undefined) {\n return new $jsObjectPtr(undefined);\n }\n switch (v.constructor) {\n case Int8Array:\n return new ($sliceType($Int8))(v);\n case Int16Array:\n return new ($sliceType($Int16))(v);\n case Int32Array:\n return new ($sliceType($Int))(v);\n case Uint8Array:\n return new ($sliceType($Uint8))(v);\n case Uint16Array:\n return new ($sliceType($Uint16))(v);\n case Uint32Array:\n return new ($sliceType($Uint))(v);\n case Float32Array:\n return new ($sliceType($Float32))(v);\n case Float64Array:\n return new ($sliceType($Float64))(v);\n case Array:\n return $internalize(v, $sliceType($emptyInterface));\n case Boolean:\n return new $Bool(!!v);\n case Date:\n if (timePkg === undefined) {\n /* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */\n return new $jsObjectPtr(v);\n }\n return new timePkg.Time($internalize(v, timePkg.Time));\n case Function:\n var funcType = $funcType([$sliceType($emptyInterface)], [$jsObjectPtr], true);\n return new funcType($internalize(v, funcType));\n case Number:\n return new $Float64(parseFloat(v));\n case String:\n return new $String($internalize(v, $String));\n default:\n if ($global.Node && v instanceof $global.Node) {\n return new $jsObjectPtr(v);\n }\n var mapType = $mapType($String, $emptyInterface);\n return new mapType($internalize(v, mapType));\n }\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var k = $internalize(keys[i], t.key);\n m[t.key.keyFor(k)] = { k: k, v: $internalize(v[keys[i]], t.elem) };\n }\n return m;\n case $kindPtr:\n if (t.elem.kind === $kindStruct) {\n return $internalize(v, t.elem);\n }\n case $kindSlice:\n return new t($mapArray(v, function(e) { return $internalize(e, t.elem); }));\n case $kindString:\n v = String(v);\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\";\n var i = 0;\n while (i < v.length) {\n var h = v.charCodeAt(i);\n if (0xD800 <= h && h <= 0xDBFF) {\n var l = v.charCodeAt(i + 1);\n var c = (h - 0xD800) * 0x400 + l - 0xDC00 + 0x10000;\n s += $encodeRune(c);\n i += 2;\n continue;\n }\n s += $encodeRune(h);\n i++;\n }\n return s;\n case $kindStruct:\n var noJsObject = {};\n var searchJsObject = function(t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n switch (t.kind) {\n case $kindPtr:\n return searchJsObject(t.elem);\n case $kindStruct:\n var f = t.fields[0];\n var o = searchJsObject(f.typ);\n if (o !== noJsObject) {\n var n = new t.ptr();\n n[f.prop] = o;\n return n;\n }\n return noJsObject;\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(t);\n if (o !== noJsObject) {\n return o;\n }\n }\n $throwRuntimeError(\"cannot internalize \" + t.string);\n};\n\n/* $isASCII reports whether string s contains only ASCII characters. */\nvar $isASCII = function(s) {\n for (var i = 0; i < s.length; i++) {\n if (s.charCodeAt(i) >= 128) {\n return false;\n }\n }\n return true;\n};\n" +const Prelude = "Error.stackTraceLimit = Infinity;\n\nvar $global, $module;\nif (typeof window !== \"undefined\") {\n /* web page */\n $global = window;\n} else if (typeof self !== \"undefined\") {\n /* web worker */\n $global = self;\n} else if (typeof global !== \"undefined\") {\n /* Node.js */\n $global = global;\n $global.require = require;\n} else {\n /* others (e.g. Nashorn) */\n $global = this;\n}\n\nif ($global === undefined || $global.Array === undefined) {\n throw new Error(\"no global object found\");\n}\nif (typeof module !== \"undefined\") {\n $module = module;\n}\n\nvar $packages = {},\n $idCounter = 0;\nvar $keys = function(m) {\n return m ? Object.keys(m) : [];\n};\nvar $flushConsole = function() {};\nvar $throwRuntimeError; /* set by package \"runtime\" */\nvar $throwNilPointerError = function() {\n $throwRuntimeError(\"invalid memory address or nil pointer dereference\");\n};\nvar $call = function(fn, rcvr, args) {\n return fn.apply(rcvr, args);\n};\nvar $makeFunc = function(fn) {\n return function() {\n return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface);\n };\n};\nvar $unused = function(v) {};\n\nvar $mapArray = function(array, f) {\n var newArray = new array.constructor(array.length);\n for (var i = 0; i < array.length; i++) {\n newArray[i] = f(array[i]);\n }\n return newArray;\n};\n\nvar $methodVal = function(recv, name) {\n var vals = recv.$methodVals || {};\n recv.$methodVals = vals; /* noop for primitives */\n var f = vals[name];\n if (f !== undefined) {\n return f;\n }\n var method = recv[name];\n f = function() {\n $stackDepthOffset--;\n try {\n return method.apply(recv, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n vals[name] = f;\n return f;\n};\n\nvar $methodExpr = function(typ, name) {\n var method = typ.prototype[name];\n if (method.$expr === undefined) {\n method.$expr = function() {\n $stackDepthOffset--;\n try {\n if (typ.wrapped) {\n arguments[0] = new typ(arguments[0]);\n }\n return Function.call.apply(method, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return method.$expr;\n};\n\nvar $ifaceMethodExprs = {};\nvar $ifaceMethodExpr = function(name) {\n var expr = $ifaceMethodExprs[\"$\" + name];\n if (expr === undefined) {\n expr = $ifaceMethodExprs[\"$\" + name] = function() {\n $stackDepthOffset--;\n try {\n return Function.call.apply(arguments[0][name], arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return expr;\n};\n\nvar $subslice = function(slice, low, high, max) {\n if (high === undefined) {\n high = slice.$length;\n }\n if (max === undefined) {\n max = slice.$capacity;\n }\n if (low < 0 || high < low || max < high || high > slice.$capacity || max > slice.$capacity) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n var s = new slice.constructor(slice.$array);\n s.$offset = slice.$offset + low;\n s.$length = high - low;\n s.$capacity = max - low;\n return s;\n};\n\nvar $substring = function(str, low, high) {\n if (low < 0 || high < low || high > str.length) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n return str.substring(low, high);\n};\n\nvar $sliceToArray = function(slice) {\n if (slice.$array.constructor !== Array) {\n return slice.$array.subarray(slice.$offset, slice.$offset + slice.$length);\n }\n return slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n};\n\nvar $decodeRune = function(str, pos) {\n var c0 = str.charCodeAt(pos);\n\n if (c0 < 0x80) {\n return [c0, 1];\n }\n\n if (c0 !== c0 || c0 < 0xc0) {\n return [0xfffd, 1];\n }\n\n var c1 = str.charCodeAt(pos + 1);\n if (c1 !== c1 || c1 < 0x80 || 0xc0 <= c1) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xe0) {\n var r = ((c0 & 0x1f) << 6) | (c1 & 0x3f);\n if (r <= 0x7f) {\n return [0xfffd, 1];\n }\n return [r, 2];\n }\n\n var c2 = str.charCodeAt(pos + 2);\n if (c2 !== c2 || c2 < 0x80 || 0xc0 <= c2) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xf0) {\n var r = ((c0 & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f);\n if (r <= 0x7ff) {\n return [0xfffd, 1];\n }\n if (0xd800 <= r && r <= 0xdfff) {\n return [0xfffd, 1];\n }\n return [r, 3];\n }\n\n var c3 = str.charCodeAt(pos + 3);\n if (c3 !== c3 || c3 < 0x80 || 0xc0 <= c3) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xf8) {\n var r = ((c0 & 0x07) << 18) | ((c1 & 0x3f) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f);\n if (r <= 0xffff || 0x10ffff < r) {\n return [0xfffd, 1];\n }\n return [r, 4];\n }\n\n return [0xfffd, 1];\n};\n\nvar $encodeRune = function(r) {\n if (r < 0 || r > 0x10ffff || (0xd800 <= r && r <= 0xdfff)) {\n r = 0xfffd;\n }\n if (r <= 0x7f) {\n return String.fromCharCode(r);\n }\n if (r <= 0x7ff) {\n return String.fromCharCode(0xc0 | (r >> 6), 0x80 | (r & 0x3f));\n }\n if (r <= 0xffff) {\n return String.fromCharCode(0xe0 | (r >> 12), 0x80 | ((r >> 6) & 0x3f), 0x80 | (r & 0x3f));\n }\n return String.fromCharCode(0xf0 | (r >> 18), 0x80 | ((r >> 12) & 0x3f), 0x80 | ((r >> 6) & 0x3f), 0x80 | (r & 0x3f));\n};\n\nvar $stringToBytes = function(str) {\n var array = new Uint8Array(str.length);\n for (var i = 0; i < str.length; i++) {\n array[i] = str.charCodeAt(i);\n }\n return array;\n};\n\nvar $bytesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i += 10000) {\n str += String.fromCharCode.apply(undefined, slice.$array.subarray(slice.$offset + i, slice.$offset + Math.min(slice.$length, i + 10000)));\n }\n return str;\n};\n\nvar $stringToRunes = function(str) {\n var array = new Int32Array(str.length);\n var rune,\n j = 0;\n for (var i = 0; i < str.length; i += rune[1], j++) {\n rune = $decodeRune(str, i);\n array[j] = rune[0];\n }\n return array.subarray(0, j);\n};\n\nvar $runesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i++) {\n str += $encodeRune(slice.$array[slice.$offset + i]);\n }\n return str;\n};\n\nvar $copyString = function(dst, src) {\n var n = Math.min(src.length, dst.$length);\n for (var i = 0; i < n; i++) {\n dst.$array[dst.$offset + i] = src.charCodeAt(i);\n }\n return n;\n};\n\nvar $copySlice = function(dst, src) {\n var n = Math.min(src.$length, dst.$length);\n $copyArray(dst.$array, src.$array, dst.$offset, src.$offset, n, dst.constructor.elem);\n return n;\n};\n\nvar $copyArray = function(dst, src, dstOffset, srcOffset, n, elem) {\n if (n === 0 || (dst === src && dstOffset === srcOffset)) {\n return;\n }\n\n if (src.subarray) {\n dst.set(src.subarray(srcOffset, srcOffset + n), dstOffset);\n return;\n }\n\n switch (elem.kind) {\n case $kindArray:\n case $kindStruct:\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n};\n\nvar $clone = function(src, type) {\n var clone = type.zero();\n type.copy(clone, src);\n return clone;\n};\n\nvar $pointerOfStructConversion = function(obj, type) {\n if (obj.$proxies === undefined) {\n obj.$proxies = {};\n obj.$proxies[obj.constructor.string] = obj;\n }\n var proxy = obj.$proxies[type.string];\n if (proxy === undefined) {\n var properties = {};\n for (var i = 0; i < type.elem.fields.length; i++) {\n (function(fieldProp) {\n properties[fieldProp] = {\n get: function() {\n return obj[fieldProp];\n },\n set: function(value) {\n obj[fieldProp] = value;\n },\n };\n })(type.elem.fields[i].prop);\n }\n proxy = Object.create(type.prototype, properties);\n proxy.$val = proxy;\n obj.$proxies[type.string] = proxy;\n proxy.$proxies = obj.$proxies;\n }\n return proxy;\n};\n\nvar $append = function(slice) {\n return $internalAppend(slice, arguments, 1, arguments.length - 1);\n};\n\nvar $appendSlice = function(slice, toAppend) {\n if (toAppend.constructor === String) {\n var bytes = $stringToBytes(toAppend);\n return $internalAppend(slice, bytes, 0, bytes.length);\n }\n return $internalAppend(slice, toAppend.$array, toAppend.$offset, toAppend.$length);\n};\n\nvar $internalAppend = function(slice, array, offset, length) {\n if (length === 0) {\n return slice;\n }\n\n var newArray = slice.$array;\n var newOffset = slice.$offset;\n var newLength = slice.$length + length;\n var newCapacity = slice.$capacity;\n\n if (newLength > newCapacity) {\n newOffset = 0;\n newCapacity = Math.max(newLength, slice.$capacity < 1024 ? slice.$capacity * 2 : Math.floor(slice.$capacity * 5 / 4));\n\n if (slice.$array.constructor === Array) {\n newArray = slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n newArray.length = newCapacity;\n var zero = slice.constructor.elem.zero;\n for (var i = slice.$length; i < newCapacity; i++) {\n newArray[i] = zero();\n }\n } else {\n newArray = new slice.$array.constructor(newCapacity);\n newArray.set(slice.$array.subarray(slice.$offset, slice.$offset + slice.$length));\n }\n }\n\n $copyArray(newArray, array, newOffset + slice.$length, offset, length, slice.constructor.elem);\n\n var newSlice = new slice.constructor(newArray);\n newSlice.$offset = newOffset;\n newSlice.$length = newLength;\n newSlice.$capacity = newCapacity;\n return newSlice;\n};\n\nvar $equal = function(a, b, type) {\n if (type === $jsObjectPtr) {\n return a === b;\n }\n switch (type.kind) {\n case $kindComplex64:\n case $kindComplex128:\n return a.$real === b.$real && a.$imag === b.$imag;\n case $kindInt64:\n case $kindUint64:\n return a.$high === b.$high && a.$low === b.$low;\n case $kindArray:\n if (a.length !== b.length) {\n return false;\n }\n for (var i = 0; i < a.length; i++) {\n if (!$equal(a[i], b[i], type.elem)) {\n return false;\n }\n }\n return true;\n case $kindStruct:\n for (var i = 0; i < type.fields.length; i++) {\n var f = type.fields[i];\n if (!$equal(a[f.prop], b[f.prop], f.typ)) {\n return false;\n }\n }\n return true;\n case $kindInterface:\n return $interfaceIsEqual(a, b);\n default:\n return a === b;\n }\n};\n\nvar $interfaceIsEqual = function(a, b) {\n if (a === $ifaceNil || b === $ifaceNil) {\n return a === b;\n }\n if (a.constructor !== b.constructor) {\n return false;\n }\n if (a.constructor === $jsObjectPtr) {\n return a.object === b.object;\n }\n if (!a.constructor.comparable) {\n $throwRuntimeError(\"comparing uncomparable type \" + a.constructor.string);\n }\n return $equal(a.$val, b.$val, a.constructor);\n};\nvar $min = Math.min;\nvar $mod = function(x, y) {\n return x % y;\n};\nvar $parseInt = parseInt;\nvar $parseFloat = function(f) {\n if (f !== undefined && f !== null && f.constructor === Number) {\n return f;\n }\n return parseFloat(f);\n};\n\nvar $froundBuf = new Float32Array(1);\nvar $fround =\n Math.fround ||\n function(f) {\n $froundBuf[0] = f;\n return $froundBuf[0];\n };\n\nvar $imul =\n Math.imul ||\n function(a, b) {\n var ah = (a >>> 16) & 0xffff;\n var al = a & 0xffff;\n var bh = (b >>> 16) & 0xffff;\n var bl = b & 0xffff;\n return (al * bl + (((ah * bl + al * bh) << 16) >>> 0)) >> 0;\n };\n\nvar $floatKey = function(f) {\n if (f !== f) {\n $idCounter++;\n return \"NaN$\" + $idCounter;\n }\n return String(f);\n};\n\nvar $flatten64 = function(x) {\n return x.$high * 4294967296 + x.$low;\n};\n\nvar $shiftLeft64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor((x.$high << y) | (x.$low >>> (32 - y)), (x.$low << y) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$low << (y - 32), 0);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightInt64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >> y, ((x.$low >>> y) | (x.$high << (32 - y))) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$high >> 31, (x.$high >> (y - 32)) >>> 0);\n }\n if (x.$high < 0) {\n return new x.constructor(-1, 4294967295);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightUint64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >>> y, ((x.$low >>> y) | (x.$high << (32 - y))) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(0, x.$high >>> (y - 32));\n }\n return new x.constructor(0, 0);\n};\n\nvar $mul64 = function(x, y) {\n var high = 0,\n low = 0;\n if ((y.$low & 1) !== 0) {\n high = x.$high;\n low = x.$low;\n }\n for (var i = 1; i < 32; i++) {\n if ((y.$low & (1 << i)) !== 0) {\n high += (x.$high << i) | (x.$low >>> (32 - i));\n low += (x.$low << i) >>> 0;\n }\n }\n for (var i = 0; i < 32; i++) {\n if ((y.$high & (1 << i)) !== 0) {\n high += x.$low << i;\n }\n }\n return new x.constructor(high, low);\n};\n\nvar $div64 = function(x, y, returnRemainder) {\n if (y.$high === 0 && y.$low === 0) {\n $throwRuntimeError(\"integer divide by zero\");\n }\n\n var s = 1;\n var rs = 1;\n\n var xHigh = x.$high;\n var xLow = x.$low;\n if (xHigh < 0) {\n s = -1;\n rs = -1;\n xHigh = -xHigh;\n if (xLow !== 0) {\n xHigh--;\n xLow = 4294967296 - xLow;\n }\n }\n\n var yHigh = y.$high;\n var yLow = y.$low;\n if (y.$high < 0) {\n s *= -1;\n yHigh = -yHigh;\n if (yLow !== 0) {\n yHigh--;\n yLow = 4294967296 - yLow;\n }\n }\n\n var high = 0,\n low = 0,\n n = 0;\n while (yHigh < 2147483648 && (xHigh > yHigh || (xHigh === yHigh && xLow > yLow))) {\n yHigh = ((yHigh << 1) | (yLow >>> 31)) >>> 0;\n yLow = (yLow << 1) >>> 0;\n n++;\n }\n for (var i = 0; i <= n; i++) {\n high = (high << 1) | (low >>> 31);\n low = (low << 1) >>> 0;\n if (xHigh > yHigh || (xHigh === yHigh && xLow >= yLow)) {\n xHigh = xHigh - yHigh;\n xLow = xLow - yLow;\n if (xLow < 0) {\n xHigh--;\n xLow += 4294967296;\n }\n low++;\n if (low === 4294967296) {\n high++;\n low = 0;\n }\n }\n yLow = ((yLow >>> 1) | (yHigh << (32 - 1))) >>> 0;\n yHigh = yHigh >>> 1;\n }\n\n if (returnRemainder) {\n return new x.constructor(xHigh * rs, xLow * rs);\n }\n return new x.constructor(high * s, low * s);\n};\n\nvar $divComplex = function(n, d) {\n var ninf = n.$real === Infinity || n.$real === -Infinity || n.$imag === Infinity || n.$imag === -Infinity;\n var dinf = d.$real === Infinity || d.$real === -Infinity || d.$imag === Infinity || d.$imag === -Infinity;\n var nnan = !ninf && (n.$real !== n.$real || n.$imag !== n.$imag);\n var dnan = !dinf && (d.$real !== d.$real || d.$imag !== d.$imag);\n if (nnan || dnan) {\n return new n.constructor(NaN, NaN);\n }\n if (ninf && !dinf) {\n return new n.constructor(Infinity, Infinity);\n }\n if (!ninf && dinf) {\n return new n.constructor(0, 0);\n }\n if (d.$real === 0 && d.$imag === 0) {\n if (n.$real === 0 && n.$imag === 0) {\n return new n.constructor(NaN, NaN);\n }\n return new n.constructor(Infinity, Infinity);\n }\n var a = Math.abs(d.$real);\n var b = Math.abs(d.$imag);\n if (a <= b) {\n var ratio = d.$real / d.$imag;\n var denom = d.$real * ratio + d.$imag;\n return new n.constructor((n.$real * ratio + n.$imag) / denom, (n.$imag * ratio - n.$real) / denom);\n }\n var ratio = d.$imag / d.$real;\n var denom = d.$imag * ratio + d.$real;\n return new n.constructor((n.$imag * ratio + n.$real) / denom, (n.$imag - n.$real * ratio) / denom);\n};\nvar $kindBool = 1;\nvar $kindInt = 2;\nvar $kindInt8 = 3;\nvar $kindInt16 = 4;\nvar $kindInt32 = 5;\nvar $kindInt64 = 6;\nvar $kindUint = 7;\nvar $kindUint8 = 8;\nvar $kindUint16 = 9;\nvar $kindUint32 = 10;\nvar $kindUint64 = 11;\nvar $kindUintptr = 12;\nvar $kindFloat32 = 13;\nvar $kindFloat64 = 14;\nvar $kindComplex64 = 15;\nvar $kindComplex128 = 16;\nvar $kindArray = 17;\nvar $kindChan = 18;\nvar $kindFunc = 19;\nvar $kindInterface = 20;\nvar $kindMap = 21;\nvar $kindPtr = 22;\nvar $kindSlice = 23;\nvar $kindString = 24;\nvar $kindStruct = 25;\nvar $kindUnsafePointer = 26;\n\nvar $methodSynthesizers = [];\nvar $addMethodSynthesizer = function(f) {\n if ($methodSynthesizers === null) {\n f();\n return;\n }\n $methodSynthesizers.push(f);\n};\nvar $synthesizeMethods = function() {\n $methodSynthesizers.forEach(function(f) {\n f();\n });\n $methodSynthesizers = null;\n};\n\nvar $ifaceKeyFor = function(x) {\n if (x === $ifaceNil) {\n return \"nil\";\n }\n var c = x.constructor;\n return c.string + \"$\" + c.keyFor(x.$val);\n};\n\nvar $identity = function(x) {\n return x;\n};\n\nvar $typeIDCounter = 0;\n\nvar $idKey = function(x) {\n if (x.$id === undefined) {\n $idCounter++;\n x.$id = $idCounter;\n }\n return String(x.$id);\n};\n\nvar $newType = function(size, kind, string, named, pkg, exported, constructor) {\n var typ;\n switch (kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = $identity;\n break;\n\n case $kindString:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = function(x) {\n return \"$\" + x;\n };\n break;\n\n case $kindFloat32:\n case $kindFloat64:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = function(x) {\n return $floatKey(x);\n };\n break;\n\n case $kindInt64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$high + \"$\" + x.$low;\n };\n break;\n\n case $kindUint64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >>> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$high + \"$\" + x.$low;\n };\n break;\n\n case $kindComplex64:\n typ = function(real, imag) {\n this.$real = $fround(real);\n this.$imag = $fround(imag);\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$real + \"$\" + x.$imag;\n };\n break;\n\n case $kindComplex128:\n typ = function(real, imag) {\n this.$real = real;\n this.$imag = imag;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$real + \"$\" + x.$imag;\n };\n break;\n\n case $kindArray:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, \"\", false, function(array) {\n this.$get = function() {\n return array;\n };\n this.$set = function(v) {\n typ.copy(this, v);\n };\n this.$val = array;\n });\n typ.init = function(elem, len) {\n typ.elem = elem;\n typ.len = len;\n typ.comparable = elem.comparable;\n typ.keyFor = function(x) {\n return Array.prototype.join.call(\n $mapArray(x, function(e) {\n return String(elem.keyFor(e))\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\$/g, \"\\\\$\");\n }),\n \"$\"\n );\n };\n typ.copy = function(dst, src) {\n $copyArray(dst, src, 0, 0, src.length, elem);\n };\n typ.ptr.init(typ);\n Object.defineProperty(typ.ptr.nil, \"nilCheck\", { get: $throwNilPointerError });\n };\n break;\n\n case $kindChan:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = $idKey;\n typ.init = function(elem, sendOnly, recvOnly) {\n typ.elem = elem;\n typ.sendOnly = sendOnly;\n typ.recvOnly = recvOnly;\n };\n break;\n\n case $kindFunc:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.init = function(params, results, variadic) {\n typ.params = params;\n typ.results = results;\n typ.variadic = variadic;\n typ.comparable = false;\n };\n break;\n\n case $kindInterface:\n typ = { implementedBy: {}, missingMethodFor: {} };\n typ.keyFor = $ifaceKeyFor;\n typ.init = function(methods) {\n typ.methods = methods;\n methods.forEach(function(m) {\n $ifaceNil[m.prop] = $throwNilPointerError;\n });\n };\n break;\n\n case $kindMap:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.init = function(key, elem) {\n typ.key = key;\n typ.elem = elem;\n typ.comparable = false;\n };\n break;\n\n case $kindPtr:\n typ =\n constructor ||\n function(getter, setter, target) {\n this.$get = getter;\n this.$set = setter;\n this.$target = target;\n this.$val = this;\n };\n typ.keyFor = $idKey;\n typ.init = function(elem) {\n typ.elem = elem;\n typ.wrapped = elem.kind === $kindArray;\n typ.nil = new typ($throwNilPointerError, $throwNilPointerError);\n };\n break;\n\n case $kindSlice:\n typ = function(array) {\n if (array.constructor !== typ.nativeArray) {\n array = new typ.nativeArray(array);\n }\n this.$array = array;\n this.$offset = 0;\n this.$length = array.length;\n this.$capacity = array.length;\n this.$val = this;\n };\n typ.init = function(elem) {\n typ.elem = elem;\n typ.comparable = false;\n typ.nativeArray = $nativeArray(elem.kind);\n typ.nil = new typ([]);\n };\n break;\n\n case $kindStruct:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, pkg, exported, constructor);\n typ.ptr.elem = typ;\n typ.ptr.prototype.$get = function() {\n return this;\n };\n typ.ptr.prototype.$set = function(v) {\n typ.copy(this, v);\n };\n typ.init = function(pkgPath, fields) {\n typ.pkgPath = pkgPath;\n typ.fields = fields;\n fields.forEach(function(f) {\n if (!f.typ.comparable) {\n typ.comparable = false;\n }\n });\n typ.keyFor = function(x) {\n var val = x.$val;\n return $mapArray(fields, function(f) {\n return String(f.typ.keyFor(val[f.prop]))\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\$/g, \"\\\\$\");\n }).join(\"$\");\n };\n typ.copy = function(dst, src) {\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n switch (f.typ.kind) {\n case $kindArray:\n case $kindStruct:\n f.typ.copy(dst[f.prop], src[f.prop]);\n continue;\n default:\n dst[f.prop] = src[f.prop];\n continue;\n }\n }\n };\n /* nil value */\n var properties = {};\n fields.forEach(function(f) {\n properties[f.prop] = { get: $throwNilPointerError, set: $throwNilPointerError };\n });\n typ.ptr.nil = Object.create(constructor.prototype, properties);\n typ.ptr.nil.$val = typ.ptr.nil;\n /* methods for embedded fields */\n $addMethodSynthesizer(function() {\n var synthesizeMethod = function(target, m, f) {\n if (target.prototype[m.prop] !== undefined) {\n return;\n }\n target.prototype[m.prop] = function() {\n var v = this.$val[f.prop];\n if (f.typ === $jsObjectPtr) {\n v = new $jsObjectPtr(v);\n }\n if (v.$val === undefined) {\n v = new f.typ(v);\n }\n return v[m.prop].apply(v, arguments);\n };\n };\n fields.forEach(function(f) {\n if (f.anonymous) {\n $methodSet(f.typ).forEach(function(m) {\n synthesizeMethod(typ, m, f);\n synthesizeMethod(typ.ptr, m, f);\n });\n $methodSet($ptrType(f.typ)).forEach(function(m) {\n synthesizeMethod(typ.ptr, m, f);\n });\n }\n });\n });\n };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n switch (kind) {\n case $kindBool:\n case $kindMap:\n typ.zero = function() {\n return false;\n };\n break;\n\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n case $kindFloat32:\n case $kindFloat64:\n typ.zero = function() {\n return 0;\n };\n break;\n\n case $kindString:\n typ.zero = function() {\n return \"\";\n };\n break;\n\n case $kindInt64:\n case $kindUint64:\n case $kindComplex64:\n case $kindComplex128:\n var zero = new typ(0, 0);\n typ.zero = function() {\n return zero;\n };\n break;\n\n case $kindPtr:\n case $kindSlice:\n typ.zero = function() {\n return typ.nil;\n };\n break;\n\n case $kindChan:\n typ.zero = function() {\n return $chanNil;\n };\n break;\n\n case $kindFunc:\n typ.zero = function() {\n return $throwNilPointerError;\n };\n break;\n\n case $kindInterface:\n typ.zero = function() {\n return $ifaceNil;\n };\n break;\n\n case $kindArray:\n typ.zero = function() {\n var arrayClass = $nativeArray(typ.elem.kind);\n if (arrayClass !== Array) {\n return new arrayClass(typ.len);\n }\n var array = new Array(typ.len);\n for (var i = 0; i < typ.len; i++) {\n array[i] = typ.elem.zero();\n }\n return array;\n };\n break;\n\n case $kindStruct:\n typ.zero = function() {\n return new typ.ptr();\n };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n typ.id = $typeIDCounter;\n $typeIDCounter++;\n typ.size = size;\n typ.kind = kind;\n typ.string = string;\n typ.named = named;\n typ.pkg = pkg;\n typ.exported = exported;\n typ.methods = [];\n typ.methodSetCache = null;\n typ.comparable = true;\n return typ;\n};\n\nvar $methodSet = function(typ) {\n if (typ.methodSetCache !== null) {\n return typ.methodSetCache;\n }\n var base = {};\n\n var isPtr = typ.kind === $kindPtr;\n if (isPtr && typ.elem.kind === $kindInterface) {\n typ.methodSetCache = [];\n return [];\n }\n\n var current = [{ typ: isPtr ? typ.elem : typ, indirect: isPtr }];\n\n var seen = {};\n\n while (current.length > 0) {\n var next = [];\n var mset = [];\n\n current.forEach(function(e) {\n if (seen[e.typ.string]) {\n return;\n }\n seen[e.typ.string] = true;\n\n if (e.typ.named) {\n mset = mset.concat(e.typ.methods);\n if (e.indirect) {\n mset = mset.concat($ptrType(e.typ).methods);\n }\n }\n\n switch (e.typ.kind) {\n case $kindStruct:\n e.typ.fields.forEach(function(f) {\n if (f.anonymous) {\n var fTyp = f.typ;\n var fIsPtr = fTyp.kind === $kindPtr;\n next.push({ typ: fIsPtr ? fTyp.elem : fTyp, indirect: e.indirect || fIsPtr });\n }\n });\n break;\n\n case $kindInterface:\n mset = mset.concat(e.typ.methods);\n break;\n }\n });\n\n mset.forEach(function(m) {\n if (base[m.name] === undefined) {\n base[m.name] = m;\n }\n });\n\n current = next;\n }\n\n typ.methodSetCache = [];\n Object.keys(base)\n .sort()\n .forEach(function(name) {\n typ.methodSetCache.push(base[name]);\n });\n return typ.methodSetCache;\n};\n\nvar $Bool = $newType(1, $kindBool, \"bool\", true, \"\", false, null);\nvar $Int = $newType(4, $kindInt, \"int\", true, \"\", false, null);\nvar $Int8 = $newType(1, $kindInt8, \"int8\", true, \"\", false, null);\nvar $Int16 = $newType(2, $kindInt16, \"int16\", true, \"\", false, null);\nvar $Int32 = $newType(4, $kindInt32, \"int32\", true, \"\", false, null);\nvar $Int64 = $newType(8, $kindInt64, \"int64\", true, \"\", false, null);\nvar $Uint = $newType(4, $kindUint, \"uint\", true, \"\", false, null);\nvar $Uint8 = $newType(1, $kindUint8, \"uint8\", true, \"\", false, null);\nvar $Uint16 = $newType(2, $kindUint16, \"uint16\", true, \"\", false, null);\nvar $Uint32 = $newType(4, $kindUint32, \"uint32\", true, \"\", false, null);\nvar $Uint64 = $newType(8, $kindUint64, \"uint64\", true, \"\", false, null);\nvar $Uintptr = $newType(4, $kindUintptr, \"uintptr\", true, \"\", false, null);\nvar $Float32 = $newType(4, $kindFloat32, \"float32\", true, \"\", false, null);\nvar $Float64 = $newType(8, $kindFloat64, \"float64\", true, \"\", false, null);\nvar $Complex64 = $newType(8, $kindComplex64, \"complex64\", true, \"\", false, null);\nvar $Complex128 = $newType(16, $kindComplex128, \"complex128\", true, \"\", false, null);\nvar $String = $newType(8, $kindString, \"string\", true, \"\", false, null);\nvar $UnsafePointer = $newType(4, $kindUnsafePointer, \"unsafe.Pointer\", true, \"\", false, null);\n\nvar $nativeArray = function(elemKind) {\n switch (elemKind) {\n case $kindInt:\n return Int32Array;\n case $kindInt8:\n return Int8Array;\n case $kindInt16:\n return Int16Array;\n case $kindInt32:\n return Int32Array;\n case $kindUint:\n return Uint32Array;\n case $kindUint8:\n return Uint8Array;\n case $kindUint16:\n return Uint16Array;\n case $kindUint32:\n return Uint32Array;\n case $kindUintptr:\n return Uint32Array;\n case $kindFloat32:\n return Float32Array;\n case $kindFloat64:\n return Float64Array;\n default:\n return Array;\n }\n};\nvar $toNativeArray = function(elemKind, array) {\n var nativeArray = $nativeArray(elemKind);\n if (nativeArray === Array) {\n return array;\n }\n return new nativeArray(array);\n};\nvar $arrayTypes = {};\nvar $arrayType = function(elem, len) {\n var typeKey = elem.id + \"$\" + len;\n var typ = $arrayTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(12, $kindArray, \"[\" + len + \"]\" + elem.string, false, \"\", false, null);\n $arrayTypes[typeKey] = typ;\n typ.init(elem, len);\n }\n return typ;\n};\n\nvar $chanType = function(elem, sendOnly, recvOnly) {\n var string = (recvOnly ? \"<-\" : \"\") + \"chan\" + (sendOnly ? \"<- \" : \" \") + elem.string;\n var field = sendOnly ? \"SendChan\" : recvOnly ? \"RecvChan\" : \"Chan\";\n var typ = elem[field];\n if (typ === undefined) {\n typ = $newType(4, $kindChan, string, false, \"\", false, null);\n elem[field] = typ;\n typ.init(elem, sendOnly, recvOnly);\n }\n return typ;\n};\nvar $Chan = function(elem, capacity) {\n if (capacity < 0 || capacity > 2147483647) {\n $throwRuntimeError(\"makechan: size out of range\");\n }\n this.$elem = elem;\n this.$capacity = capacity;\n this.$buffer = [];\n this.$sendQueue = [];\n this.$recvQueue = [];\n this.$closed = false;\n};\nvar $chanNil = new $Chan(null, 0);\n$chanNil.$sendQueue = $chanNil.$recvQueue = {\n length: 0,\n push: function() {},\n shift: function() {\n return undefined;\n },\n indexOf: function() {\n return -1;\n },\n};\n\nvar $funcTypes = {};\nvar $funcType = function(params, results, variadic) {\n var typeKey =\n $mapArray(params, function(p) {\n return p.id;\n }).join(\",\") +\n \"$\" +\n $mapArray(results, function(r) {\n return r.id;\n }).join(\",\") +\n \"$\" +\n variadic;\n var typ = $funcTypes[typeKey];\n if (typ === undefined) {\n var paramTypes = $mapArray(params, function(p) {\n return p.string;\n });\n if (variadic) {\n paramTypes[paramTypes.length - 1] = \"...\" + paramTypes[paramTypes.length - 1].substr(2);\n }\n var string = \"func(\" + paramTypes.join(\", \") + \")\";\n if (results.length === 1) {\n string += \" \" + results[0].string;\n } else if (results.length > 1) {\n string +=\n \" (\" +\n $mapArray(results, function(r) {\n return r.string;\n }).join(\", \") +\n \")\";\n }\n typ = $newType(4, $kindFunc, string, false, \"\", false, null);\n $funcTypes[typeKey] = typ;\n typ.init(params, results, variadic);\n }\n return typ;\n};\n\nvar $interfaceTypes = {};\nvar $interfaceType = function(methods) {\n var typeKey = $mapArray(methods, function(m) {\n return m.pkg + \",\" + m.name + \",\" + m.typ.id;\n }).join(\"$\");\n var typ = $interfaceTypes[typeKey];\n if (typ === undefined) {\n var string = \"interface {}\";\n if (methods.length !== 0) {\n string =\n \"interface { \" +\n $mapArray(methods, function(m) {\n return (m.pkg !== \"\" ? m.pkg + \".\" : \"\") + m.name + m.typ.string.substr(4);\n }).join(\"; \") +\n \" }\";\n }\n typ = $newType(8, $kindInterface, string, false, \"\", false, null);\n $interfaceTypes[typeKey] = typ;\n typ.init(methods);\n }\n return typ;\n};\nvar $emptyInterface = $interfaceType([]);\nvar $ifaceNil = {};\nvar $error = $newType(8, $kindInterface, \"error\", true, \"\", false, null);\n$error.init([{ prop: \"Error\", name: \"Error\", pkg: \"\", typ: $funcType([], [$String], false) }]);\n\nvar $mapTypes = {};\nvar $mapType = function(key, elem) {\n var typeKey = key.id + \"$\" + elem.id;\n var typ = $mapTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(4, $kindMap, \"map[\" + key.string + \"]\" + elem.string, false, \"\", false, null);\n $mapTypes[typeKey] = typ;\n typ.init(key, elem);\n }\n return typ;\n};\nvar $makeMap = function(keyForFunc, entries) {\n var m = {};\n for (var i = 0; i < entries.length; i++) {\n var e = entries[i];\n m[keyForFunc(e.k)] = e;\n }\n return m;\n};\n\nvar $ptrType = function(elem) {\n var typ = elem.ptr;\n if (typ === undefined) {\n typ = $newType(4, $kindPtr, \"*\" + elem.string, false, \"\", elem.exported, null);\n elem.ptr = typ;\n typ.init(elem);\n }\n return typ;\n};\n\nvar $newDataPointer = function(data, constructor) {\n if (constructor.elem.kind === $kindStruct) {\n return data;\n }\n return new constructor(\n function() {\n return data;\n },\n function(v) {\n data = v;\n }\n );\n};\n\nvar $indexPtr = function(array, index, constructor) {\n array.$ptr = array.$ptr || {};\n return (\n array.$ptr[index] ||\n (array.$ptr[index] = new constructor(\n function() {\n return array[index];\n },\n function(v) {\n array[index] = v;\n }\n ))\n );\n};\n\nvar $sliceType = function(elem) {\n var typ = elem.slice;\n if (typ === undefined) {\n typ = $newType(12, $kindSlice, \"[]\" + elem.string, false, \"\", false, null);\n elem.slice = typ;\n typ.init(elem);\n }\n return typ;\n};\nvar $makeSlice = function(typ, length, capacity) {\n capacity = capacity || length;\n if (length < 0 || length > 2147483647) {\n $throwRuntimeError(\"makeslice: len out of range\");\n }\n if (capacity < 0 || capacity < length || capacity > 2147483647) {\n $throwRuntimeError(\"makeslice: cap out of range\");\n }\n var array = new typ.nativeArray(capacity);\n if (typ.nativeArray === Array) {\n for (var i = 0; i < capacity; i++) {\n array[i] = typ.elem.zero();\n }\n }\n var slice = new typ(array);\n slice.$length = length;\n return slice;\n};\n\nvar $structTypes = {};\nvar $structType = function(pkgPath, fields) {\n var typeKey = $mapArray(fields, function(f) {\n return f.name + \",\" + f.typ.id + \",\" + f.tag;\n }).join(\"$\");\n var typ = $structTypes[typeKey];\n if (typ === undefined) {\n var string =\n \"struct { \" +\n $mapArray(fields, function(f) {\n return f.name + \" \" + f.typ.string + (f.tag !== \"\" ? ' \"' + f.tag.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"') + '\"' : \"\");\n }).join(\"; \") +\n \" }\";\n if (fields.length === 0) {\n string = \"struct {}\";\n }\n typ = $newType(0, $kindStruct, string, false, \"\", false, function() {\n this.$val = this;\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n var arg = arguments[i];\n this[f.prop] = arg !== undefined ? arg : f.typ.zero();\n }\n });\n $structTypes[typeKey] = typ;\n typ.init(pkgPath, fields);\n }\n return typ;\n};\n\nvar $assertType = function(value, type, returnTuple) {\n var isInterface = type.kind === $kindInterface,\n ok,\n missingMethod = \"\";\n if (value === $ifaceNil) {\n ok = false;\n } else if (!isInterface) {\n ok = value.constructor === type;\n } else {\n var valueTypeString = value.constructor.string;\n ok = type.implementedBy[valueTypeString];\n if (ok === undefined) {\n ok = true;\n var valueMethodSet = $methodSet(value.constructor);\n var interfaceMethods = type.methods;\n for (var i = 0; i < interfaceMethods.length; i++) {\n var tm = interfaceMethods[i];\n var found = false;\n for (var j = 0; j < valueMethodSet.length; j++) {\n var vm = valueMethodSet[j];\n if (vm.name === tm.name && vm.pkg === tm.pkg && vm.typ === tm.typ) {\n found = true;\n break;\n }\n }\n if (!found) {\n ok = false;\n type.missingMethodFor[valueTypeString] = tm.name;\n break;\n }\n }\n type.implementedBy[valueTypeString] = ok;\n }\n if (!ok) {\n missingMethod = type.missingMethodFor[valueTypeString];\n }\n }\n\n if (!ok) {\n if (returnTuple) {\n return [type.zero(), false];\n }\n $panic(new $packages[\"runtime\"].TypeAssertionError.ptr(\"\", value === $ifaceNil ? \"\" : value.constructor.string, type.string, missingMethod));\n }\n\n if (!isInterface) {\n value = value.$val;\n }\n if (type === $jsObjectPtr) {\n value = value.object;\n }\n return returnTuple ? [value, true] : value;\n};\nvar $stackDepthOffset = 0;\nvar $getStackDepth = function() {\n var err = new Error();\n if (err.stack === undefined) {\n return undefined;\n }\n return $stackDepthOffset + err.stack.split(\"\\n\").length;\n};\n\nvar $panicStackDepth = null,\n $panicValue;\nvar $callDeferred = function(deferred, jsErr, fromPanic) {\n if (!fromPanic && deferred !== null && deferred.index >= $curGoroutine.deferStack.length) {\n throw jsErr;\n }\n if (jsErr !== null) {\n var newErr = null;\n try {\n $curGoroutine.deferStack.push(deferred);\n $panic(new $jsErrorPtr(jsErr));\n } catch (err) {\n newErr = err;\n }\n $curGoroutine.deferStack.pop();\n $callDeferred(deferred, newErr);\n return;\n }\n if ($curGoroutine.asleep) {\n return;\n }\n\n $stackDepthOffset--;\n var outerPanicStackDepth = $panicStackDepth;\n var outerPanicValue = $panicValue;\n\n var localPanicValue = $curGoroutine.panicStack.pop();\n if (localPanicValue !== undefined) {\n $panicStackDepth = $getStackDepth();\n $panicValue = localPanicValue;\n }\n\n try {\n while (true) {\n if (deferred === null) {\n deferred = $curGoroutine.deferStack[$curGoroutine.deferStack.length - 1];\n if (deferred === undefined) {\n /* The panic reached the top of the stack. Clear it and throw it as a JavaScript error. */\n $panicStackDepth = null;\n if (localPanicValue.Object instanceof Error) {\n throw localPanicValue.Object;\n }\n var msg;\n if (localPanicValue.constructor === $String) {\n msg = localPanicValue.$val;\n } else if (localPanicValue.Error !== undefined) {\n msg = localPanicValue.Error();\n } else if (localPanicValue.String !== undefined) {\n msg = localPanicValue.String();\n } else {\n msg = localPanicValue;\n }\n throw new Error(msg);\n }\n }\n var call = deferred.pop();\n if (call === undefined) {\n $curGoroutine.deferStack.pop();\n if (localPanicValue !== undefined) {\n deferred = null;\n continue;\n }\n return;\n }\n var r = call[0].apply(call[2], call[1]);\n if (r && r.$blk !== undefined) {\n deferred.push([r.$blk, [], r]);\n if (fromPanic) {\n throw null;\n }\n return;\n }\n\n if (localPanicValue !== undefined && $panicStackDepth === null) {\n throw null; /* error was recovered */\n }\n }\n } finally {\n if (localPanicValue !== undefined) {\n if ($panicStackDepth !== null) {\n $curGoroutine.panicStack.push(localPanicValue);\n }\n $panicStackDepth = outerPanicStackDepth;\n $panicValue = outerPanicValue;\n }\n $stackDepthOffset++;\n }\n};\n\nvar $panic = function(value) {\n $curGoroutine.panicStack.push(value);\n $callDeferred(null, null, true);\n};\nvar $recover = function() {\n if ($panicStackDepth === null || ($panicStackDepth !== undefined && $panicStackDepth !== $getStackDepth() - 2)) {\n return $ifaceNil;\n }\n $panicStackDepth = null;\n return $panicValue;\n};\nvar $throw = function(err) {\n throw err;\n};\n\nvar $noGoroutine = {\n asleep: false,\n exit: false,\n deferStack: [],\n panicStack: [],\n};\nvar $curGoroutine = $noGoroutine,\n $totalGoroutines = 0,\n $awakeGoroutines = 0,\n $checkForDeadlock = true;\nvar $mainFinished = false;\nvar $go = function(fun, args) {\n $totalGoroutines++;\n $awakeGoroutines++;\n var $goroutine = function() {\n try {\n $curGoroutine = $goroutine;\n var r = fun.apply(undefined, args);\n if (r && r.$blk !== undefined) {\n fun = function() {\n return r.$blk();\n };\n args = [];\n return;\n }\n $goroutine.exit = true;\n } catch (err) {\n if (!$goroutine.exit) {\n throw err;\n }\n } finally {\n $curGoroutine = $noGoroutine;\n if ($goroutine.exit) {\n /* also set by runtime.Goexit() */\n $totalGoroutines--;\n $goroutine.asleep = true;\n }\n if ($goroutine.asleep) {\n $awakeGoroutines--;\n if (!$mainFinished && $awakeGoroutines === 0 && $checkForDeadlock) {\n console.error(\"fatal error: all goroutines are asleep - deadlock!\");\n if ($global.process !== undefined) {\n $global.process.exit(2);\n }\n }\n }\n }\n };\n $goroutine.asleep = false;\n $goroutine.exit = false;\n $goroutine.deferStack = [];\n $goroutine.panicStack = [];\n $schedule($goroutine);\n};\n\nvar $scheduled = [];\nvar $runScheduled = function() {\n try {\n var r;\n while ((r = $scheduled.shift()) !== undefined) {\n r();\n }\n } finally {\n if ($scheduled.length > 0) {\n setTimeout($runScheduled, 0);\n }\n }\n};\n\nvar $schedule = function(goroutine) {\n if (goroutine.asleep) {\n goroutine.asleep = false;\n $awakeGoroutines++;\n }\n $scheduled.push(goroutine);\n if ($curGoroutine === $noGoroutine) {\n $runScheduled();\n }\n};\n\nvar $setTimeout = function(f, t) {\n $awakeGoroutines++;\n return setTimeout(function() {\n $awakeGoroutines--;\n f();\n }, t);\n};\n\nvar $block = function() {\n if ($curGoroutine === $noGoroutine) {\n $throwRuntimeError(\"cannot block in JavaScript callback, fix by wrapping code in goroutine\");\n }\n $curGoroutine.asleep = true;\n};\n\nvar $send = function(chan, value) {\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv !== undefined) {\n queuedRecv([value, true]);\n return;\n }\n if (chan.$buffer.length < chan.$capacity) {\n chan.$buffer.push(value);\n return;\n }\n\n var thisGoroutine = $curGoroutine;\n var closedDuringSend;\n chan.$sendQueue.push(function(closed) {\n closedDuringSend = closed;\n $schedule(thisGoroutine);\n return value;\n });\n $block();\n return {\n $blk: function() {\n if (closedDuringSend) {\n $throwRuntimeError(\"send on closed channel\");\n }\n },\n };\n};\nvar $recv = function(chan) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend !== undefined) {\n chan.$buffer.push(queuedSend(false));\n }\n var bufferedValue = chan.$buffer.shift();\n if (bufferedValue !== undefined) {\n return [bufferedValue, true];\n }\n if (chan.$closed) {\n return [chan.$elem.zero(), false];\n }\n\n var thisGoroutine = $curGoroutine;\n var f = {\n $blk: function() {\n return this.value;\n },\n };\n var queueEntry = function(v) {\n f.value = v;\n $schedule(thisGoroutine);\n };\n chan.$recvQueue.push(queueEntry);\n $block();\n return f;\n};\nvar $close = function(chan) {\n if (chan.$closed) {\n $throwRuntimeError(\"close of closed channel\");\n }\n chan.$closed = true;\n while (true) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend === undefined) {\n break;\n }\n queuedSend(true); /* will panic */\n }\n while (true) {\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv === undefined) {\n break;\n }\n queuedRecv([chan.$elem.zero(), false]);\n }\n};\nvar $select = function(comms) {\n var ready = [];\n var selection = -1;\n for (var i = 0; i < comms.length; i++) {\n var comm = comms[i];\n var chan = comm[0];\n switch (comm.length) {\n case 0 /* default */:\n selection = i;\n break;\n case 1 /* recv */:\n if (chan.$sendQueue.length !== 0 || chan.$buffer.length !== 0 || chan.$closed) {\n ready.push(i);\n }\n break;\n case 2 /* send */:\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n if (chan.$recvQueue.length !== 0 || chan.$buffer.length < chan.$capacity) {\n ready.push(i);\n }\n break;\n }\n }\n\n if (ready.length !== 0) {\n selection = ready[Math.floor(Math.random() * ready.length)];\n }\n if (selection !== -1) {\n var comm = comms[selection];\n switch (comm.length) {\n case 0 /* default */:\n return [selection];\n case 1 /* recv */:\n return [selection, $recv(comm[0])];\n case 2 /* send */:\n $send(comm[0], comm[1]);\n return [selection];\n }\n }\n\n var entries = [];\n var thisGoroutine = $curGoroutine;\n var f = {\n $blk: function() {\n return this.selection;\n },\n };\n var removeFromQueues = function() {\n for (var i = 0; i < entries.length; i++) {\n var entry = entries[i];\n var queue = entry[0];\n var index = queue.indexOf(entry[1]);\n if (index !== -1) {\n queue.splice(index, 1);\n }\n }\n };\n for (var i = 0; i < comms.length; i++) {\n (function(i) {\n var comm = comms[i];\n switch (comm.length) {\n case 1 /* recv */:\n var queueEntry = function(value) {\n f.selection = [i, value];\n removeFromQueues();\n $schedule(thisGoroutine);\n };\n entries.push([comm[0].$recvQueue, queueEntry]);\n comm[0].$recvQueue.push(queueEntry);\n break;\n case 2 /* send */:\n var queueEntry = function() {\n if (comm[0].$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n f.selection = [i];\n removeFromQueues();\n $schedule(thisGoroutine);\n return comm[1];\n };\n entries.push([comm[0].$sendQueue, queueEntry]);\n comm[0].$sendQueue.push(queueEntry);\n break;\n }\n })(i);\n }\n $block();\n return f;\n};\nvar $jsObjectPtr, $jsErrorPtr;\n\nvar $needsExternalization = function(t) {\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return false;\n default:\n return t !== $jsObjectPtr;\n }\n};\n\nvar $externalize = function(v, t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return v;\n case $kindInt64:\n case $kindUint64:\n return $flatten64(v);\n case $kindArray:\n if ($needsExternalization(t.elem)) {\n return $mapArray(v, function(e) {\n return $externalize(e, t.elem);\n });\n }\n return v;\n case $kindFunc:\n return $externalizeFunction(v, t, false);\n case $kindInterface:\n if (v === $ifaceNil) {\n return null;\n }\n if (v.constructor === $jsObjectPtr) {\n return v.$val.object;\n }\n return $externalize(v.$val, v.constructor);\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var entry = v[keys[i]];\n m[$externalize(entry.k, t.key)] = $externalize(entry.v, t.elem);\n }\n return m;\n case $kindPtr:\n if (v === t.nil) {\n return null;\n }\n return $externalize(v.$get(), t.elem);\n case $kindSlice:\n if ($needsExternalization(t.elem)) {\n return $mapArray($sliceToArray(v), function(e) {\n return $externalize(e, t.elem);\n });\n }\n return $sliceToArray(v);\n case $kindString:\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\",\n r;\n for (var i = 0; i < v.length; i += r[1]) {\n r = $decodeRune(v, i);\n var c = r[0];\n if (c > 0xffff) {\n var h = Math.floor((c - 0x10000) / 0x400) + 0xd800;\n var l = (c - 0x10000) % 0x400 + 0xdc00;\n s += String.fromCharCode(h, l);\n continue;\n }\n s += String.fromCharCode(c);\n }\n return s;\n case $kindStruct:\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && v.constructor === timePkg.Time.ptr) {\n var milli = $div64(v.UnixNano(), new $Int64(0, 1000000));\n return new Date($flatten64(milli));\n }\n\n var noJsObject = {};\n var searchJsObject = function(v, t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindPtr:\n if (v === t.nil) {\n return noJsObject;\n }\n return searchJsObject(v.$get(), t.elem);\n case $kindStruct:\n var f = t.fields[0];\n return searchJsObject(v[f.prop], f.typ);\n case $kindInterface:\n return searchJsObject(v.$val, v.constructor);\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(v, t);\n if (o !== noJsObject) {\n return o;\n }\n\n o = {};\n for (var i = 0; i < t.fields.length; i++) {\n var f = t.fields[i];\n if (!f.exported) {\n continue;\n }\n o[f.name] = $externalize(v[f.prop], f.typ);\n }\n return o;\n }\n $throwRuntimeError(\"cannot externalize \" + t.string);\n};\n\nvar $externalizeFunction = function(v, t, passThis) {\n if (v === $throwNilPointerError) {\n return null;\n }\n if (v.$externalizeWrapper === undefined) {\n $checkForDeadlock = false;\n v.$externalizeWrapper = function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem,\n varargs = [];\n for (var j = i; j < arguments.length; j++) {\n varargs.push($internalize(arguments[j], vt));\n }\n args.push(new t.params[i](varargs));\n break;\n }\n args.push($internalize(arguments[i], t.params[i]));\n }\n var result = v.apply(passThis ? this : undefined, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $externalize(result, t.results[0]);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $externalize(result[i], t.results[i]);\n }\n return result;\n }\n };\n }\n return v.$externalizeWrapper;\n};\n\nvar $internalize = function(v, t, recv) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n if (v && v.__internal_object__ !== undefined) {\n return $assertType(v.__internal_object__, t, false);\n }\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && t === timePkg.Time) {\n if (!(v !== null && v !== undefined && v.constructor === Date)) {\n $throwRuntimeError(\"cannot internalize time.Time from \" + typeof v + \", must be Date\");\n }\n return timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000));\n }\n switch (t.kind) {\n case $kindBool:\n return !!v;\n case $kindInt:\n return parseInt(v);\n case $kindInt8:\n return (parseInt(v) << 24) >> 24;\n case $kindInt16:\n return (parseInt(v) << 16) >> 16;\n case $kindInt32:\n return parseInt(v) >> 0;\n case $kindUint:\n return parseInt(v);\n case $kindUint8:\n return (parseInt(v) << 24) >>> 24;\n case $kindUint16:\n return (parseInt(v) << 16) >>> 16;\n case $kindUint32:\n case $kindUintptr:\n return parseInt(v) >>> 0;\n case $kindInt64:\n case $kindUint64:\n return new t(0, v);\n case $kindFloat32:\n case $kindFloat64:\n return parseFloat(v);\n case $kindArray:\n if (v.length !== t.len) {\n $throwRuntimeError(\"got array with wrong size from JavaScript native\");\n }\n return $mapArray(v, function(e) {\n return $internalize(e, t.elem);\n });\n case $kindFunc:\n return function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem,\n varargs = arguments[i];\n for (var j = 0; j < varargs.$length; j++) {\n args.push($externalize(varargs.$array[varargs.$offset + j], vt));\n }\n break;\n }\n args.push($externalize(arguments[i], t.params[i]));\n }\n var result = v.apply(recv, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $internalize(result, t.results[0]);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $internalize(result[i], t.results[i]);\n }\n return result;\n }\n };\n case $kindInterface:\n if (t.methods.length !== 0) {\n $throwRuntimeError(\"cannot internalize \" + t.string);\n }\n if (v === null) {\n return $ifaceNil;\n }\n if (v === undefined) {\n return new $jsObjectPtr(undefined);\n }\n switch (v.constructor) {\n case Int8Array:\n return new ($sliceType($Int8))(v);\n case Int16Array:\n return new ($sliceType($Int16))(v);\n case Int32Array:\n return new ($sliceType($Int))(v);\n case Uint8Array:\n return new ($sliceType($Uint8))(v);\n case Uint16Array:\n return new ($sliceType($Uint16))(v);\n case Uint32Array:\n return new ($sliceType($Uint))(v);\n case Float32Array:\n return new ($sliceType($Float32))(v);\n case Float64Array:\n return new ($sliceType($Float64))(v);\n case Array:\n return $internalize(v, $sliceType($emptyInterface));\n case Boolean:\n return new $Bool(!!v);\n case Date:\n if (timePkg === undefined) {\n /* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */\n return new $jsObjectPtr(v);\n }\n return new timePkg.Time($internalize(v, timePkg.Time));\n case Function:\n var funcType = $funcType([$sliceType($emptyInterface)], [$jsObjectPtr], true);\n return new funcType($internalize(v, funcType));\n case Number:\n return new $Float64(parseFloat(v));\n case String:\n return new $String($internalize(v, $String));\n default:\n if ($global.Node && v instanceof $global.Node) {\n return new $jsObjectPtr(v);\n }\n var mapType = $mapType($String, $emptyInterface);\n return new mapType($internalize(v, mapType));\n }\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var k = $internalize(keys[i], t.key);\n m[t.key.keyFor(k)] = { k: k, v: $internalize(v[keys[i]], t.elem) };\n }\n return m;\n case $kindPtr:\n if (t.elem.kind === $kindStruct) {\n return $internalize(v, t.elem);\n }\n case $kindSlice:\n return new t(\n $mapArray(v, function(e) {\n return $internalize(e, t.elem);\n })\n );\n case $kindString:\n v = String(v);\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\";\n var i = 0;\n while (i < v.length) {\n var h = v.charCodeAt(i);\n if (0xd800 <= h && h <= 0xdbff) {\n var l = v.charCodeAt(i + 1);\n var c = (h - 0xd800) * 0x400 + l - 0xdc00 + 0x10000;\n s += $encodeRune(c);\n i += 2;\n continue;\n }\n s += $encodeRune(h);\n i++;\n }\n return s;\n case $kindStruct:\n var noJsObject = {};\n var searchJsObject = function(t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n switch (t.kind) {\n case $kindPtr:\n return searchJsObject(t.elem);\n case $kindStruct:\n var f = t.fields[0];\n var o = searchJsObject(f.typ);\n if (o !== noJsObject) {\n var n = new t.ptr();\n n[f.prop] = o;\n return n;\n }\n return noJsObject;\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(t);\n if (o !== noJsObject) {\n return o;\n }\n }\n $throwRuntimeError(\"cannot internalize \" + t.string);\n};\n\n/* $isASCII reports whether string s contains only ASCII characters. */\nvar $isASCII = function(s) {\n for (var i = 0; i < s.length; i++) {\n if (s.charCodeAt(i) >= 128) {\n return false;\n }\n }\n return true;\n};\n" diff --git a/compiler/prelude/prelude.js b/compiler/prelude/prelude.js index 58ad4e0d3..586161e2c 100644 --- a/compiler/prelude/prelude.js +++ b/compiler/prelude/prelude.js @@ -1,14 +1,18 @@ Error.stackTraceLimit = Infinity; var $global, $module; -if (typeof window !== "undefined") { /* web page */ +if (typeof window !== "undefined") { + /* web page */ $global = window; -} else if (typeof self !== "undefined") { /* web worker */ +} else if (typeof self !== "undefined") { + /* web worker */ $global = self; -} else if (typeof global !== "undefined") { /* Node.js */ +} else if (typeof global !== "undefined") { + /* Node.js */ $global = global; $global.require = require; -} else { /* others (e.g. Nashorn) */ +} else { + /* others (e.g. Nashorn) */ $global = this; } @@ -19,13 +23,24 @@ if (typeof module !== "undefined") { $module = module; } -var $packages = {}, $idCounter = 0; -var $keys = function(m) { return m ? Object.keys(m) : []; }; +var $packages = {}, + $idCounter = 0; +var $keys = function(m) { + return m ? Object.keys(m) : []; +}; var $flushConsole = function() {}; var $throwRuntimeError; /* set by package "runtime" */ -var $throwNilPointerError = function() { $throwRuntimeError("invalid memory address or nil pointer dereference"); }; -var $call = function(fn, rcvr, args) { return fn.apply(rcvr, args); }; -var $makeFunc = function(fn) { return function() { return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface); }; }; +var $throwNilPointerError = function() { + $throwRuntimeError("invalid memory address or nil pointer dereference"); +}; +var $call = function(fn, rcvr, args) { + return fn.apply(rcvr, args); +}; +var $makeFunc = function(fn) { + return function() { + return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface); + }; +}; var $unused = function(v) {}; var $mapArray = function(array, f) { @@ -128,69 +143,69 @@ var $decodeRune = function(str, pos) { return [c0, 1]; } - if (c0 !== c0 || c0 < 0xC0) { - return [0xFFFD, 1]; + if (c0 !== c0 || c0 < 0xc0) { + return [0xfffd, 1]; } var c1 = str.charCodeAt(pos + 1); - if (c1 !== c1 || c1 < 0x80 || 0xC0 <= c1) { - return [0xFFFD, 1]; + if (c1 !== c1 || c1 < 0x80 || 0xc0 <= c1) { + return [0xfffd, 1]; } - if (c0 < 0xE0) { - var r = (c0 & 0x1F) << 6 | (c1 & 0x3F); - if (r <= 0x7F) { - return [0xFFFD, 1]; + if (c0 < 0xe0) { + var r = ((c0 & 0x1f) << 6) | (c1 & 0x3f); + if (r <= 0x7f) { + return [0xfffd, 1]; } return [r, 2]; } var c2 = str.charCodeAt(pos + 2); - if (c2 !== c2 || c2 < 0x80 || 0xC0 <= c2) { - return [0xFFFD, 1]; + if (c2 !== c2 || c2 < 0x80 || 0xc0 <= c2) { + return [0xfffd, 1]; } - if (c0 < 0xF0) { - var r = (c0 & 0x0F) << 12 | (c1 & 0x3F) << 6 | (c2 & 0x3F); - if (r <= 0x7FF) { - return [0xFFFD, 1]; + if (c0 < 0xf0) { + var r = ((c0 & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f); + if (r <= 0x7ff) { + return [0xfffd, 1]; } - if (0xD800 <= r && r <= 0xDFFF) { - return [0xFFFD, 1]; + if (0xd800 <= r && r <= 0xdfff) { + return [0xfffd, 1]; } return [r, 3]; } var c3 = str.charCodeAt(pos + 3); - if (c3 !== c3 || c3 < 0x80 || 0xC0 <= c3) { - return [0xFFFD, 1]; + if (c3 !== c3 || c3 < 0x80 || 0xc0 <= c3) { + return [0xfffd, 1]; } - if (c0 < 0xF8) { - var r = (c0 & 0x07) << 18 | (c1 & 0x3F) << 12 | (c2 & 0x3F) << 6 | (c3 & 0x3F); - if (r <= 0xFFFF || 0x10FFFF < r) { - return [0xFFFD, 1]; + if (c0 < 0xf8) { + var r = ((c0 & 0x07) << 18) | ((c1 & 0x3f) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f); + if (r <= 0xffff || 0x10ffff < r) { + return [0xfffd, 1]; } return [r, 4]; } - return [0xFFFD, 1]; + return [0xfffd, 1]; }; var $encodeRune = function(r) { - if (r < 0 || r > 0x10FFFF || (0xD800 <= r && r <= 0xDFFF)) { - r = 0xFFFD; + if (r < 0 || r > 0x10ffff || (0xd800 <= r && r <= 0xdfff)) { + r = 0xfffd; } - if (r <= 0x7F) { + if (r <= 0x7f) { return String.fromCharCode(r); } - if (r <= 0x7FF) { - return String.fromCharCode(0xC0 | r >> 6, 0x80 | (r & 0x3F)); + if (r <= 0x7ff) { + return String.fromCharCode(0xc0 | (r >> 6), 0x80 | (r & 0x3f)); } - if (r <= 0xFFFF) { - return String.fromCharCode(0xE0 | r >> 12, 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F)); + if (r <= 0xffff) { + return String.fromCharCode(0xe0 | (r >> 12), 0x80 | ((r >> 6) & 0x3f), 0x80 | (r & 0x3f)); } - return String.fromCharCode(0xF0 | r >> 18, 0x80 | (r >> 12 & 0x3F), 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F)); + return String.fromCharCode(0xf0 | (r >> 18), 0x80 | ((r >> 12) & 0x3f), 0x80 | ((r >> 6) & 0x3f), 0x80 | (r & 0x3f)); }; var $stringToBytes = function(str) { @@ -214,7 +229,8 @@ var $bytesToString = function(slice) { var $stringToRunes = function(str) { var array = new Int32Array(str.length); - var rune, j = 0; + var rune, + j = 0; for (var i = 0; i < str.length; i += rune[1], j++) { rune = $decodeRune(str, i); array[j] = rune[0]; @@ -258,18 +274,18 @@ var $copyArray = function(dst, src, dstOffset, srcOffset, n, elem) { } switch (elem.kind) { - case $kindArray: - case $kindStruct: - if (dst === src && dstOffset > srcOffset) { - for (var i = n - 1; i >= 0; i--) { + case $kindArray: + case $kindStruct: + if (dst === src && dstOffset > srcOffset) { + for (var i = n - 1; i >= 0; i--) { + elem.copy(dst[dstOffset + i], src[srcOffset + i]); + } + return; + } + for (var i = 0; i < n; i++) { elem.copy(dst[dstOffset + i], src[srcOffset + i]); } return; - } - for (var i = 0; i < n; i++) { - elem.copy(dst[dstOffset + i], src[srcOffset + i]); - } - return; } if (dst === src && dstOffset > srcOffset) { @@ -290,7 +306,7 @@ var $clone = function(src, type) { }; var $pointerOfStructConversion = function(obj, type) { - if(obj.$proxies === undefined) { + if (obj.$proxies === undefined) { obj.$proxies = {}; obj.$proxies[obj.constructor.string] = obj; } @@ -300,8 +316,12 @@ var $pointerOfStructConversion = function(obj, type) { for (var i = 0; i < type.elem.fields.length; i++) { (function(fieldProp) { properties[fieldProp] = { - get: function() { return obj[fieldProp]; }, - set: function(value) { obj[fieldProp] = value; } + get: function() { + return obj[fieldProp]; + }, + set: function(value) { + obj[fieldProp] = value; + }, }; })(type.elem.fields[i].prop); } @@ -366,34 +386,34 @@ var $equal = function(a, b, type) { return a === b; } switch (type.kind) { - case $kindComplex64: - case $kindComplex128: - return a.$real === b.$real && a.$imag === b.$imag; - case $kindInt64: - case $kindUint64: - return a.$high === b.$high && a.$low === b.$low; - case $kindArray: - if (a.length !== b.length) { - return false; - } - for (var i = 0; i < a.length; i++) { - if (!$equal(a[i], b[i], type.elem)) { + case $kindComplex64: + case $kindComplex128: + return a.$real === b.$real && a.$imag === b.$imag; + case $kindInt64: + case $kindUint64: + return a.$high === b.$high && a.$low === b.$low; + case $kindArray: + if (a.length !== b.length) { return false; } - } - return true; - case $kindStruct: - for (var i = 0; i < type.fields.length; i++) { - var f = type.fields[i]; - if (!$equal(a[f.prop], b[f.prop], f.typ)) { - return false; + for (var i = 0; i < a.length; i++) { + if (!$equal(a[i], b[i], type.elem)) { + return false; + } } - } - return true; - case $kindInterface: - return $interfaceIsEqual(a, b); - default: - return a === b; + return true; + case $kindStruct: + for (var i = 0; i < type.fields.length; i++) { + var f = type.fields[i]; + if (!$equal(a[f.prop], b[f.prop], f.typ)) { + return false; + } + } + return true; + case $kindInterface: + return $interfaceIsEqual(a, b); + default: + return a === b; } }; diff --git a/compiler/prelude/prettier_options.json b/compiler/prelude/prettier_options.json new file mode 100644 index 000000000..4db654bda --- /dev/null +++ b/compiler/prelude/prettier_options.json @@ -0,0 +1,4 @@ +{ + "printWidth": 1000000, + "trailingComma": "es5" +} diff --git a/compiler/prelude/types.js b/compiler/prelude/types.js index e645ab3f5..aef54a2ba 100644 --- a/compiler/prelude/types.js +++ b/compiler/prelude/types.js @@ -34,19 +34,23 @@ var $addMethodSynthesizer = function(f) { $methodSynthesizers.push(f); }; var $synthesizeMethods = function() { - $methodSynthesizers.forEach(function(f) { f(); }); + $methodSynthesizers.forEach(function(f) { + f(); + }); $methodSynthesizers = null; }; var $ifaceKeyFor = function(x) { if (x === $ifaceNil) { - return 'nil'; + return "nil"; } var c = x.constructor; - return c.string + '$' + c.keyFor(x.$val); + return c.string + "$" + c.keyFor(x.$val); }; -var $identity = function(x) { return x; }; +var $identity = function(x) { + return x; +}; var $typeIDCounter = 0; @@ -60,320 +64,385 @@ var $idKey = function(x) { var $newType = function(size, kind, string, named, pkg, exported, constructor) { var typ; - switch(kind) { - case $kindBool: - case $kindInt: - case $kindInt8: - case $kindInt16: - case $kindInt32: - case $kindUint: - case $kindUint8: - case $kindUint16: - case $kindUint32: - case $kindUintptr: - case $kindUnsafePointer: - typ = function(v) { this.$val = v; }; - typ.wrapped = true; - typ.keyFor = $identity; - break; - - case $kindString: - typ = function(v) { this.$val = v; }; - typ.wrapped = true; - typ.keyFor = function(x) { return "$" + x; }; - break; - - case $kindFloat32: - case $kindFloat64: - typ = function(v) { this.$val = v; }; - typ.wrapped = true; - typ.keyFor = function(x) { return $floatKey(x); }; - break; - - case $kindInt64: - typ = function(high, low) { - this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >> 0; - this.$low = low >>> 0; - this.$val = this; - }; - typ.keyFor = function(x) { return x.$high + "$" + x.$low; }; - break; - - case $kindUint64: - typ = function(high, low) { - this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >>> 0; - this.$low = low >>> 0; - this.$val = this; - }; - typ.keyFor = function(x) { return x.$high + "$" + x.$low; }; - break; - - case $kindComplex64: - typ = function(real, imag) { - this.$real = $fround(real); - this.$imag = $fround(imag); - this.$val = this; - }; - typ.keyFor = function(x) { return x.$real + "$" + x.$imag; }; - break; - - case $kindComplex128: - typ = function(real, imag) { - this.$real = real; - this.$imag = imag; - this.$val = this; - }; - typ.keyFor = function(x) { return x.$real + "$" + x.$imag; }; - break; - - case $kindArray: - typ = function(v) { this.$val = v; }; - typ.wrapped = true; - typ.ptr = $newType(4, $kindPtr, "*" + string, false, "", false, function(array) { - this.$get = function() { return array; }; - this.$set = function(v) { typ.copy(this, v); }; - this.$val = array; - }); - typ.init = function(elem, len) { - typ.elem = elem; - typ.len = len; - typ.comparable = elem.comparable; + switch (kind) { + case $kindBool: + case $kindInt: + case $kindInt8: + case $kindInt16: + case $kindInt32: + case $kindUint: + case $kindUint8: + case $kindUint16: + case $kindUint32: + case $kindUintptr: + case $kindUnsafePointer: + typ = function(v) { + this.$val = v; + }; + typ.wrapped = true; + typ.keyFor = $identity; + break; + + case $kindString: + typ = function(v) { + this.$val = v; + }; + typ.wrapped = true; typ.keyFor = function(x) { - return Array.prototype.join.call($mapArray(x, function(e) { - return String(elem.keyFor(e)).replace(/\\/g, "\\\\").replace(/\$/g, "\\$"); - }), "$"); - }; - typ.copy = function(dst, src) { - $copyArray(dst, src, 0, 0, src.length, elem); - }; - typ.ptr.init(typ); - Object.defineProperty(typ.ptr.nil, "nilCheck", { get: $throwNilPointerError }); - }; - break; - - case $kindChan: - typ = function(v) { this.$val = v; }; - typ.wrapped = true; - typ.keyFor = $idKey; - typ.init = function(elem, sendOnly, recvOnly) { - typ.elem = elem; - typ.sendOnly = sendOnly; - typ.recvOnly = recvOnly; - }; - break; - - case $kindFunc: - typ = function(v) { this.$val = v; }; - typ.wrapped = true; - typ.init = function(params, results, variadic) { - typ.params = params; - typ.results = results; - typ.variadic = variadic; - typ.comparable = false; - }; - break; - - case $kindInterface: - typ = { implementedBy: {}, missingMethodFor: {} }; - typ.keyFor = $ifaceKeyFor; - typ.init = function(methods) { - typ.methods = methods; - methods.forEach(function(m) { - $ifaceNil[m.prop] = $throwNilPointerError; - }); - }; - break; - - case $kindMap: - typ = function(v) { this.$val = v; }; - typ.wrapped = true; - typ.init = function(key, elem) { - typ.key = key; - typ.elem = elem; - typ.comparable = false; - }; - break; - - case $kindPtr: - typ = constructor || function(getter, setter, target) { - this.$get = getter; - this.$set = setter; - this.$target = target; - this.$val = this; - }; - typ.keyFor = $idKey; - typ.init = function(elem) { - typ.elem = elem; - typ.wrapped = (elem.kind === $kindArray); - typ.nil = new typ($throwNilPointerError, $throwNilPointerError); - }; - break; - - case $kindSlice: - typ = function(array) { - if (array.constructor !== typ.nativeArray) { - array = new typ.nativeArray(array); - } - this.$array = array; - this.$offset = 0; - this.$length = array.length; - this.$capacity = array.length; - this.$val = this; - }; - typ.init = function(elem) { - typ.elem = elem; - typ.comparable = false; - typ.nativeArray = $nativeArray(elem.kind); - typ.nil = new typ([]); - }; - break; - - case $kindStruct: - typ = function(v) { this.$val = v; }; - typ.wrapped = true; - typ.ptr = $newType(4, $kindPtr, "*" + string, false, pkg, exported, constructor); - typ.ptr.elem = typ; - typ.ptr.prototype.$get = function() { return this; }; - typ.ptr.prototype.$set = function(v) { typ.copy(this, v); }; - typ.init = function(pkgPath, fields) { - typ.pkgPath = pkgPath; - typ.fields = fields; - fields.forEach(function(f) { - if (!f.typ.comparable) { - typ.comparable = false; - } - }); + return "$" + x; + }; + break; + + case $kindFloat32: + case $kindFloat64: + typ = function(v) { + this.$val = v; + }; + typ.wrapped = true; typ.keyFor = function(x) { - var val = x.$val; - return $mapArray(fields, function(f) { - return String(f.typ.keyFor(val[f.prop])).replace(/\\/g, "\\\\").replace(/\$/g, "\\$"); - }).join("$"); - }; - typ.copy = function(dst, src) { - for (var i = 0; i < fields.length; i++) { - var f = fields[i]; - switch (f.typ.kind) { - case $kindArray: - case $kindStruct: - f.typ.copy(dst[f.prop], src[f.prop]); - continue; - default: - dst[f.prop] = src[f.prop]; - continue; - } - } + return $floatKey(x); + }; + break; + + case $kindInt64: + typ = function(high, low) { + this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >> 0; + this.$low = low >>> 0; + this.$val = this; + }; + typ.keyFor = function(x) { + return x.$high + "$" + x.$low; + }; + break; + + case $kindUint64: + typ = function(high, low) { + this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >>> 0; + this.$low = low >>> 0; + this.$val = this; }; - /* nil value */ - var properties = {}; - fields.forEach(function(f) { - properties[f.prop] = { get: $throwNilPointerError, set: $throwNilPointerError }; + typ.keyFor = function(x) { + return x.$high + "$" + x.$low; + }; + break; + + case $kindComplex64: + typ = function(real, imag) { + this.$real = $fround(real); + this.$imag = $fround(imag); + this.$val = this; + }; + typ.keyFor = function(x) { + return x.$real + "$" + x.$imag; + }; + break; + + case $kindComplex128: + typ = function(real, imag) { + this.$real = real; + this.$imag = imag; + this.$val = this; + }; + typ.keyFor = function(x) { + return x.$real + "$" + x.$imag; + }; + break; + + case $kindArray: + typ = function(v) { + this.$val = v; + }; + typ.wrapped = true; + typ.ptr = $newType(4, $kindPtr, "*" + string, false, "", false, function(array) { + this.$get = function() { + return array; + }; + this.$set = function(v) { + typ.copy(this, v); + }; + this.$val = array; }); - typ.ptr.nil = Object.create(constructor.prototype, properties); - typ.ptr.nil.$val = typ.ptr.nil; - /* methods for embedded fields */ - $addMethodSynthesizer(function() { - var synthesizeMethod = function(target, m, f) { - if (target.prototype[m.prop] !== undefined) { return; } - target.prototype[m.prop] = function() { - var v = this.$val[f.prop]; - if (f.typ === $jsObjectPtr) { - v = new $jsObjectPtr(v); - } - if (v.$val === undefined) { - v = new f.typ(v); - } - return v[m.prop].apply(v, arguments); - }; + typ.init = function(elem, len) { + typ.elem = elem; + typ.len = len; + typ.comparable = elem.comparable; + typ.keyFor = function(x) { + return Array.prototype.join.call( + $mapArray(x, function(e) { + return String(elem.keyFor(e)) + .replace(/\\/g, "\\\\") + .replace(/\$/g, "\\$"); + }), + "$" + ); + }; + typ.copy = function(dst, src) { + $copyArray(dst, src, 0, 0, src.length, elem); }; + typ.ptr.init(typ); + Object.defineProperty(typ.ptr.nil, "nilCheck", { get: $throwNilPointerError }); + }; + break; + + case $kindChan: + typ = function(v) { + this.$val = v; + }; + typ.wrapped = true; + typ.keyFor = $idKey; + typ.init = function(elem, sendOnly, recvOnly) { + typ.elem = elem; + typ.sendOnly = sendOnly; + typ.recvOnly = recvOnly; + }; + break; + + case $kindFunc: + typ = function(v) { + this.$val = v; + }; + typ.wrapped = true; + typ.init = function(params, results, variadic) { + typ.params = params; + typ.results = results; + typ.variadic = variadic; + typ.comparable = false; + }; + break; + + case $kindInterface: + typ = { implementedBy: {}, missingMethodFor: {} }; + typ.keyFor = $ifaceKeyFor; + typ.init = function(methods) { + typ.methods = methods; + methods.forEach(function(m) { + $ifaceNil[m.prop] = $throwNilPointerError; + }); + }; + break; + + case $kindMap: + typ = function(v) { + this.$val = v; + }; + typ.wrapped = true; + typ.init = function(key, elem) { + typ.key = key; + typ.elem = elem; + typ.comparable = false; + }; + break; + + case $kindPtr: + typ = + constructor || + function(getter, setter, target) { + this.$get = getter; + this.$set = setter; + this.$target = target; + this.$val = this; + }; + typ.keyFor = $idKey; + typ.init = function(elem) { + typ.elem = elem; + typ.wrapped = elem.kind === $kindArray; + typ.nil = new typ($throwNilPointerError, $throwNilPointerError); + }; + break; + + case $kindSlice: + typ = function(array) { + if (array.constructor !== typ.nativeArray) { + array = new typ.nativeArray(array); + } + this.$array = array; + this.$offset = 0; + this.$length = array.length; + this.$capacity = array.length; + this.$val = this; + }; + typ.init = function(elem) { + typ.elem = elem; + typ.comparable = false; + typ.nativeArray = $nativeArray(elem.kind); + typ.nil = new typ([]); + }; + break; + + case $kindStruct: + typ = function(v) { + this.$val = v; + }; + typ.wrapped = true; + typ.ptr = $newType(4, $kindPtr, "*" + string, false, pkg, exported, constructor); + typ.ptr.elem = typ; + typ.ptr.prototype.$get = function() { + return this; + }; + typ.ptr.prototype.$set = function(v) { + typ.copy(this, v); + }; + typ.init = function(pkgPath, fields) { + typ.pkgPath = pkgPath; + typ.fields = fields; fields.forEach(function(f) { - if (f.anonymous) { - $methodSet(f.typ).forEach(function(m) { - synthesizeMethod(typ, m, f); - synthesizeMethod(typ.ptr, m, f); - }); - $methodSet($ptrType(f.typ)).forEach(function(m) { - synthesizeMethod(typ.ptr, m, f); - }); + if (!f.typ.comparable) { + typ.comparable = false; } }); - }); - }; - break; + typ.keyFor = function(x) { + var val = x.$val; + return $mapArray(fields, function(f) { + return String(f.typ.keyFor(val[f.prop])) + .replace(/\\/g, "\\\\") + .replace(/\$/g, "\\$"); + }).join("$"); + }; + typ.copy = function(dst, src) { + for (var i = 0; i < fields.length; i++) { + var f = fields[i]; + switch (f.typ.kind) { + case $kindArray: + case $kindStruct: + f.typ.copy(dst[f.prop], src[f.prop]); + continue; + default: + dst[f.prop] = src[f.prop]; + continue; + } + } + }; + /* nil value */ + var properties = {}; + fields.forEach(function(f) { + properties[f.prop] = { get: $throwNilPointerError, set: $throwNilPointerError }; + }); + typ.ptr.nil = Object.create(constructor.prototype, properties); + typ.ptr.nil.$val = typ.ptr.nil; + /* methods for embedded fields */ + $addMethodSynthesizer(function() { + var synthesizeMethod = function(target, m, f) { + if (target.prototype[m.prop] !== undefined) { + return; + } + target.prototype[m.prop] = function() { + var v = this.$val[f.prop]; + if (f.typ === $jsObjectPtr) { + v = new $jsObjectPtr(v); + } + if (v.$val === undefined) { + v = new f.typ(v); + } + return v[m.prop].apply(v, arguments); + }; + }; + fields.forEach(function(f) { + if (f.anonymous) { + $methodSet(f.typ).forEach(function(m) { + synthesizeMethod(typ, m, f); + synthesizeMethod(typ.ptr, m, f); + }); + $methodSet($ptrType(f.typ)).forEach(function(m) { + synthesizeMethod(typ.ptr, m, f); + }); + } + }); + }); + }; + break; - default: - $panic(new $String("invalid kind: " + kind)); + default: + $panic(new $String("invalid kind: " + kind)); } switch (kind) { - case $kindBool: - case $kindMap: - typ.zero = function() { return false; }; - break; - - case $kindInt: - case $kindInt8: - case $kindInt16: - case $kindInt32: - case $kindUint: - case $kindUint8 : - case $kindUint16: - case $kindUint32: - case $kindUintptr: - case $kindUnsafePointer: - case $kindFloat32: - case $kindFloat64: - typ.zero = function() { return 0; }; - break; - - case $kindString: - typ.zero = function() { return ""; }; - break; - - case $kindInt64: - case $kindUint64: - case $kindComplex64: - case $kindComplex128: - var zero = new typ(0, 0); - typ.zero = function() { return zero; }; - break; - - case $kindPtr: - case $kindSlice: - typ.zero = function() { return typ.nil; }; - break; - - case $kindChan: - typ.zero = function() { return $chanNil; }; - break; - - case $kindFunc: - typ.zero = function() { return $throwNilPointerError; }; - break; - - case $kindInterface: - typ.zero = function() { return $ifaceNil; }; - break; - - case $kindArray: - typ.zero = function() { - var arrayClass = $nativeArray(typ.elem.kind); - if (arrayClass !== Array) { - return new arrayClass(typ.len); - } - var array = new Array(typ.len); - for (var i = 0; i < typ.len; i++) { - array[i] = typ.elem.zero(); - } - return array; - }; - break; + case $kindBool: + case $kindMap: + typ.zero = function() { + return false; + }; + break; + + case $kindInt: + case $kindInt8: + case $kindInt16: + case $kindInt32: + case $kindUint: + case $kindUint8: + case $kindUint16: + case $kindUint32: + case $kindUintptr: + case $kindUnsafePointer: + case $kindFloat32: + case $kindFloat64: + typ.zero = function() { + return 0; + }; + break; - case $kindStruct: - typ.zero = function() { return new typ.ptr(); }; - break; + case $kindString: + typ.zero = function() { + return ""; + }; + break; + + case $kindInt64: + case $kindUint64: + case $kindComplex64: + case $kindComplex128: + var zero = new typ(0, 0); + typ.zero = function() { + return zero; + }; + break; + + case $kindPtr: + case $kindSlice: + typ.zero = function() { + return typ.nil; + }; + break; + + case $kindChan: + typ.zero = function() { + return $chanNil; + }; + break; + + case $kindFunc: + typ.zero = function() { + return $throwNilPointerError; + }; + break; + + case $kindInterface: + typ.zero = function() { + return $ifaceNil; + }; + break; + + case $kindArray: + typ.zero = function() { + var arrayClass = $nativeArray(typ.elem.kind); + if (arrayClass !== Array) { + return new arrayClass(typ.len); + } + var array = new Array(typ.len); + for (var i = 0; i < typ.len; i++) { + array[i] = typ.elem.zero(); + } + return array; + }; + break; - default: - $panic(new $String("invalid kind: " + kind)); + case $kindStruct: + typ.zero = function() { + return new typ.ptr(); + }; + break; + + default: + $panic(new $String("invalid kind: " + kind)); } typ.id = $typeIDCounter; @@ -396,13 +465,13 @@ var $methodSet = function(typ) { } var base = {}; - var isPtr = (typ.kind === $kindPtr); + var isPtr = typ.kind === $kindPtr; if (isPtr && typ.elem.kind === $kindInterface) { typ.methodSetCache = []; return []; } - var current = [{typ: isPtr ? typ.elem : typ, indirect: isPtr}]; + var current = [{ typ: isPtr ? typ.elem : typ, indirect: isPtr }]; var seen = {}; @@ -424,19 +493,19 @@ var $methodSet = function(typ) { } switch (e.typ.kind) { - case $kindStruct: - e.typ.fields.forEach(function(f) { - if (f.anonymous) { - var fTyp = f.typ; - var fIsPtr = (fTyp.kind === $kindPtr); - next.push({typ: fIsPtr ? fTyp.elem : fTyp, indirect: e.indirect || fIsPtr}); - } - }); - break; + case $kindStruct: + e.typ.fields.forEach(function(f) { + if (f.anonymous) { + var fTyp = f.typ; + var fIsPtr = fTyp.kind === $kindPtr; + next.push({ typ: fIsPtr ? fTyp.elem : fTyp, indirect: e.indirect || fIsPtr }); + } + }); + break; - case $kindInterface: - mset = mset.concat(e.typ.methods); - break; + case $kindInterface: + mset = mset.concat(e.typ.methods); + break; } }); @@ -450,57 +519,59 @@ var $methodSet = function(typ) { } typ.methodSetCache = []; - Object.keys(base).sort().forEach(function(name) { - typ.methodSetCache.push(base[name]); - }); + Object.keys(base) + .sort() + .forEach(function(name) { + typ.methodSetCache.push(base[name]); + }); return typ.methodSetCache; }; -var $Bool = $newType( 1, $kindBool, "bool", true, "", false, null); -var $Int = $newType( 4, $kindInt, "int", true, "", false, null); -var $Int8 = $newType( 1, $kindInt8, "int8", true, "", false, null); -var $Int16 = $newType( 2, $kindInt16, "int16", true, "", false, null); -var $Int32 = $newType( 4, $kindInt32, "int32", true, "", false, null); -var $Int64 = $newType( 8, $kindInt64, "int64", true, "", false, null); -var $Uint = $newType( 4, $kindUint, "uint", true, "", false, null); -var $Uint8 = $newType( 1, $kindUint8, "uint8", true, "", false, null); -var $Uint16 = $newType( 2, $kindUint16, "uint16", true, "", false, null); -var $Uint32 = $newType( 4, $kindUint32, "uint32", true, "", false, null); -var $Uint64 = $newType( 8, $kindUint64, "uint64", true, "", false, null); -var $Uintptr = $newType( 4, $kindUintptr, "uintptr", true, "", false, null); -var $Float32 = $newType( 4, $kindFloat32, "float32", true, "", false, null); -var $Float64 = $newType( 8, $kindFloat64, "float64", true, "", false, null); -var $Complex64 = $newType( 8, $kindComplex64, "complex64", true, "", false, null); -var $Complex128 = $newType(16, $kindComplex128, "complex128", true, "", false, null); -var $String = $newType( 8, $kindString, "string", true, "", false, null); -var $UnsafePointer = $newType( 4, $kindUnsafePointer, "unsafe.Pointer", true, "", false, null); +var $Bool = $newType(1, $kindBool, "bool", true, "", false, null); +var $Int = $newType(4, $kindInt, "int", true, "", false, null); +var $Int8 = $newType(1, $kindInt8, "int8", true, "", false, null); +var $Int16 = $newType(2, $kindInt16, "int16", true, "", false, null); +var $Int32 = $newType(4, $kindInt32, "int32", true, "", false, null); +var $Int64 = $newType(8, $kindInt64, "int64", true, "", false, null); +var $Uint = $newType(4, $kindUint, "uint", true, "", false, null); +var $Uint8 = $newType(1, $kindUint8, "uint8", true, "", false, null); +var $Uint16 = $newType(2, $kindUint16, "uint16", true, "", false, null); +var $Uint32 = $newType(4, $kindUint32, "uint32", true, "", false, null); +var $Uint64 = $newType(8, $kindUint64, "uint64", true, "", false, null); +var $Uintptr = $newType(4, $kindUintptr, "uintptr", true, "", false, null); +var $Float32 = $newType(4, $kindFloat32, "float32", true, "", false, null); +var $Float64 = $newType(8, $kindFloat64, "float64", true, "", false, null); +var $Complex64 = $newType(8, $kindComplex64, "complex64", true, "", false, null); +var $Complex128 = $newType(16, $kindComplex128, "complex128", true, "", false, null); +var $String = $newType(8, $kindString, "string", true, "", false, null); +var $UnsafePointer = $newType(4, $kindUnsafePointer, "unsafe.Pointer", true, "", false, null); var $nativeArray = function(elemKind) { switch (elemKind) { - case $kindInt: - return Int32Array; - case $kindInt8: - return Int8Array; - case $kindInt16: - return Int16Array; - case $kindInt32: - return Int32Array; - case $kindUint: - return Uint32Array; - case $kindUint8: - return Uint8Array; - case $kindUint16: - return Uint16Array; - case $kindUint32: - return Uint32Array; - case $kindUintptr: - return Uint32Array; - case $kindFloat32: - return Float32Array; - case $kindFloat64: - return Float64Array; - default: - return Array; + case $kindInt: + return Int32Array; + case $kindInt8: + return Int8Array; + case $kindInt16: + return Int16Array; + case $kindInt32: + return Int32Array; + case $kindUint: + return Uint32Array; + case $kindUint8: + return Uint8Array; + case $kindUint16: + return Uint16Array; + case $kindUint32: + return Uint32Array; + case $kindUintptr: + return Uint32Array; + case $kindFloat32: + return Float32Array; + case $kindFloat64: + return Float64Array; + default: + return Array; } }; var $toNativeArray = function(elemKind, array) { @@ -524,7 +595,7 @@ var $arrayType = function(elem, len) { var $chanType = function(elem, sendOnly, recvOnly) { var string = (recvOnly ? "<-" : "") + "chan" + (sendOnly ? "<- " : " ") + elem.string; - var field = sendOnly ? "SendChan" : (recvOnly ? "RecvChan" : "Chan"); + var field = sendOnly ? "SendChan" : recvOnly ? "RecvChan" : "Chan"; var typ = elem[field]; if (typ === undefined) { typ = $newType(4, $kindChan, string, false, "", false, null); @@ -545,14 +616,34 @@ var $Chan = function(elem, capacity) { this.$closed = false; }; var $chanNil = new $Chan(null, 0); -$chanNil.$sendQueue = $chanNil.$recvQueue = { length: 0, push: function() {}, shift: function() { return undefined; }, indexOf: function() { return -1; } }; +$chanNil.$sendQueue = $chanNil.$recvQueue = { + length: 0, + push: function() {}, + shift: function() { + return undefined; + }, + indexOf: function() { + return -1; + }, +}; var $funcTypes = {}; var $funcType = function(params, results, variadic) { - var typeKey = $mapArray(params, function(p) { return p.id; }).join(",") + "$" + $mapArray(results, function(r) { return r.id; }).join(",") + "$" + variadic; + var typeKey = + $mapArray(params, function(p) { + return p.id; + }).join(",") + + "$" + + $mapArray(results, function(r) { + return r.id; + }).join(",") + + "$" + + variadic; var typ = $funcTypes[typeKey]; if (typ === undefined) { - var paramTypes = $mapArray(params, function(p) { return p.string; }); + var paramTypes = $mapArray(params, function(p) { + return p.string; + }); if (variadic) { paramTypes[paramTypes.length - 1] = "..." + paramTypes[paramTypes.length - 1].substr(2); } @@ -560,7 +651,12 @@ var $funcType = function(params, results, variadic) { if (results.length === 1) { string += " " + results[0].string; } else if (results.length > 1) { - string += " (" + $mapArray(results, function(r) { return r.string; }).join(", ") + ")"; + string += + " (" + + $mapArray(results, function(r) { + return r.string; + }).join(", ") + + ")"; } typ = $newType(4, $kindFunc, string, false, "", false, null); $funcTypes[typeKey] = typ; @@ -571,14 +667,19 @@ var $funcType = function(params, results, variadic) { var $interfaceTypes = {}; var $interfaceType = function(methods) { - var typeKey = $mapArray(methods, function(m) { return m.pkg + "," + m.name + "," + m.typ.id; }).join("$"); + var typeKey = $mapArray(methods, function(m) { + return m.pkg + "," + m.name + "," + m.typ.id; + }).join("$"); var typ = $interfaceTypes[typeKey]; if (typ === undefined) { var string = "interface {}"; if (methods.length !== 0) { - string = "interface { " + $mapArray(methods, function(m) { - return (m.pkg !== "" ? m.pkg + "." : "") + m.name + m.typ.string.substr(4); - }).join("; ") + " }"; + string = + "interface { " + + $mapArray(methods, function(m) { + return (m.pkg !== "" ? m.pkg + "." : "") + m.name + m.typ.string.substr(4); + }).join("; ") + + " }"; } typ = $newType(8, $kindInterface, string, false, "", false, null); $interfaceTypes[typeKey] = typ; @@ -589,7 +690,7 @@ var $interfaceType = function(methods) { var $emptyInterface = $interfaceType([]); var $ifaceNil = {}; var $error = $newType(8, $kindInterface, "error", true, "", false, null); -$error.init([{prop: "Error", name: "Error", pkg: "", typ: $funcType([], [$String], false)}]); +$error.init([{ prop: "Error", name: "Error", pkg: "", typ: $funcType([], [$String], false) }]); var $mapTypes = {}; var $mapType = function(key, elem) { @@ -625,12 +726,29 @@ var $newDataPointer = function(data, constructor) { if (constructor.elem.kind === $kindStruct) { return data; } - return new constructor(function() { return data; }, function(v) { data = v; }); + return new constructor( + function() { + return data; + }, + function(v) { + data = v; + } + ); }; var $indexPtr = function(array, index, constructor) { array.$ptr = array.$ptr || {}; - return array.$ptr[index] || (array.$ptr[index] = new constructor(function() { return array[index]; }, function(v) { array[index] = v; })); + return ( + array.$ptr[index] || + (array.$ptr[index] = new constructor( + function() { + return array[index]; + }, + function(v) { + array[index] = v; + } + )) + ); }; var $sliceType = function(elem) { @@ -663,12 +781,17 @@ var $makeSlice = function(typ, length, capacity) { var $structTypes = {}; var $structType = function(pkgPath, fields) { - var typeKey = $mapArray(fields, function(f) { return f.name + "," + f.typ.id + "," + f.tag; }).join("$"); + var typeKey = $mapArray(fields, function(f) { + return f.name + "," + f.typ.id + "," + f.tag; + }).join("$"); var typ = $structTypes[typeKey]; if (typ === undefined) { - var string = "struct { " + $mapArray(fields, function(f) { - return f.name + " " + f.typ.string + (f.tag !== "" ? (" \"" + f.tag.replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + "\"") : ""); - }).join("; ") + " }"; + var string = + "struct { " + + $mapArray(fields, function(f) { + return f.name + " " + f.typ.string + (f.tag !== "" ? ' "' + f.tag.replace(/\\/g, "\\\\").replace(/"/g, '\\"') + '"' : ""); + }).join("; ") + + " }"; if (fields.length === 0) { string = "struct {}"; } @@ -687,7 +810,9 @@ var $structType = function(pkgPath, fields) { }; var $assertType = function(value, type, returnTuple) { - var isInterface = (type.kind === $kindInterface), ok, missingMethod = ""; + var isInterface = type.kind === $kindInterface, + ok, + missingMethod = ""; if (value === $ifaceNil) { ok = false; } else if (!isInterface) { @@ -726,7 +851,7 @@ var $assertType = function(value, type, returnTuple) { if (returnTuple) { return [type.zero(), false]; } - $panic(new $packages["runtime"].TypeAssertionError.ptr("", (value === $ifaceNil ? "" : value.constructor.string), type.string, missingMethod)); + $panic(new $packages["runtime"].TypeAssertionError.ptr("", value === $ifaceNil ? "" : value.constructor.string, type.string, missingMethod)); } if (!isInterface) { diff --git a/package-lock.json b/package-lock.json index ed79b7a9b..057edb3e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,19 +6,25 @@ "commander": { "version": "2.13.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", - "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", + "integrity": "sha1-aWS8pnaF33wfFDDFhPB9dZeIW5w=", + "dev": true + }, + "prettier": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.12.0.tgz", + "integrity": "sha512-Wz0SMncgaglBzDcohH3ZIAi4nVpzOIEweFzCOmgVEoRSeO72b4dcKGfgxoRGVMaFlh1r7dlVaJ+f3CIHfeH6xg==", "dev": true }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", "dev": true }, "uglify-es": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", - "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", + "integrity": "sha1-DBxPBwC+2NvBJM2zBNJZLKID5nc=", "dev": true, "requires": { "commander": "2.13.0", diff --git a/package.json b/package.json index e74269587..183ba6139 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "gopherjs", "devDependencies": { - "uglify-es": "3.3.9" + "uglify-es": "3.3.9", + "prettier": "1.12.0" } } From 89cfdc69a830d12224d8872c0761905b1f015bd0 Mon Sep 17 00:00:00 2001 From: Paul Jolly Date: Mon, 2 Jul 2018 20:59:43 +0100 Subject: [PATCH 05/10] compiler: use hash calculation for determining staleness (#5) --- build/build.go | 176 +++++++++++++++++++++++++++----------- compiler/compiler.go | 1 + staleness_test.go | 197 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 326 insertions(+), 48 deletions(-) create mode 100644 staleness_test.go diff --git a/build/build.go b/build/build.go index 82edb1f24..ffd8655f0 100644 --- a/build/build.go +++ b/build/build.go @@ -1,6 +1,8 @@ package build import ( + "bytes" + "crypto/sha256" "fmt" "go/ast" "go/build" @@ -15,9 +17,9 @@ import ( "path" "path/filepath" "runtime" + "sort" "strconv" "strings" - "time" "github.com/fsnotify/fsnotify" "github.com/gopherjs/gopherjs/compiler" @@ -28,6 +30,25 @@ import ( "golang.org/x/tools/go/buildutil" ) +const ( + hashDebug = false +) + +var ( + compilerBinaryHash string +) + +func init() { + // We do this here because it will only fail in truly bad situations, i.e. + // machine running out of resources. We also panic if there is a problem + // because it's unlikely anything else will be useful/work + h, err := hashCompilerBinary() + if err != nil { + panic(err) + } + compilerBinaryHash = h +} + type ImportCError struct { pkgPath string } @@ -457,11 +478,10 @@ func (o *Options) PrintSuccess(format string, a ...interface{}) { type PackageData struct { *build.Package - JSFiles []string - IsTest bool // IsTest is true if the package is being built for running tests. - SrcModTime time.Time - UpToDate bool - IsVirtual bool // If true, the package does not have a corresponding physical directory on disk. + JSFiles []string + IsTest bool // IsTest is true if the package is being built for running tests. + UpToDate bool + IsVirtual bool // If true, the package does not have a corresponding physical directory on disk. } type Session struct { @@ -591,24 +611,64 @@ func (s *Session) buildImportPathWithSrcDir(path string, srcDir string) (*Packag return pkg, archive, nil } +func hashCompilerBinary() (string, error) { + if compilerBinaryHash != "" { + return compilerBinaryHash, nil + } + + binHash := sha256.New() + binPath, err := os.Executable() + if err != nil { + return "", fmt.Errorf("could not locate GopherJS binary: %v", err) + } + binFile, err := os.Open(binPath) + if err != nil { + return "", fmt.Errorf("could not open %v: %v", binPath, err) + } + defer binFile.Close() + if _, err := io.Copy(binHash, binFile); err != nil { + return "", fmt.Errorf("failed to hash %v: %v", binPath, err) + } + compilerBinaryHash = fmt.Sprintf("%#x", binHash.Sum(nil)) + return compilerBinaryHash, nil +} + func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) { if archive, ok := s.Archives[pkg.ImportPath]; ok { return archive, nil } + // For non-main and test packages we build up a hash that will help + // determine staleness. Set hashDebug to see this in action. The format is: + // + // ## + // compiler binary hash: 0x519d22c6ab65a950f5b6278e4d65cb75dbd3a7eb1cf16e976a40b9f1febc0446 + // build tags: + // import: + // hash: 0xb966d7680c1c8ca75026f993c153aff0102dc9551f314e5352043187b5f9c9a6 + // ... + // + // file: + // + // N bytes + // ... + + pkgHash := sha256.New() + var hw io.Writer = pkgHash + var hashDebugOut *bytes.Buffer + if hashDebug { + hashDebugOut = new(bytes.Buffer) + hw = io.MultiWriter(hashDebugOut, pkgHash) + } + if pkg.PkgObj != "" { - var fileInfo os.FileInfo - gopherjsBinary, err := os.Executable() - if err == nil { - fileInfo, err = os.Stat(gopherjsBinary) - if err == nil { - pkg.SrcModTime = fileInfo.ModTime() - } - } - if err != nil { - os.Stderr.WriteString("Could not get GopherJS binary's modification timestamp. Please report issue.\n") - pkg.SrcModTime = time.Now() - } + fmt.Fprintf(hw, "## %v\n", pkg.ImportPath) + fmt.Fprintf(hw, "compiler binary hash: %v\n", compilerBinaryHash) + + orderedBuildTags := append([]string{}, s.options.BuildTags...) + sort.Strings(orderedBuildTags) + + fmt.Fprintf(hw, "build tags: %v\n", strings.Join(orderedBuildTags, ",")) for _, importedPkgPath := range pkg.Imports { // Ignore all imports that aren't mentioned in import specs of pkg. @@ -630,50 +690,72 @@ func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) { if importedPkgPath == "unsafe" || ignored { continue } - importedPkg, _, err := s.buildImportPathWithSrcDir(importedPkgPath, pkg.Dir) + _, importedArchive, err := s.buildImportPathWithSrcDir(importedPkgPath, pkg.Dir) if err != nil { return nil, err } - impModTime := importedPkg.SrcModTime - if impModTime.After(pkg.SrcModTime) { - pkg.SrcModTime = impModTime - } + + fmt.Fprintf(hw, "import: %v\n", importedPkgPath) + fmt.Fprintf(hw, " hash: %#x\n", importedArchive.Hash) } for _, name := range append(pkg.GoFiles, pkg.JSFiles...) { - fileInfo, err := statFile(filepath.Join(pkg.Dir, name)) - if err != nil { - return nil, err + hashFile := func() error { + fp := filepath.Join(pkg.Dir, name) + file, err := s.bctx.OpenFile(fp) + if err != nil { + return fmt.Errorf("failed to open %v: %v", fp, err) + } + defer file.Close() + fmt.Fprintf(hw, "file: %v\n", fp) + n, err := io.Copy(hw, file) + if err != nil { + return fmt.Errorf("failed to hash file contents: %v", err) + } + fmt.Fprintf(hw, "%d bytes\n", n) + return nil } - if fileInfo.ModTime().After(pkg.SrcModTime) { - pkg.SrcModTime = fileInfo.ModTime() + + if err := hashFile(); err != nil { + return nil, fmt.Errorf("failed to hash file %v: %v", name, err) } } - pkgObjFileInfo, err := os.Stat(pkg.PkgObj) - if err == nil && !pkg.SrcModTime.After(pkgObjFileInfo.ModTime()) { - // package object is up to date, load from disk if library - pkg.UpToDate = true - if pkg.IsCommand() { - return nil, nil - } + if hashDebug { + fmt.Printf("%s", hashDebugOut.String()) + } - objFile, err := os.Open(pkg.PkgObj) - if err != nil { - return nil, err - } - defer objFile.Close() + // no commands are archived + if pkg.IsCommand() { + goto CacheMiss + } - archive, err := compiler.ReadArchive(pkg.PkgObj, pkg.ImportPath, objFile, s.Types) - if err != nil { - return nil, err + objFile, err := os.Open(pkg.PkgObj) + if err != nil { + if os.IsNotExist(err) { + goto CacheMiss } + return nil, err + } + defer objFile.Close() + archive, err := compiler.ReadArchive(pkg.PkgObj, pkg.ImportPath, objFile, s.Types) + if err != nil { + return nil, err + } + + if bytes.Equal(archive.Hash, pkgHash.Sum(nil)) { s.Archives[pkg.ImportPath] = archive - return archive, err + return archive, nil } } +CacheMiss: + + if s.options.Verbose { + fmt.Printf("Cache miss for %v\n", pkg.ImportPath) + } + fileSet := token.NewFileSet() files, err := parseAndAugment(s.bctx, pkg.Package, pkg.IsTest, fileSet) if err != nil { @@ -700,6 +782,8 @@ func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) { return nil, err } + archive.Hash = pkgHash.Sum(nil) + for _, jsFile := range pkg.JSFiles { code, err := ioutil.ReadFile(filepath.Join(pkg.Dir, jsFile)) if err != nil { @@ -710,10 +794,6 @@ func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) { archive.IncJSCode = append(archive.IncJSCode, []byte("\n\t}).call($global);\n")...) } - if s.options.Verbose { - fmt.Println(pkg.ImportPath) - } - s.Archives[pkg.ImportPath] = archive if pkg.PkgObj == "" || pkg.IsCommand() { diff --git a/compiler/compiler.go b/compiler/compiler.go index c5828514e..b4756ee5a 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -32,6 +32,7 @@ func (err ErrorList) Error() string { } type Archive struct { + Hash []byte ImportPath string Name string Imports []string diff --git a/staleness_test.go b/staleness_test.go new file mode 100644 index 000000000..21c7bfa65 --- /dev/null +++ b/staleness_test.go @@ -0,0 +1,197 @@ +package main_test + +import ( + "fmt" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "testing" + "time" +) + +func TestBasicHashStaleness(t *testing.T) { + defer func() { + err := recover() + if err != nil { + t.Fatalf("got an expected error: %v", err.(error)) + } + }() + + h := newHashTester(t) + + td := h.tempDir() + defer os.RemoveAll(td) + h.setEnv("GOPATH", td) + h.dir = h.mkdir(td, "src", "example.com", "rubbish") + h.mkdir(h.dir, "blah") + h.writeFile("main.go", ` + package main + import "example.com/rubbish/blah" + func main() { + print(blah.Name) + } + `) + h.writeFile(filepath.Join("blah", "blah.go"), ` + package blah + const Name = "blah" + `) + m := filepath.Join(td, "bin", "rubbish.js") + a := filepath.Join(td, "pkg", fmt.Sprintf("%v_js", runtime.GOOS), "example.com", "rubbish", "blah.a") + + // variables to hold the current (c) and new (n) archive (a) and main (m) + // os.FileInfos + var ca, cm, na, nm os.FileInfo + + // at this point neither main nor archive should exist + if h.statFile(m) != nil { + t.Fatalf("main %v existed when it shouldn't have", m) + } + if h.statFile(a) != nil { + t.Fatalf("archive %v existed when it shouldn't have", a) + } + + h.run("gopherjs", "install", "example.com/rubbish") + + // now both main and the archive should exist + ca = h.statFile(a) + if ca == nil { + t.Fatalf("archive %v should exist but doesn't", a) + } + cm = h.statFile(m) + if cm == nil { + t.Fatalf("main %v should exist but doesn't", a) + } + + // re-running the install will cause main to be rewritten; not the package archive + h.run("gopherjs", "install", "example.com/rubbish") + nm = h.statFile(m) + if !nm.ModTime().After(cm.ModTime()) { + t.Fatalf("expected to see modified main file %v; got %v; prev %v", m, nm.ModTime(), cm.ModTime()) + } + cm = nm + if na := h.statFile(a); !na.ModTime().Equal(ca.ModTime()) { + t.Fatalf("expected not to see modified archive file %v; got %v; want %v", a, na.ModTime(), ca.ModTime()) + } + + // touching the package file should have no effect on the archive + h.touch(filepath.Join("blah", "blah.go")) + h.run("gopherjs", "install", "example.com/rubbish/blah") // only install the package here + if na := h.statFile(a); !na.ModTime().Equal(ca.ModTime()) { + t.Fatalf("expected not to see modified archive file %v; got %v; want %v", a, na.ModTime(), ca.ModTime()) + } + + // now update package file - should cause modification time change + h.writeFile(filepath.Join("blah", "blah.go"), ` + package blah + const Name = "GopherJS" + `) + h.run("gopherjs", "install", "example.com/rubbish") + na = h.statFile(a) + if !na.ModTime().After(ca.ModTime()) { + t.Fatalf("expected to see modified archive file %v; got %v; prev %v", a, na.ModTime(), ca.ModTime()) + } + ca = na + + // now change build tags - should cause modification time change + h.run("gopherjs", "install", "--tags", "asdf", "example.com/rubbish") + na = h.statFile(a) + if !na.ModTime().After(ca.ModTime()) { + t.Fatalf("expected to see modified archive file %v; got %v; prev %v", a, na.ModTime(), ca.ModTime()) + } + ca = na +} + +type hashTester struct { + t *testing.T + dir string + env []string +} + +func newHashTester(t *testing.T) *hashTester { + wd, err := os.Getwd() + if err != nil { + fatalf("run failed to get working directory: %v", err) + } + return &hashTester{ + t: t, + dir: wd, + env: os.Environ(), + } +} + +func (h *hashTester) touch(path string) { + path = filepath.Join(h.dir, path) + now := time.Now().UTC() + if err := os.Chtimes(path, now, now); err != nil { + fatalf("failed to touch %v: %v", path, err) + } +} + +func (h *hashTester) statFile(path string) os.FileInfo { + fi, err := os.Stat(path) + if err != nil { + if os.IsNotExist(err) { + return nil + } + fatalf("failed to stat %v: %v", path, err) + } + + return fi +} + +func (h *hashTester) setEnv(key, val string) { + newEnv := []string{fmt.Sprintf("%v=%v", key, val)} + for _, e := range h.env { + if !strings.HasPrefix(e, key+"=") { + newEnv = append(newEnv, e) + } + } + h.env = newEnv +} + +func (h *hashTester) mkdir(dirs ...string) string { + d := filepath.Join(dirs...) + if err := os.MkdirAll(d, 0755); err != nil { + fatalf("failed to mkdir %v: %v\n", d, err) + } + return d +} + +func (h *hashTester) writeFile(path, contents string) { + path = filepath.Join(h.dir, path) + if err := ioutil.WriteFile(path, []byte(contents), 0644); err != nil { + fatalf("failed to write file %v: %v", path, err) + } +} + +func (h *hashTester) tempDir() string { + h.t.Helper() + + td, err := ioutil.TempDir("", "gopherjs_hashTester") + if err != nil { + fatalf("failed to create temp dir: %v", err) + } + + return td +} + +func (h *hashTester) run(c string, args ...string) { + h.t.Helper() + + cmd := exec.Command(c, args...) + cmd.Dir = h.dir + cmd.Env = h.env + + out, err := cmd.CombinedOutput() + if err != nil { + fullCmd := append([]string{c}, args...) + fatalf("failed to run %v: %v\n%v", strings.Join(fullCmd, " "), err, string(out)) + } +} + +func fatalf(format string, args ...interface{}) { + panic(fmt.Errorf(format, args...)) +} From bd71904b00d2886407fcbb5f229696bed03f245f Mon Sep 17 00:00:00 2001 From: Paul Jolly Date: Mon, 2 Jul 2018 21:23:12 +0100 Subject: [PATCH 06/10] compiler: fix variadic args not being nil when zero length. (#6) --- compiler/utils.go | 4 ++++ tests/compiler_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tests/compiler_test.go diff --git a/compiler/utils.go b/compiler/utils.go index d5452e0a6..98e3ed3c0 100644 --- a/compiler/utils.go +++ b/compiler/utils.go @@ -95,6 +95,10 @@ func (c *funcContext) translateArgs(sig *types.Signature, argExprs []ast.Expr, e varargType = sig.Params().At(paramsLen - 1).Type().(*types.Slice) } + if sig.Variadic() && len(argExprs) == 0 { + return []string{fmt.Sprintf("%s.nil", c.typeName(varargType))} + } + preserveOrder := false for i := 1; i < len(argExprs); i++ { preserveOrder = preserveOrder || c.Blocking[argExprs[i]] diff --git a/tests/compiler_test.go b/tests/compiler_test.go new file mode 100644 index 000000000..1ed209596 --- /dev/null +++ b/tests/compiler_test.go @@ -0,0 +1,29 @@ +package tests + +import ( + "testing" +) + +func TestVariadicNil(t *testing.T) { + printVari := func(strs ...string) []string { + return strs + } + + if got := printVari(); got != nil { + t.Errorf("printVari(): got: %#v; want %#v.", got, nil) + } + + { + var want []string + if got := printVari(want...); got != nil { + t.Errorf("printVari(want...): got: %#v; want %#v.", got, nil) + } + } + + { + want := []string{} + if got := printVari(want...); got == nil || len(got) != len(want) { + t.Errorf("printVari(want...): got: %#v; want %#v.", got, want) + } + } +} From e13dc1aefa91d0f55ccf30757d6b1e82173f11fd Mon Sep 17 00:00:00 2001 From: Paul Jolly Date: Mon, 2 Jul 2018 21:40:43 +0100 Subject: [PATCH 07/10] vendor: vendor go/types to workaround bug in method set calc. (#7) Per https://github.com/golang/go/issues/25008#issuecomment-385553082 the fix for method set calculation will not be back ported to Go 1.10. Instead gri suggests we vendor the latest version of go/types. This PR does just that. It is effectively a temporary sticking plaster until Go 1.11 lands, or more specifically until we release GopherJS for Go 1.11. In order to successfully vendor go/types, however, we need to move compiler/vendor to the repo root (because build also uses go/types). And because golang.org/x/tools/go/gcexportdata and golang.org/x/tools/go/types/typeutil also reference go/types we need to vendor them as well. vendor/vendor.json is updated using govendor, with the one exception being a manual addition for go/types (govendor doesn't appear to understand how to vendor a standard library package). Fixes #808. --- .circleci/config.yml | 2 +- compiler/vendor/vendor.json | 13 - .../github.com/neelance/astrewrite/LICENSE | 0 .../neelance/astrewrite/simplify.go | 0 vendor/go/types/api.go | 376 ++++ vendor/go/types/assignments.go | 339 ++++ vendor/go/types/builtins.go | 683 +++++++ vendor/go/types/call.go | 478 +++++ vendor/go/types/check.go | 356 ++++ vendor/go/types/conversions.go | 160 ++ vendor/go/types/decl.go | 486 +++++ vendor/go/types/errors.go | 103 ++ vendor/go/types/eval.go | 82 + vendor/go/types/expr.go | 1622 +++++++++++++++++ vendor/go/types/exprstring.go | 224 +++ vendor/go/types/gotype.go | 354 ++++ vendor/go/types/initorder.go | 297 +++ vendor/go/types/interfaces.go | 443 +++++ vendor/go/types/labels.go | 268 +++ vendor/go/types/lookup.go | 354 ++++ vendor/go/types/methodset.go | 262 +++ vendor/go/types/object.go | 424 +++++ vendor/go/types/objset.go | 31 + vendor/go/types/operand.go | 275 +++ vendor/go/types/package.go | 64 + vendor/go/types/predicates.go | 320 ++++ vendor/go/types/resolver.go | 631 +++++++ vendor/go/types/return.go | 184 ++ vendor/go/types/scope.go | 191 ++ vendor/go/types/selection.go | 143 ++ vendor/go/types/sizes.go | 255 +++ vendor/go/types/stmt.go | 866 +++++++++ vendor/go/types/type.go | 465 +++++ vendor/go/types/typestring.go | 307 ++++ vendor/go/types/typexpr.go | 743 ++++++++ vendor/go/types/universe.go | 229 +++ vendor/golang.org/x/tools/LICENSE | 27 + vendor/golang.org/x/tools/PATENTS | 22 + .../x/tools/go/gcexportdata/gcexportdata.go | 97 + .../x/tools/go/gcexportdata/importer.go | 73 + .../x/tools/go/internal/gcimporter/bexport.go | 828 +++++++++ .../x/tools/go/internal/gcimporter/bimport.go | 1027 +++++++++++ .../go/internal/gcimporter/exportdata.go | 93 + .../go/internal/gcimporter/gcimporter.go | 1037 +++++++++++ .../x/tools/go/internal/gcimporter/iimport.go | 585 ++++++ .../tools/go/internal/gcimporter/isAlias18.go | 13 + .../tools/go/internal/gcimporter/isAlias19.go | 13 + .../x/tools/go/types/typeutil/imports.go | 31 + .../x/tools/go/types/typeutil/map.go | 313 ++++ .../tools/go/types/typeutil/methodsetcache.go | 72 + .../x/tools/go/types/typeutil/ui.go | 52 + vendor/vendor.json | 35 + 52 files changed, 16334 insertions(+), 14 deletions(-) delete mode 100644 compiler/vendor/vendor.json rename {compiler/vendor => vendor}/github.com/neelance/astrewrite/LICENSE (100%) rename {compiler/vendor => vendor}/github.com/neelance/astrewrite/simplify.go (100%) create mode 100644 vendor/go/types/api.go create mode 100644 vendor/go/types/assignments.go create mode 100644 vendor/go/types/builtins.go create mode 100644 vendor/go/types/call.go create mode 100644 vendor/go/types/check.go create mode 100644 vendor/go/types/conversions.go create mode 100644 vendor/go/types/decl.go create mode 100644 vendor/go/types/errors.go create mode 100644 vendor/go/types/eval.go create mode 100644 vendor/go/types/expr.go create mode 100644 vendor/go/types/exprstring.go create mode 100644 vendor/go/types/gotype.go create mode 100644 vendor/go/types/initorder.go create mode 100644 vendor/go/types/interfaces.go create mode 100644 vendor/go/types/labels.go create mode 100644 vendor/go/types/lookup.go create mode 100644 vendor/go/types/methodset.go create mode 100644 vendor/go/types/object.go create mode 100644 vendor/go/types/objset.go create mode 100644 vendor/go/types/operand.go create mode 100644 vendor/go/types/package.go create mode 100644 vendor/go/types/predicates.go create mode 100644 vendor/go/types/resolver.go create mode 100644 vendor/go/types/return.go create mode 100644 vendor/go/types/scope.go create mode 100644 vendor/go/types/selection.go create mode 100644 vendor/go/types/sizes.go create mode 100644 vendor/go/types/stmt.go create mode 100644 vendor/go/types/type.go create mode 100644 vendor/go/types/typestring.go create mode 100644 vendor/go/types/typexpr.go create mode 100644 vendor/go/types/universe.go create mode 100644 vendor/golang.org/x/tools/LICENSE create mode 100644 vendor/golang.org/x/tools/PATENTS create mode 100644 vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go create mode 100644 vendor/golang.org/x/tools/go/gcexportdata/importer.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/isAlias18.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/isAlias19.go create mode 100644 vendor/golang.org/x/tools/go/types/typeutil/imports.go create mode 100644 vendor/golang.org/x/tools/go/types/typeutil/map.go create mode 100644 vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go create mode 100644 vendor/golang.org/x/tools/go/types/typeutil/ui.go create mode 100644 vendor/vendor.json diff --git a/.circleci/config.yml b/.circleci/config.yml index 00ebcae6a..d674a44c6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -75,7 +75,7 @@ jobs: go tool vet *.go echo ">> vet all subdirectories except tests and third_party." - for d in */; do echo $d; done | grep -v tests/ | grep -v third_party/ | xargs go tool vet + for d in */; do echo $d; done | grep -v tests/ | grep -v third_party/ | grep -v vendor/ | xargs go tool vet echo ">> All those packages should have // +build js." diff -u <(echo -n) <(go list ./compiler/natives/src/...) diff --git a/compiler/vendor/vendor.json b/compiler/vendor/vendor.json deleted file mode 100644 index e9add8eb3..000000000 --- a/compiler/vendor/vendor.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "comment": "", - "ignore": "test", - "package": [ - { - "checksumSHA1": "CaUaJLLnql96d2JGRgCpYsKomxw=", - "path": "github.com/neelance/astrewrite", - "revision": "99348263ae862cc230986ce88deaddbf7edcc034", - "revisionTime": "2016-05-11T09:36:45Z" - } - ], - "rootPath": "github.com/gopherjs/gopherjs/compiler" -} diff --git a/compiler/vendor/github.com/neelance/astrewrite/LICENSE b/vendor/github.com/neelance/astrewrite/LICENSE similarity index 100% rename from compiler/vendor/github.com/neelance/astrewrite/LICENSE rename to vendor/github.com/neelance/astrewrite/LICENSE diff --git a/compiler/vendor/github.com/neelance/astrewrite/simplify.go b/vendor/github.com/neelance/astrewrite/simplify.go similarity index 100% rename from compiler/vendor/github.com/neelance/astrewrite/simplify.go rename to vendor/github.com/neelance/astrewrite/simplify.go diff --git a/vendor/go/types/api.go b/vendor/go/types/api.go new file mode 100644 index 000000000..f202eb0c3 --- /dev/null +++ b/vendor/go/types/api.go @@ -0,0 +1,376 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package types declares the data types and implements +// the algorithms for type-checking of Go packages. Use +// Config.Check to invoke the type checker for a package. +// Alternatively, create a new type checker with NewChecker +// and invoke it incrementally by calling Checker.Files. +// +// Type-checking consists of several interdependent phases: +// +// Name resolution maps each identifier (ast.Ident) in the program to the +// language object (Object) it denotes. +// Use Info.{Defs,Uses,Implicits} for the results of name resolution. +// +// Constant folding computes the exact constant value (constant.Value) +// for every expression (ast.Expr) that is a compile-time constant. +// Use Info.Types[expr].Value for the results of constant folding. +// +// Type inference computes the type (Type) of every expression (ast.Expr) +// and checks for compliance with the language specification. +// Use Info.Types[expr].Type for the results of type inference. +// +// For a tutorial, see https://golang.org/s/types-tutorial. +// +package types + +import ( + "bytes" + "fmt" + "go/ast" + "go/constant" + "go/token" +) + +// An Error describes a type-checking error; it implements the error interface. +// A "soft" error is an error that still permits a valid interpretation of a +// package (such as "unused variable"); "hard" errors may lead to unpredictable +// behavior if ignored. +type Error struct { + Fset *token.FileSet // file set for interpretation of Pos + Pos token.Pos // error position + Msg string // error message + Soft bool // if set, error is "soft" +} + +// Error returns an error string formatted as follows: +// filename:line:column: message +func (err Error) Error() string { + return fmt.Sprintf("%s: %s", err.Fset.Position(err.Pos), err.Msg) +} + +// An Importer resolves import paths to Packages. +// +// CAUTION: This interface does not support the import of locally +// vendored packages. See https://golang.org/s/go15vendor. +// If possible, external implementations should implement ImporterFrom. +type Importer interface { + // Import returns the imported package for the given import path. + // The semantics is like for ImporterFrom.ImportFrom except that + // dir and mode are ignored (since they are not present). + Import(path string) (*Package, error) +} + +// ImportMode is reserved for future use. +type ImportMode int + +// An ImporterFrom resolves import paths to packages; it +// supports vendoring per https://golang.org/s/go15vendor. +// Use go/importer to obtain an ImporterFrom implementation. +type ImporterFrom interface { + // Importer is present for backward-compatibility. Calling + // Import(path) is the same as calling ImportFrom(path, "", 0); + // i.e., locally vendored packages may not be found. + // The types package does not call Import if an ImporterFrom + // is present. + Importer + + // ImportFrom returns the imported package for the given import + // path when imported by a package file located in dir. + // If the import failed, besides returning an error, ImportFrom + // is encouraged to cache and return a package anyway, if one + // was created. This will reduce package inconsistencies and + // follow-on type checker errors due to the missing package. + // The mode value must be 0; it is reserved for future use. + // Two calls to ImportFrom with the same path and dir must + // return the same package. + ImportFrom(path, dir string, mode ImportMode) (*Package, error) +} + +// A Config specifies the configuration for type checking. +// The zero value for Config is a ready-to-use default configuration. +type Config struct { + // If IgnoreFuncBodies is set, function bodies are not + // type-checked. + IgnoreFuncBodies bool + + // If FakeImportC is set, `import "C"` (for packages requiring Cgo) + // declares an empty "C" package and errors are omitted for qualified + // identifiers referring to package C (which won't find an object). + // This feature is intended for the standard library cmd/api tool. + // + // Caution: Effects may be unpredictable due to follow-on errors. + // Do not use casually! + FakeImportC bool + + // If Error != nil, it is called with each error found + // during type checking; err has dynamic type Error. + // Secondary errors (for instance, to enumerate all types + // involved in an invalid recursive type declaration) have + // error strings that start with a '\t' character. + // If Error == nil, type-checking stops with the first + // error found. + Error func(err error) + + // An importer is used to import packages referred to from + // import declarations. + // If the installed importer implements ImporterFrom, the type + // checker calls ImportFrom instead of Import. + // The type checker reports an error if an importer is needed + // but none was installed. + Importer Importer + + // If Sizes != nil, it provides the sizing functions for package unsafe. + // Otherwise SizesFor("gc", "amd64") is used instead. + Sizes Sizes + + // If DisableUnusedImportCheck is set, packages are not checked + // for unused imports. + DisableUnusedImportCheck bool +} + +// Info holds result type information for a type-checked package. +// Only the information for which a map is provided is collected. +// If the package has type errors, the collected information may +// be incomplete. +type Info struct { + // Types maps expressions to their types, and for constant + // expressions, also their values. Invalid expressions are + // omitted. + // + // For (possibly parenthesized) identifiers denoting built-in + // functions, the recorded signatures are call-site specific: + // if the call result is not a constant, the recorded type is + // an argument-specific signature. Otherwise, the recorded type + // is invalid. + // + // The Types map does not record the type of every identifier, + // only those that appear where an arbitrary expression is + // permitted. For instance, the identifier f in a selector + // expression x.f is found only in the Selections map, the + // identifier z in a variable declaration 'var z int' is found + // only in the Defs map, and identifiers denoting packages in + // qualified identifiers are collected in the Uses map. + Types map[ast.Expr]TypeAndValue + + // Defs maps identifiers to the objects they define (including + // package names, dots "." of dot-imports, and blank "_" identifiers). + // For identifiers that do not denote objects (e.g., the package name + // in package clauses, or symbolic variables t in t := x.(type) of + // type switch headers), the corresponding objects are nil. + // + // For an anonymous field, Defs returns the field *Var it defines. + // + // Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos() + Defs map[*ast.Ident]Object + + // Uses maps identifiers to the objects they denote. + // + // For an anonymous field, Uses returns the *TypeName it denotes. + // + // Invariant: Uses[id].Pos() != id.Pos() + Uses map[*ast.Ident]Object + + // Implicits maps nodes to their implicitly declared objects, if any. + // The following node and object types may appear: + // + // node declared object + // + // *ast.ImportSpec *PkgName for imports without renames + // *ast.CaseClause type-specific *Var for each type switch case clause (incl. default) + // *ast.Field anonymous parameter *Var + // + Implicits map[ast.Node]Object + + // Selections maps selector expressions (excluding qualified identifiers) + // to their corresponding selections. + Selections map[*ast.SelectorExpr]*Selection + + // Scopes maps ast.Nodes to the scopes they define. Package scopes are not + // associated with a specific node but with all files belonging to a package. + // Thus, the package scope can be found in the type-checked Package object. + // Scopes nest, with the Universe scope being the outermost scope, enclosing + // the package scope, which contains (one or more) files scopes, which enclose + // function scopes which in turn enclose statement and function literal scopes. + // Note that even though package-level functions are declared in the package + // scope, the function scopes are embedded in the file scope of the file + // containing the function declaration. + // + // The following node types may appear in Scopes: + // + // *ast.File + // *ast.FuncType + // *ast.BlockStmt + // *ast.IfStmt + // *ast.SwitchStmt + // *ast.TypeSwitchStmt + // *ast.CaseClause + // *ast.CommClause + // *ast.ForStmt + // *ast.RangeStmt + // + Scopes map[ast.Node]*Scope + + // InitOrder is the list of package-level initializers in the order in which + // they must be executed. Initializers referring to variables related by an + // initialization dependency appear in topological order, the others appear + // in source order. Variables without an initialization expression do not + // appear in this list. + InitOrder []*Initializer +} + +// TypeOf returns the type of expression e, or nil if not found. +// Precondition: the Types, Uses and Defs maps are populated. +// +func (info *Info) TypeOf(e ast.Expr) Type { + if t, ok := info.Types[e]; ok { + return t.Type + } + if id, _ := e.(*ast.Ident); id != nil { + if obj := info.ObjectOf(id); obj != nil { + return obj.Type() + } + } + return nil +} + +// ObjectOf returns the object denoted by the specified id, +// or nil if not found. +// +// If id is an anonymous struct field, ObjectOf returns the field (*Var) +// it uses, not the type (*TypeName) it defines. +// +// Precondition: the Uses and Defs maps are populated. +// +func (info *Info) ObjectOf(id *ast.Ident) Object { + if obj := info.Defs[id]; obj != nil { + return obj + } + return info.Uses[id] +} + +// TypeAndValue reports the type and value (for constants) +// of the corresponding expression. +type TypeAndValue struct { + mode operandMode + Type Type + Value constant.Value +} + +// TODO(gri) Consider eliminating the IsVoid predicate. Instead, report +// "void" values as regular values but with the empty tuple type. + +// IsVoid reports whether the corresponding expression +// is a function call without results. +func (tv TypeAndValue) IsVoid() bool { + return tv.mode == novalue +} + +// IsType reports whether the corresponding expression specifies a type. +func (tv TypeAndValue) IsType() bool { + return tv.mode == typexpr +} + +// IsBuiltin reports whether the corresponding expression denotes +// a (possibly parenthesized) built-in function. +func (tv TypeAndValue) IsBuiltin() bool { + return tv.mode == builtin +} + +// IsValue reports whether the corresponding expression is a value. +// Builtins are not considered values. Constant values have a non- +// nil Value. +func (tv TypeAndValue) IsValue() bool { + switch tv.mode { + case constant_, variable, mapindex, value, commaok: + return true + } + return false +} + +// IsNil reports whether the corresponding expression denotes the +// predeclared value nil. +func (tv TypeAndValue) IsNil() bool { + return tv.mode == value && tv.Type == Typ[UntypedNil] +} + +// Addressable reports whether the corresponding expression +// is addressable (https://golang.org/ref/spec#Address_operators). +func (tv TypeAndValue) Addressable() bool { + return tv.mode == variable +} + +// Assignable reports whether the corresponding expression +// is assignable to (provided a value of the right type). +func (tv TypeAndValue) Assignable() bool { + return tv.mode == variable || tv.mode == mapindex +} + +// HasOk reports whether the corresponding expression may be +// used on the rhs of a comma-ok assignment. +func (tv TypeAndValue) HasOk() bool { + return tv.mode == commaok || tv.mode == mapindex +} + +// An Initializer describes a package-level variable, or a list of variables in case +// of a multi-valued initialization expression, and the corresponding initialization +// expression. +type Initializer struct { + Lhs []*Var // var Lhs = Rhs + Rhs ast.Expr +} + +func (init *Initializer) String() string { + var buf bytes.Buffer + for i, lhs := range init.Lhs { + if i > 0 { + buf.WriteString(", ") + } + buf.WriteString(lhs.Name()) + } + buf.WriteString(" = ") + WriteExpr(&buf, init.Rhs) + return buf.String() +} + +// Check type-checks a package and returns the resulting package object and +// the first error if any. Additionally, if info != nil, Check populates each +// of the non-nil maps in the Info struct. +// +// The package is marked as complete if no errors occurred, otherwise it is +// incomplete. See Config.Error for controlling behavior in the presence of +// errors. +// +// The package is specified by a list of *ast.Files and corresponding +// file set, and the package path the package is identified with. +// The clean path must not be empty or dot ("."). +func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, info *Info) (*Package, error) { + pkg := NewPackage(path, "") + return pkg, NewChecker(conf, fset, pkg, info).Files(files) +} + +// AssertableTo reports whether a value of type V can be asserted to have type T. +func AssertableTo(V *Interface, T Type) bool { + m, _ := assertableTo(V, T) + return m == nil +} + +// AssignableTo reports whether a value of type V is assignable to a variable of type T. +func AssignableTo(V, T Type) bool { + x := operand{mode: value, typ: V} + return x.assignableTo(nil, T, nil) // config not needed for non-constant x +} + +// ConvertibleTo reports whether a value of type V is convertible to a value of type T. +func ConvertibleTo(V, T Type) bool { + x := operand{mode: value, typ: V} + return x.convertibleTo(nil, T) // config not needed for non-constant x +} + +// Implements reports whether type V implements interface T. +func Implements(V Type, T *Interface) bool { + f, _ := MissingMethod(V, T, true) + return f == nil +} diff --git a/vendor/go/types/assignments.go b/vendor/go/types/assignments.go new file mode 100644 index 000000000..cb0fe3bc3 --- /dev/null +++ b/vendor/go/types/assignments.go @@ -0,0 +1,339 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements initialization and assignment checks. + +package types + +import ( + "go/ast" + "go/token" +) + +// assignment reports whether x can be assigned to a variable of type T, +// if necessary by attempting to convert untyped values to the appropriate +// type. context describes the context in which the assignment takes place. +// Use T == nil to indicate assignment to an untyped blank identifier. +// x.mode is set to invalid if the assignment failed. +func (check *Checker) assignment(x *operand, T Type, context string) { + check.singleValue(x) + + switch x.mode { + case invalid: + return // error reported before + case constant_, variable, mapindex, value, commaok: + // ok + default: + unreachable() + } + + if isUntyped(x.typ) { + target := T + // spec: "If an untyped constant is assigned to a variable of interface + // type or the blank identifier, the constant is first converted to type + // bool, rune, int, float64, complex128 or string respectively, depending + // on whether the value is a boolean, rune, integer, floating-point, complex, + // or string constant." + if T == nil || IsInterface(T) { + if T == nil && x.typ == Typ[UntypedNil] { + check.errorf(x.pos(), "use of untyped nil in %s", context) + x.mode = invalid + return + } + target = Default(x.typ) + } + check.convertUntyped(x, target) + if x.mode == invalid { + return + } + } + // x.typ is typed + + // spec: "If a left-hand side is the blank identifier, any typed or + // non-constant value except for the predeclared identifier nil may + // be assigned to it." + if T == nil { + return + } + + if reason := ""; !x.assignableTo(check.conf, T, &reason) { + if reason != "" { + check.errorf(x.pos(), "cannot use %s as %s value in %s: %s", x, T, context, reason) + } else { + check.errorf(x.pos(), "cannot use %s as %s value in %s", x, T, context) + } + x.mode = invalid + } +} + +func (check *Checker) initConst(lhs *Const, x *operand) { + if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] { + if lhs.typ == nil { + lhs.typ = Typ[Invalid] + } + return + } + + // rhs must be a constant + if x.mode != constant_ { + check.errorf(x.pos(), "%s is not constant", x) + if lhs.typ == nil { + lhs.typ = Typ[Invalid] + } + return + } + assert(isConstType(x.typ)) + + // If the lhs doesn't have a type yet, use the type of x. + if lhs.typ == nil { + lhs.typ = x.typ + } + + check.assignment(x, lhs.typ, "constant declaration") + if x.mode == invalid { + return + } + + lhs.val = x.val +} + +func (check *Checker) initVar(lhs *Var, x *operand, context string) Type { + if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] { + if lhs.typ == nil { + lhs.typ = Typ[Invalid] + } + return nil + } + + // If the lhs doesn't have a type yet, use the type of x. + if lhs.typ == nil { + typ := x.typ + if isUntyped(typ) { + // convert untyped types to default types + if typ == Typ[UntypedNil] { + check.errorf(x.pos(), "use of untyped nil in %s", context) + lhs.typ = Typ[Invalid] + return nil + } + typ = Default(typ) + } + lhs.typ = typ + } + + check.assignment(x, lhs.typ, context) + if x.mode == invalid { + return nil + } + + return x.typ +} + +func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type { + if x.mode == invalid || x.typ == Typ[Invalid] { + return nil + } + + // Determine if the lhs is a (possibly parenthesized) identifier. + ident, _ := unparen(lhs).(*ast.Ident) + + // Don't evaluate lhs if it is the blank identifier. + if ident != nil && ident.Name == "_" { + check.recordDef(ident, nil) + check.assignment(x, nil, "assignment to _ identifier") + if x.mode == invalid { + return nil + } + return x.typ + } + + // If the lhs is an identifier denoting a variable v, this assignment + // is not a 'use' of v. Remember current value of v.used and restore + // after evaluating the lhs via check.expr. + var v *Var + var v_used bool + if ident != nil { + if obj := check.lookup(ident.Name); obj != nil { + // It's ok to mark non-local variables, but ignore variables + // from other packages to avoid potential race conditions with + // dot-imported variables. + if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg { + v = w + v_used = v.used + } + } + } + + var z operand + check.expr(&z, lhs) + if v != nil { + v.used = v_used // restore v.used + } + + if z.mode == invalid || z.typ == Typ[Invalid] { + return nil + } + + // spec: "Each left-hand side operand must be addressable, a map index + // expression, or the blank identifier. Operands may be parenthesized." + switch z.mode { + case invalid: + return nil + case variable, mapindex: + // ok + default: + if sel, ok := z.expr.(*ast.SelectorExpr); ok { + var op operand + check.expr(&op, sel.X) + if op.mode == mapindex { + check.errorf(z.pos(), "cannot assign to struct field %s in map", ExprString(z.expr)) + return nil + } + } + check.errorf(z.pos(), "cannot assign to %s", &z) + return nil + } + + check.assignment(x, z.typ, "assignment") + if x.mode == invalid { + return nil + } + + return x.typ +} + +// If returnPos is valid, initVars is called to type-check the assignment of +// return expressions, and returnPos is the position of the return statement. +func (check *Checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos) { + l := len(lhs) + get, r, commaOk := unpack(func(x *operand, i int) { check.multiExpr(x, rhs[i]) }, len(rhs), l == 2 && !returnPos.IsValid()) + if get == nil || l != r { + // invalidate lhs and use rhs + for _, obj := range lhs { + if obj.typ == nil { + obj.typ = Typ[Invalid] + } + } + if get == nil { + return // error reported by unpack + } + check.useGetter(get, r) + if returnPos.IsValid() { + check.errorf(returnPos, "wrong number of return values (want %d, got %d)", l, r) + return + } + check.errorf(rhs[0].Pos(), "cannot initialize %d variables with %d values", l, r) + return + } + + context := "assignment" + if returnPos.IsValid() { + context = "return statement" + } + + var x operand + if commaOk { + var a [2]Type + for i := range a { + get(&x, i) + a[i] = check.initVar(lhs[i], &x, context) + } + check.recordCommaOkTypes(rhs[0], a) + return + } + + for i, lhs := range lhs { + get(&x, i) + check.initVar(lhs, &x, context) + } +} + +func (check *Checker) assignVars(lhs, rhs []ast.Expr) { + l := len(lhs) + get, r, commaOk := unpack(func(x *operand, i int) { check.multiExpr(x, rhs[i]) }, len(rhs), l == 2) + if get == nil { + check.useLHS(lhs...) + return // error reported by unpack + } + if l != r { + check.useGetter(get, r) + check.errorf(rhs[0].Pos(), "cannot assign %d values to %d variables", r, l) + return + } + + var x operand + if commaOk { + var a [2]Type + for i := range a { + get(&x, i) + a[i] = check.assignVar(lhs[i], &x) + } + check.recordCommaOkTypes(rhs[0], a) + return + } + + for i, lhs := range lhs { + get(&x, i) + check.assignVar(lhs, &x) + } +} + +func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) { + top := len(check.delayed) + scope := check.scope + + // collect lhs variables + var newVars []*Var + var lhsVars = make([]*Var, len(lhs)) + for i, lhs := range lhs { + var obj *Var + if ident, _ := lhs.(*ast.Ident); ident != nil { + // Use the correct obj if the ident is redeclared. The + // variable's scope starts after the declaration; so we + // must use Scope.Lookup here and call Scope.Insert + // (via check.declare) later. + name := ident.Name + if alt := scope.Lookup(name); alt != nil { + // redeclared object must be a variable + if alt, _ := alt.(*Var); alt != nil { + obj = alt + } else { + check.errorf(lhs.Pos(), "cannot assign to %s", lhs) + } + check.recordUse(ident, alt) + } else { + // declare new variable, possibly a blank (_) variable + obj = NewVar(ident.Pos(), check.pkg, name, nil) + if name != "_" { + newVars = append(newVars, obj) + } + check.recordDef(ident, obj) + } + } else { + check.errorf(lhs.Pos(), "cannot declare %s", lhs) + } + if obj == nil { + obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable + } + lhsVars[i] = obj + } + + check.initVars(lhsVars, rhs, token.NoPos) + + // process function literals in rhs expressions before scope changes + check.processDelayed(top) + + // declare new variables + if len(newVars) > 0 { + // spec: "The scope of a constant or variable identifier declared inside + // a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl + // for short variable declarations) and ends at the end of the innermost + // containing block." + scopePos := rhs[len(rhs)-1].End() + for _, obj := range newVars { + check.declare(scope, nil, obj, scopePos) // recordObject already called + } + } else { + check.softErrorf(pos, "no new variables on left side of :=") + } +} diff --git a/vendor/go/types/builtins.go b/vendor/go/types/builtins.go new file mode 100644 index 000000000..afe5f5d0f --- /dev/null +++ b/vendor/go/types/builtins.go @@ -0,0 +1,683 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements typechecking of builtin function calls. + +package types + +import ( + "go/ast" + "go/constant" + "go/token" +) + +// builtin type-checks a call to the built-in specified by id and +// returns true if the call is valid, with *x holding the result; +// but x.expr is not set. If the call is invalid, the result is +// false, and *x is undefined. +// +func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ bool) { + // append is the only built-in that permits the use of ... for the last argument + bin := predeclaredFuncs[id] + if call.Ellipsis.IsValid() && id != _Append { + check.invalidOp(call.Ellipsis, "invalid use of ... with built-in %s", bin.name) + check.use(call.Args...) + return + } + + // For len(x) and cap(x) we need to know if x contains any function calls or + // receive operations. Save/restore current setting and set hasCallOrRecv to + // false for the evaluation of x so that we can check it afterwards. + // Note: We must do this _before_ calling unpack because unpack evaluates the + // first argument before we even call arg(x, 0)! + if id == _Len || id == _Cap { + defer func(b bool) { + check.hasCallOrRecv = b + }(check.hasCallOrRecv) + check.hasCallOrRecv = false + } + + // determine actual arguments + var arg getter + nargs := len(call.Args) + switch id { + default: + // make argument getter + arg, nargs, _ = unpack(func(x *operand, i int) { check.multiExpr(x, call.Args[i]) }, nargs, false) + if arg == nil { + return + } + // evaluate first argument, if present + if nargs > 0 { + arg(x, 0) + if x.mode == invalid { + return + } + } + case _Make, _New, _Offsetof, _Trace: + // arguments require special handling + } + + // check argument count + { + msg := "" + if nargs < bin.nargs { + msg = "not enough" + } else if !bin.variadic && nargs > bin.nargs { + msg = "too many" + } + if msg != "" { + check.invalidOp(call.Rparen, "%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs) + return + } + } + + switch id { + case _Append: + // append(s S, x ...T) S, where T is the element type of S + // spec: "The variadic function append appends zero or more values x to s of type + // S, which must be a slice type, and returns the resulting slice, also of type S. + // The values x are passed to a parameter of type ...T where T is the element type + // of S and the respective parameter passing rules apply." + S := x.typ + var T Type + if s, _ := S.Underlying().(*Slice); s != nil { + T = s.elem + } else { + check.invalidArg(x.pos(), "%s is not a slice", x) + return + } + + // remember arguments that have been evaluated already + alist := []operand{*x} + + // spec: "As a special case, append also accepts a first argument assignable + // to type []byte with a second argument of string type followed by ... . + // This form appends the bytes of the string. + if nargs == 2 && call.Ellipsis.IsValid() && x.assignableTo(check.conf, NewSlice(universeByte), nil) { + arg(x, 1) + if x.mode == invalid { + return + } + if isString(x.typ) { + if check.Types != nil { + sig := makeSig(S, S, x.typ) + sig.variadic = true + check.recordBuiltinType(call.Fun, sig) + } + x.mode = value + x.typ = S + break + } + alist = append(alist, *x) + // fallthrough + } + + // check general case by creating custom signature + sig := makeSig(S, S, NewSlice(T)) // []T required for variadic signature + sig.variadic = true + check.arguments(x, call, sig, func(x *operand, i int) { + // only evaluate arguments that have not been evaluated before + if i < len(alist) { + *x = alist[i] + return + } + arg(x, i) + }, nargs) + // ok to continue even if check.arguments reported errors + + x.mode = value + x.typ = S + if check.Types != nil { + check.recordBuiltinType(call.Fun, sig) + } + + case _Cap, _Len: + // cap(x) + // len(x) + mode := invalid + var typ Type + var val constant.Value + switch typ = implicitArrayDeref(x.typ.Underlying()); t := typ.(type) { + case *Basic: + if isString(t) && id == _Len { + if x.mode == constant_ { + mode = constant_ + val = constant.MakeInt64(int64(len(constant.StringVal(x.val)))) + } else { + mode = value + } + } + + case *Array: + mode = value + // spec: "The expressions len(s) and cap(s) are constants + // if the type of s is an array or pointer to an array and + // the expression s does not contain channel receives or + // function calls; in this case s is not evaluated." + if !check.hasCallOrRecv { + mode = constant_ + if t.len >= 0 { + val = constant.MakeInt64(t.len) + } else { + val = constant.MakeUnknown() + } + } + + case *Slice, *Chan: + mode = value + + case *Map: + if id == _Len { + mode = value + } + } + + if mode == invalid { + check.invalidArg(x.pos(), "%s for %s", x, bin.name) + return + } + + x.mode = mode + x.typ = Typ[Int] + x.val = val + if check.Types != nil && mode != constant_ { + check.recordBuiltinType(call.Fun, makeSig(x.typ, typ)) + } + + case _Close: + // close(c) + c, _ := x.typ.Underlying().(*Chan) + if c == nil { + check.invalidArg(x.pos(), "%s is not a channel", x) + return + } + if c.dir == RecvOnly { + check.invalidArg(x.pos(), "%s must not be a receive-only channel", x) + return + } + + x.mode = novalue + if check.Types != nil { + check.recordBuiltinType(call.Fun, makeSig(nil, c)) + } + + case _Complex: + // complex(x, y floatT) complexT + var y operand + arg(&y, 1) + if y.mode == invalid { + return + } + + // convert or check untyped arguments + d := 0 + if isUntyped(x.typ) { + d |= 1 + } + if isUntyped(y.typ) { + d |= 2 + } + switch d { + case 0: + // x and y are typed => nothing to do + case 1: + // only x is untyped => convert to type of y + check.convertUntyped(x, y.typ) + case 2: + // only y is untyped => convert to type of x + check.convertUntyped(&y, x.typ) + case 3: + // x and y are untyped => + // 1) if both are constants, convert them to untyped + // floating-point numbers if possible, + // 2) if one of them is not constant (possible because + // it contains a shift that is yet untyped), convert + // both of them to float64 since they must have the + // same type to succeed (this will result in an error + // because shifts of floats are not permitted) + if x.mode == constant_ && y.mode == constant_ { + toFloat := func(x *operand) { + if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 { + x.typ = Typ[UntypedFloat] + } + } + toFloat(x) + toFloat(&y) + } else { + check.convertUntyped(x, Typ[Float64]) + check.convertUntyped(&y, Typ[Float64]) + // x and y should be invalid now, but be conservative + // and check below + } + } + if x.mode == invalid || y.mode == invalid { + return + } + + // both argument types must be identical + if !Identical(x.typ, y.typ) { + check.invalidArg(x.pos(), "mismatched types %s and %s", x.typ, y.typ) + return + } + + // the argument types must be of floating-point type + if !isFloat(x.typ) { + check.invalidArg(x.pos(), "arguments have type %s, expected floating-point", x.typ) + return + } + + // if both arguments are constants, the result is a constant + if x.mode == constant_ && y.mode == constant_ { + x.val = constant.BinaryOp(constant.ToFloat(x.val), token.ADD, constant.MakeImag(constant.ToFloat(y.val))) + } else { + x.mode = value + } + + // determine result type + var res BasicKind + switch x.typ.Underlying().(*Basic).kind { + case Float32: + res = Complex64 + case Float64: + res = Complex128 + case UntypedFloat: + res = UntypedComplex + default: + unreachable() + } + resTyp := Typ[res] + + if check.Types != nil && x.mode != constant_ { + check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ)) + } + + x.typ = resTyp + + case _Copy: + // copy(x, y []T) int + var dst Type + if t, _ := x.typ.Underlying().(*Slice); t != nil { + dst = t.elem + } + + var y operand + arg(&y, 1) + if y.mode == invalid { + return + } + var src Type + switch t := y.typ.Underlying().(type) { + case *Basic: + if isString(y.typ) { + src = universeByte + } + case *Slice: + src = t.elem + } + + if dst == nil || src == nil { + check.invalidArg(x.pos(), "copy expects slice arguments; found %s and %s", x, &y) + return + } + + if !Identical(dst, src) { + check.invalidArg(x.pos(), "arguments to copy %s and %s have different element types %s and %s", x, &y, dst, src) + return + } + + if check.Types != nil { + check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ)) + } + x.mode = value + x.typ = Typ[Int] + + case _Delete: + // delete(m, k) + m, _ := x.typ.Underlying().(*Map) + if m == nil { + check.invalidArg(x.pos(), "%s is not a map", x) + return + } + arg(x, 1) // k + if x.mode == invalid { + return + } + + if !x.assignableTo(check.conf, m.key, nil) { + check.invalidArg(x.pos(), "%s is not assignable to %s", x, m.key) + return + } + + x.mode = novalue + if check.Types != nil { + check.recordBuiltinType(call.Fun, makeSig(nil, m, m.key)) + } + + case _Imag, _Real: + // imag(complexT) floatT + // real(complexT) floatT + + // convert or check untyped argument + if isUntyped(x.typ) { + if x.mode == constant_ { + // an untyped constant number can alway be considered + // as a complex constant + if isNumeric(x.typ) { + x.typ = Typ[UntypedComplex] + } + } else { + // an untyped non-constant argument may appear if + // it contains a (yet untyped non-constant) shift + // expression: convert it to complex128 which will + // result in an error (shift of complex value) + check.convertUntyped(x, Typ[Complex128]) + // x should be invalid now, but be conservative and check + if x.mode == invalid { + return + } + } + } + + // the argument must be of complex type + if !isComplex(x.typ) { + check.invalidArg(x.pos(), "argument has type %s, expected complex type", x.typ) + return + } + + // if the argument is a constant, the result is a constant + if x.mode == constant_ { + if id == _Real { + x.val = constant.Real(x.val) + } else { + x.val = constant.Imag(x.val) + } + } else { + x.mode = value + } + + // determine result type + var res BasicKind + switch x.typ.Underlying().(*Basic).kind { + case Complex64: + res = Float32 + case Complex128: + res = Float64 + case UntypedComplex: + res = UntypedFloat + default: + unreachable() + } + resTyp := Typ[res] + + if check.Types != nil && x.mode != constant_ { + check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ)) + } + + x.typ = resTyp + + case _Make: + // make(T, n) + // make(T, n, m) + // (no argument evaluated yet) + arg0 := call.Args[0] + T := check.typ(arg0) + if T == Typ[Invalid] { + return + } + + var min int // minimum number of arguments + switch T.Underlying().(type) { + case *Slice: + min = 2 + case *Map, *Chan: + min = 1 + default: + check.invalidArg(arg0.Pos(), "cannot make %s; type must be slice, map, or channel", arg0) + return + } + if nargs < min || min+1 < nargs { + check.errorf(call.Pos(), "%v expects %d or %d arguments; found %d", call, min, min+1, nargs) + return + } + var sizes []int64 // constant integer arguments, if any + for _, arg := range call.Args[1:] { + if s, ok := check.index(arg, -1); ok && s >= 0 { + sizes = append(sizes, s) + } + } + if len(sizes) == 2 && sizes[0] > sizes[1] { + check.invalidArg(call.Args[1].Pos(), "length and capacity swapped") + // safe to continue + } + x.mode = value + x.typ = T + if check.Types != nil { + params := [...]Type{T, Typ[Int], Typ[Int]} + check.recordBuiltinType(call.Fun, makeSig(x.typ, params[:1+len(sizes)]...)) + } + + case _New: + // new(T) + // (no argument evaluated yet) + T := check.typ(call.Args[0]) + if T == Typ[Invalid] { + return + } + + x.mode = value + x.typ = &Pointer{base: T} + if check.Types != nil { + check.recordBuiltinType(call.Fun, makeSig(x.typ, T)) + } + + case _Panic: + // panic(x) + // record panic call if inside a function with result parameters + // (for use in Checker.isTerminating) + if check.sig.results.Len() > 0 { + // function has result parameters + p := check.isPanic + if p == nil { + // allocate lazily + p = make(map[*ast.CallExpr]bool) + check.isPanic = p + } + p[call] = true + } + + check.assignment(x, &emptyInterface, "argument to panic") + if x.mode == invalid { + return + } + + x.mode = novalue + if check.Types != nil { + check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface)) + } + + case _Print, _Println: + // print(x, y, ...) + // println(x, y, ...) + var params []Type + if nargs > 0 { + params = make([]Type, nargs) + for i := 0; i < nargs; i++ { + if i > 0 { + arg(x, i) // first argument already evaluated + } + check.assignment(x, nil, "argument to "+predeclaredFuncs[id].name) + if x.mode == invalid { + // TODO(gri) "use" all arguments? + return + } + params[i] = x.typ + } + } + + x.mode = novalue + if check.Types != nil { + check.recordBuiltinType(call.Fun, makeSig(nil, params...)) + } + + case _Recover: + // recover() interface{} + x.mode = value + x.typ = &emptyInterface + if check.Types != nil { + check.recordBuiltinType(call.Fun, makeSig(x.typ)) + } + + case _Alignof: + // unsafe.Alignof(x T) uintptr + check.assignment(x, nil, "argument to unsafe.Alignof") + if x.mode == invalid { + return + } + + x.mode = constant_ + x.val = constant.MakeInt64(check.conf.alignof(x.typ)) + x.typ = Typ[Uintptr] + // result is constant - no need to record signature + + case _Offsetof: + // unsafe.Offsetof(x T) uintptr, where x must be a selector + // (no argument evaluated yet) + arg0 := call.Args[0] + selx, _ := unparen(arg0).(*ast.SelectorExpr) + if selx == nil { + check.invalidArg(arg0.Pos(), "%s is not a selector expression", arg0) + check.use(arg0) + return + } + + check.expr(x, selx.X) + if x.mode == invalid { + return + } + + base := derefStructPtr(x.typ) + sel := selx.Sel.Name + obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel) + switch obj.(type) { + case nil: + check.invalidArg(x.pos(), "%s has no single field %s", base, sel) + return + case *Func: + // TODO(gri) Using derefStructPtr may result in methods being found + // that don't actually exist. An error either way, but the error + // message is confusing. See: https://play.golang.org/p/al75v23kUy , + // but go/types reports: "invalid argument: x.m is a method value". + check.invalidArg(arg0.Pos(), "%s is a method value", arg0) + return + } + if indirect { + check.invalidArg(x.pos(), "field %s is embedded via a pointer in %s", sel, base) + return + } + + // TODO(gri) Should we pass x.typ instead of base (and indirect report if derefStructPtr indirected)? + check.recordSelection(selx, FieldVal, base, obj, index, false) + + offs := check.conf.offsetof(base, index) + x.mode = constant_ + x.val = constant.MakeInt64(offs) + x.typ = Typ[Uintptr] + // result is constant - no need to record signature + + case _Sizeof: + // unsafe.Sizeof(x T) uintptr + check.assignment(x, nil, "argument to unsafe.Sizeof") + if x.mode == invalid { + return + } + + x.mode = constant_ + x.val = constant.MakeInt64(check.conf.sizeof(x.typ)) + x.typ = Typ[Uintptr] + // result is constant - no need to record signature + + case _Assert: + // assert(pred) causes a typechecker error if pred is false. + // The result of assert is the value of pred if there is no error. + // Note: assert is only available in self-test mode. + if x.mode != constant_ || !isBoolean(x.typ) { + check.invalidArg(x.pos(), "%s is not a boolean constant", x) + return + } + if x.val.Kind() != constant.Bool { + check.errorf(x.pos(), "internal error: value of %s should be a boolean constant", x) + return + } + if !constant.BoolVal(x.val) { + check.errorf(call.Pos(), "%v failed", call) + // compile-time assertion failure - safe to continue + } + // result is constant - no need to record signature + + case _Trace: + // trace(x, y, z, ...) dumps the positions, expressions, and + // values of its arguments. The result of trace is the value + // of the first argument. + // Note: trace is only available in self-test mode. + // (no argument evaluated yet) + if nargs == 0 { + check.dump("%v: trace() without arguments", call.Pos()) + x.mode = novalue + break + } + var t operand + x1 := x + for _, arg := range call.Args { + check.rawExpr(x1, arg, nil) // permit trace for types, e.g.: new(trace(T)) + check.dump("%v: %s", x1.pos(), x1) + x1 = &t // use incoming x only for first argument + } + // trace is only available in test mode - no need to record signature + + default: + unreachable() + } + + return true +} + +// makeSig makes a signature for the given argument and result types. +// Default types are used for untyped arguments, and res may be nil. +func makeSig(res Type, args ...Type) *Signature { + list := make([]*Var, len(args)) + for i, param := range args { + list[i] = NewVar(token.NoPos, nil, "", Default(param)) + } + params := NewTuple(list...) + var result *Tuple + if res != nil { + assert(!isUntyped(res)) + result = NewTuple(NewVar(token.NoPos, nil, "", res)) + } + return &Signature{params: params, results: result} +} + +// implicitArrayDeref returns A if typ is of the form *A and A is an array; +// otherwise it returns typ. +// +func implicitArrayDeref(typ Type) Type { + if p, ok := typ.(*Pointer); ok { + if a, ok := p.base.Underlying().(*Array); ok { + return a + } + } + return typ +} + +// unparen returns e with any enclosing parentheses stripped. +func unparen(e ast.Expr) ast.Expr { + for { + p, ok := e.(*ast.ParenExpr) + if !ok { + return e + } + e = p.X + } +} diff --git a/vendor/go/types/call.go b/vendor/go/types/call.go new file mode 100644 index 000000000..1b40651b7 --- /dev/null +++ b/vendor/go/types/call.go @@ -0,0 +1,478 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements typechecking of call and selector expressions. + +package types + +import ( + "go/ast" + "go/token" +) + +func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind { + check.exprOrType(x, e.Fun) + + switch x.mode { + case invalid: + check.use(e.Args...) + x.mode = invalid + x.expr = e + return statement + + case typexpr: + // conversion + T := x.typ + x.mode = invalid + switch n := len(e.Args); n { + case 0: + check.errorf(e.Rparen, "missing argument in conversion to %s", T) + case 1: + check.expr(x, e.Args[0]) + if x.mode != invalid { + check.conversion(x, T) + } + default: + check.errorf(e.Args[n-1].Pos(), "too many arguments in conversion to %s", T) + } + x.expr = e + return conversion + + case builtin: + id := x.id + if !check.builtin(x, e, id) { + x.mode = invalid + } + x.expr = e + // a non-constant result implies a function call + if x.mode != invalid && x.mode != constant_ { + check.hasCallOrRecv = true + } + return predeclaredFuncs[id].kind + + default: + // function/method call + sig, _ := x.typ.Underlying().(*Signature) + if sig == nil { + check.invalidOp(x.pos(), "cannot call non-function %s", x) + x.mode = invalid + x.expr = e + return statement + } + + arg, n, _ := unpack(func(x *operand, i int) { check.multiExpr(x, e.Args[i]) }, len(e.Args), false) + if arg != nil { + check.arguments(x, e, sig, arg, n) + } else { + x.mode = invalid + } + + // determine result + switch sig.results.Len() { + case 0: + x.mode = novalue + case 1: + x.mode = value + x.typ = sig.results.vars[0].typ // unpack tuple + default: + x.mode = value + x.typ = sig.results + } + + x.expr = e + check.hasCallOrRecv = true + + return statement + } +} + +// use type-checks each argument. +// Useful to make sure expressions are evaluated +// (and variables are "used") in the presence of other errors. +// The arguments may be nil. +func (check *Checker) use(arg ...ast.Expr) { + var x operand + for _, e := range arg { + // The nil check below is necessary since certain AST fields + // may legally be nil (e.g., the ast.SliceExpr.High field). + if e != nil { + check.rawExpr(&x, e, nil) + } + } +} + +// useLHS is like use, but doesn't "use" top-level identifiers. +// It should be called instead of use if the arguments are +// expressions on the lhs of an assignment. +// The arguments must not be nil. +func (check *Checker) useLHS(arg ...ast.Expr) { + var x operand + for _, e := range arg { + // If the lhs is an identifier denoting a variable v, this assignment + // is not a 'use' of v. Remember current value of v.used and restore + // after evaluating the lhs via check.rawExpr. + var v *Var + var v_used bool + if ident, _ := unparen(e).(*ast.Ident); ident != nil { + // never type-check the blank name on the lhs + if ident.Name == "_" { + continue + } + if _, obj := check.scope.LookupParent(ident.Name, token.NoPos); obj != nil { + // It's ok to mark non-local variables, but ignore variables + // from other packages to avoid potential race conditions with + // dot-imported variables. + if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg { + v = w + v_used = v.used + } + } + } + check.rawExpr(&x, e, nil) + if v != nil { + v.used = v_used // restore v.used + } + } +} + +// useGetter is like use, but takes a getter instead of a list of expressions. +// It should be called instead of use if a getter is present to avoid repeated +// evaluation of the first argument (since the getter was likely obtained via +// unpack, which may have evaluated the first argument already). +func (check *Checker) useGetter(get getter, n int) { + var x operand + for i := 0; i < n; i++ { + get(&x, i) + } +} + +// A getter sets x as the i'th operand, where 0 <= i < n and n is the total +// number of operands (context-specific, and maintained elsewhere). A getter +// type-checks the i'th operand; the details of the actual check are getter- +// specific. +type getter func(x *operand, i int) + +// unpack takes a getter get and a number of operands n. If n == 1, unpack +// calls the incoming getter for the first operand. If that operand is +// invalid, unpack returns (nil, 0, false). Otherwise, if that operand is a +// function call, or a comma-ok expression and allowCommaOk is set, the result +// is a new getter and operand count providing access to the function results, +// or comma-ok values, respectively. The third result value reports if it +// is indeed the comma-ok case. In all other cases, the incoming getter and +// operand count are returned unchanged, and the third result value is false. +// +// In other words, if there's exactly one operand that - after type-checking +// by calling get - stands for multiple operands, the resulting getter provides +// access to those operands instead. +// +// If the returned getter is called at most once for a given operand index i +// (including i == 0), that operand is guaranteed to cause only one call of +// the incoming getter with that i. +// +func unpack(get getter, n int, allowCommaOk bool) (getter, int, bool) { + if n != 1 { + // zero or multiple values + return get, n, false + } + // possibly result of an n-valued function call or comma,ok value + var x0 operand + get(&x0, 0) + if x0.mode == invalid { + return nil, 0, false + } + + if t, ok := x0.typ.(*Tuple); ok { + // result of an n-valued function call + return func(x *operand, i int) { + x.mode = value + x.expr = x0.expr + x.typ = t.At(i).typ + }, t.Len(), false + } + + if x0.mode == mapindex || x0.mode == commaok { + // comma-ok value + if allowCommaOk { + a := [2]Type{x0.typ, Typ[UntypedBool]} + return func(x *operand, i int) { + x.mode = value + x.expr = x0.expr + x.typ = a[i] + }, 2, true + } + x0.mode = value + } + + // single value + return func(x *operand, i int) { + if i != 0 { + unreachable() + } + *x = x0 + }, 1, false +} + +// arguments checks argument passing for the call with the given signature. +// The arg function provides the operand for the i'th argument. +func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature, arg getter, n int) { + if call.Ellipsis.IsValid() { + // last argument is of the form x... + if !sig.variadic { + check.errorf(call.Ellipsis, "cannot use ... in call to non-variadic %s", call.Fun) + check.useGetter(arg, n) + return + } + if len(call.Args) == 1 && n > 1 { + // f()... is not permitted if f() is multi-valued + check.errorf(call.Ellipsis, "cannot use ... with %d-valued %s", n, call.Args[0]) + check.useGetter(arg, n) + return + } + } + + // evaluate arguments + for i := 0; i < n; i++ { + arg(x, i) + if x.mode != invalid { + var ellipsis token.Pos + if i == n-1 && call.Ellipsis.IsValid() { + ellipsis = call.Ellipsis + } + check.argument(call.Fun, sig, i, x, ellipsis) + } + } + + // check argument count + if sig.variadic { + // a variadic function accepts an "empty" + // last argument: count one extra + n++ + } + if n < sig.params.Len() { + check.errorf(call.Rparen, "too few arguments in call to %s", call.Fun) + // ok to continue + } +} + +// argument checks passing of argument x to the i'th parameter of the given signature. +// If ellipsis is valid, the argument is followed by ... at that position in the call. +func (check *Checker) argument(fun ast.Expr, sig *Signature, i int, x *operand, ellipsis token.Pos) { + check.singleValue(x) + if x.mode == invalid { + return + } + + n := sig.params.Len() + + // determine parameter type + var typ Type + switch { + case i < n: + typ = sig.params.vars[i].typ + case sig.variadic: + typ = sig.params.vars[n-1].typ + if debug { + if _, ok := typ.(*Slice); !ok { + check.dump("%v: expected unnamed slice type, got %s", sig.params.vars[n-1].Pos(), typ) + } + } + default: + check.errorf(x.pos(), "too many arguments") + return + } + + if ellipsis.IsValid() { + // argument is of the form x... and x is single-valued + if i != n-1 { + check.errorf(ellipsis, "can only use ... with matching parameter") + return + } + if _, ok := x.typ.Underlying().(*Slice); !ok && x.typ != Typ[UntypedNil] { // see issue #18268 + check.errorf(x.pos(), "cannot use %s as parameter of type %s", x, typ) + return + } + } else if sig.variadic && i >= n-1 { + // use the variadic parameter slice's element type + typ = typ.(*Slice).elem + } + + check.assignment(x, typ, check.sprintf("argument to %s", fun)) +} + +func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { + // these must be declared before the "goto Error" statements + var ( + obj Object + index []int + indirect bool + ) + + sel := e.Sel.Name + // If the identifier refers to a package, handle everything here + // so we don't need a "package" mode for operands: package names + // can only appear in qualified identifiers which are mapped to + // selector expressions. + if ident, ok := e.X.(*ast.Ident); ok { + obj := check.lookup(ident.Name) + if pname, _ := obj.(*PkgName); pname != nil { + assert(pname.pkg == check.pkg) + check.recordUse(ident, pname) + pname.used = true + pkg := pname.imported + exp := pkg.scope.Lookup(sel) + if exp == nil { + if !pkg.fake { + check.errorf(e.Sel.Pos(), "%s not declared by package %s", sel, pkg.name) + } + goto Error + } + if !exp.Exported() { + check.errorf(e.Sel.Pos(), "%s not exported by package %s", sel, pkg.name) + // ok to continue + } + check.recordUse(e.Sel, exp) + + // Simplified version of the code for *ast.Idents: + // - imported objects are always fully initialized + switch exp := exp.(type) { + case *Const: + assert(exp.Val() != nil) + x.mode = constant_ + x.typ = exp.typ + x.val = exp.val + case *TypeName: + x.mode = typexpr + x.typ = exp.typ + case *Var: + x.mode = variable + x.typ = exp.typ + case *Func: + x.mode = value + x.typ = exp.typ + case *Builtin: + x.mode = builtin + x.typ = exp.typ + x.id = exp.id + default: + check.dump("unexpected object %v", exp) + unreachable() + } + x.expr = e + return + } + } + + check.exprOrType(x, e.X) + if x.mode == invalid { + goto Error + } + + obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel) + if obj == nil { + switch { + case index != nil: + // TODO(gri) should provide actual type where the conflict happens + check.invalidOp(e.Sel.Pos(), "ambiguous selector %s", sel) + case indirect: + check.invalidOp(e.Sel.Pos(), "%s is not in method set of %s", sel, x.typ) + default: + check.invalidOp(e.Sel.Pos(), "%s has no field or method %s", x, sel) + } + goto Error + } + + if x.mode == typexpr { + // method expression + m, _ := obj.(*Func) + if m == nil { + check.invalidOp(e.Sel.Pos(), "%s has no method %s", x, sel) + goto Error + } + + check.recordSelection(e, MethodExpr, x.typ, m, index, indirect) + + // the receiver type becomes the type of the first function + // argument of the method expression's function type + var params []*Var + sig := m.typ.(*Signature) + if sig.params != nil { + params = sig.params.vars + } + x.mode = value + x.typ = &Signature{ + params: NewTuple(append([]*Var{NewVar(token.NoPos, check.pkg, "", x.typ)}, params...)...), + results: sig.results, + variadic: sig.variadic, + } + + check.addDeclDep(m) + + } else { + // regular selector + switch obj := obj.(type) { + case *Var: + check.recordSelection(e, FieldVal, x.typ, obj, index, indirect) + if x.mode == variable || indirect { + x.mode = variable + } else { + x.mode = value + } + x.typ = obj.typ + + case *Func: + // TODO(gri) If we needed to take into account the receiver's + // addressability, should we report the type &(x.typ) instead? + check.recordSelection(e, MethodVal, x.typ, obj, index, indirect) + + if debug { + // Verify that LookupFieldOrMethod and MethodSet.Lookup agree. + typ := x.typ + if x.mode == variable { + // If typ is not an (unnamed) pointer or an interface, + // use *typ instead, because the method set of *typ + // includes the methods of typ. + // Variables are addressable, so we can always take their + // address. + if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) { + typ = &Pointer{base: typ} + } + } + // If we created a synthetic pointer type above, we will throw + // away the method set computed here after use. + // TODO(gri) Method set computation should probably always compute + // both, the value and the pointer receiver method set and represent + // them in a single structure. + // TODO(gri) Consider also using a method set cache for the lifetime + // of checker once we rely on MethodSet lookup instead of individual + // lookup. + mset := NewMethodSet(typ) + if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj { + check.dump("%v: (%s).%v -> %s", e.Pos(), typ, obj.name, m) + check.dump("%s\n", mset) + panic("method sets and lookup don't agree") + } + } + + x.mode = value + + // remove receiver + sig := *obj.typ.(*Signature) + sig.recv = nil + x.typ = &sig + + check.addDeclDep(obj) + + default: + unreachable() + } + } + + // everything went well + x.expr = e + return + +Error: + x.mode = invalid + x.expr = e +} diff --git a/vendor/go/types/check.go b/vendor/go/types/check.go new file mode 100644 index 000000000..177065fde --- /dev/null +++ b/vendor/go/types/check.go @@ -0,0 +1,356 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements the Check function, which drives type-checking. + +package types + +import ( + "go/ast" + "go/constant" + "go/token" +) + +// debugging/development support +const ( + debug = false // leave on during development + trace = false // turn on for detailed type resolution traces +) + +// If Strict is set, the type-checker enforces additional +// rules not specified by the Go 1 spec, but which will +// catch guaranteed run-time errors if the respective +// code is executed. In other words, programs passing in +// Strict mode are Go 1 compliant, but not all Go 1 programs +// will pass in Strict mode. The additional rules are: +// +// - A type assertion x.(T) where T is an interface type +// is invalid if any (statically known) method that exists +// for both x and T have different signatures. +// +const strict = false + +// exprInfo stores information about an untyped expression. +type exprInfo struct { + isLhs bool // expression is lhs operand of a shift with delayed type-check + mode operandMode + typ *Basic + val constant.Value // constant value; or nil (if not a constant) +} + +// A context represents the context within which an object is type-checked. +type context struct { + decl *declInfo // package-level declaration whose init expression/function body is checked + scope *Scope // top-most scope for lookups + pos token.Pos // if valid, identifiers are looked up as if at position pos (used by Eval) + iota constant.Value // value of iota in a constant declaration; nil otherwise + sig *Signature // function signature if inside a function; nil otherwise + isPanic map[*ast.CallExpr]bool // set of panic call expressions (used for termination check) + hasLabel bool // set if a function makes use of labels (only ~1% of functions); unused outside functions + hasCallOrRecv bool // set if an expression contains a function call or channel receive operation +} + +// lookup looks up name in the current context and returns the matching object, or nil. +func (ctxt *context) lookup(name string) Object { + _, obj := ctxt.scope.LookupParent(name, ctxt.pos) + return obj +} + +// An importKey identifies an imported package by import path and source directory +// (directory containing the file containing the import). In practice, the directory +// may always be the same, or may not matter. Given an (import path, directory), an +// importer must always return the same package (but given two different import paths, +// an importer may still return the same package by mapping them to the same package +// paths). +type importKey struct { + path, dir string +} + +// A Checker maintains the state of the type checker. +// It must be created with NewChecker. +type Checker struct { + // package information + // (initialized by NewChecker, valid for the life-time of checker) + conf *Config + fset *token.FileSet + pkg *Package + *Info + objMap map[Object]*declInfo // maps package-level object to declaration info + impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package + + // information collected during type-checking of a set of package files + // (initialized by Files, valid only for the duration of check.Files; + // maps and lists are allocated on demand) + files []*ast.File // package files + unusedDotImports map[*Scope]map[*Package]token.Pos // positions of unused dot-imported packages for each file scope + + firstErr error // first error encountered + methods map[*TypeName][]*Func // maps package scope type names to associated non-blank, non-interface methods + interfaces map[*TypeName]*ifaceInfo // maps interface type names to corresponding interface infos + untyped map[ast.Expr]exprInfo // map of expressions without final type + delayed []func() // stack of delayed actions + + // context within which the current object is type-checked + // (valid only for the duration of type-checking a specific object) + context + + // debugging + indent int // indentation for tracing +} + +// addUnusedImport adds the position of a dot-imported package +// pkg to the map of dot imports for the given file scope. +func (check *Checker) addUnusedDotImport(scope *Scope, pkg *Package, pos token.Pos) { + mm := check.unusedDotImports + if mm == nil { + mm = make(map[*Scope]map[*Package]token.Pos) + check.unusedDotImports = mm + } + m := mm[scope] + if m == nil { + m = make(map[*Package]token.Pos) + mm[scope] = m + } + m[pkg] = pos +} + +// addDeclDep adds the dependency edge (check.decl -> to) if check.decl exists +func (check *Checker) addDeclDep(to Object) { + from := check.decl + if from == nil { + return // not in a package-level init expression + } + if _, found := check.objMap[to]; !found { + return // to is not a package-level object + } + from.addDep(to) +} + +func (check *Checker) rememberUntyped(e ast.Expr, lhs bool, mode operandMode, typ *Basic, val constant.Value) { + m := check.untyped + if m == nil { + m = make(map[ast.Expr]exprInfo) + check.untyped = m + } + m[e] = exprInfo{lhs, mode, typ, val} +} + +// later pushes f on to the stack of actions that will be processed later; +// either at the end of the current statement, or in case of a local constant +// or variable declaration, before the constant or variable is in scope +// (so that f still sees the scope before any new declarations). +func (check *Checker) later(f func()) { + check.delayed = append(check.delayed, f) +} + +// NewChecker returns a new Checker instance for a given package. +// Package files may be added incrementally via checker.Files. +func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Checker { + // make sure we have a configuration + if conf == nil { + conf = new(Config) + } + + // make sure we have an info struct + if info == nil { + info = new(Info) + } + + return &Checker{ + conf: conf, + fset: fset, + pkg: pkg, + Info: info, + objMap: make(map[Object]*declInfo), + impMap: make(map[importKey]*Package), + } +} + +// initFiles initializes the files-specific portion of checker. +// The provided files must all belong to the same package. +func (check *Checker) initFiles(files []*ast.File) { + // start with a clean slate (check.Files may be called multiple times) + check.files = nil + check.unusedDotImports = nil + + check.firstErr = nil + check.methods = nil + check.interfaces = nil + check.untyped = nil + check.delayed = nil + + // determine package name and collect valid files + pkg := check.pkg + for _, file := range files { + switch name := file.Name.Name; pkg.name { + case "": + if name != "_" { + pkg.name = name + } else { + check.errorf(file.Name.Pos(), "invalid package name _") + } + fallthrough + + case name: + check.files = append(check.files, file) + + default: + check.errorf(file.Package, "package %s; expected %s", name, pkg.name) + // ignore this file + } + } +} + +// A bailout panic is used for early termination. +type bailout struct{} + +func (check *Checker) handleBailout(err *error) { + switch p := recover().(type) { + case nil, bailout: + // normal return or early exit + *err = check.firstErr + default: + // re-panic + panic(p) + } +} + +// Files checks the provided files as part of the checker's package. +func (check *Checker) Files(files []*ast.File) error { return check.checkFiles(files) } + +func (check *Checker) checkFiles(files []*ast.File) (err error) { + defer check.handleBailout(&err) + + check.initFiles(files) + + check.collectObjects() + + check.packageObjects() + + check.processDelayed(0) // incl. all functions + + check.initOrder() + + if !check.conf.DisableUnusedImportCheck { + check.unusedImports() + } + + check.recordUntyped() + + check.pkg.complete = true + return +} + +func (check *Checker) recordUntyped() { + if !debug && check.Types == nil { + return // nothing to do + } + + for x, info := range check.untyped { + if debug && isTyped(info.typ) { + check.dump("%v: %s (type %s) is typed", x.Pos(), x, info.typ) + unreachable() + } + check.recordTypeAndValue(x, info.mode, info.typ, info.val) + } +} + +func (check *Checker) recordTypeAndValue(x ast.Expr, mode operandMode, typ Type, val constant.Value) { + assert(x != nil) + assert(typ != nil) + if mode == invalid { + return // omit + } + assert(typ != nil) + if mode == constant_ { + assert(val != nil) + assert(typ == Typ[Invalid] || isConstType(typ)) + } + if m := check.Types; m != nil { + m[x] = TypeAndValue{mode, typ, val} + } +} + +func (check *Checker) recordBuiltinType(f ast.Expr, sig *Signature) { + // f must be a (possibly parenthesized) identifier denoting a built-in + // (built-ins in package unsafe always produce a constant result and + // we don't record their signatures, so we don't see qualified idents + // here): record the signature for f and possible children. + for { + check.recordTypeAndValue(f, builtin, sig, nil) + switch p := f.(type) { + case *ast.Ident: + return // we're done + case *ast.ParenExpr: + f = p.X + default: + unreachable() + } + } +} + +func (check *Checker) recordCommaOkTypes(x ast.Expr, a [2]Type) { + assert(x != nil) + if a[0] == nil || a[1] == nil { + return + } + assert(isTyped(a[0]) && isTyped(a[1]) && isBoolean(a[1])) + if m := check.Types; m != nil { + for { + tv := m[x] + assert(tv.Type != nil) // should have been recorded already + pos := x.Pos() + tv.Type = NewTuple( + NewVar(pos, check.pkg, "", a[0]), + NewVar(pos, check.pkg, "", a[1]), + ) + m[x] = tv + // if x is a parenthesized expression (p.X), update p.X + p, _ := x.(*ast.ParenExpr) + if p == nil { + break + } + x = p.X + } + } +} + +func (check *Checker) recordDef(id *ast.Ident, obj Object) { + assert(id != nil) + if m := check.Defs; m != nil { + m[id] = obj + } +} + +func (check *Checker) recordUse(id *ast.Ident, obj Object) { + assert(id != nil) + assert(obj != nil) + if m := check.Uses; m != nil { + m[id] = obj + } +} + +func (check *Checker) recordImplicit(node ast.Node, obj Object) { + assert(node != nil) + assert(obj != nil) + if m := check.Implicits; m != nil { + m[node] = obj + } +} + +func (check *Checker) recordSelection(x *ast.SelectorExpr, kind SelectionKind, recv Type, obj Object, index []int, indirect bool) { + assert(obj != nil && (recv == nil || len(index) > 0)) + check.recordUse(x.Sel, obj) + if m := check.Selections; m != nil { + m[x] = &Selection{kind, recv, obj, index, indirect} + } +} + +func (check *Checker) recordScope(node ast.Node, scope *Scope) { + assert(node != nil) + assert(scope != nil) + if m := check.Scopes; m != nil { + m[node] = scope + } +} diff --git a/vendor/go/types/conversions.go b/vendor/go/types/conversions.go new file mode 100644 index 000000000..81a65838f --- /dev/null +++ b/vendor/go/types/conversions.go @@ -0,0 +1,160 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements typechecking of conversions. + +package types + +import "go/constant" + +// Conversion type-checks the conversion T(x). +// The result is in x. +func (check *Checker) conversion(x *operand, T Type) { + constArg := x.mode == constant_ + + var ok bool + switch { + case constArg && isConstType(T): + // constant conversion + switch t := T.Underlying().(*Basic); { + case representableConst(x.val, check.conf, t, &x.val): + ok = true + case isInteger(x.typ) && isString(t): + codepoint := int64(-1) + if i, ok := constant.Int64Val(x.val); ok { + codepoint = i + } + // If codepoint < 0 the absolute value is too large (or unknown) for + // conversion. This is the same as converting any other out-of-range + // value - let string(codepoint) do the work. + x.val = constant.MakeString(string(codepoint)) + ok = true + } + case x.convertibleTo(check.conf, T): + // non-constant conversion + x.mode = value + ok = true + } + + if !ok { + check.errorf(x.pos(), "cannot convert %s to %s", x, T) + x.mode = invalid + return + } + + // The conversion argument types are final. For untyped values the + // conversion provides the type, per the spec: "A constant may be + // given a type explicitly by a constant declaration or conversion,...". + if isUntyped(x.typ) { + final := T + // - For conversions to interfaces, use the argument's default type. + // - For conversions of untyped constants to non-constant types, also + // use the default type (e.g., []byte("foo") should report string + // not []byte as type for the constant "foo"). + // - Keep untyped nil for untyped nil arguments. + // - For integer to string conversions, keep the argument type. + // (See also the TODO below.) + if IsInterface(T) || constArg && !isConstType(T) { + final = Default(x.typ) + } else if isInteger(x.typ) && isString(T) { + final = x.typ + } + check.updateExprType(x.expr, final, true) + } + + x.typ = T +} + +// TODO(gri) convertibleTo checks if T(x) is valid. It assumes that the type +// of x is fully known, but that's not the case for say string(1<b-> ... ->g for a path [a, b, ... g]. +func pathString(path []*TypeName) string { + var s string + for i, p := range path { + if i > 0 { + s += "->" + } + s += p.Name() + } + return s +} + +// objDecl type-checks the declaration of obj in its respective (file) context. +// See check.typ for the details on def and path. +func (check *Checker) objDecl(obj Object, def *Named, path []*TypeName) { + if obj.Type() != nil { + return // already checked - nothing to do + } + + if trace { + check.trace(obj.Pos(), "-- checking %s (path = %s)", obj, pathString(path)) + check.indent++ + defer func() { + check.indent-- + check.trace(obj.Pos(), "=> %s", obj) + }() + } + + d := check.objMap[obj] + if d == nil { + check.dump("%v: %s should have been declared", obj.Pos(), obj) + unreachable() + } + + // save/restore current context and setup object context + defer func(ctxt context) { + check.context = ctxt + }(check.context) + check.context = context{ + scope: d.file, + } + + // Const and var declarations must not have initialization + // cycles. We track them by remembering the current declaration + // in check.decl. Initialization expressions depending on other + // consts, vars, or functions, add dependencies to the current + // check.decl. + switch obj := obj.(type) { + case *Const: + check.decl = d // new package-level const decl + check.constDecl(obj, d.typ, d.init) + case *Var: + check.decl = d // new package-level var decl + check.varDecl(obj, d.lhs, d.typ, d.init) + case *TypeName: + // invalid recursive types are detected via path + check.typeDecl(obj, d.typ, def, path, d.alias) + case *Func: + // functions may be recursive - no need to track dependencies + check.funcDecl(obj, d) + default: + unreachable() + } +} + +func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) { + assert(obj.typ == nil) + + if obj.visited { + obj.typ = Typ[Invalid] + return + } + obj.visited = true + + // use the correct value of iota + check.iota = obj.val + defer func() { check.iota = nil }() + + // provide valid constant value under all circumstances + obj.val = constant.MakeUnknown() + + // determine type, if any + if typ != nil { + t := check.typ(typ) + if !isConstType(t) { + // don't report an error if the type is an invalid C (defined) type + // (issue #22090) + if t.Underlying() != Typ[Invalid] { + check.errorf(typ.Pos(), "invalid constant type %s", t) + } + obj.typ = Typ[Invalid] + return + } + obj.typ = t + } + + // check initialization + var x operand + if init != nil { + check.expr(&x, init) + } + check.initConst(obj, &x) +} + +func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) { + assert(obj.typ == nil) + + if obj.visited { + obj.typ = Typ[Invalid] + return + } + obj.visited = true + + // determine type, if any + if typ != nil { + obj.typ = check.typ(typ) + // We cannot spread the type to all lhs variables if there + // are more than one since that would mark them as checked + // (see Checker.objDecl) and the assignment of init exprs, + // if any, would not be checked. + // + // TODO(gri) If we have no init expr, we should distribute + // a given type otherwise we need to re-evalate the type + // expr for each lhs variable, leading to duplicate work. + } + + // check initialization + if init == nil { + if typ == nil { + // error reported before by arityMatch + obj.typ = Typ[Invalid] + } + return + } + + if lhs == nil || len(lhs) == 1 { + assert(lhs == nil || lhs[0] == obj) + var x operand + check.expr(&x, init) + check.initVar(obj, &x, "variable declaration") + return + } + + if debug { + // obj must be one of lhs + found := false + for _, lhs := range lhs { + if obj == lhs { + found = true + break + } + } + if !found { + panic("inconsistent lhs") + } + } + + // We have multiple variables on the lhs and one init expr. + // Make sure all variables have been given the same type if + // one was specified, otherwise they assume the type of the + // init expression values (was issue #15755). + if typ != nil { + for _, lhs := range lhs { + lhs.typ = obj.typ + } + } + + check.initVars(lhs, []ast.Expr{init}, token.NoPos) +} + +// underlying returns the underlying type of typ; possibly by following +// forward chains of named types. Such chains only exist while named types +// are incomplete. +func underlying(typ Type) Type { + for { + n, _ := typ.(*Named) + if n == nil { + break + } + typ = n.underlying + } + return typ +} + +func (n *Named) setUnderlying(typ Type) { + if n != nil { + n.underlying = typ + } +} + +func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, path []*TypeName, alias bool) { + assert(obj.typ == nil) + + if alias { + + obj.typ = Typ[Invalid] + obj.typ = check.typExpr(typ, nil, append(path, obj)) + + } else { + + named := &Named{obj: obj} + def.setUnderlying(named) + obj.typ = named // make sure recursive type declarations terminate + + // determine underlying type of named + check.typExpr(typ, named, append(path, obj)) + + // The underlying type of named may be itself a named type that is + // incomplete: + // + // type ( + // A B + // B *C + // C A + // ) + // + // The type of C is the (named) type of A which is incomplete, + // and which has as its underlying type the named type B. + // Determine the (final, unnamed) underlying type by resolving + // any forward chain (they always end in an unnamed type). + named.underlying = underlying(named.underlying) + + } + + // check and add associated methods + // TODO(gri) It's easy to create pathological cases where the + // current approach is incorrect: In general we need to know + // and add all methods _before_ type-checking the type. + // See https://play.golang.org/p/WMpE0q2wK8 + check.addMethodDecls(obj) +} + +func (check *Checker) addMethodDecls(obj *TypeName) { + // get associated methods + // (Checker.collectObjects only collects methods with non-blank names; + // Checker.resolveBaseTypeName ensures that obj is not an alias name + // if it has attached methods.) + methods := check.methods[obj] + if methods == nil { + return + } + delete(check.methods, obj) + assert(!obj.IsAlias()) + + // use an objset to check for name conflicts + var mset objset + + // spec: "If the base type is a struct type, the non-blank method + // and field names must be distinct." + base, _ := obj.typ.(*Named) // shouldn't fail but be conservative + if base != nil { + if t, _ := base.underlying.(*Struct); t != nil { + for _, fld := range t.fields { + if fld.name != "_" { + assert(mset.insert(fld) == nil) + } + } + } + + // Checker.Files may be called multiple times; additional package files + // may add methods to already type-checked types. Add pre-existing methods + // so that we can detect redeclarations. + for _, m := range base.methods { + assert(m.name != "_") + assert(mset.insert(m) == nil) + } + } + + // type-check methods + for _, m := range methods { + // spec: "For a base type, the non-blank names of methods bound + // to it must be unique." + assert(m.name != "_") + if alt := mset.insert(m); alt != nil { + switch alt.(type) { + case *Var: + check.errorf(m.pos, "field and method with the same name %s", m.name) + case *Func: + check.errorf(m.pos, "method %s already declared for %s", m.name, obj) + default: + unreachable() + } + check.reportAltDecl(alt) + continue + } + + // type-check + check.objDecl(m, nil, nil) + + if base != nil { + base.methods = append(base.methods, m) + } + } +} + +func (check *Checker) funcDecl(obj *Func, decl *declInfo) { + assert(obj.typ == nil) + + // func declarations cannot use iota + assert(check.iota == nil) + + sig := new(Signature) + obj.typ = sig // guard against cycles + fdecl := decl.fdecl + check.funcType(sig, fdecl.Recv, fdecl.Type) + if sig.recv == nil && obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) { + check.errorf(fdecl.Pos(), "func init must have no arguments and no return values") + // ok to continue + } + + // function body must be type-checked after global declarations + // (functions implemented elsewhere have no body) + if !check.conf.IgnoreFuncBodies && fdecl.Body != nil { + check.later(func() { + check.funcBody(decl, obj.name, sig, fdecl.Body, nil) + }) + } +} + +func (check *Checker) declStmt(decl ast.Decl) { + pkg := check.pkg + + switch d := decl.(type) { + case *ast.BadDecl: + // ignore + + case *ast.GenDecl: + var last *ast.ValueSpec // last ValueSpec with type or init exprs seen + for iota, spec := range d.Specs { + switch s := spec.(type) { + case *ast.ValueSpec: + switch d.Tok { + case token.CONST: + top := len(check.delayed) + + // determine which init exprs to use + switch { + case s.Type != nil || len(s.Values) > 0: + last = s + case last == nil: + last = new(ast.ValueSpec) // make sure last exists + } + + // declare all constants + lhs := make([]*Const, len(s.Names)) + for i, name := range s.Names { + obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota))) + lhs[i] = obj + + var init ast.Expr + if i < len(last.Values) { + init = last.Values[i] + } + + check.constDecl(obj, last.Type, init) + } + + check.arityMatch(s, last) + + // process function literals in init expressions before scope changes + check.processDelayed(top) + + // spec: "The scope of a constant or variable identifier declared + // inside a function begins at the end of the ConstSpec or VarSpec + // (ShortVarDecl for short variable declarations) and ends at the + // end of the innermost containing block." + scopePos := s.End() + for i, name := range s.Names { + check.declare(check.scope, name, lhs[i], scopePos) + } + + case token.VAR: + top := len(check.delayed) + + lhs0 := make([]*Var, len(s.Names)) + for i, name := range s.Names { + lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil) + } + + // initialize all variables + for i, obj := range lhs0 { + var lhs []*Var + var init ast.Expr + switch len(s.Values) { + case len(s.Names): + // lhs and rhs match + init = s.Values[i] + case 1: + // rhs is expected to be a multi-valued expression + lhs = lhs0 + init = s.Values[0] + default: + if i < len(s.Values) { + init = s.Values[i] + } + } + check.varDecl(obj, lhs, s.Type, init) + if len(s.Values) == 1 { + // If we have a single lhs variable we are done either way. + // If we have a single rhs expression, it must be a multi- + // valued expression, in which case handling the first lhs + // variable will cause all lhs variables to have a type + // assigned, and we are done as well. + if debug { + for _, obj := range lhs0 { + assert(obj.typ != nil) + } + } + break + } + } + + check.arityMatch(s, nil) + + // process function literals in init expressions before scope changes + check.processDelayed(top) + + // declare all variables + // (only at this point are the variable scopes (parents) set) + scopePos := s.End() // see constant declarations + for i, name := range s.Names { + // see constant declarations + check.declare(check.scope, name, lhs0[i], scopePos) + } + + default: + check.invalidAST(s.Pos(), "invalid token %s", d.Tok) + } + + case *ast.TypeSpec: + obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil) + // spec: "The scope of a type identifier declared inside a function + // begins at the identifier in the TypeSpec and ends at the end of + // the innermost containing block." + scopePos := s.Name.Pos() + check.declare(check.scope, s.Name, obj, scopePos) + check.typeDecl(obj, s.Type, nil, nil, s.Assign.IsValid()) + + default: + check.invalidAST(s.Pos(), "const, type, or var declaration expected") + } + } + + default: + check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d) + } +} diff --git a/vendor/go/types/errors.go b/vendor/go/types/errors.go new file mode 100644 index 000000000..0c0049b1f --- /dev/null +++ b/vendor/go/types/errors.go @@ -0,0 +1,103 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements various error reporters. + +package types + +import ( + "fmt" + "go/ast" + "go/token" + "strings" +) + +func assert(p bool) { + if !p { + panic("assertion failed") + } +} + +func unreachable() { + panic("unreachable") +} + +func (check *Checker) qualifier(pkg *Package) string { + if pkg != check.pkg { + return pkg.path + } + return "" +} + +func (check *Checker) sprintf(format string, args ...interface{}) string { + for i, arg := range args { + switch a := arg.(type) { + case nil: + arg = "" + case operand: + panic("internal error: should always pass *operand") + case *operand: + arg = operandString(a, check.qualifier) + case token.Pos: + arg = check.fset.Position(a).String() + case ast.Expr: + arg = ExprString(a) + case Object: + arg = ObjectString(a, check.qualifier) + case Type: + arg = TypeString(a, check.qualifier) + } + args[i] = arg + } + return fmt.Sprintf(format, args...) +} + +func (check *Checker) trace(pos token.Pos, format string, args ...interface{}) { + fmt.Printf("%s:\t%s%s\n", + check.fset.Position(pos), + strings.Repeat(". ", check.indent), + check.sprintf(format, args...), + ) +} + +// dump is only needed for debugging +func (check *Checker) dump(format string, args ...interface{}) { + fmt.Println(check.sprintf(format, args...)) +} + +func (check *Checker) err(pos token.Pos, msg string, soft bool) { + err := Error{check.fset, pos, msg, soft} + if check.firstErr == nil { + check.firstErr = err + } + f := check.conf.Error + if f == nil { + panic(bailout{}) // report only first error + } + f(err) +} + +func (check *Checker) error(pos token.Pos, msg string) { + check.err(pos, msg, false) +} + +func (check *Checker) errorf(pos token.Pos, format string, args ...interface{}) { + check.err(pos, check.sprintf(format, args...), false) +} + +func (check *Checker) softErrorf(pos token.Pos, format string, args ...interface{}) { + check.err(pos, check.sprintf(format, args...), true) +} + +func (check *Checker) invalidAST(pos token.Pos, format string, args ...interface{}) { + check.errorf(pos, "invalid AST: "+format, args...) +} + +func (check *Checker) invalidArg(pos token.Pos, format string, args ...interface{}) { + check.errorf(pos, "invalid argument: "+format, args...) +} + +func (check *Checker) invalidOp(pos token.Pos, format string, args ...interface{}) { + check.errorf(pos, "invalid operation: "+format, args...) +} diff --git a/vendor/go/types/eval.go b/vendor/go/types/eval.go new file mode 100644 index 000000000..8d4db48a9 --- /dev/null +++ b/vendor/go/types/eval.go @@ -0,0 +1,82 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package types + +import ( + "fmt" + "go/parser" + "go/token" +) + +// Eval returns the type and, if constant, the value for the +// expression expr, evaluated at position pos of package pkg, +// which must have been derived from type-checking an AST with +// complete position information relative to the provided file +// set. +// +// If pkg == nil, the Universe scope is used and the provided +// position pos is ignored. If pkg != nil, and pos is invalid, +// the package scope is used. Otherwise, pos must belong to the +// package. +// +// An error is returned if pos is not within the package or +// if the node cannot be evaluated. +// +// Note: Eval should not be used instead of running Check to compute +// types and values, but in addition to Check. Eval will re-evaluate +// its argument each time, and it also does not know about the context +// in which an expression is used (e.g., an assignment). Thus, top- +// level untyped constants will return an untyped type rather then the +// respective context-specific type. +// +func Eval(fset *token.FileSet, pkg *Package, pos token.Pos, expr string) (_ TypeAndValue, err error) { + // determine scope + var scope *Scope + if pkg == nil { + scope = Universe + pos = token.NoPos + } else if !pos.IsValid() { + scope = pkg.scope + } else { + // The package scope extent (position information) may be + // incorrect (files spread across a wide range of fset + // positions) - ignore it and just consider its children + // (file scopes). + for _, fscope := range pkg.scope.children { + if scope = fscope.Innermost(pos); scope != nil { + break + } + } + if scope == nil || debug { + s := scope + for s != nil && s != pkg.scope { + s = s.parent + } + // s == nil || s == pkg.scope + if s == nil { + return TypeAndValue{}, fmt.Errorf("no position %s found in package %s", fset.Position(pos), pkg.name) + } + } + } + + // parse expressions + node, err := parser.ParseExprFrom(fset, "eval", expr, 0) + if err != nil { + return TypeAndValue{}, err + } + + // initialize checker + check := NewChecker(nil, fset, pkg, nil) + check.scope = scope + check.pos = pos + defer check.handleBailout(&err) + + // evaluate node + var x operand + check.rawExpr(&x, node, nil) + check.processDelayed(0) // incl. all functions + + return TypeAndValue{x.mode, x.typ, x.val}, nil +} diff --git a/vendor/go/types/expr.go b/vendor/go/types/expr.go new file mode 100644 index 000000000..0a2a811bd --- /dev/null +++ b/vendor/go/types/expr.go @@ -0,0 +1,1622 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements typechecking of expressions. + +package types + +import ( + "fmt" + "go/ast" + "go/constant" + "go/token" + "math" +) + +/* +Basic algorithm: + +Expressions are checked recursively, top down. Expression checker functions +are generally of the form: + + func f(x *operand, e *ast.Expr, ...) + +where e is the expression to be checked, and x is the result of the check. +The check performed by f may fail in which case x.mode == invalid, and +related error messages will have been issued by f. + +If a hint argument is present, it is the composite literal element type +of an outer composite literal; it is used to type-check composite literal +elements that have no explicit type specification in the source +(e.g.: []T{{...}, {...}}, the hint is the type T in this case). + +All expressions are checked via rawExpr, which dispatches according +to expression kind. Upon returning, rawExpr is recording the types and +constant values for all expressions that have an untyped type (those types +may change on the way up in the expression tree). Usually these are constants, +but the results of comparisons or non-constant shifts of untyped constants +may also be untyped, but not constant. + +Untyped expressions may eventually become fully typed (i.e., not untyped), +typically when the value is assigned to a variable, or is used otherwise. +The updateExprType method is used to record this final type and update +the recorded types: the type-checked expression tree is again traversed down, +and the new type is propagated as needed. Untyped constant expression values +that become fully typed must now be representable by the full type (constant +sub-expression trees are left alone except for their roots). This mechanism +ensures that a client sees the actual (run-time) type an untyped value would +have. It also permits type-checking of lhs shift operands "as if the shift +were not present": when updateExprType visits an untyped lhs shift operand +and assigns it it's final type, that type must be an integer type, and a +constant lhs must be representable as an integer. + +When an expression gets its final type, either on the way out from rawExpr, +on the way down in updateExprType, or at the end of the type checker run, +the type (and constant value, if any) is recorded via Info.Types, if present. +*/ + +type opPredicates map[token.Token]func(Type) bool + +var unaryOpPredicates = opPredicates{ + token.ADD: isNumeric, + token.SUB: isNumeric, + token.XOR: isInteger, + token.NOT: isBoolean, +} + +func (check *Checker) op(m opPredicates, x *operand, op token.Token) bool { + if pred := m[op]; pred != nil { + if !pred(x.typ) { + check.invalidOp(x.pos(), "operator %s not defined for %s", op, x) + return false + } + } else { + check.invalidAST(x.pos(), "unknown operator %s", op) + return false + } + return true +} + +// The unary expression e may be nil. It's passed in for better error messages only. +func (check *Checker) unary(x *operand, e *ast.UnaryExpr, op token.Token) { + switch op { + case token.AND: + // spec: "As an exception to the addressability + // requirement x may also be a composite literal." + if _, ok := unparen(x.expr).(*ast.CompositeLit); !ok && x.mode != variable { + check.invalidOp(x.pos(), "cannot take address of %s", x) + x.mode = invalid + return + } + x.mode = value + x.typ = &Pointer{base: x.typ} + return + + case token.ARROW: + typ, ok := x.typ.Underlying().(*Chan) + if !ok { + check.invalidOp(x.pos(), "cannot receive from non-channel %s", x) + x.mode = invalid + return + } + if typ.dir == SendOnly { + check.invalidOp(x.pos(), "cannot receive from send-only channel %s", x) + x.mode = invalid + return + } + x.mode = commaok + x.typ = typ.elem + check.hasCallOrRecv = true + return + } + + if !check.op(unaryOpPredicates, x, op) { + x.mode = invalid + return + } + + if x.mode == constant_ { + typ := x.typ.Underlying().(*Basic) + var prec uint + if isUnsigned(typ) { + prec = uint(check.conf.sizeof(typ) * 8) + } + x.val = constant.UnaryOp(op, x.val, prec) + // Typed constants must be representable in + // their type after each constant operation. + if isTyped(typ) { + if e != nil { + x.expr = e // for better error message + } + check.representable(x, typ) + } + return + } + + x.mode = value + // x.typ remains unchanged +} + +func isShift(op token.Token) bool { + return op == token.SHL || op == token.SHR +} + +func isComparison(op token.Token) bool { + // Note: tokens are not ordered well to make this much easier + switch op { + case token.EQL, token.NEQ, token.LSS, token.LEQ, token.GTR, token.GEQ: + return true + } + return false +} + +func fitsFloat32(x constant.Value) bool { + f32, _ := constant.Float32Val(x) + f := float64(f32) + return !math.IsInf(f, 0) +} + +func roundFloat32(x constant.Value) constant.Value { + f32, _ := constant.Float32Val(x) + f := float64(f32) + if !math.IsInf(f, 0) { + return constant.MakeFloat64(f) + } + return nil +} + +func fitsFloat64(x constant.Value) bool { + f, _ := constant.Float64Val(x) + return !math.IsInf(f, 0) +} + +func roundFloat64(x constant.Value) constant.Value { + f, _ := constant.Float64Val(x) + if !math.IsInf(f, 0) { + return constant.MakeFloat64(f) + } + return nil +} + +// representableConst reports whether x can be represented as +// value of the given basic type and for the configuration +// provided (only needed for int/uint sizes). +// +// If rounded != nil, *rounded is set to the rounded value of x for +// representable floating-point and complex values, and to an Int +// value for integer values; it is left alone otherwise. +// It is ok to provide the addressof the first argument for rounded. +func representableConst(x constant.Value, conf *Config, typ *Basic, rounded *constant.Value) bool { + if x.Kind() == constant.Unknown { + return true // avoid follow-up errors + } + + switch { + case isInteger(typ): + x := constant.ToInt(x) + if x.Kind() != constant.Int { + return false + } + if rounded != nil { + *rounded = x + } + if x, ok := constant.Int64Val(x); ok { + switch typ.kind { + case Int: + var s = uint(conf.sizeof(typ)) * 8 + return int64(-1)<<(s-1) <= x && x <= int64(1)<<(s-1)-1 + case Int8: + const s = 8 + return -1<<(s-1) <= x && x <= 1<<(s-1)-1 + case Int16: + const s = 16 + return -1<<(s-1) <= x && x <= 1<<(s-1)-1 + case Int32: + const s = 32 + return -1<<(s-1) <= x && x <= 1<<(s-1)-1 + case Int64, UntypedInt: + return true + case Uint, Uintptr: + if s := uint(conf.sizeof(typ)) * 8; s < 64 { + return 0 <= x && x <= int64(1)<= 0 && n <= int(s) + case Uint64: + return constant.Sign(x) >= 0 && n <= 64 + case UntypedInt: + return true + } + + case isFloat(typ): + x := constant.ToFloat(x) + if x.Kind() != constant.Float { + return false + } + switch typ.kind { + case Float32: + if rounded == nil { + return fitsFloat32(x) + } + r := roundFloat32(x) + if r != nil { + *rounded = r + return true + } + case Float64: + if rounded == nil { + return fitsFloat64(x) + } + r := roundFloat64(x) + if r != nil { + *rounded = r + return true + } + case UntypedFloat: + return true + default: + unreachable() + } + + case isComplex(typ): + x := constant.ToComplex(x) + if x.Kind() != constant.Complex { + return false + } + switch typ.kind { + case Complex64: + if rounded == nil { + return fitsFloat32(constant.Real(x)) && fitsFloat32(constant.Imag(x)) + } + re := roundFloat32(constant.Real(x)) + im := roundFloat32(constant.Imag(x)) + if re != nil && im != nil { + *rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) + return true + } + case Complex128: + if rounded == nil { + return fitsFloat64(constant.Real(x)) && fitsFloat64(constant.Imag(x)) + } + re := roundFloat64(constant.Real(x)) + im := roundFloat64(constant.Imag(x)) + if re != nil && im != nil { + *rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) + return true + } + case UntypedComplex: + return true + default: + unreachable() + } + + case isString(typ): + return x.Kind() == constant.String + + case isBoolean(typ): + return x.Kind() == constant.Bool + } + + return false +} + +// representable checks that a constant operand is representable in the given basic type. +func (check *Checker) representable(x *operand, typ *Basic) { + assert(x.mode == constant_) + if !representableConst(x.val, check.conf, typ, &x.val) { + var msg string + if isNumeric(x.typ) && isNumeric(typ) { + // numeric conversion : error msg + // + // integer -> integer : overflows + // integer -> float : overflows (actually not possible) + // float -> integer : truncated + // float -> float : overflows + // + if !isInteger(x.typ) && isInteger(typ) { + msg = "%s truncated to %s" + } else { + msg = "%s overflows %s" + } + } else { + msg = "cannot convert %s to %s" + } + check.errorf(x.pos(), msg, x, typ) + x.mode = invalid + } +} + +// updateExprType updates the type of x to typ and invokes itself +// recursively for the operands of x, depending on expression kind. +// If typ is still an untyped and not the final type, updateExprType +// only updates the recorded untyped type for x and possibly its +// operands. Otherwise (i.e., typ is not an untyped type anymore, +// or it is the final type for x), the type and value are recorded. +// Also, if x is a constant, it must be representable as a value of typ, +// and if x is the (formerly untyped) lhs operand of a non-constant +// shift, it must be an integer value. +// +func (check *Checker) updateExprType(x ast.Expr, typ Type, final bool) { + old, found := check.untyped[x] + if !found { + return // nothing to do + } + + // update operands of x if necessary + switch x := x.(type) { + case *ast.BadExpr, + *ast.FuncLit, + *ast.CompositeLit, + *ast.IndexExpr, + *ast.SliceExpr, + *ast.TypeAssertExpr, + *ast.StarExpr, + *ast.KeyValueExpr, + *ast.ArrayType, + *ast.StructType, + *ast.FuncType, + *ast.InterfaceType, + *ast.MapType, + *ast.ChanType: + // These expression are never untyped - nothing to do. + // The respective sub-expressions got their final types + // upon assignment or use. + if debug { + check.dump("%v: found old type(%s): %s (new: %s)", x.Pos(), x, old.typ, typ) + unreachable() + } + return + + case *ast.CallExpr: + // Resulting in an untyped constant (e.g., built-in complex). + // The respective calls take care of calling updateExprType + // for the arguments if necessary. + + case *ast.Ident, *ast.BasicLit, *ast.SelectorExpr: + // An identifier denoting a constant, a constant literal, + // or a qualified identifier (imported untyped constant). + // No operands to take care of. + + case *ast.ParenExpr: + check.updateExprType(x.X, typ, final) + + case *ast.UnaryExpr: + // If x is a constant, the operands were constants. + // The operands don't need to be updated since they + // never get "materialized" into a typed value. If + // left in the untyped map, they will be processed + // at the end of the type check. + if old.val != nil { + break + } + check.updateExprType(x.X, typ, final) + + case *ast.BinaryExpr: + if old.val != nil { + break // see comment for unary expressions + } + if isComparison(x.Op) { + // The result type is independent of operand types + // and the operand types must have final types. + } else if isShift(x.Op) { + // The result type depends only on lhs operand. + // The rhs type was updated when checking the shift. + check.updateExprType(x.X, typ, final) + } else { + // The operand types match the result type. + check.updateExprType(x.X, typ, final) + check.updateExprType(x.Y, typ, final) + } + + default: + unreachable() + } + + // If the new type is not final and still untyped, just + // update the recorded type. + if !final && isUntyped(typ) { + old.typ = typ.Underlying().(*Basic) + check.untyped[x] = old + return + } + + // Otherwise we have the final (typed or untyped type). + // Remove it from the map of yet untyped expressions. + delete(check.untyped, x) + + if old.isLhs { + // If x is the lhs of a shift, its final type must be integer. + // We already know from the shift check that it is representable + // as an integer if it is a constant. + if !isInteger(typ) { + check.invalidOp(x.Pos(), "shifted operand %s (type %s) must be integer", x, typ) + return + } + } else if old.val != nil { + // If x is a constant, it must be representable as a value of typ. + c := operand{old.mode, x, old.typ, old.val, 0} + check.convertUntyped(&c, typ) + if c.mode == invalid { + return + } + } + + // Everything's fine, record final type and value for x. + check.recordTypeAndValue(x, old.mode, typ, old.val) +} + +// updateExprVal updates the value of x to val. +func (check *Checker) updateExprVal(x ast.Expr, val constant.Value) { + if info, ok := check.untyped[x]; ok { + info.val = val + check.untyped[x] = info + } +} + +// convertUntyped attempts to set the type of an untyped value to the target type. +func (check *Checker) convertUntyped(x *operand, target Type) { + if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] { + return + } + + // TODO(gri) Sloppy code - clean up. This function is central + // to assignment and expression checking. + + if isUntyped(target) { + // both x and target are untyped + xkind := x.typ.(*Basic).kind + tkind := target.(*Basic).kind + if isNumeric(x.typ) && isNumeric(target) { + if xkind < tkind { + x.typ = target + check.updateExprType(x.expr, target, false) + } + } else if xkind != tkind { + goto Error + } + return + } + + // typed target + switch t := target.Underlying().(type) { + case *Basic: + if x.mode == constant_ { + check.representable(x, t) + if x.mode == invalid { + return + } + // expression value may have been rounded - update if needed + check.updateExprVal(x.expr, x.val) + } else { + // Non-constant untyped values may appear as the + // result of comparisons (untyped bool), intermediate + // (delayed-checked) rhs operands of shifts, and as + // the value nil. + switch x.typ.(*Basic).kind { + case UntypedBool: + if !isBoolean(target) { + goto Error + } + case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex: + if !isNumeric(target) { + goto Error + } + case UntypedString: + // Non-constant untyped string values are not + // permitted by the spec and should not occur. + unreachable() + case UntypedNil: + // Unsafe.Pointer is a basic type that includes nil. + if !hasNil(target) { + goto Error + } + default: + goto Error + } + } + case *Interface: + if !x.isNil() && !t.Empty() /* empty interfaces are ok */ { + goto Error + } + // Update operand types to the default type rather then + // the target (interface) type: values must have concrete + // dynamic types. If the value is nil, keep it untyped + // (this is important for tools such as go vet which need + // the dynamic type for argument checking of say, print + // functions) + if x.isNil() { + target = Typ[UntypedNil] + } else { + // cannot assign untyped values to non-empty interfaces + if !t.Empty() { + goto Error + } + target = Default(x.typ) + } + case *Pointer, *Signature, *Slice, *Map, *Chan: + if !x.isNil() { + goto Error + } + // keep nil untyped - see comment for interfaces, above + target = Typ[UntypedNil] + default: + goto Error + } + + x.typ = target + check.updateExprType(x.expr, target, true) // UntypedNils are final + return + +Error: + check.errorf(x.pos(), "cannot convert %s to %s", x, target) + x.mode = invalid +} + +func (check *Checker) comparison(x, y *operand, op token.Token) { + // spec: "In any comparison, the first operand must be assignable + // to the type of the second operand, or vice versa." + err := "" + if x.assignableTo(check.conf, y.typ, nil) || y.assignableTo(check.conf, x.typ, nil) { + defined := false + switch op { + case token.EQL, token.NEQ: + // spec: "The equality operators == and != apply to operands that are comparable." + defined = Comparable(x.typ) || x.isNil() && hasNil(y.typ) || y.isNil() && hasNil(x.typ) + case token.LSS, token.LEQ, token.GTR, token.GEQ: + // spec: The ordering operators <, <=, >, and >= apply to operands that are ordered." + defined = isOrdered(x.typ) + default: + unreachable() + } + if !defined { + typ := x.typ + if x.isNil() { + typ = y.typ + } + err = check.sprintf("operator %s not defined for %s", op, typ) + } + } else { + err = check.sprintf("mismatched types %s and %s", x.typ, y.typ) + } + + if err != "" { + check.errorf(x.pos(), "cannot compare %s %s %s (%s)", x.expr, op, y.expr, err) + x.mode = invalid + return + } + + if x.mode == constant_ && y.mode == constant_ { + x.val = constant.MakeBool(constant.Compare(x.val, op, y.val)) + // The operands are never materialized; no need to update + // their types. + } else { + x.mode = value + // The operands have now their final types, which at run- + // time will be materialized. Update the expression trees. + // If the current types are untyped, the materialized type + // is the respective default type. + check.updateExprType(x.expr, Default(x.typ), true) + check.updateExprType(y.expr, Default(y.typ), true) + } + + // spec: "Comparison operators compare two operands and yield + // an untyped boolean value." + x.typ = Typ[UntypedBool] +} + +func (check *Checker) shift(x, y *operand, e *ast.BinaryExpr, op token.Token) { + untypedx := isUntyped(x.typ) + + var xval constant.Value + if x.mode == constant_ { + xval = constant.ToInt(x.val) + } + + if isInteger(x.typ) || untypedx && xval != nil && xval.Kind() == constant.Int { + // The lhs is of integer type or an untyped constant representable + // as an integer. Nothing to do. + } else { + // shift has no chance + check.invalidOp(x.pos(), "shifted operand %s must be integer", x) + x.mode = invalid + return + } + + // spec: "The right operand in a shift expression must have unsigned + // integer type or be an untyped constant representable by a value of + // type uint." + switch { + case isUnsigned(y.typ): + // nothing to do + case isUntyped(y.typ): + check.convertUntyped(y, Typ[Uint]) + if y.mode == invalid { + x.mode = invalid + return + } + default: + check.invalidOp(y.pos(), "shift count %s must be unsigned integer", y) + x.mode = invalid + return + } + + if x.mode == constant_ { + if y.mode == constant_ { + // rhs must be an integer value + yval := constant.ToInt(y.val) + if yval.Kind() != constant.Int { + check.invalidOp(y.pos(), "shift count %s must be unsigned integer", y) + x.mode = invalid + return + } + // rhs must be within reasonable bounds + const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64 + s, ok := constant.Uint64Val(yval) + if !ok || s > shiftBound { + check.invalidOp(y.pos(), "invalid shift count %s", y) + x.mode = invalid + return + } + // The lhs is representable as an integer but may not be an integer + // (e.g., 2.0, an untyped float) - this can only happen for untyped + // non-integer numeric constants. Correct the type so that the shift + // result is of integer type. + if !isInteger(x.typ) { + x.typ = Typ[UntypedInt] + } + // x is a constant so xval != nil and it must be of Int kind. + x.val = constant.Shift(xval, op, uint(s)) + // Typed constants must be representable in + // their type after each constant operation. + if isTyped(x.typ) { + if e != nil { + x.expr = e // for better error message + } + check.representable(x, x.typ.Underlying().(*Basic)) + } + return + } + + // non-constant shift with constant lhs + if untypedx { + // spec: "If the left operand of a non-constant shift + // expression is an untyped constant, the type of the + // constant is what it would be if the shift expression + // were replaced by its left operand alone.". + // + // Delay operand checking until we know the final type + // by marking the lhs expression as lhs shift operand. + // + // Usually (in correct programs), the lhs expression + // is in the untyped map. However, it is possible to + // create incorrect programs where the same expression + // is evaluated twice (via a declaration cycle) such + // that the lhs expression type is determined in the + // first round and thus deleted from the map, and then + // not found in the second round (double insertion of + // the same expr node still just leads to one entry for + // that node, and it can only be deleted once). + // Be cautious and check for presence of entry. + // Example: var e, f = int(1<<""[f]) // issue 11347 + if info, found := check.untyped[x.expr]; found { + info.isLhs = true + check.untyped[x.expr] = info + } + // keep x's type + x.mode = value + return + } + } + + // constant rhs must be >= 0 + if y.mode == constant_ && constant.Sign(y.val) < 0 { + check.invalidOp(y.pos(), "shift count %s must not be negative", y) + } + + // non-constant shift - lhs must be an integer + if !isInteger(x.typ) { + check.invalidOp(x.pos(), "shifted operand %s must be integer", x) + x.mode = invalid + return + } + + x.mode = value +} + +var binaryOpPredicates = opPredicates{ + token.ADD: func(typ Type) bool { return isNumeric(typ) || isString(typ) }, + token.SUB: isNumeric, + token.MUL: isNumeric, + token.QUO: isNumeric, + token.REM: isInteger, + + token.AND: isInteger, + token.OR: isInteger, + token.XOR: isInteger, + token.AND_NOT: isInteger, + + token.LAND: isBoolean, + token.LOR: isBoolean, +} + +// The binary expression e may be nil. It's passed in for better error messages only. +func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, op token.Token) { + var y operand + + check.expr(x, lhs) + check.expr(&y, rhs) + + if x.mode == invalid { + return + } + if y.mode == invalid { + x.mode = invalid + x.expr = y.expr + return + } + + if isShift(op) { + check.shift(x, &y, e, op) + return + } + + check.convertUntyped(x, y.typ) + if x.mode == invalid { + return + } + check.convertUntyped(&y, x.typ) + if y.mode == invalid { + x.mode = invalid + return + } + + if isComparison(op) { + check.comparison(x, &y, op) + return + } + + if !Identical(x.typ, y.typ) { + // only report an error if we have valid types + // (otherwise we had an error reported elsewhere already) + if x.typ != Typ[Invalid] && y.typ != Typ[Invalid] { + check.invalidOp(x.pos(), "mismatched types %s and %s", x.typ, y.typ) + } + x.mode = invalid + return + } + + if !check.op(binaryOpPredicates, x, op) { + x.mode = invalid + return + } + + if op == token.QUO || op == token.REM { + // check for zero divisor + if (x.mode == constant_ || isInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 { + check.invalidOp(y.pos(), "division by zero") + x.mode = invalid + return + } + + // check for divisor underflow in complex division (see issue 20227) + if x.mode == constant_ && y.mode == constant_ && isComplex(x.typ) { + re, im := constant.Real(y.val), constant.Imag(y.val) + re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im) + if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 { + check.invalidOp(y.pos(), "division by zero") + x.mode = invalid + return + } + } + } + + if x.mode == constant_ && y.mode == constant_ { + xval := x.val + yval := y.val + typ := x.typ.Underlying().(*Basic) + // force integer division of integer operands + if op == token.QUO && isInteger(typ) { + op = token.QUO_ASSIGN + } + x.val = constant.BinaryOp(xval, op, yval) + // Typed constants must be representable in + // their type after each constant operation. + if isTyped(typ) { + if e != nil { + x.expr = e // for better error message + } + check.representable(x, typ) + } + return + } + + x.mode = value + // x.typ is unchanged +} + +// index checks an index expression for validity. +// If max >= 0, it is the upper bound for index. +// If index is valid and the result i >= 0, then i is the constant value of index. +func (check *Checker) index(index ast.Expr, max int64) (i int64, valid bool) { + var x operand + check.expr(&x, index) + if x.mode == invalid { + return + } + + // an untyped constant must be representable as Int + check.convertUntyped(&x, Typ[Int]) + if x.mode == invalid { + return + } + + // the index must be of integer type + if !isInteger(x.typ) { + check.invalidArg(x.pos(), "index %s must be integer", &x) + return + } + + // a constant index i must be in bounds + if x.mode == constant_ { + if constant.Sign(x.val) < 0 { + check.invalidArg(x.pos(), "index %s must not be negative", &x) + return + } + i, valid = constant.Int64Val(constant.ToInt(x.val)) + if !valid || max >= 0 && i >= max { + check.errorf(x.pos(), "index %s is out of bounds", &x) + return i, false + } + // 0 <= i [ && i < max ] + return i, true + } + + return -1, true +} + +// indexElts checks the elements (elts) of an array or slice composite literal +// against the literal's element type (typ), and the element indices against +// the literal length if known (length >= 0). It returns the length of the +// literal (maximum index value + 1). +// +func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 { + visited := make(map[int64]bool, len(elts)) + var index, max int64 + for _, e := range elts { + // determine and check index + validIndex := false + eval := e + if kv, _ := e.(*ast.KeyValueExpr); kv != nil { + if i, ok := check.index(kv.Key, length); ok { + if i >= 0 { + index = i + validIndex = true + } else { + check.errorf(e.Pos(), "index %s must be integer constant", kv.Key) + } + } + eval = kv.Value + } else if length >= 0 && index >= length { + check.errorf(e.Pos(), "index %d is out of bounds (>= %d)", index, length) + } else { + validIndex = true + } + + // if we have a valid index, check for duplicate entries + if validIndex { + if visited[index] { + check.errorf(e.Pos(), "duplicate index %d in array or slice literal", index) + } + visited[index] = true + } + index++ + if index > max { + max = index + } + + // check element against composite literal element type + var x operand + check.exprWithHint(&x, eval, typ) + check.assignment(&x, typ, "array or slice literal") + } + return max +} + +// exprKind describes the kind of an expression; the kind +// determines if an expression is valid in 'statement context'. +type exprKind int + +const ( + conversion exprKind = iota + expression + statement +) + +// rawExpr typechecks expression e and initializes x with the expression +// value or type. If an error occurred, x.mode is set to invalid. +// If hint != nil, it is the type of a composite literal element. +// +func (check *Checker) rawExpr(x *operand, e ast.Expr, hint Type) exprKind { + if trace { + check.trace(e.Pos(), "%s", e) + check.indent++ + defer func() { + check.indent-- + check.trace(e.Pos(), "=> %s", x) + }() + } + + kind := check.exprInternal(x, e, hint) + + // convert x into a user-friendly set of values + // TODO(gri) this code can be simplified + var typ Type + var val constant.Value + switch x.mode { + case invalid: + typ = Typ[Invalid] + case novalue: + typ = (*Tuple)(nil) + case constant_: + typ = x.typ + val = x.val + default: + typ = x.typ + } + assert(x.expr != nil && typ != nil) + + if isUntyped(typ) { + // delay type and value recording until we know the type + // or until the end of type checking + check.rememberUntyped(x.expr, false, x.mode, typ.(*Basic), val) + } else { + check.recordTypeAndValue(e, x.mode, typ, val) + } + + return kind +} + +// exprInternal contains the core of type checking of expressions. +// Must only be called by rawExpr. +// +func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { + // make sure x has a valid state in case of bailout + // (was issue 5770) + x.mode = invalid + x.typ = Typ[Invalid] + + switch e := e.(type) { + case *ast.BadExpr: + goto Error // error was reported before + + case *ast.Ident: + check.ident(x, e, nil, nil) + + case *ast.Ellipsis: + // ellipses are handled explicitly where they are legal + // (array composite literals and parameter lists) + check.error(e.Pos(), "invalid use of '...'") + goto Error + + case *ast.BasicLit: + x.setConst(e.Kind, e.Value) + if x.mode == invalid { + check.invalidAST(e.Pos(), "invalid literal %v", e.Value) + goto Error + } + + case *ast.FuncLit: + if sig, ok := check.typ(e.Type).(*Signature); ok { + // Anonymous functions are considered part of the + // init expression/func declaration which contains + // them: use existing package-level declaration info. + decl := check.decl // capture for use in closure below + iota := check.iota // capture for use in closure below (#22345) + // Don't type-check right away because the function may + // be part of a type definition to which the function + // body refers. Instead, type-check as soon as possible, + // but before the enclosing scope contents changes (#22992). + check.later(func() { + check.funcBody(decl, "", sig, e.Body, iota) + }) + x.mode = value + x.typ = sig + } else { + check.invalidAST(e.Pos(), "invalid function literal %s", e) + goto Error + } + + case *ast.CompositeLit: + var typ, base Type + + switch { + case e.Type != nil: + // composite literal type present - use it + // [...]T array types may only appear with composite literals. + // Check for them here so we don't have to handle ... in general. + if atyp, _ := e.Type.(*ast.ArrayType); atyp != nil && atyp.Len != nil { + if ellip, _ := atyp.Len.(*ast.Ellipsis); ellip != nil && ellip.Elt == nil { + // We have an "open" [...]T array type. + // Create a new ArrayType with unknown length (-1) + // and finish setting it up after analyzing the literal. + typ = &Array{len: -1, elem: check.typ(atyp.Elt)} + base = typ + break + } + } + typ = check.typ(e.Type) + base = typ + + case hint != nil: + // no composite literal type present - use hint (element type of enclosing type) + typ = hint + base, _ = deref(typ.Underlying()) // *T implies &T{} + + default: + // TODO(gri) provide better error messages depending on context + check.error(e.Pos(), "missing type in composite literal") + goto Error + } + + switch utyp := base.Underlying().(type) { + case *Struct: + if len(e.Elts) == 0 { + break + } + fields := utyp.fields + if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok { + // all elements must have keys + visited := make([]bool, len(fields)) + for _, e := range e.Elts { + kv, _ := e.(*ast.KeyValueExpr) + if kv == nil { + check.error(e.Pos(), "mixture of field:value and value elements in struct literal") + continue + } + key, _ := kv.Key.(*ast.Ident) + if key == nil { + check.errorf(kv.Pos(), "invalid field name %s in struct literal", kv.Key) + continue + } + i := fieldIndex(utyp.fields, check.pkg, key.Name) + if i < 0 { + check.errorf(kv.Pos(), "unknown field %s in struct literal", key.Name) + continue + } + fld := fields[i] + check.recordUse(key, fld) + // 0 <= i < len(fields) + if visited[i] { + check.errorf(kv.Pos(), "duplicate field name %s in struct literal", key.Name) + continue + } + visited[i] = true + check.expr(x, kv.Value) + etyp := fld.typ + check.assignment(x, etyp, "struct literal") + } + } else { + // no element must have a key + for i, e := range e.Elts { + if kv, _ := e.(*ast.KeyValueExpr); kv != nil { + check.error(kv.Pos(), "mixture of field:value and value elements in struct literal") + continue + } + check.expr(x, e) + if i >= len(fields) { + check.error(x.pos(), "too many values in struct literal") + break // cannot continue + } + // i < len(fields) + fld := fields[i] + if !fld.Exported() && fld.pkg != check.pkg { + check.errorf(x.pos(), "implicit assignment to unexported field %s in %s literal", fld.name, typ) + continue + } + etyp := fld.typ + check.assignment(x, etyp, "struct literal") + } + if len(e.Elts) < len(fields) { + check.error(e.Rbrace, "too few values in struct literal") + // ok to continue + } + } + + case *Array: + // Prevent crash if the array referred to is not yet set up. + // This is a stop-gap solution; a better approach would use the mechanism of + // Checker.ident (typexpr.go) using a path of types. But that would require + // passing the path everywhere (all expression-checking methods, not just + // type expression checking), and we're not set up for that (quite possibly + // an indication that cycle detection needs to be rethought). Was issue #18643. + if utyp.elem == nil { + check.error(e.Pos(), "illegal cycle in type declaration") + goto Error + } + n := check.indexedElts(e.Elts, utyp.elem, utyp.len) + // If we have an "open" [...]T array, set the length now that we know it + // and record the type for [...] (usually done by check.typExpr which is + // not called for [...]). + if utyp.len < 0 { + utyp.len = n + check.recordTypeAndValue(e.Type, typexpr, utyp, nil) + } + + case *Slice: + // Prevent crash if the slice referred to is not yet set up. + // See analogous comment for *Array. + if utyp.elem == nil { + check.error(e.Pos(), "illegal cycle in type declaration") + goto Error + } + check.indexedElts(e.Elts, utyp.elem, -1) + + case *Map: + // Prevent crash if the map referred to is not yet set up. + // See analogous comment for *Array. + if utyp.key == nil || utyp.elem == nil { + check.error(e.Pos(), "illegal cycle in type declaration") + goto Error + } + visited := make(map[interface{}][]Type, len(e.Elts)) + for _, e := range e.Elts { + kv, _ := e.(*ast.KeyValueExpr) + if kv == nil { + check.error(e.Pos(), "missing key in map literal") + continue + } + check.exprWithHint(x, kv.Key, utyp.key) + check.assignment(x, utyp.key, "map literal") + if x.mode == invalid { + continue + } + if x.mode == constant_ { + duplicate := false + // if the key is of interface type, the type is also significant when checking for duplicates + xkey := keyVal(x.val) + if _, ok := utyp.key.Underlying().(*Interface); ok { + for _, vtyp := range visited[xkey] { + if Identical(vtyp, x.typ) { + duplicate = true + break + } + } + visited[xkey] = append(visited[xkey], x.typ) + } else { + _, duplicate = visited[xkey] + visited[xkey] = nil + } + if duplicate { + check.errorf(x.pos(), "duplicate key %s in map literal", x.val) + continue + } + } + check.exprWithHint(x, kv.Value, utyp.elem) + check.assignment(x, utyp.elem, "map literal") + } + + default: + // when "using" all elements unpack KeyValueExpr + // explicitly because check.use doesn't accept them + for _, e := range e.Elts { + if kv, _ := e.(*ast.KeyValueExpr); kv != nil { + // Ideally, we should also "use" kv.Key but we can't know + // if it's an externally defined struct key or not. Going + // forward anyway can lead to other errors. Give up instead. + e = kv.Value + } + check.use(e) + } + // if utyp is invalid, an error was reported before + if utyp != Typ[Invalid] { + check.errorf(e.Pos(), "invalid composite literal type %s", typ) + goto Error + } + } + + x.mode = value + x.typ = typ + + case *ast.ParenExpr: + kind := check.rawExpr(x, e.X, nil) + x.expr = e + return kind + + case *ast.SelectorExpr: + check.selector(x, e) + + case *ast.IndexExpr: + check.expr(x, e.X) + if x.mode == invalid { + check.use(e.Index) + goto Error + } + + valid := false + length := int64(-1) // valid if >= 0 + switch typ := x.typ.Underlying().(type) { + case *Basic: + if isString(typ) { + valid = true + if x.mode == constant_ { + length = int64(len(constant.StringVal(x.val))) + } + // an indexed string always yields a byte value + // (not a constant) even if the string and the + // index are constant + x.mode = value + x.typ = universeByte // use 'byte' name + } + + case *Array: + valid = true + length = typ.len + if x.mode != variable { + x.mode = value + } + x.typ = typ.elem + + case *Pointer: + if typ, _ := typ.base.Underlying().(*Array); typ != nil { + valid = true + length = typ.len + x.mode = variable + x.typ = typ.elem + } + + case *Slice: + valid = true + x.mode = variable + x.typ = typ.elem + + case *Map: + var key operand + check.expr(&key, e.Index) + check.assignment(&key, typ.key, "map index") + if x.mode == invalid { + goto Error + } + x.mode = mapindex + x.typ = typ.elem + x.expr = e + return expression + } + + if !valid { + check.invalidOp(x.pos(), "cannot index %s", x) + goto Error + } + + if e.Index == nil { + check.invalidAST(e.Pos(), "missing index for %s", x) + goto Error + } + + check.index(e.Index, length) + // ok to continue + + case *ast.SliceExpr: + check.expr(x, e.X) + if x.mode == invalid { + check.use(e.Low, e.High, e.Max) + goto Error + } + + valid := false + length := int64(-1) // valid if >= 0 + switch typ := x.typ.Underlying().(type) { + case *Basic: + if isString(typ) { + if e.Slice3 { + check.invalidOp(x.pos(), "3-index slice of string") + goto Error + } + valid = true + if x.mode == constant_ { + length = int64(len(constant.StringVal(x.val))) + } + // spec: "For untyped string operands the result + // is a non-constant value of type string." + if typ.kind == UntypedString { + x.typ = Typ[String] + } + } + + case *Array: + valid = true + length = typ.len + if x.mode != variable { + check.invalidOp(x.pos(), "cannot slice %s (value not addressable)", x) + goto Error + } + x.typ = &Slice{elem: typ.elem} + + case *Pointer: + if typ, _ := typ.base.Underlying().(*Array); typ != nil { + valid = true + length = typ.len + x.typ = &Slice{elem: typ.elem} + } + + case *Slice: + valid = true + // x.typ doesn't change + } + + if !valid { + check.invalidOp(x.pos(), "cannot slice %s", x) + goto Error + } + + x.mode = value + + // spec: "Only the first index may be omitted; it defaults to 0." + if e.Slice3 && (e.High == nil || e.Max == nil) { + check.error(e.Rbrack, "2nd and 3rd index required in 3-index slice") + goto Error + } + + // check indices + var ind [3]int64 + for i, expr := range []ast.Expr{e.Low, e.High, e.Max} { + x := int64(-1) + switch { + case expr != nil: + // The "capacity" is only known statically for strings, arrays, + // and pointers to arrays, and it is the same as the length for + // those types. + max := int64(-1) + if length >= 0 { + max = length + 1 + } + if t, ok := check.index(expr, max); ok && t >= 0 { + x = t + } + case i == 0: + // default is 0 for the first index + x = 0 + case length >= 0: + // default is length (== capacity) otherwise + x = length + } + ind[i] = x + } + + // constant indices must be in range + // (check.index already checks that existing indices >= 0) + L: + for i, x := range ind[:len(ind)-1] { + if x > 0 { + for _, y := range ind[i+1:] { + if y >= 0 && x > y { + check.errorf(e.Rbrack, "invalid slice indices: %d > %d", x, y) + break L // only report one error, ok to continue + } + } + } + } + + case *ast.TypeAssertExpr: + check.expr(x, e.X) + if x.mode == invalid { + goto Error + } + xtyp, _ := x.typ.Underlying().(*Interface) + if xtyp == nil { + check.invalidOp(x.pos(), "%s is not an interface", x) + goto Error + } + // x.(type) expressions are handled explicitly in type switches + if e.Type == nil { + check.invalidAST(e.Pos(), "use of .(type) outside type switch") + goto Error + } + T := check.typ(e.Type) + if T == Typ[Invalid] { + goto Error + } + check.typeAssertion(x.pos(), x, xtyp, T) + x.mode = commaok + x.typ = T + + case *ast.CallExpr: + return check.call(x, e) + + case *ast.StarExpr: + check.exprOrType(x, e.X) + switch x.mode { + case invalid: + goto Error + case typexpr: + x.typ = &Pointer{base: x.typ} + default: + if typ, ok := x.typ.Underlying().(*Pointer); ok { + x.mode = variable + x.typ = typ.base + } else { + check.invalidOp(x.pos(), "cannot indirect %s", x) + goto Error + } + } + + case *ast.UnaryExpr: + check.expr(x, e.X) + if x.mode == invalid { + goto Error + } + check.unary(x, e, e.Op) + if x.mode == invalid { + goto Error + } + if e.Op == token.ARROW { + x.expr = e + return statement // receive operations may appear in statement context + } + + case *ast.BinaryExpr: + check.binary(x, e, e.X, e.Y, e.Op) + if x.mode == invalid { + goto Error + } + + case *ast.KeyValueExpr: + // key:value expressions are handled in composite literals + check.invalidAST(e.Pos(), "no key:value expected") + goto Error + + case *ast.ArrayType, *ast.StructType, *ast.FuncType, + *ast.InterfaceType, *ast.MapType, *ast.ChanType: + x.mode = typexpr + x.typ = check.typ(e) + // Note: rawExpr (caller of exprInternal) will call check.recordTypeAndValue + // even though check.typ has already called it. This is fine as both + // times the same expression and type are recorded. It is also not a + // performance issue because we only reach here for composite literal + // types, which are comparatively rare. + + default: + panic(fmt.Sprintf("%s: unknown expression type %T", check.fset.Position(e.Pos()), e)) + } + + // everything went well + x.expr = e + return expression + +Error: + x.mode = invalid + x.expr = e + return statement // avoid follow-up errors +} + +func keyVal(x constant.Value) interface{} { + switch x.Kind() { + case constant.Bool: + return constant.BoolVal(x) + case constant.String: + return constant.StringVal(x) + case constant.Int: + if v, ok := constant.Int64Val(x); ok { + return v + } + if v, ok := constant.Uint64Val(x); ok { + return v + } + case constant.Float: + v, _ := constant.Float64Val(x) + return v + case constant.Complex: + r, _ := constant.Float64Val(constant.Real(x)) + i, _ := constant.Float64Val(constant.Imag(x)) + return complex(r, i) + } + return x +} + +// typeAssertion checks that x.(T) is legal; xtyp must be the type of x. +func (check *Checker) typeAssertion(pos token.Pos, x *operand, xtyp *Interface, T Type) { + method, wrongType := assertableTo(xtyp, T) + if method == nil { + return + } + + var msg string + if wrongType { + msg = "wrong type for method" + } else { + msg = "missing method" + } + check.errorf(pos, "%s cannot have dynamic type %s (%s %s)", x, T, msg, method.name) +} + +func (check *Checker) singleValue(x *operand) { + if x.mode == value { + // tuple types are never named - no need for underlying type below + if t, ok := x.typ.(*Tuple); ok { + assert(t.Len() != 1) + check.errorf(x.pos(), "%d-valued %s where single value is expected", t.Len(), x) + x.mode = invalid + } + } +} + +// expr typechecks expression e and initializes x with the expression value. +// The result must be a single value. +// If an error occurred, x.mode is set to invalid. +// +func (check *Checker) expr(x *operand, e ast.Expr) { + check.multiExpr(x, e) + check.singleValue(x) +} + +// multiExpr is like expr but the result may be a multi-value. +func (check *Checker) multiExpr(x *operand, e ast.Expr) { + check.rawExpr(x, e, nil) + var msg string + switch x.mode { + default: + return + case novalue: + msg = "%s used as value" + case builtin: + msg = "%s must be called" + case typexpr: + msg = "%s is not an expression" + } + check.errorf(x.pos(), msg, x) + x.mode = invalid +} + +// exprWithHint typechecks expression e and initializes x with the expression value; +// hint is the type of a composite literal element. +// If an error occurred, x.mode is set to invalid. +// +func (check *Checker) exprWithHint(x *operand, e ast.Expr, hint Type) { + assert(hint != nil) + check.rawExpr(x, e, hint) + check.singleValue(x) + var msg string + switch x.mode { + default: + return + case novalue: + msg = "%s used as value" + case builtin: + msg = "%s must be called" + case typexpr: + msg = "%s is not an expression" + } + check.errorf(x.pos(), msg, x) + x.mode = invalid +} + +// exprOrType typechecks expression or type e and initializes x with the expression value or type. +// If an error occurred, x.mode is set to invalid. +// +func (check *Checker) exprOrType(x *operand, e ast.Expr) { + check.rawExpr(x, e, nil) + check.singleValue(x) + if x.mode == novalue { + check.errorf(x.pos(), "%s used as value or type", x) + x.mode = invalid + } +} diff --git a/vendor/go/types/exprstring.go b/vendor/go/types/exprstring.go new file mode 100644 index 000000000..28d605f5e --- /dev/null +++ b/vendor/go/types/exprstring.go @@ -0,0 +1,224 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements printing of expressions. + +package types + +import ( + "bytes" + "go/ast" +) + +// ExprString returns the (possibly shortened) string representation for x. +// Shortened representations are suitable for user interfaces but may not +// necessarily follow Go syntax. +func ExprString(x ast.Expr) string { + var buf bytes.Buffer + WriteExpr(&buf, x) + return buf.String() +} + +// WriteExpr writes the (possibly shortened) string representation for x to buf. +// Shortened representations are suitable for user interfaces but may not +// necessarily follow Go syntax. +func WriteExpr(buf *bytes.Buffer, x ast.Expr) { + // The AST preserves source-level parentheses so there is + // no need to introduce them here to correct for different + // operator precedences. (This assumes that the AST was + // generated by a Go parser.) + + switch x := x.(type) { + default: + buf.WriteString("(bad expr)") // nil, ast.BadExpr, ast.KeyValueExpr + + case *ast.Ident: + buf.WriteString(x.Name) + + case *ast.Ellipsis: + buf.WriteString("...") + if x.Elt != nil { + WriteExpr(buf, x.Elt) + } + + case *ast.BasicLit: + buf.WriteString(x.Value) + + case *ast.FuncLit: + buf.WriteByte('(') + WriteExpr(buf, x.Type) + buf.WriteString(" literal)") // shortened + + case *ast.CompositeLit: + buf.WriteByte('(') + WriteExpr(buf, x.Type) + buf.WriteString(" literal)") // shortened + + case *ast.ParenExpr: + buf.WriteByte('(') + WriteExpr(buf, x.X) + buf.WriteByte(')') + + case *ast.SelectorExpr: + WriteExpr(buf, x.X) + buf.WriteByte('.') + buf.WriteString(x.Sel.Name) + + case *ast.IndexExpr: + WriteExpr(buf, x.X) + buf.WriteByte('[') + WriteExpr(buf, x.Index) + buf.WriteByte(']') + + case *ast.SliceExpr: + WriteExpr(buf, x.X) + buf.WriteByte('[') + if x.Low != nil { + WriteExpr(buf, x.Low) + } + buf.WriteByte(':') + if x.High != nil { + WriteExpr(buf, x.High) + } + if x.Slice3 { + buf.WriteByte(':') + if x.Max != nil { + WriteExpr(buf, x.Max) + } + } + buf.WriteByte(']') + + case *ast.TypeAssertExpr: + WriteExpr(buf, x.X) + buf.WriteString(".(") + WriteExpr(buf, x.Type) + buf.WriteByte(')') + + case *ast.CallExpr: + WriteExpr(buf, x.Fun) + buf.WriteByte('(') + for i, arg := range x.Args { + if i > 0 { + buf.WriteString(", ") + } + WriteExpr(buf, arg) + } + if x.Ellipsis.IsValid() { + buf.WriteString("...") + } + buf.WriteByte(')') + + case *ast.StarExpr: + buf.WriteByte('*') + WriteExpr(buf, x.X) + + case *ast.UnaryExpr: + buf.WriteString(x.Op.String()) + WriteExpr(buf, x.X) + + case *ast.BinaryExpr: + WriteExpr(buf, x.X) + buf.WriteByte(' ') + buf.WriteString(x.Op.String()) + buf.WriteByte(' ') + WriteExpr(buf, x.Y) + + case *ast.ArrayType: + buf.WriteByte('[') + if x.Len != nil { + WriteExpr(buf, x.Len) + } + buf.WriteByte(']') + WriteExpr(buf, x.Elt) + + case *ast.StructType: + buf.WriteString("struct{") + writeFieldList(buf, x.Fields, "; ", false) + buf.WriteByte('}') + + case *ast.FuncType: + buf.WriteString("func") + writeSigExpr(buf, x) + + case *ast.InterfaceType: + buf.WriteString("interface{") + writeFieldList(buf, x.Methods, "; ", true) + buf.WriteByte('}') + + case *ast.MapType: + buf.WriteString("map[") + WriteExpr(buf, x.Key) + buf.WriteByte(']') + WriteExpr(buf, x.Value) + + case *ast.ChanType: + var s string + switch x.Dir { + case ast.SEND: + s = "chan<- " + case ast.RECV: + s = "<-chan " + default: + s = "chan " + } + buf.WriteString(s) + WriteExpr(buf, x.Value) + } +} + +func writeSigExpr(buf *bytes.Buffer, sig *ast.FuncType) { + buf.WriteByte('(') + writeFieldList(buf, sig.Params, ", ", false) + buf.WriteByte(')') + + res := sig.Results + n := res.NumFields() + if n == 0 { + // no result + return + } + + buf.WriteByte(' ') + if n == 1 && len(res.List[0].Names) == 0 { + // single unnamed result + WriteExpr(buf, res.List[0].Type) + return + } + + // multiple or named result(s) + buf.WriteByte('(') + writeFieldList(buf, res, ", ", false) + buf.WriteByte(')') +} + +func writeFieldList(buf *bytes.Buffer, fields *ast.FieldList, sep string, iface bool) { + for i, f := range fields.List { + if i > 0 { + buf.WriteString(sep) + } + + // field list names + for i, name := range f.Names { + if i > 0 { + buf.WriteString(", ") + } + buf.WriteString(name.Name) + } + + // types of interface methods consist of signatures only + if sig, _ := f.Type.(*ast.FuncType); sig != nil && iface { + writeSigExpr(buf, sig) + continue + } + + // named fields are separated with a blank from the field type + if len(f.Names) > 0 { + buf.WriteByte(' ') + } + + WriteExpr(buf, f.Type) + + // ignore tag + } +} diff --git a/vendor/go/types/gotype.go b/vendor/go/types/gotype.go new file mode 100644 index 000000000..cde373f35 --- /dev/null +++ b/vendor/go/types/gotype.go @@ -0,0 +1,354 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// Build this command explicitly: go build gotype.go + +/* +The gotype command, like the front-end of a Go compiler, parses and +type-checks a single Go package. Errors are reported if the analysis +fails; otherwise gotype is quiet (unless -v is set). + +Without a list of paths, gotype reads from standard input, which +must provide a single Go source file defining a complete package. + +With a single directory argument, gotype checks the Go files in +that directory, comprising a single package. Use -t to include the +(in-package) _test.go files. Use -x to type check only external +test files. + +Otherwise, each path must be the filename of a Go file belonging +to the same package. + +Imports are processed by importing directly from the source of +imported packages (default), or by importing from compiled and +installed packages (by setting -c to the respective compiler). + +The -c flag must be set to a compiler ("gc", "gccgo") when type- +checking packages containing imports with relative import paths +(import "./mypkg") because the source importer cannot know which +files to include for such packages. + +Usage: + gotype [flags] [path...] + +The flags are: + -t + include local test files in a directory (ignored if -x is provided) + -x + consider only external test files in a directory + -e + report all errors (not just the first 10) + -v + verbose mode + -c + compiler used for installed packages (gc, gccgo, or source); default: source + +Flags controlling additional output: + -ast + print AST (forces -seq) + -trace + print parse trace (forces -seq) + -comments + parse comments (ignored unless -ast or -trace is provided) + -panic + panic on first error + +Examples: + +To check the files a.go, b.go, and c.go: + + gotype a.go b.go c.go + +To check an entire package including (in-package) tests in the directory dir and print the processed files: + + gotype -t -v dir + +To check the external test package (if any) in the current directory, based on installed packages compiled with +cmd/compile: + + gotype -c=gc -x . + +To verify the output of a pipe: + + echo "package foo" | gotype + +*/ +package main + +import ( + "flag" + "fmt" + "go/ast" + "go/build" + "go/importer" + "go/parser" + "go/scanner" + "go/token" + "go/types" + "io/ioutil" + "os" + "path/filepath" + "sync" + "time" +) + +var ( + // main operation modes + testFiles = flag.Bool("t", false, "include in-package test files in a directory") + xtestFiles = flag.Bool("x", false, "consider only external test files in a directory") + allErrors = flag.Bool("e", false, "report all errors, not just the first 10") + verbose = flag.Bool("v", false, "verbose mode") + compiler = flag.String("c", "source", "compiler used for installed packages (gc, gccgo, or source)") + + // additional output control + printAST = flag.Bool("ast", false, "print AST (forces -seq)") + printTrace = flag.Bool("trace", false, "print parse trace (forces -seq)") + parseComments = flag.Bool("comments", false, "parse comments (ignored unless -ast or -trace is provided)") + panicOnError = flag.Bool("panic", false, "panic on first error") +) + +var ( + fset = token.NewFileSet() + errorCount = 0 + sequential = false + parserMode parser.Mode +) + +func initParserMode() { + if *allErrors { + parserMode |= parser.AllErrors + } + if *printAST { + sequential = true + } + if *printTrace { + parserMode |= parser.Trace + sequential = true + } + if *parseComments && (*printAST || *printTrace) { + parserMode |= parser.ParseComments + } +} + +const usageString = `usage: gotype [flags] [path ...] + +The gotype command, like the front-end of a Go compiler, parses and +type-checks a single Go package. Errors are reported if the analysis +fails; otherwise gotype is quiet (unless -v is set). + +Without a list of paths, gotype reads from standard input, which +must provide a single Go source file defining a complete package. + +With a single directory argument, gotype checks the Go files in +that directory, comprising a single package. Use -t to include the +(in-package) _test.go files. Use -x to type check only external +test files. + +Otherwise, each path must be the filename of a Go file belonging +to the same package. + +Imports are processed by importing directly from the source of +imported packages (default), or by importing from compiled and +installed packages (by setting -c to the respective compiler). + +The -c flag must be set to a compiler ("gc", "gccgo") when type- +checking packages containing imports with relative import paths +(import "./mypkg") because the source importer cannot know which +files to include for such packages. +` + +func usage() { + fmt.Fprintln(os.Stderr, usageString) + flag.PrintDefaults() + os.Exit(2) +} + +func report(err error) { + if *panicOnError { + panic(err) + } + scanner.PrintError(os.Stderr, err) + if list, ok := err.(scanner.ErrorList); ok { + errorCount += len(list) + return + } + errorCount++ +} + +// parse may be called concurrently +func parse(filename string, src interface{}) (*ast.File, error) { + if *verbose { + fmt.Println(filename) + } + file, err := parser.ParseFile(fset, filename, src, parserMode) // ok to access fset concurrently + if *printAST { + ast.Print(fset, file) + } + return file, err +} + +func parseStdin() (*ast.File, error) { + src, err := ioutil.ReadAll(os.Stdin) + if err != nil { + return nil, err + } + return parse("", src) +} + +func parseFiles(dir string, filenames []string) ([]*ast.File, error) { + files := make([]*ast.File, len(filenames)) + errors := make([]error, len(filenames)) + + var wg sync.WaitGroup + for i, filename := range filenames { + wg.Add(1) + go func(i int, filepath string) { + defer wg.Done() + files[i], errors[i] = parse(filepath, nil) + }(i, filepath.Join(dir, filename)) + if sequential { + wg.Wait() + } + } + wg.Wait() + + // If there are errors, return the first one for deterministic results. + var first error + for _, err := range errors { + if err != nil { + first = err + // If we have an error, some files may be nil. + // Remove them. (The go/parser always returns + // a possibly partial AST even in the presence + // of errors, except if the file doesn't exist + // in the first place, in which case it cannot + // matter.) + i := 0 + for _, f := range files { + if f != nil { + files[i] = f + i++ + } + } + files = files[:i] + break + } + } + + return files, first +} + +func parseDir(dir string) ([]*ast.File, error) { + ctxt := build.Default + pkginfo, err := ctxt.ImportDir(dir, 0) + if _, nogo := err.(*build.NoGoError); err != nil && !nogo { + return nil, err + } + + if *xtestFiles { + return parseFiles(dir, pkginfo.XTestGoFiles) + } + + filenames := append(pkginfo.GoFiles, pkginfo.CgoFiles...) + if *testFiles { + filenames = append(filenames, pkginfo.TestGoFiles...) + } + return parseFiles(dir, filenames) +} + +func getPkgFiles(args []string) ([]*ast.File, error) { + if len(args) == 0 { + // stdin + file, err := parseStdin() + if err != nil { + return nil, err + } + return []*ast.File{file}, nil + } + + if len(args) == 1 { + // possibly a directory + path := args[0] + info, err := os.Stat(path) + if err != nil { + return nil, err + } + if info.IsDir() { + return parseDir(path) + } + } + + // list of files + return parseFiles("", args) +} + +func checkPkgFiles(files []*ast.File) { + type bailout struct{} + + // if checkPkgFiles is called multiple times, set up conf only once + conf := types.Config{ + FakeImportC: true, + Error: func(err error) { + if !*allErrors && errorCount >= 10 { + panic(bailout{}) + } + report(err) + }, + Importer: importer.For(*compiler, nil), + Sizes: types.SizesFor(build.Default.Compiler, build.Default.GOARCH), + } + + defer func() { + switch p := recover().(type) { + case nil, bailout: + // normal return or early exit + default: + // re-panic + panic(p) + } + }() + + const path = "pkg" // any non-empty string will do for now + conf.Check(path, fset, files, nil) +} + +func printStats(d time.Duration) { + fileCount := 0 + lineCount := 0 + fset.Iterate(func(f *token.File) bool { + fileCount++ + lineCount += f.LineCount() + return true + }) + + fmt.Printf( + "%s (%d files, %d lines, %d lines/s)\n", + d, fileCount, lineCount, int64(float64(lineCount)/d.Seconds()), + ) +} + +func main() { + flag.Usage = usage + flag.Parse() + initParserMode() + + start := time.Now() + + files, err := getPkgFiles(flag.Args()) + if err != nil { + report(err) + // ok to continue (files may be empty, but not nil) + } + + checkPkgFiles(files) + if errorCount > 0 { + os.Exit(2) + } + + if *verbose { + printStats(time.Since(start)) + } +} diff --git a/vendor/go/types/initorder.go b/vendor/go/types/initorder.go new file mode 100644 index 000000000..966dccb82 --- /dev/null +++ b/vendor/go/types/initorder.go @@ -0,0 +1,297 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package types + +import ( + "container/heap" + "fmt" +) + +// initOrder computes the Info.InitOrder for package variables. +func (check *Checker) initOrder() { + // An InitOrder may already have been computed if a package is + // built from several calls to (*Checker).Files. Clear it. + check.Info.InitOrder = check.Info.InitOrder[:0] + + // Compute the object dependency graph and initialize + // a priority queue with the list of graph nodes. + pq := nodeQueue(dependencyGraph(check.objMap)) + heap.Init(&pq) + + const debug = false + if debug { + fmt.Printf("Computing initialization order for %s\n\n", check.pkg) + fmt.Println("Object dependency graph:") + for obj, d := range check.objMap { + // only print objects that may appear in the dependency graph + if obj, _ := obj.(dependency); obj != nil { + if len(d.deps) > 0 { + fmt.Printf("\t%s depends on\n", obj.Name()) + for dep := range d.deps { + fmt.Printf("\t\t%s\n", dep.Name()) + } + } else { + fmt.Printf("\t%s has no dependencies\n", obj.Name()) + } + } + } + fmt.Println() + + fmt.Println("Transposed object dependency graph (functions eliminated):") + for _, n := range pq { + fmt.Printf("\t%s depends on %d nodes\n", n.obj.Name(), n.ndeps) + for p := range n.pred { + fmt.Printf("\t\t%s is dependent\n", p.obj.Name()) + } + } + fmt.Println() + + fmt.Println("Processing nodes:") + } + + // Determine initialization order by removing the highest priority node + // (the one with the fewest dependencies) and its edges from the graph, + // repeatedly, until there are no nodes left. + // In a valid Go program, those nodes always have zero dependencies (after + // removing all incoming dependencies), otherwise there are initialization + // cycles. + emitted := make(map[*declInfo]bool) + for len(pq) > 0 { + // get the next node + n := heap.Pop(&pq).(*graphNode) + + if debug { + fmt.Printf("\t%s (src pos %d) depends on %d nodes now\n", + n.obj.Name(), n.obj.order(), n.ndeps) + } + + // if n still depends on other nodes, we have a cycle + if n.ndeps > 0 { + cycle := findPath(check.objMap, n.obj, n.obj, make(objSet)) + // If n.obj is not part of the cycle (e.g., n.obj->b->c->d->c), + // cycle will be nil. Don't report anything in that case since + // the cycle is reported when the algorithm gets to an object + // in the cycle. + // Furthermore, once an object in the cycle is encountered, + // the cycle will be broken (dependency count will be reduced + // below), and so the remaining nodes in the cycle don't trigger + // another error (unless they are part of multiple cycles). + if cycle != nil { + check.reportCycle(cycle) + } + // Ok to continue, but the variable initialization order + // will be incorrect at this point since it assumes no + // cycle errors. + } + + // reduce dependency count of all dependent nodes + // and update priority queue + for p := range n.pred { + p.ndeps-- + heap.Fix(&pq, p.index) + } + + // record the init order for variables with initializers only + v, _ := n.obj.(*Var) + info := check.objMap[v] + if v == nil || !info.hasInitializer() { + continue + } + + // n:1 variable declarations such as: a, b = f() + // introduce a node for each lhs variable (here: a, b); + // but they all have the same initializer - emit only + // one, for the first variable seen + if emitted[info] { + continue // initializer already emitted, if any + } + emitted[info] = true + + infoLhs := info.lhs // possibly nil (see declInfo.lhs field comment) + if infoLhs == nil { + infoLhs = []*Var{v} + } + init := &Initializer{infoLhs, info.init} + check.Info.InitOrder = append(check.Info.InitOrder, init) + } + + if debug { + fmt.Println() + fmt.Println("Initialization order:") + for _, init := range check.Info.InitOrder { + fmt.Printf("\t%s\n", init) + } + fmt.Println() + } +} + +// findPath returns the (reversed) list of objects []Object{to, ... from} +// such that there is a path of object dependencies from 'from' to 'to'. +// If there is no such path, the result is nil. +func findPath(objMap map[Object]*declInfo, from, to Object, visited objSet) []Object { + if visited[from] { + return nil // node already seen + } + visited[from] = true + + for d := range objMap[from].deps { + if d == to { + return []Object{d} + } + if P := findPath(objMap, d, to, visited); P != nil { + return append(P, d) + } + } + + return nil +} + +// reportCycle reports an error for the given cycle. +func (check *Checker) reportCycle(cycle []Object) { + obj := cycle[0] + check.errorf(obj.Pos(), "initialization cycle for %s", obj.Name()) + // subtle loop: print cycle[i] for i = 0, n-1, n-2, ... 1 for len(cycle) = n + for i := len(cycle) - 1; i >= 0; i-- { + check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented + obj = cycle[i] + } + // print cycle[0] again to close the cycle + check.errorf(obj.Pos(), "\t%s", obj.Name()) +} + +// ---------------------------------------------------------------------------- +// Object dependency graph + +// A dependency is an object that may be a dependency in an initialization +// expression. Only constants, variables, and functions can be dependencies. +// Constants are here because constant expression cycles are reported during +// initialization order computation. +type dependency interface { + Object + isDependency() +} + +// A graphNode represents a node in the object dependency graph. +// Each node p in n.pred represents an edge p->n, and each node +// s in n.succ represents an edge n->s; with a->b indicating that +// a depends on b. +type graphNode struct { + obj dependency // object represented by this node + pred, succ nodeSet // consumers and dependencies of this node (lazily initialized) + index int // node index in graph slice/priority queue + ndeps int // number of outstanding dependencies before this object can be initialized +} + +type nodeSet map[*graphNode]bool + +func (s *nodeSet) add(p *graphNode) { + if *s == nil { + *s = make(nodeSet) + } + (*s)[p] = true +} + +// dependencyGraph computes the object dependency graph from the given objMap, +// with any function nodes removed. The resulting graph contains only constants +// and variables. +func dependencyGraph(objMap map[Object]*declInfo) []*graphNode { + // M is the dependency (Object) -> graphNode mapping + M := make(map[dependency]*graphNode) + for obj := range objMap { + // only consider nodes that may be an initialization dependency + if obj, _ := obj.(dependency); obj != nil { + M[obj] = &graphNode{obj: obj} + } + } + + // compute edges for graph M + // (We need to include all nodes, even isolated ones, because they still need + // to be scheduled for initialization in correct order relative to other nodes.) + for obj, n := range M { + // for each dependency obj -> d (= deps[i]), create graph edges n->s and s->n + for d := range objMap[obj].deps { + // only consider nodes that may be an initialization dependency + if d, _ := d.(dependency); d != nil { + d := M[d] + n.succ.add(d) + d.pred.add(n) + } + } + } + + // remove function nodes and collect remaining graph nodes in G + // (Mutually recursive functions may introduce cycles among themselves + // which are permitted. Yet such cycles may incorrectly inflate the dependency + // count for variables which in turn may not get scheduled for initialization + // in correct order.) + var G []*graphNode + for obj, n := range M { + if _, ok := obj.(*Func); ok { + // connect each predecessor p of n with each successor s + // and drop the function node (don't collect it in G) + for p := range n.pred { + // ignore self-cycles + if p != n { + // Each successor s of n becomes a successor of p, and + // each predecessor p of n becomes a predecessor of s. + for s := range n.succ { + // ignore self-cycles + if s != n { + p.succ.add(s) + s.pred.add(p) + delete(s.pred, n) // remove edge to n + } + } + delete(p.succ, n) // remove edge to n + } + } + } else { + // collect non-function nodes + G = append(G, n) + } + } + + // fill in index and ndeps fields + for i, n := range G { + n.index = i + n.ndeps = len(n.succ) + } + + return G +} + +// ---------------------------------------------------------------------------- +// Priority queue + +// nodeQueue implements the container/heap interface; +// a nodeQueue may be used as a priority queue. +type nodeQueue []*graphNode + +func (a nodeQueue) Len() int { return len(a) } + +func (a nodeQueue) Swap(i, j int) { + x, y := a[i], a[j] + a[i], a[j] = y, x + x.index, y.index = j, i +} + +func (a nodeQueue) Less(i, j int) bool { + x, y := a[i], a[j] + // nodes are prioritized by number of incoming dependencies (1st key) + // and source order (2nd key) + return x.ndeps < y.ndeps || x.ndeps == y.ndeps && x.obj.order() < y.obj.order() +} + +func (a *nodeQueue) Push(x interface{}) { + panic("unreachable") +} + +func (a *nodeQueue) Pop() interface{} { + n := len(*a) + x := (*a)[n-1] + x.index = -1 // for safety + *a = (*a)[:n-1] + return x +} diff --git a/vendor/go/types/interfaces.go b/vendor/go/types/interfaces.go new file mode 100644 index 000000000..b4efebae5 --- /dev/null +++ b/vendor/go/types/interfaces.go @@ -0,0 +1,443 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this src code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package types + +import ( + "bytes" + "fmt" + "go/ast" + "go/token" +) + +// This file implements the collection of an interface's methods +// without relying on partially computed types of methods or interfaces +// for interface types declared at the package level. +// +// Because interfaces must not embed themselves, directly or indirectly, +// the method set of a valid interface can always be computed independent +// of any cycles that might exist via method signatures (see also issue #18395). +// +// Except for blank method name and interface cycle errors, no errors +// are reported. Affected methods or embedded interfaces are silently +// dropped. Subsequent type-checking of the interface will check +// signatures and embedded interfaces and report errors at that time. +// +// Only infoFromTypeLit should be called directly from code outside this file +// to compute an ifaceInfo. + +// ifaceInfo describes the method set for an interface. +// The zero value for an ifaceInfo is a ready-to-use ifaceInfo representing +// the empty interface. +type ifaceInfo struct { + explicits int // number of explicitly declared methods + methods []*methodInfo // all methods, starting with explicitly declared ones in source order +} + +// emptyIfaceInfo represents the ifaceInfo for the empty interface. +var emptyIfaceInfo ifaceInfo + +func (info *ifaceInfo) String() string { + var buf bytes.Buffer + fmt.Fprintf(&buf, "interface{") + for i, m := range info.methods { + if i > 0 { + fmt.Fprint(&buf, " ") + } + fmt.Fprint(&buf, m) + } + fmt.Fprintf(&buf, "}") + return buf.String() +} + +// methodInfo represents an interface method. +// At least one of src or fun must be non-nil. +// (Methods declared in the current package have a non-nil scope +// and src, and eventually a non-nil fun field; imported and pre- +// declared methods have a nil scope and src, and only a non-nil +// fun field.) +type methodInfo struct { + scope *Scope // scope of interface method; or nil + src *ast.Field // syntax tree representation of interface method; or nil + fun *Func // corresponding fully type-checked method type; or nil +} + +func (info *methodInfo) String() string { + if info.fun != nil { + return info.fun.name + } + return info.src.Names[0].Name +} + +func (info *methodInfo) Pos() token.Pos { + if info.fun != nil { + return info.fun.Pos() + } + return info.src.Pos() +} + +func (info *methodInfo) id(pkg *Package) string { + if info.fun != nil { + return info.fun.Id() + } + return Id(pkg, info.src.Names[0].Name) +} + +// A methodInfoSet maps method ids to methodInfos. +// It is used to determine duplicate declarations. +// (A methodInfo set is the equivalent of an objset +// but for methodInfos rather than Objects.) +type methodInfoSet map[string]*methodInfo + +// insert attempts to insert an method m into the method set s. +// If s already contains an alternative method alt with +// the same name, insert leaves s unchanged and returns alt. +// Otherwise it inserts m and returns nil. +func (s *methodInfoSet) insert(pkg *Package, m *methodInfo) *methodInfo { + id := m.id(pkg) + if alt := (*s)[id]; alt != nil { + return alt + } + if *s == nil { + *s = make(methodInfoSet) + } + (*s)[id] = m + return nil +} + +// like Checker.declareInSet but for method infos. +func (check *Checker) declareInMethodSet(mset *methodInfoSet, pos token.Pos, m *methodInfo) bool { + if alt := mset.insert(check.pkg, m); alt != nil { + check.errorf(pos, "%s redeclared", m) + check.reportAltMethod(alt) + return false + } + return true +} + +// like Checker.reportAltDecl but for method infos. +func (check *Checker) reportAltMethod(m *methodInfo) { + if pos := m.Pos(); pos.IsValid() { + // We use "other" rather than "previous" here because + // the first declaration seen may not be textually + // earlier in the source. + check.errorf(pos, "\tother declaration of %s", m) // secondary error, \t indented + } +} + +// infoFromTypeLit computes the method set for the given interface iface +// declared in scope. +// If a corresponding type name exists (tname != nil), it is used for +// cycle detection and to cache the method set. +// The result is the method set, or nil if there is a cycle via embedded +// interfaces. A non-nil result doesn't mean that there were no errors, +// but they were either reported (e.g., blank methods), or will be found +// (again) when computing the interface's type. +// If tname is not nil it must be the last element in path. +func (check *Checker) infoFromTypeLit(scope *Scope, iface *ast.InterfaceType, tname *TypeName, path []*TypeName) (info *ifaceInfo) { + assert(iface != nil) + + // lazy-allocate interfaces map + if check.interfaces == nil { + check.interfaces = make(map[*TypeName]*ifaceInfo) + } + + if trace { + check.trace(iface.Pos(), "-- collect methods for %v (path = %s)", iface, pathString(path)) + check.indent++ + defer func() { + check.indent-- + check.trace(iface.Pos(), "=> %s", info) + }() + } + + // If the interface is named, check if we computed info already. + // + // This is not simply an optimization; we may run into stack + // overflow with recursive interface declarations. Example: + // + // type T interface { + // m() interface { T } + // } + // + // (Since recursive definitions can only be expressed via names, + // it is sufficient to track named interfaces here.) + // + // While at it, use the same mechanism to detect cycles. (We still + // have the path-based cycle check because we want to report the + // entire cycle if present.) + if tname != nil { + assert(path[len(path)-1] == tname) // tname must be last path element + var found bool + if info, found = check.interfaces[tname]; found { + if info == nil { + // We have a cycle and use check.cycle to report it. + // We are guaranteed that check.cycle also finds the + // cycle because when infoFromTypeLit is called, any + // tname that's already in check.interfaces was also + // added to the path. (But the converse is not true: + // A non-nil tname is always the last element in path.) + ok := check.cycle(tname, path, true) + assert(ok) + } + return + } + check.interfaces[tname] = nil // computation started but not complete + } + + if iface.Methods.List == nil { + // fast track for empty interface + info = &emptyIfaceInfo + } else { + // (syntactically) non-empty interface + info = new(ifaceInfo) + + // collect explicitly declared methods and embedded interfaces + var mset methodInfoSet + var embeddeds []*ifaceInfo + var positions []token.Pos // entries correspond to positions of embeddeds; used for error reporting + for _, f := range iface.Methods.List { + if len(f.Names) > 0 { + // We have a method with name f.Names[0]. + // (The parser ensures that there's only one method + // and we don't care if a constructed AST has more.) + + // spec: "As with all method sets, in an interface type, + // each method must have a unique non-blank name." + if name := f.Names[0]; name.Name == "_" { + check.errorf(name.Pos(), "invalid method name _") + continue // ignore + } + + m := &methodInfo{scope: scope, src: f} + if check.declareInMethodSet(&mset, f.Pos(), m) { + info.methods = append(info.methods, m) + } + } else { + // We have an embedded interface and f.Type is its + // (possibly qualified) embedded type name. Collect + // it if it's a valid interface. + var e *ifaceInfo + switch ename := f.Type.(type) { + case *ast.Ident: + e = check.infoFromTypeName(scope, ename, path) + case *ast.SelectorExpr: + e = check.infoFromQualifiedTypeName(scope, ename) + default: + // The parser makes sure we only see one of the above. + // Constructed ASTs may contain other (invalid) nodes; + // we simply ignore them. The full type-checking pass + // will report those as errors later. + } + if e != nil { + embeddeds = append(embeddeds, e) + positions = append(positions, f.Type.Pos()) + } + } + } + info.explicits = len(info.methods) + + // collect methods of embedded interfaces + for i, e := range embeddeds { + pos := positions[i] // position of type name of embedded interface + for _, m := range e.methods { + if check.declareInMethodSet(&mset, pos, m) { + info.methods = append(info.methods, m) + } + } + } + } + + // mark check.interfaces as complete + assert(info != nil) + if tname != nil { + check.interfaces[tname] = info + } + + return +} + +// infoFromTypeName computes the method set for the given type name +// which must denote a type whose underlying type is an interface. +// The same result qualifications apply as for infoFromTypeLit. +// infoFromTypeName should only be called from infoFromTypeLit. +func (check *Checker) infoFromTypeName(scope *Scope, name *ast.Ident, path []*TypeName) *ifaceInfo { + // A single call of infoFromTypeName handles a sequence of (possibly + // recursive) type declarations connected via unqualified type names. + // Each type declaration leading to another typename causes a "tail call" + // (goto) of this function. The general scenario looks like this: + // + // ... + // type Pn T // previous declarations leading to T, path = [..., Pn] + // type T interface { T0; ... } // T0 leads to call of infoFromTypeName + // + // // infoFromTypeName(name = T0, path = [..., Pn, T]) + // type T0 T1 // path = [..., Pn, T, T0] + // type T1 T2 <-+ // path = [..., Pn, T, T0, T1] + // type T2 ... | // path = [..., Pn, T, T0, T1, T2] + // type Tn T1 --+ // path = [..., Pn, T, T0, T1, T2, Tn] and T1 is in path => cycle + // + // infoFromTypeName returns nil when such a cycle is detected. But in + // contrast to cycles involving interfaces, we must not report the + // error for "type name only" cycles because they will be found again + // during type-checking of embedded interfaces. Reporting those cycles + // here would lead to double reporting. Cycles involving embedding are + // not reported again later because type-checking of interfaces relies + // on the ifaceInfos computed here which are cycle-free by design. + // + // Remember the path length to detect "type name only" cycles. + start := len(path) + +typenameLoop: + // name must be a type name denoting a type whose underlying type is an interface + _, obj := scope.LookupParent(name.Name, check.pos) + if obj == nil { + return nil + } + tname, _ := obj.(*TypeName) + if tname == nil { + return nil + } + + // We have a type name. It may be predeclared (error type), + // imported (dot import), or declared by a type declaration. + // It may not be an interface (e.g., predeclared type int). + // Resolve it by analyzing each possible case. + + // Abort but don't report an error if we have a "type name only" + // cycle (see big function comment). + if check.cycle(tname, path[start:], false) { + return nil + } + + // Abort and report an error if we have a general cycle. + if check.cycle(tname, path, true) { + return nil + } + + path = append(path, tname) + + // If tname is a package-level type declaration, it must be + // in the objMap. Follow the RHS of that declaration if so. + // The RHS may be a literal type (likely case), or another + // (possibly parenthesized and/or qualified) type name. + // (The declaration may be an alias declaration, but it + // doesn't matter for the purpose of determining the under- + // lying interface.) + if decl := check.objMap[tname]; decl != nil { + switch typ := unparen(decl.typ).(type) { + case *ast.Ident: + // type tname T + name = typ + goto typenameLoop + case *ast.SelectorExpr: + // type tname p.T + return check.infoFromQualifiedTypeName(decl.file, typ) + case *ast.InterfaceType: + // type tname interface{...} + return check.infoFromTypeLit(decl.file, typ, tname, path) + } + // type tname X // and X is not an interface type + return nil + } + + // If tname is not a package-level declaration, in a well-typed + // program it should be a predeclared (error type), imported (dot + // import), or function local declaration. Either way, it should + // have been fully declared before use, except if there is a direct + // cycle, and direct cycles will be caught above. Also, the denoted + // type should be an interface (e.g., int is not an interface). + if typ := tname.typ; typ != nil { + // typ should be an interface + if ityp, _ := typ.Underlying().(*Interface); ityp != nil { + return infoFromType(ityp) + } + } + + // In all other cases we have some error. + return nil +} + +// infoFromQualifiedTypeName computes the method set for the given qualified type name, or nil. +func (check *Checker) infoFromQualifiedTypeName(scope *Scope, qname *ast.SelectorExpr) *ifaceInfo { + // see also Checker.selector + name, _ := qname.X.(*ast.Ident) + if name == nil { + return nil + } + _, obj1 := scope.LookupParent(name.Name, check.pos) + if obj1 == nil { + return nil + } + pname, _ := obj1.(*PkgName) + if pname == nil { + return nil + } + assert(pname.pkg == check.pkg) + obj2 := pname.imported.scope.Lookup(qname.Sel.Name) + if obj2 == nil || !obj2.Exported() { + return nil + } + tname, _ := obj2.(*TypeName) + if tname == nil { + return nil + } + ityp, _ := tname.typ.Underlying().(*Interface) + if ityp == nil { + return nil + } + return infoFromType(ityp) +} + +// infoFromType computes the method set for the given interface type. +// The result is never nil. +func infoFromType(typ *Interface) *ifaceInfo { + assert(typ.allMethods != nil) // typ must be completely set up + + // fast track for empty interface + n := len(typ.allMethods) + if n == 0 { + return &emptyIfaceInfo + } + + info := new(ifaceInfo) + info.explicits = len(typ.methods) + info.methods = make([]*methodInfo, n) + + // If there are no embedded interfaces, simply collect the + // explicitly declared methods (optimization of common case). + if len(typ.methods) == n { + for i, m := range typ.methods { + info.methods[i] = &methodInfo{fun: m} + } + return info + } + + // Interface types have a separate list for explicitly declared methods + // which shares its methods with the list of all (explicitly declared or + // embedded) methods. Collect all methods in a set so we can separate + // the embedded methods from the explicitly declared ones. + all := make(map[*Func]bool, n) + for _, m := range typ.allMethods { + all[m] = true + } + assert(len(all) == n) // methods must be unique + + // collect explicitly declared methods + info.methods = make([]*methodInfo, n) + for i, m := range typ.methods { + info.methods[i] = &methodInfo{fun: m} + delete(all, m) + } + + // collect remaining (embedded) methods + i := len(typ.methods) + for m := range all { + info.methods[i] = &methodInfo{fun: m} + i++ + } + assert(i == n) + + return info +} diff --git a/vendor/go/types/labels.go b/vendor/go/types/labels.go new file mode 100644 index 000000000..3b43b4ba0 --- /dev/null +++ b/vendor/go/types/labels.go @@ -0,0 +1,268 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package types + +import ( + "go/ast" + "go/token" +) + +// labels checks correct label use in body. +func (check *Checker) labels(body *ast.BlockStmt) { + // set of all labels in this body + all := NewScope(nil, body.Pos(), body.End(), "label") + + fwdJumps := check.blockBranches(all, nil, nil, body.List) + + // If there are any forward jumps left, no label was found for + // the corresponding goto statements. Either those labels were + // never defined, or they are inside blocks and not reachable + // for the respective gotos. + for _, jmp := range fwdJumps { + var msg string + name := jmp.Label.Name + if alt := all.Lookup(name); alt != nil { + msg = "goto %s jumps into block" + alt.(*Label).used = true // avoid another error + } else { + msg = "label %s not declared" + } + check.errorf(jmp.Label.Pos(), msg, name) + } + + // spec: "It is illegal to define a label that is never used." + for _, obj := range all.elems { + if lbl := obj.(*Label); !lbl.used { + check.softErrorf(lbl.pos, "label %s declared but not used", lbl.name) + } + } +} + +// A block tracks label declarations in a block and its enclosing blocks. +type block struct { + parent *block // enclosing block + lstmt *ast.LabeledStmt // labeled statement to which this block belongs, or nil + labels map[string]*ast.LabeledStmt // allocated lazily +} + +// insert records a new label declaration for the current block. +// The label must not have been declared before in any block. +func (b *block) insert(s *ast.LabeledStmt) { + name := s.Label.Name + if debug { + assert(b.gotoTarget(name) == nil) + } + labels := b.labels + if labels == nil { + labels = make(map[string]*ast.LabeledStmt) + b.labels = labels + } + labels[name] = s +} + +// gotoTarget returns the labeled statement in the current +// or an enclosing block with the given label name, or nil. +func (b *block) gotoTarget(name string) *ast.LabeledStmt { + for s := b; s != nil; s = s.parent { + if t := s.labels[name]; t != nil { + return t + } + } + return nil +} + +// enclosingTarget returns the innermost enclosing labeled +// statement with the given label name, or nil. +func (b *block) enclosingTarget(name string) *ast.LabeledStmt { + for s := b; s != nil; s = s.parent { + if t := s.lstmt; t != nil && t.Label.Name == name { + return t + } + } + return nil +} + +// blockBranches processes a block's statement list and returns the set of outgoing forward jumps. +// all is the scope of all declared labels, parent the set of labels declared in the immediately +// enclosing block, and lstmt is the labeled statement this block is associated with (or nil). +func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.LabeledStmt, list []ast.Stmt) []*ast.BranchStmt { + b := &block{parent: parent, lstmt: lstmt} + + var ( + varDeclPos token.Pos + fwdJumps, badJumps []*ast.BranchStmt + ) + + // All forward jumps jumping over a variable declaration are possibly + // invalid (they may still jump out of the block and be ok). + // recordVarDecl records them for the given position. + recordVarDecl := func(pos token.Pos) { + varDeclPos = pos + badJumps = append(badJumps[:0], fwdJumps...) // copy fwdJumps to badJumps + } + + jumpsOverVarDecl := func(jmp *ast.BranchStmt) bool { + if varDeclPos.IsValid() { + for _, bad := range badJumps { + if jmp == bad { + return true + } + } + } + return false + } + + blockBranches := func(lstmt *ast.LabeledStmt, list []ast.Stmt) { + // Unresolved forward jumps inside the nested block + // become forward jumps in the current block. + fwdJumps = append(fwdJumps, check.blockBranches(all, b, lstmt, list)...) + } + + var stmtBranches func(ast.Stmt) + stmtBranches = func(s ast.Stmt) { + switch s := s.(type) { + case *ast.DeclStmt: + if d, _ := s.Decl.(*ast.GenDecl); d != nil && d.Tok == token.VAR { + recordVarDecl(d.Pos()) + } + + case *ast.LabeledStmt: + // declare non-blank label + if name := s.Label.Name; name != "_" { + lbl := NewLabel(s.Label.Pos(), check.pkg, name) + if alt := all.Insert(lbl); alt != nil { + check.softErrorf(lbl.pos, "label %s already declared", name) + check.reportAltDecl(alt) + // ok to continue + } else { + b.insert(s) + check.recordDef(s.Label, lbl) + } + // resolve matching forward jumps and remove them from fwdJumps + i := 0 + for _, jmp := range fwdJumps { + if jmp.Label.Name == name { + // match + lbl.used = true + check.recordUse(jmp.Label, lbl) + if jumpsOverVarDecl(jmp) { + check.softErrorf( + jmp.Label.Pos(), + "goto %s jumps over variable declaration at line %d", + name, + check.fset.Position(varDeclPos).Line, + ) + // ok to continue + } + } else { + // no match - record new forward jump + fwdJumps[i] = jmp + i++ + } + } + fwdJumps = fwdJumps[:i] + lstmt = s + } + stmtBranches(s.Stmt) + + case *ast.BranchStmt: + if s.Label == nil { + return // checked in 1st pass (check.stmt) + } + + // determine and validate target + name := s.Label.Name + switch s.Tok { + case token.BREAK: + // spec: "If there is a label, it must be that of an enclosing + // "for", "switch", or "select" statement, and that is the one + // whose execution terminates." + valid := false + if t := b.enclosingTarget(name); t != nil { + switch t.Stmt.(type) { + case *ast.SwitchStmt, *ast.TypeSwitchStmt, *ast.SelectStmt, *ast.ForStmt, *ast.RangeStmt: + valid = true + } + } + if !valid { + check.errorf(s.Label.Pos(), "invalid break label %s", name) + return + } + + case token.CONTINUE: + // spec: "If there is a label, it must be that of an enclosing + // "for" statement, and that is the one whose execution advances." + valid := false + if t := b.enclosingTarget(name); t != nil { + switch t.Stmt.(type) { + case *ast.ForStmt, *ast.RangeStmt: + valid = true + } + } + if !valid { + check.errorf(s.Label.Pos(), "invalid continue label %s", name) + return + } + + case token.GOTO: + if b.gotoTarget(name) == nil { + // label may be declared later - add branch to forward jumps + fwdJumps = append(fwdJumps, s) + return + } + + default: + check.invalidAST(s.Pos(), "branch statement: %s %s", s.Tok, name) + return + } + + // record label use + obj := all.Lookup(name) + obj.(*Label).used = true + check.recordUse(s.Label, obj) + + case *ast.AssignStmt: + if s.Tok == token.DEFINE { + recordVarDecl(s.Pos()) + } + + case *ast.BlockStmt: + blockBranches(lstmt, s.List) + + case *ast.IfStmt: + stmtBranches(s.Body) + if s.Else != nil { + stmtBranches(s.Else) + } + + case *ast.CaseClause: + blockBranches(nil, s.Body) + + case *ast.SwitchStmt: + stmtBranches(s.Body) + + case *ast.TypeSwitchStmt: + stmtBranches(s.Body) + + case *ast.CommClause: + blockBranches(nil, s.Body) + + case *ast.SelectStmt: + stmtBranches(s.Body) + + case *ast.ForStmt: + stmtBranches(s.Body) + + case *ast.RangeStmt: + stmtBranches(s.Body) + } + } + + for _, s := range list { + stmtBranches(s) + } + + return fwdJumps +} diff --git a/vendor/go/types/lookup.go b/vendor/go/types/lookup.go new file mode 100644 index 000000000..ee8202d9e --- /dev/null +++ b/vendor/go/types/lookup.go @@ -0,0 +1,354 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements various field and method lookup functions. + +package types + +// LookupFieldOrMethod looks up a field or method with given package and name +// in T and returns the corresponding *Var or *Func, an index sequence, and a +// bool indicating if there were any pointer indirections on the path to the +// field or method. If addressable is set, T is the type of an addressable +// variable (only matters for method lookups). +// +// The last index entry is the field or method index in the (possibly embedded) +// type where the entry was found, either: +// +// 1) the list of declared methods of a named type; or +// 2) the list of all methods (method set) of an interface type; or +// 3) the list of fields of a struct type. +// +// The earlier index entries are the indices of the anonymous struct fields +// traversed to get to the found entry, starting at depth 0. +// +// If no entry is found, a nil object is returned. In this case, the returned +// index and indirect values have the following meaning: +// +// - If index != nil, the index sequence points to an ambiguous entry +// (the same name appeared more than once at the same embedding level). +// +// - If indirect is set, a method with a pointer receiver type was found +// but there was no pointer on the path from the actual receiver type to +// the method's formal receiver base type, nor was the receiver addressable. +// +func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) { + // Methods cannot be associated to a named pointer type + // (spec: "The type denoted by T is called the receiver base type; + // it must not be a pointer or interface type and it must be declared + // in the same package as the method."). + // Thus, if we have a named pointer type, proceed with the underlying + // pointer type but discard the result if it is a method since we would + // not have found it for T (see also issue 8590). + if t, _ := T.(*Named); t != nil { + if p, _ := t.underlying.(*Pointer); p != nil { + obj, index, indirect = lookupFieldOrMethod(p, false, pkg, name) + if _, ok := obj.(*Func); ok { + return nil, nil, false + } + return + } + } + + return lookupFieldOrMethod(T, addressable, pkg, name) +} + +// TODO(gri) The named type consolidation and seen maps below must be +// indexed by unique keys for a given type. Verify that named +// types always have only one representation (even when imported +// indirectly via different packages.) + +func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) { + // WARNING: The code in this function is extremely subtle - do not modify casually! + // This function and NewMethodSet should be kept in sync. + + if name == "_" { + return // blank fields/methods are never found + } + + typ, isPtr := deref(T) + + // *typ where typ is an interface has no methods. + if isPtr && IsInterface(typ) { + return + } + + // Start with typ as single entry at shallowest depth. + current := []embeddedType{{typ, nil, isPtr, false}} + + // Named types that we have seen already, allocated lazily. + // Used to avoid endless searches in case of recursive types. + // Since only Named types can be used for recursive types, we + // only need to track those. + // (If we ever allow type aliases to construct recursive types, + // we must use type identity rather than pointer equality for + // the map key comparison, as we do in consolidateMultiples.) + var seen map[*Named]bool + + // search current depth + for len(current) > 0 { + var next []embeddedType // embedded types found at current depth + + // look for (pkg, name) in all types at current depth + for _, e := range current { + typ := e.typ + + // If we have a named type, we may have associated methods. + // Look for those first. + if named, _ := typ.(*Named); named != nil { + if seen[named] { + // We have seen this type before, at a more shallow depth + // (note that multiples of this type at the current depth + // were consolidated before). The type at that depth shadows + // this same type at the current depth, so we can ignore + // this one. + continue + } + if seen == nil { + seen = make(map[*Named]bool) + } + seen[named] = true + + // look for a matching attached method + if i, m := lookupMethod(named.methods, pkg, name); m != nil { + // potential match + assert(m.typ != nil) + index = concat(e.index, i) + if obj != nil || e.multiples { + return nil, index, false // collision + } + obj = m + indirect = e.indirect + continue // we can't have a matching field or interface method + } + + // continue with underlying type + typ = named.underlying + } + + switch t := typ.(type) { + case *Struct: + // look for a matching field and collect embedded types + for i, f := range t.fields { + if f.sameId(pkg, name) { + assert(f.typ != nil) + index = concat(e.index, i) + if obj != nil || e.multiples { + return nil, index, false // collision + } + obj = f + indirect = e.indirect + continue // we can't have a matching interface method + } + // Collect embedded struct fields for searching the next + // lower depth, but only if we have not seen a match yet + // (if we have a match it is either the desired field or + // we have a name collision on the same depth; in either + // case we don't need to look further). + // Embedded fields are always of the form T or *T where + // T is a type name. If e.typ appeared multiple times at + // this depth, f.typ appears multiple times at the next + // depth. + if obj == nil && f.anonymous { + typ, isPtr := deref(f.typ) + // TODO(gri) optimization: ignore types that can't + // have fields or methods (only Named, Struct, and + // Interface types need to be considered). + next = append(next, embeddedType{typ, concat(e.index, i), e.indirect || isPtr, e.multiples}) + } + } + + case *Interface: + // look for a matching method + // TODO(gri) t.allMethods is sorted - use binary search + if i, m := lookupMethod(t.allMethods, pkg, name); m != nil { + assert(m.typ != nil) + index = concat(e.index, i) + if obj != nil || e.multiples { + return nil, index, false // collision + } + obj = m + indirect = e.indirect + } + } + } + + if obj != nil { + // found a potential match + // spec: "A method call x.m() is valid if the method set of (the type of) x + // contains m and the argument list can be assigned to the parameter + // list of m. If x is addressable and &x's method set contains m, x.m() + // is shorthand for (&x).m()". + if f, _ := obj.(*Func); f != nil && ptrRecv(f) && !indirect && !addressable { + return nil, nil, true // pointer/addressable receiver required + } + return + } + + current = consolidateMultiples(next) + } + + return nil, nil, false // not found +} + +// embeddedType represents an embedded type +type embeddedType struct { + typ Type + index []int // embedded field indices, starting with index at depth 0 + indirect bool // if set, there was a pointer indirection on the path to this field + multiples bool // if set, typ appears multiple times at this depth +} + +// consolidateMultiples collects multiple list entries with the same type +// into a single entry marked as containing multiples. The result is the +// consolidated list. +func consolidateMultiples(list []embeddedType) []embeddedType { + if len(list) <= 1 { + return list // at most one entry - nothing to do + } + + n := 0 // number of entries w/ unique type + prev := make(map[Type]int) // index at which type was previously seen + for _, e := range list { + if i, found := lookupType(prev, e.typ); found { + list[i].multiples = true + // ignore this entry + } else { + prev[e.typ] = n + list[n] = e + n++ + } + } + return list[:n] +} + +func lookupType(m map[Type]int, typ Type) (int, bool) { + // fast path: maybe the types are equal + if i, found := m[typ]; found { + return i, true + } + + for t, i := range m { + if Identical(t, typ) { + return i, true + } + } + + return 0, false +} + +// MissingMethod returns (nil, false) if V implements T, otherwise it +// returns a missing method required by T and whether it is missing or +// just has the wrong type. +// +// For non-interface types V, or if static is set, V implements T if all +// methods of T are present in V. Otherwise (V is an interface and static +// is not set), MissingMethod only checks that methods of T which are also +// present in V have matching types (e.g., for a type assertion x.(T) where +// x is of interface type V). +// +func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) { + // fast path for common case + if T.Empty() { + return + } + + // TODO(gri) Consider using method sets here. Might be more efficient. + + if ityp, _ := V.Underlying().(*Interface); ityp != nil { + // TODO(gri) allMethods is sorted - can do this more efficiently + for _, m := range T.allMethods { + _, obj := lookupMethod(ityp.allMethods, m.pkg, m.name) + switch { + case obj == nil: + if static { + return m, false + } + case !Identical(obj.Type(), m.typ): + return m, true + } + } + return + } + + // A concrete type implements T if it implements all methods of T. + for _, m := range T.allMethods { + obj, _, _ := lookupFieldOrMethod(V, false, m.pkg, m.name) + + f, _ := obj.(*Func) + if f == nil { + return m, false + } + + if !Identical(f.typ, m.typ) { + return m, true + } + } + + return +} + +// assertableTo reports whether a value of type V can be asserted to have type T. +// It returns (nil, false) as affirmative answer. Otherwise it returns a missing +// method required by V and whether it is missing or just has the wrong type. +func assertableTo(V *Interface, T Type) (method *Func, wrongType bool) { + // no static check is required if T is an interface + // spec: "If T is an interface type, x.(T) asserts that the + // dynamic type of x implements the interface T." + if _, ok := T.Underlying().(*Interface); ok && !strict { + return + } + return MissingMethod(T, V, false) +} + +// deref dereferences typ if it is a *Pointer and returns its base and true. +// Otherwise it returns (typ, false). +func deref(typ Type) (Type, bool) { + if p, _ := typ.(*Pointer); p != nil { + return p.base, true + } + return typ, false +} + +// derefStructPtr dereferences typ if it is a (named or unnamed) pointer to a +// (named or unnamed) struct and returns its base. Otherwise it returns typ. +func derefStructPtr(typ Type) Type { + if p, _ := typ.Underlying().(*Pointer); p != nil { + if _, ok := p.base.Underlying().(*Struct); ok { + return p.base + } + } + return typ +} + +// concat returns the result of concatenating list and i. +// The result does not share its underlying array with list. +func concat(list []int, i int) []int { + var t []int + t = append(t, list...) + return append(t, i) +} + +// fieldIndex returns the index for the field with matching package and name, or a value < 0. +func fieldIndex(fields []*Var, pkg *Package, name string) int { + if name != "_" { + for i, f := range fields { + if f.sameId(pkg, name) { + return i + } + } + } + return -1 +} + +// lookupMethod returns the index of and method with matching package and name, or (-1, nil). +func lookupMethod(methods []*Func, pkg *Package, name string) (int, *Func) { + if name != "_" { + for i, m := range methods { + if m.sameId(pkg, name) { + return i, m + } + } + } + return -1, nil +} diff --git a/vendor/go/types/methodset.go b/vendor/go/types/methodset.go new file mode 100644 index 000000000..52048d494 --- /dev/null +++ b/vendor/go/types/methodset.go @@ -0,0 +1,262 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements method sets. + +package types + +import ( + "fmt" + "sort" + "strings" +) + +// A MethodSet is an ordered set of concrete or abstract (interface) methods; +// a method is a MethodVal selection, and they are ordered by ascending m.Obj().Id(). +// The zero value for a MethodSet is a ready-to-use empty method set. +type MethodSet struct { + list []*Selection +} + +func (s *MethodSet) String() string { + if s.Len() == 0 { + return "MethodSet {}" + } + + var buf strings.Builder + fmt.Fprintln(&buf, "MethodSet {") + for _, f := range s.list { + fmt.Fprintf(&buf, "\t%s\n", f) + } + fmt.Fprintln(&buf, "}") + return buf.String() +} + +// Len returns the number of methods in s. +func (s *MethodSet) Len() int { return len(s.list) } + +// At returns the i'th method in s for 0 <= i < s.Len(). +func (s *MethodSet) At(i int) *Selection { return s.list[i] } + +// Lookup returns the method with matching package and name, or nil if not found. +func (s *MethodSet) Lookup(pkg *Package, name string) *Selection { + if s.Len() == 0 { + return nil + } + + key := Id(pkg, name) + i := sort.Search(len(s.list), func(i int) bool { + m := s.list[i] + return m.obj.Id() >= key + }) + if i < len(s.list) { + m := s.list[i] + if m.obj.Id() == key { + return m + } + } + return nil +} + +// Shared empty method set. +var emptyMethodSet MethodSet + +// NewMethodSet returns the method set for the given type T. +// It always returns a non-nil method set, even if it is empty. +func NewMethodSet(T Type) *MethodSet { + // WARNING: The code in this function is extremely subtle - do not modify casually! + // This function and lookupFieldOrMethod should be kept in sync. + + // method set up to the current depth, allocated lazily + var base methodSet + + typ, isPtr := deref(T) + + // *typ where typ is an interface has no methods. + if isPtr && IsInterface(typ) { + return &emptyMethodSet + } + + // Start with typ as single entry at shallowest depth. + current := []embeddedType{{typ, nil, isPtr, false}} + + // Named types that we have seen already, allocated lazily. + // Used to avoid endless searches in case of recursive types. + // Since only Named types can be used for recursive types, we + // only need to track those. + // (If we ever allow type aliases to construct recursive types, + // we must use type identity rather than pointer equality for + // the map key comparison, as we do in consolidateMultiples.) + var seen map[*Named]bool + + // collect methods at current depth + for len(current) > 0 { + var next []embeddedType // embedded types found at current depth + + // field and method sets at current depth, allocated lazily + var fset fieldSet + var mset methodSet + + for _, e := range current { + typ := e.typ + + // If we have a named type, we may have associated methods. + // Look for those first. + if named, _ := typ.(*Named); named != nil { + if seen[named] { + // We have seen this type before, at a more shallow depth + // (note that multiples of this type at the current depth + // were consolidated before). The type at that depth shadows + // this same type at the current depth, so we can ignore + // this one. + continue + } + if seen == nil { + seen = make(map[*Named]bool) + } + seen[named] = true + + mset = mset.add(named.methods, e.index, e.indirect, e.multiples) + + // continue with underlying type + typ = named.underlying + } + + switch t := typ.(type) { + case *Struct: + for i, f := range t.fields { + fset = fset.add(f, e.multiples) + + // Embedded fields are always of the form T or *T where + // T is a type name. If typ appeared multiple times at + // this depth, f.Type appears multiple times at the next + // depth. + if f.anonymous { + typ, isPtr := deref(f.typ) + // TODO(gri) optimization: ignore types that can't + // have fields or methods (only Named, Struct, and + // Interface types need to be considered). + next = append(next, embeddedType{typ, concat(e.index, i), e.indirect || isPtr, e.multiples}) + } + } + + case *Interface: + mset = mset.add(t.allMethods, e.index, true, e.multiples) + } + } + + // Add methods and collisions at this depth to base if no entries with matching + // names exist already. + for k, m := range mset { + if _, found := base[k]; !found { + // Fields collide with methods of the same name at this depth. + if _, found := fset[k]; found { + m = nil // collision + } + if base == nil { + base = make(methodSet) + } + base[k] = m + } + } + + // Multiple fields with matching names collide at this depth and shadow all + // entries further down; add them as collisions to base if no entries with + // matching names exist already. + for k, f := range fset { + if f == nil { + if _, found := base[k]; !found { + if base == nil { + base = make(methodSet) + } + base[k] = nil // collision + } + } + } + + current = consolidateMultiples(next) + } + + if len(base) == 0 { + return &emptyMethodSet + } + + // collect methods + var list []*Selection + for _, m := range base { + if m != nil { + m.recv = T + list = append(list, m) + } + } + // sort by unique name + sort.Slice(list, func(i, j int) bool { + return list[i].obj.Id() < list[j].obj.Id() + }) + return &MethodSet{list} +} + +// A fieldSet is a set of fields and name collisions. +// A collision indicates that multiple fields with the +// same unique id appeared. +type fieldSet map[string]*Var // a nil entry indicates a name collision + +// Add adds field f to the field set s. +// If multiples is set, f appears multiple times +// and is treated as a collision. +func (s fieldSet) add(f *Var, multiples bool) fieldSet { + if s == nil { + s = make(fieldSet) + } + key := f.Id() + // if f is not in the set, add it + if !multiples { + if _, found := s[key]; !found { + s[key] = f + return s + } + } + s[key] = nil // collision + return s +} + +// A methodSet is a set of methods and name collisions. +// A collision indicates that multiple methods with the +// same unique id appeared. +type methodSet map[string]*Selection // a nil entry indicates a name collision + +// Add adds all functions in list to the method set s. +// If multiples is set, every function in list appears multiple times +// and is treated as a collision. +func (s methodSet) add(list []*Func, index []int, indirect bool, multiples bool) methodSet { + if len(list) == 0 { + return s + } + if s == nil { + s = make(methodSet) + } + for i, f := range list { + key := f.Id() + // if f is not in the set, add it + if !multiples { + // TODO(gri) A found method may not be added because it's not in the method set + // (!indirect && ptrRecv(f)). A 2nd method on the same level may be in the method + // set and may not collide with the first one, thus leading to a false positive. + // Is that possible? Investigate. + if _, found := s[key]; !found && (indirect || !ptrRecv(f)) { + s[key] = &Selection{MethodVal, nil, f, concat(index, i), indirect} + continue + } + } + s[key] = nil // collision + } + return s +} + +// ptrRecv reports whether the receiver is of the form *T. +// The receiver must exist. +func ptrRecv(f *Func) bool { + _, isPtr := deref(f.typ.(*Signature).recv.typ) + return isPtr +} diff --git a/vendor/go/types/object.go b/vendor/go/types/object.go new file mode 100644 index 000000000..633d32712 --- /dev/null +++ b/vendor/go/types/object.go @@ -0,0 +1,424 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package types + +import ( + "bytes" + "fmt" + "go/ast" + "go/constant" + "go/token" +) + +// An Object describes a named language entity such as a package, +// constant, type, variable, function (incl. methods), or label. +// All objects implement the Object interface. +// +type Object interface { + Parent() *Scope // scope in which this object is declared; nil for methods and struct fields + Pos() token.Pos // position of object identifier in declaration + Pkg() *Package // package to which this object belongs; nil for labels and objects in the Universe scope + Name() string // package local object name + Type() Type // object type + Exported() bool // reports whether the name starts with a capital letter + Id() string // object name if exported, qualified name if not exported (see func Id) + + // String returns a human-readable string of the object. + String() string + + // order reflects a package-level object's source order: if object + // a is before object b in the source, then a.order() < b.order(). + // order returns a value > 0 for package-level objects; it returns + // 0 for all other objects (including objects in file scopes). + order() uint32 + + // setOrder sets the order number of the object. It must be > 0. + setOrder(uint32) + + // setParent sets the parent scope of the object. + setParent(*Scope) + + // sameId reports whether obj.Id() and Id(pkg, name) are the same. + sameId(pkg *Package, name string) bool + + // scopePos returns the start position of the scope of this Object + scopePos() token.Pos + + // setScopePos sets the start position of the scope for this Object. + setScopePos(pos token.Pos) +} + +// Id returns name if it is exported, otherwise it +// returns the name qualified with the package path. +func Id(pkg *Package, name string) string { + if ast.IsExported(name) { + return name + } + // unexported names need the package path for differentiation + // (if there's no package, make sure we don't start with '.' + // as that may change the order of methods between a setup + // inside a package and outside a package - which breaks some + // tests) + path := "_" + // pkg is nil for objects in Universe scope and possibly types + // introduced via Eval (see also comment in object.sameId) + if pkg != nil && pkg.path != "" { + path = pkg.path + } + return path + "." + name +} + +// An object implements the common parts of an Object. +type object struct { + parent *Scope + pos token.Pos + pkg *Package + name string + typ Type + order_ uint32 + scopePos_ token.Pos +} + +func (obj *object) Parent() *Scope { return obj.parent } +func (obj *object) Pos() token.Pos { return obj.pos } +func (obj *object) Pkg() *Package { return obj.pkg } +func (obj *object) Name() string { return obj.name } +func (obj *object) Type() Type { return obj.typ } +func (obj *object) Exported() bool { return ast.IsExported(obj.name) } +func (obj *object) Id() string { return Id(obj.pkg, obj.name) } +func (obj *object) String() string { panic("abstract") } +func (obj *object) order() uint32 { return obj.order_ } +func (obj *object) scopePos() token.Pos { return obj.scopePos_ } + +func (obj *object) setParent(parent *Scope) { obj.parent = parent } +func (obj *object) setOrder(order uint32) { assert(order > 0); obj.order_ = order } +func (obj *object) setScopePos(pos token.Pos) { obj.scopePos_ = pos } + +func (obj *object) sameId(pkg *Package, name string) bool { + // spec: + // "Two identifiers are different if they are spelled differently, + // or if they appear in different packages and are not exported. + // Otherwise, they are the same." + if name != obj.name { + return false + } + // obj.Name == name + if obj.Exported() { + return true + } + // not exported, so packages must be the same (pkg == nil for + // fields in Universe scope; this can only happen for types + // introduced via Eval) + if pkg == nil || obj.pkg == nil { + return pkg == obj.pkg + } + // pkg != nil && obj.pkg != nil + return pkg.path == obj.pkg.path +} + +// A PkgName represents an imported Go package. +// PkgNames don't have a type. +type PkgName struct { + object + imported *Package + used bool // set if the package was used +} + +// NewPkgName returns a new PkgName object representing an imported package. +// The remaining arguments set the attributes found with all Objects. +func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName { + return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, token.NoPos}, imported, false} +} + +// Imported returns the package that was imported. +// It is distinct from Pkg(), which is the package containing the import statement. +func (obj *PkgName) Imported() *Package { return obj.imported } + +// A Const represents a declared constant. +type Const struct { + object + val constant.Value + visited bool // for initialization cycle detection +} + +// NewConst returns a new constant with value val. +// The remaining arguments set the attributes found with all Objects. +func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const { + return &Const{object{nil, pos, pkg, name, typ, 0, token.NoPos}, val, false} +} + +func (obj *Const) Val() constant.Value { return obj.val } +func (*Const) isDependency() {} // a constant may be a dependency of an initialization expression + +// A TypeName represents a name for a (named or alias) type. +type TypeName struct { + object +} + +// NewTypeName returns a new type name denoting the given typ. +// The remaining arguments set the attributes found with all Objects. +// +// The typ argument may be a defined (Named) type or an alias type. +// It may also be nil such that the returned TypeName can be used as +// argument for NewNamed, which will set the TypeName's type as a side- +// effect. +func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName { + return &TypeName{object{nil, pos, pkg, name, typ, 0, token.NoPos}} +} + +// IsAlias reports whether obj is an alias name for a type. +func (obj *TypeName) IsAlias() bool { + switch t := obj.typ.(type) { + case nil: + return false + case *Basic: + // unsafe.Pointer is not an alias. + if obj.pkg == Unsafe { + return false + } + // Any user-defined type name for a basic type is an alias for a + // basic type (because basic types are pre-declared in the Universe + // scope, outside any package scope), and so is any type name with + // a different name than the name of the basic type it refers to. + // Additionally, we need to look for "byte" and "rune" because they + // are aliases but have the same names (for better error messages). + return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune + case *Named: + return obj != t.obj + default: + return true + } +} + +// A Variable represents a declared variable (including function parameters and results, and struct fields). +type Var struct { + object + anonymous bool // if set, the variable is an anonymous struct field, and name is the type name + visited bool // for initialization cycle detection + isField bool // var is struct field + used bool // set if the variable was used +} + +// NewVar returns a new variable. +// The arguments set the attributes found with all Objects. +func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var { + return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}} +} + +// NewParam returns a new variable representing a function parameter. +func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var { + return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}, used: true} // parameters are always 'used' +} + +// NewField returns a new variable representing a struct field. +// For anonymous (embedded) fields, the name is the unqualified +// type name under which the field is accessible. +func NewField(pos token.Pos, pkg *Package, name string, typ Type, anonymous bool) *Var { + return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}, anonymous: anonymous, isField: true} +} + +// Anonymous reports whether the variable is an anonymous field. +func (obj *Var) Anonymous() bool { return obj.anonymous } + +// IsField reports whether the variable is a struct field. +func (obj *Var) IsField() bool { return obj.isField } + +func (*Var) isDependency() {} // a variable may be a dependency of an initialization expression + +// A Func represents a declared function, concrete method, or abstract +// (interface) method. Its Type() is always a *Signature. +// An abstract method may belong to many interfaces due to embedding. +type Func struct { + object +} + +// NewFunc returns a new function with the given signature, representing +// the function's type. +func NewFunc(pos token.Pos, pkg *Package, name string, sig *Signature) *Func { + // don't store a nil signature + var typ Type + if sig != nil { + typ = sig + } + return &Func{object{nil, pos, pkg, name, typ, 0, token.NoPos}} +} + +// FullName returns the package- or receiver-type-qualified name of +// function or method obj. +func (obj *Func) FullName() string { + var buf bytes.Buffer + writeFuncName(&buf, obj, nil) + return buf.String() +} + +// Scope returns the scope of the function's body block. +func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope } + +func (*Func) isDependency() {} // a function may be a dependency of an initialization expression + +// A Label represents a declared label. +// Labels don't have a type. +type Label struct { + object + used bool // set if the label was used +} + +// NewLabel returns a new label. +func NewLabel(pos token.Pos, pkg *Package, name string) *Label { + return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid]}, false} +} + +// A Builtin represents a built-in function. +// Builtins don't have a valid type. +type Builtin struct { + object + id builtinId +} + +func newBuiltin(id builtinId) *Builtin { + return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid]}, id} +} + +// Nil represents the predeclared value nil. +type Nil struct { + object +} + +func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) { + var tname *TypeName + typ := obj.Type() + + switch obj := obj.(type) { + case *PkgName: + fmt.Fprintf(buf, "package %s", obj.Name()) + if path := obj.imported.path; path != "" && path != obj.name { + fmt.Fprintf(buf, " (%q)", path) + } + return + + case *Const: + buf.WriteString("const") + + case *TypeName: + tname = obj + buf.WriteString("type") + + case *Var: + if obj.isField { + buf.WriteString("field") + } else { + buf.WriteString("var") + } + + case *Func: + buf.WriteString("func ") + writeFuncName(buf, obj, qf) + if typ != nil { + WriteSignature(buf, typ.(*Signature), qf) + } + return + + case *Label: + buf.WriteString("label") + typ = nil + + case *Builtin: + buf.WriteString("builtin") + typ = nil + + case *Nil: + buf.WriteString("nil") + return + + default: + panic(fmt.Sprintf("writeObject(%T)", obj)) + } + + buf.WriteByte(' ') + + // For package-level objects, qualify the name. + if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj { + writePackage(buf, obj.Pkg(), qf) + } + buf.WriteString(obj.Name()) + + if typ == nil { + return + } + + if tname != nil { + // We have a type object: Don't print anything more for + // basic types since there's no more information (names + // are the same; see also comment in TypeName.IsAlias). + if _, ok := typ.(*Basic); ok { + return + } + if tname.IsAlias() { + buf.WriteString(" =") + } else { + typ = typ.Underlying() + } + } + + buf.WriteByte(' ') + WriteType(buf, typ, qf) +} + +func writePackage(buf *bytes.Buffer, pkg *Package, qf Qualifier) { + if pkg == nil { + return + } + var s string + if qf != nil { + s = qf(pkg) + } else { + s = pkg.Path() + } + if s != "" { + buf.WriteString(s) + buf.WriteByte('.') + } +} + +// ObjectString returns the string form of obj. +// The Qualifier controls the printing of +// package-level objects, and may be nil. +func ObjectString(obj Object, qf Qualifier) string { + var buf bytes.Buffer + writeObject(&buf, obj, qf) + return buf.String() +} + +func (obj *PkgName) String() string { return ObjectString(obj, nil) } +func (obj *Const) String() string { return ObjectString(obj, nil) } +func (obj *TypeName) String() string { return ObjectString(obj, nil) } +func (obj *Var) String() string { return ObjectString(obj, nil) } +func (obj *Func) String() string { return ObjectString(obj, nil) } +func (obj *Label) String() string { return ObjectString(obj, nil) } +func (obj *Builtin) String() string { return ObjectString(obj, nil) } +func (obj *Nil) String() string { return ObjectString(obj, nil) } + +func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) { + if f.typ != nil { + sig := f.typ.(*Signature) + if recv := sig.Recv(); recv != nil { + buf.WriteByte('(') + if _, ok := recv.Type().(*Interface); ok { + // gcimporter creates abstract methods of + // named interfaces using the interface type + // (not the named type) as the receiver. + // Don't print it in full. + buf.WriteString("interface") + } else { + WriteType(buf, recv.Type(), qf) + } + buf.WriteByte(')') + buf.WriteByte('.') + } else if f.pkg != nil { + writePackage(buf, f.pkg, qf) + } + } + buf.WriteString(f.name) +} diff --git a/vendor/go/types/objset.go b/vendor/go/types/objset.go new file mode 100644 index 000000000..55eb74add --- /dev/null +++ b/vendor/go/types/objset.go @@ -0,0 +1,31 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements objsets. +// +// An objset is similar to a Scope but objset elements +// are identified by their unique id, instead of their +// object name. + +package types + +// An objset is a set of objects identified by their unique id. +// The zero value for objset is a ready-to-use empty objset. +type objset map[string]Object // initialized lazily + +// insert attempts to insert an object obj into objset s. +// If s already contains an alternative object alt with +// the same name, insert leaves s unchanged and returns alt. +// Otherwise it inserts obj and returns nil. +func (s *objset) insert(obj Object) Object { + id := obj.Id() + if alt := (*s)[id]; alt != nil { + return alt + } + if *s == nil { + *s = make(map[string]Object) + } + (*s)[id] = obj + return nil +} diff --git a/vendor/go/types/operand.go b/vendor/go/types/operand.go new file mode 100644 index 000000000..07247bd6f --- /dev/null +++ b/vendor/go/types/operand.go @@ -0,0 +1,275 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file defines operands and associated operations. + +package types + +import ( + "bytes" + "go/ast" + "go/constant" + "go/token" +) + +// An operandMode specifies the (addressing) mode of an operand. +type operandMode byte + +const ( + invalid operandMode = iota // operand is invalid + novalue // operand represents no value (result of a function call w/o result) + builtin // operand is a built-in function + typexpr // operand is a type + constant_ // operand is a constant; the operand's typ is a Basic type + variable // operand is an addressable variable + mapindex // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment) + value // operand is a computed value + commaok // like value, but operand may be used in a comma,ok expression +) + +var operandModeString = [...]string{ + invalid: "invalid operand", + novalue: "no value", + builtin: "built-in", + typexpr: "type", + constant_: "constant", + variable: "variable", + mapindex: "map index expression", + value: "value", + commaok: "comma, ok expression", +} + +// An operand represents an intermediate value during type checking. +// Operands have an (addressing) mode, the expression evaluating to +// the operand, the operand's type, a value for constants, and an id +// for built-in functions. +// The zero value of operand is a ready to use invalid operand. +// +type operand struct { + mode operandMode + expr ast.Expr + typ Type + val constant.Value + id builtinId +} + +// pos returns the position of the expression corresponding to x. +// If x is invalid the position is token.NoPos. +// +func (x *operand) pos() token.Pos { + // x.expr may not be set if x is invalid + if x.expr == nil { + return token.NoPos + } + return x.expr.Pos() +} + +// Operand string formats +// (not all "untyped" cases can appear due to the type system, +// but they fall out naturally here) +// +// mode format +// +// invalid ( ) +// novalue ( ) +// builtin ( ) +// typexpr ( ) +// +// constant ( ) +// constant ( of type ) +// constant ( ) +// constant ( of type ) +// +// variable ( ) +// variable ( of type ) +// +// mapindex ( ) +// mapindex ( of type ) +// +// value ( ) +// value ( of type ) +// +// commaok ( ) +// commaok ( of type ) +// +func operandString(x *operand, qf Qualifier) string { + var buf bytes.Buffer + + var expr string + if x.expr != nil { + expr = ExprString(x.expr) + } else { + switch x.mode { + case builtin: + expr = predeclaredFuncs[x.id].name + case typexpr: + expr = TypeString(x.typ, qf) + case constant_: + expr = x.val.String() + } + } + + // ( + if expr != "" { + buf.WriteString(expr) + buf.WriteString(" (") + } + + // + hasType := false + switch x.mode { + case invalid, novalue, builtin, typexpr: + // no type + default: + // should have a type, but be cautious (don't crash during printing) + if x.typ != nil { + if isUntyped(x.typ) { + buf.WriteString(x.typ.(*Basic).name) + buf.WriteByte(' ') + break + } + hasType = true + } + } + + // + buf.WriteString(operandModeString[x.mode]) + + // + if x.mode == constant_ { + if s := x.val.String(); s != expr { + buf.WriteByte(' ') + buf.WriteString(s) + } + } + + // + if hasType { + if x.typ != Typ[Invalid] { + buf.WriteString(" of type ") + WriteType(&buf, x.typ, qf) + } else { + buf.WriteString(" with invalid type") + } + } + + // ) + if expr != "" { + buf.WriteByte(')') + } + + return buf.String() +} + +func (x *operand) String() string { + return operandString(x, nil) +} + +// setConst sets x to the untyped constant for literal lit. +func (x *operand) setConst(tok token.Token, lit string) { + var kind BasicKind + switch tok { + case token.INT: + kind = UntypedInt + case token.FLOAT: + kind = UntypedFloat + case token.IMAG: + kind = UntypedComplex + case token.CHAR: + kind = UntypedRune + case token.STRING: + kind = UntypedString + default: + unreachable() + } + + x.mode = constant_ + x.typ = Typ[kind] + x.val = constant.MakeFromLiteral(lit, tok, 0) +} + +// isNil reports whether x is the nil value. +func (x *operand) isNil() bool { + return x.mode == value && x.typ == Typ[UntypedNil] +} + +// TODO(gri) The functions operand.assignableTo, checker.convertUntyped, +// checker.representable, and checker.assignment are +// overlapping in functionality. Need to simplify and clean up. + +// assignableTo reports whether x is assignable to a variable of type T. +// If the result is false and a non-nil reason is provided, it may be set +// to a more detailed explanation of the failure (result != ""). +func (x *operand) assignableTo(conf *Config, T Type, reason *string) bool { + if x.mode == invalid || T == Typ[Invalid] { + return true // avoid spurious errors + } + + V := x.typ + + // x's type is identical to T + if Identical(V, T) { + return true + } + + Vu := V.Underlying() + Tu := T.Underlying() + + // x is an untyped value representable by a value of type T + // TODO(gri) This is borrowing from checker.convertUntyped and + // checker.representable. Need to clean up. + if isUntyped(Vu) { + switch t := Tu.(type) { + case *Basic: + if x.isNil() && t.kind == UnsafePointer { + return true + } + if x.mode == constant_ { + return representableConst(x.val, conf, t, nil) + } + // The result of a comparison is an untyped boolean, + // but may not be a constant. + if Vb, _ := Vu.(*Basic); Vb != nil { + return Vb.kind == UntypedBool && isBoolean(Tu) + } + case *Interface: + return x.isNil() || t.Empty() + case *Pointer, *Signature, *Slice, *Map, *Chan: + return x.isNil() + } + } + // Vu is typed + + // x's type V and T have identical underlying types + // and at least one of V or T is not a named type + if Identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) { + return true + } + + // T is an interface type and x implements T + if Ti, ok := Tu.(*Interface); ok { + if m, wrongType := MissingMethod(x.typ, Ti, true); m != nil /* Implements(x.typ, Ti) */ { + if reason != nil { + if wrongType { + *reason = "wrong type for method " + m.Name() + } else { + *reason = "missing method " + m.Name() + } + } + return false + } + return true + } + + // x is a bidirectional channel value, T is a channel + // type, x's type V and T have identical element types, + // and at least one of V or T is not a named type + if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv { + if Tc, ok := Tu.(*Chan); ok && Identical(Vc.elem, Tc.elem) { + return !isNamed(V) || !isNamed(T) + } + } + + return false +} diff --git a/vendor/go/types/package.go b/vendor/go/types/package.go new file mode 100644 index 000000000..cd202a0ed --- /dev/null +++ b/vendor/go/types/package.go @@ -0,0 +1,64 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package types + +import ( + "fmt" + "go/token" +) + +// A Package describes a Go package. +type Package struct { + path string + name string + scope *Scope + complete bool + imports []*Package + fake bool // scope lookup errors are silently dropped if package is fake (internal use only) +} + +// NewPackage returns a new Package for the given package path and name. +// The package is not complete and contains no explicit imports. +func NewPackage(path, name string) *Package { + scope := NewScope(Universe, token.NoPos, token.NoPos, fmt.Sprintf("package %q", path)) + return &Package{path: path, name: name, scope: scope} +} + +// Path returns the package path. +func (pkg *Package) Path() string { return pkg.path } + +// Name returns the package name. +func (pkg *Package) Name() string { return pkg.name } + +// SetName sets the package name. +func (pkg *Package) SetName(name string) { pkg.name = name } + +// Scope returns the (complete or incomplete) package scope +// holding the objects declared at package level (TypeNames, +// Consts, Vars, and Funcs). +func (pkg *Package) Scope() *Scope { return pkg.scope } + +// A package is complete if its scope contains (at least) all +// exported objects; otherwise it is incomplete. +func (pkg *Package) Complete() bool { return pkg.complete } + +// MarkComplete marks a package as complete. +func (pkg *Package) MarkComplete() { pkg.complete = true } + +// Imports returns the list of packages directly imported by +// pkg; the list is in source order. +// +// If pkg was loaded from export data, Imports includes packages that +// provide package-level objects referenced by pkg. This may be more or +// less than the set of packages directly imported by pkg's source code. +func (pkg *Package) Imports() []*Package { return pkg.imports } + +// SetImports sets the list of explicitly imported packages to list. +// It is the caller's responsibility to make sure list elements are unique. +func (pkg *Package) SetImports(list []*Package) { pkg.imports = list } + +func (pkg *Package) String() string { + return fmt.Sprintf("package %s (%q)", pkg.name, pkg.path) +} diff --git a/vendor/go/types/predicates.go b/vendor/go/types/predicates.go new file mode 100644 index 000000000..1ca146f59 --- /dev/null +++ b/vendor/go/types/predicates.go @@ -0,0 +1,320 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements commonly used type predicates. + +package types + +import "sort" + +func isNamed(typ Type) bool { + if _, ok := typ.(*Basic); ok { + return ok + } + _, ok := typ.(*Named) + return ok +} + +func isBoolean(typ Type) bool { + t, ok := typ.Underlying().(*Basic) + return ok && t.info&IsBoolean != 0 +} + +func isInteger(typ Type) bool { + t, ok := typ.Underlying().(*Basic) + return ok && t.info&IsInteger != 0 +} + +func isUnsigned(typ Type) bool { + t, ok := typ.Underlying().(*Basic) + return ok && t.info&IsUnsigned != 0 +} + +func isFloat(typ Type) bool { + t, ok := typ.Underlying().(*Basic) + return ok && t.info&IsFloat != 0 +} + +func isComplex(typ Type) bool { + t, ok := typ.Underlying().(*Basic) + return ok && t.info&IsComplex != 0 +} + +func isNumeric(typ Type) bool { + t, ok := typ.Underlying().(*Basic) + return ok && t.info&IsNumeric != 0 +} + +func isString(typ Type) bool { + t, ok := typ.Underlying().(*Basic) + return ok && t.info&IsString != 0 +} + +func isTyped(typ Type) bool { + t, ok := typ.Underlying().(*Basic) + return !ok || t.info&IsUntyped == 0 +} + +func isUntyped(typ Type) bool { + t, ok := typ.Underlying().(*Basic) + return ok && t.info&IsUntyped != 0 +} + +func isOrdered(typ Type) bool { + t, ok := typ.Underlying().(*Basic) + return ok && t.info&IsOrdered != 0 +} + +func isConstType(typ Type) bool { + t, ok := typ.Underlying().(*Basic) + return ok && t.info&IsConstType != 0 +} + +// IsInterface reports whether typ is an interface type. +func IsInterface(typ Type) bool { + _, ok := typ.Underlying().(*Interface) + return ok +} + +// Comparable reports whether values of type T are comparable. +func Comparable(T Type) bool { + switch t := T.Underlying().(type) { + case *Basic: + // assume invalid types to be comparable + // to avoid follow-up errors + return t.kind != UntypedNil + case *Pointer, *Interface, *Chan: + return true + case *Struct: + for _, f := range t.fields { + if !Comparable(f.typ) { + return false + } + } + return true + case *Array: + return Comparable(t.elem) + } + return false +} + +// hasNil reports whether a type includes the nil value. +func hasNil(typ Type) bool { + switch t := typ.Underlying().(type) { + case *Basic: + return t.kind == UnsafePointer + case *Slice, *Pointer, *Signature, *Interface, *Map, *Chan: + return true + } + return false +} + +// Identical reports whether x and y are identical types. +// Receivers of Signature types are ignored. +func Identical(x, y Type) bool { + return identical(x, y, true, nil) +} + +// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored. +// Receivers of Signature types are ignored. +func IdenticalIgnoreTags(x, y Type) bool { + return identical(x, y, false, nil) +} + +// An ifacePair is a node in a stack of interface type pairs compared for identity. +type ifacePair struct { + x, y *Interface + prev *ifacePair +} + +func (p *ifacePair) identical(q *ifacePair) bool { + return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x +} + +func identical(x, y Type, cmpTags bool, p *ifacePair) bool { + if x == y { + return true + } + + switch x := x.(type) { + case *Basic: + // Basic types are singletons except for the rune and byte + // aliases, thus we cannot solely rely on the x == y check + // above. See also comment in TypeName.IsAlias. + if y, ok := y.(*Basic); ok { + return x.kind == y.kind + } + + case *Array: + // Two array types are identical if they have identical element types + // and the same array length. + if y, ok := y.(*Array); ok { + // If one or both array lengths are unknown (< 0) due to some error, + // assume they are the same to avoid spurious follow-on errors. + return (x.len < 0 || y.len < 0 || x.len == y.len) && identical(x.elem, y.elem, cmpTags, p) + } + + case *Slice: + // Two slice types are identical if they have identical element types. + if y, ok := y.(*Slice); ok { + return identical(x.elem, y.elem, cmpTags, p) + } + + case *Struct: + // Two struct types are identical if they have the same sequence of fields, + // and if corresponding fields have the same names, and identical types, + // and identical tags. Two anonymous fields are considered to have the same + // name. Lower-case field names from different packages are always different. + if y, ok := y.(*Struct); ok { + if x.NumFields() == y.NumFields() { + for i, f := range x.fields { + g := y.fields[i] + if f.anonymous != g.anonymous || + cmpTags && x.Tag(i) != y.Tag(i) || + !f.sameId(g.pkg, g.name) || + !identical(f.typ, g.typ, cmpTags, p) { + return false + } + } + return true + } + } + + case *Pointer: + // Two pointer types are identical if they have identical base types. + if y, ok := y.(*Pointer); ok { + return identical(x.base, y.base, cmpTags, p) + } + + case *Tuple: + // Two tuples types are identical if they have the same number of elements + // and corresponding elements have identical types. + if y, ok := y.(*Tuple); ok { + if x.Len() == y.Len() { + if x != nil { + for i, v := range x.vars { + w := y.vars[i] + if !identical(v.typ, w.typ, cmpTags, p) { + return false + } + } + } + return true + } + } + + case *Signature: + // Two function types are identical if they have the same number of parameters + // and result values, corresponding parameter and result types are identical, + // and either both functions are variadic or neither is. Parameter and result + // names are not required to match. + if y, ok := y.(*Signature); ok { + return x.variadic == y.variadic && + identical(x.params, y.params, cmpTags, p) && + identical(x.results, y.results, cmpTags, p) + } + + case *Interface: + // Two interface types are identical if they have the same set of methods with + // the same names and identical function types. Lower-case method names from + // different packages are always different. The order of the methods is irrelevant. + if y, ok := y.(*Interface); ok { + a := x.allMethods + b := y.allMethods + if len(a) == len(b) { + // Interface types are the only types where cycles can occur + // that are not "terminated" via named types; and such cycles + // can only be created via method parameter types that are + // anonymous interfaces (directly or indirectly) embedding + // the current interface. Example: + // + // type T interface { + // m() interface{T} + // } + // + // If two such (differently named) interfaces are compared, + // endless recursion occurs if the cycle is not detected. + // + // If x and y were compared before, they must be equal + // (if they were not, the recursion would have stopped); + // search the ifacePair stack for the same pair. + // + // This is a quadratic algorithm, but in practice these stacks + // are extremely short (bounded by the nesting depth of interface + // type declarations that recur via parameter types, an extremely + // rare occurrence). An alternative implementation might use a + // "visited" map, but that is probably less efficient overall. + q := &ifacePair{x, y, p} + for p != nil { + if p.identical(q) { + return true // same pair was compared before + } + p = p.prev + } + if debug { + assert(sort.IsSorted(byUniqueMethodName(a))) + assert(sort.IsSorted(byUniqueMethodName(b))) + } + for i, f := range a { + g := b[i] + if f.Id() != g.Id() || !identical(f.typ, g.typ, cmpTags, q) { + return false + } + } + return true + } + } + + case *Map: + // Two map types are identical if they have identical key and value types. + if y, ok := y.(*Map); ok { + return identical(x.key, y.key, cmpTags, p) && identical(x.elem, y.elem, cmpTags, p) + } + + case *Chan: + // Two channel types are identical if they have identical value types + // and the same direction. + if y, ok := y.(*Chan); ok { + return x.dir == y.dir && identical(x.elem, y.elem, cmpTags, p) + } + + case *Named: + // Two named types are identical if their type names originate + // in the same type declaration. + if y, ok := y.(*Named); ok { + return x.obj == y.obj + } + + case nil: + + default: + unreachable() + } + + return false +} + +// Default returns the default "typed" type for an "untyped" type; +// it returns the incoming type for all other types. The default type +// for untyped nil is untyped nil. +// +func Default(typ Type) Type { + if t, ok := typ.(*Basic); ok { + switch t.kind { + case UntypedBool: + return Typ[Bool] + case UntypedInt: + return Typ[Int] + case UntypedRune: + return universeRune // use 'rune' name + case UntypedFloat: + return Typ[Float64] + case UntypedComplex: + return Typ[Complex128] + case UntypedString: + return Typ[String] + } + } + return typ +} diff --git a/vendor/go/types/resolver.go b/vendor/go/types/resolver.go new file mode 100644 index 000000000..de8ae0bd1 --- /dev/null +++ b/vendor/go/types/resolver.go @@ -0,0 +1,631 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package types + +import ( + "fmt" + "go/ast" + "go/constant" + "go/token" + "sort" + "strconv" + "strings" + "unicode" +) + +// A declInfo describes a package-level const, type, var, or func declaration. +type declInfo struct { + file *Scope // scope of file containing this declaration + lhs []*Var // lhs of n:1 variable declarations, or nil + typ ast.Expr // type, or nil + init ast.Expr // init/orig expression, or nil + fdecl *ast.FuncDecl // func declaration, or nil + alias bool // type alias declaration + + // The deps field tracks initialization expression dependencies. + deps objSet // lazily initialized +} + +// An objSet is simply a set of objects. +type objSet map[Object]bool + +// hasInitializer reports whether the declared object has an initialization +// expression or function body. +func (d *declInfo) hasInitializer() bool { + return d.init != nil || d.fdecl != nil && d.fdecl.Body != nil +} + +// addDep adds obj to the set of objects d's init expression depends on. +func (d *declInfo) addDep(obj Object) { + m := d.deps + if m == nil { + m = make(objSet) + d.deps = m + } + m[obj] = true +} + +// arityMatch checks that the lhs and rhs of a const or var decl +// have the appropriate number of names and init exprs. For const +// decls, init is the value spec providing the init exprs; for +// var decls, init is nil (the init exprs are in s in this case). +func (check *Checker) arityMatch(s, init *ast.ValueSpec) { + l := len(s.Names) + r := len(s.Values) + if init != nil { + r = len(init.Values) + } + + switch { + case init == nil && r == 0: + // var decl w/o init expr + if s.Type == nil { + check.errorf(s.Pos(), "missing type or init expr") + } + case l < r: + if l < len(s.Values) { + // init exprs from s + n := s.Values[l] + check.errorf(n.Pos(), "extra init expr %s", n) + // TODO(gri) avoid declared but not used error here + } else { + // init exprs "inherited" + check.errorf(s.Pos(), "extra init expr at %s", check.fset.Position(init.Pos())) + // TODO(gri) avoid declared but not used error here + } + case l > r && (init != nil || r != 1): + n := s.Names[r] + check.errorf(n.Pos(), "missing init expr for %s", n) + } +} + +func validatedImportPath(path string) (string, error) { + s, err := strconv.Unquote(path) + if err != nil { + return "", err + } + if s == "" { + return "", fmt.Errorf("empty string") + } + const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD" + for _, r := range s { + if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) { + return s, fmt.Errorf("invalid character %#U", r) + } + } + return s, nil +} + +// declarePkgObj declares obj in the package scope, records its ident -> obj mapping, +// and updates check.objMap. The object must not be a function or method. +func (check *Checker) declarePkgObj(ident *ast.Ident, obj Object, d *declInfo) { + assert(ident.Name == obj.Name()) + + // spec: "A package-scope or file-scope identifier with name init + // may only be declared to be a function with this (func()) signature." + if ident.Name == "init" { + check.errorf(ident.Pos(), "cannot declare init - must be func") + return + } + + // spec: "The main package must have package name main and declare + // a function main that takes no arguments and returns no value." + if ident.Name == "main" && check.pkg.name == "main" { + check.errorf(ident.Pos(), "cannot declare main - must be func") + return + } + + check.declare(check.pkg.scope, ident, obj, token.NoPos) + check.objMap[obj] = d + obj.setOrder(uint32(len(check.objMap))) +} + +// filename returns a filename suitable for debugging output. +func (check *Checker) filename(fileNo int) string { + file := check.files[fileNo] + if pos := file.Pos(); pos.IsValid() { + return check.fset.File(pos).Name() + } + return fmt.Sprintf("file[%d]", fileNo) +} + +func (check *Checker) importPackage(pos token.Pos, path, dir string) *Package { + // If we already have a package for the given (path, dir) + // pair, use it instead of doing a full import. + // Checker.impMap only caches packages that are marked Complete + // or fake (dummy packages for failed imports). Incomplete but + // non-fake packages do require an import to complete them. + key := importKey{path, dir} + imp := check.impMap[key] + if imp != nil { + return imp + } + + // no package yet => import it + if path == "C" && check.conf.FakeImportC { + imp = NewPackage("C", "C") + imp.fake = true + } else { + // ordinary import + var err error + if importer := check.conf.Importer; importer == nil { + err = fmt.Errorf("Config.Importer not installed") + } else if importerFrom, ok := importer.(ImporterFrom); ok { + imp, err = importerFrom.ImportFrom(path, dir, 0) + if imp == nil && err == nil { + err = fmt.Errorf("Config.Importer.ImportFrom(%s, %s, 0) returned nil but no error", path, dir) + } + } else { + imp, err = importer.Import(path) + if imp == nil && err == nil { + err = fmt.Errorf("Config.Importer.Import(%s) returned nil but no error", path) + } + } + // make sure we have a valid package name + // (errors here can only happen through manipulation of packages after creation) + if err == nil && imp != nil && (imp.name == "_" || imp.name == "") { + err = fmt.Errorf("invalid package name: %q", imp.name) + imp = nil // create fake package below + } + if err != nil { + check.errorf(pos, "could not import %s (%s)", path, err) + if imp == nil { + // create a new fake package + // come up with a sensible package name (heuristic) + name := path + if i := len(name); i > 0 && name[i-1] == '/' { + name = name[:i-1] + } + if i := strings.LastIndex(name, "/"); i >= 0 { + name = name[i+1:] + } + imp = NewPackage(path, name) + } + // continue to use the package as best as we can + imp.fake = true // avoid follow-up lookup failures + } + } + + // package should be complete or marked fake, but be cautious + if imp.complete || imp.fake { + check.impMap[key] = imp + return imp + } + + // something went wrong (importer may have returned incomplete package without error) + return nil +} + +// collectObjects collects all file and package objects and inserts them +// into their respective scopes. It also performs imports and associates +// methods with receiver base type names. +func (check *Checker) collectObjects() { + pkg := check.pkg + + // pkgImports is the set of packages already imported by any package file seen + // so far. Used to avoid duplicate entries in pkg.imports. Allocate and populate + // it (pkg.imports may not be empty if we are checking test files incrementally). + // Note that pkgImports is keyed by package (and thus package path), not by an + // importKey value. Two different importKey values may map to the same package + // which is why we cannot use the check.impMap here. + var pkgImports = make(map[*Package]bool) + for _, imp := range pkg.imports { + pkgImports[imp] = true + } + + var methods []*Func // list of methods with non-blank _ names + for fileNo, file := range check.files { + // The package identifier denotes the current package, + // but there is no corresponding package object. + check.recordDef(file.Name, nil) + + // Use the actual source file extent rather than *ast.File extent since the + // latter doesn't include comments which appear at the start or end of the file. + // Be conservative and use the *ast.File extent if we don't have a *token.File. + pos, end := file.Pos(), file.End() + if f := check.fset.File(file.Pos()); f != nil { + pos, end = token.Pos(f.Base()), token.Pos(f.Base()+f.Size()) + } + fileScope := NewScope(check.pkg.scope, pos, end, check.filename(fileNo)) + check.recordScope(file, fileScope) + + // determine file directory, necessary to resolve imports + // FileName may be "" (typically for tests) in which case + // we get "." as the directory which is what we would want. + fileDir := dir(check.fset.Position(file.Name.Pos()).Filename) + + for _, decl := range file.Decls { + switch d := decl.(type) { + case *ast.BadDecl: + // ignore + + case *ast.GenDecl: + var last *ast.ValueSpec // last ValueSpec with type or init exprs seen + for iota, spec := range d.Specs { + switch s := spec.(type) { + case *ast.ImportSpec: + // import package + path, err := validatedImportPath(s.Path.Value) + if err != nil { + check.errorf(s.Path.Pos(), "invalid import path (%s)", err) + continue + } + + imp := check.importPackage(s.Path.Pos(), path, fileDir) + if imp == nil { + continue + } + + // add package to list of explicit imports + // (this functionality is provided as a convenience + // for clients; it is not needed for type-checking) + if !pkgImports[imp] { + pkgImports[imp] = true + pkg.imports = append(pkg.imports, imp) + } + + // local name overrides imported package name + name := imp.name + if s.Name != nil { + name = s.Name.Name + if path == "C" { + // match cmd/compile (not prescribed by spec) + check.errorf(s.Name.Pos(), `cannot rename import "C"`) + continue + } + if name == "init" { + check.errorf(s.Name.Pos(), "cannot declare init - must be func") + continue + } + } + + obj := NewPkgName(s.Pos(), pkg, name, imp) + if s.Name != nil { + // in a dot-import, the dot represents the package + check.recordDef(s.Name, obj) + } else { + check.recordImplicit(s, obj) + } + + if path == "C" { + // match cmd/compile (not prescribed by spec) + obj.used = true + } + + // add import to file scope + if name == "." { + // merge imported scope with file scope + for _, obj := range imp.scope.elems { + // A package scope may contain non-exported objects, + // do not import them! + if obj.Exported() { + // TODO(gri) When we import a package, we create + // a new local package object. We should do the + // same for each dot-imported object. That way + // they can have correct position information. + // (We must not modify their existing position + // information because the same package - found + // via Config.Packages - may be dot-imported in + // another package!) + check.declare(fileScope, nil, obj, token.NoPos) + } + } + // add position to set of dot-import positions for this file + // (this is only needed for "imported but not used" errors) + check.addUnusedDotImport(fileScope, imp, s.Pos()) + } else { + // declare imported package object in file scope + check.declare(fileScope, nil, obj, token.NoPos) + } + + case *ast.ValueSpec: + switch d.Tok { + case token.CONST: + // determine which initialization expressions to use + switch { + case s.Type != nil || len(s.Values) > 0: + last = s + case last == nil: + last = new(ast.ValueSpec) // make sure last exists + } + + // declare all constants + for i, name := range s.Names { + obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota))) + + var init ast.Expr + if i < len(last.Values) { + init = last.Values[i] + } + + d := &declInfo{file: fileScope, typ: last.Type, init: init} + check.declarePkgObj(name, obj, d) + } + + check.arityMatch(s, last) + + case token.VAR: + lhs := make([]*Var, len(s.Names)) + // If there's exactly one rhs initializer, use + // the same declInfo d1 for all lhs variables + // so that each lhs variable depends on the same + // rhs initializer (n:1 var declaration). + var d1 *declInfo + if len(s.Values) == 1 { + // The lhs elements are only set up after the for loop below, + // but that's ok because declareVar only collects the declInfo + // for a later phase. + d1 = &declInfo{file: fileScope, lhs: lhs, typ: s.Type, init: s.Values[0]} + } + + // declare all variables + for i, name := range s.Names { + obj := NewVar(name.Pos(), pkg, name.Name, nil) + lhs[i] = obj + + d := d1 + if d == nil { + // individual assignments + var init ast.Expr + if i < len(s.Values) { + init = s.Values[i] + } + d = &declInfo{file: fileScope, typ: s.Type, init: init} + } + + check.declarePkgObj(name, obj, d) + } + + check.arityMatch(s, nil) + + default: + check.invalidAST(s.Pos(), "invalid token %s", d.Tok) + } + + case *ast.TypeSpec: + obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil) + check.declarePkgObj(s.Name, obj, &declInfo{file: fileScope, typ: s.Type, alias: s.Assign.IsValid()}) + + default: + check.invalidAST(s.Pos(), "unknown ast.Spec node %T", s) + } + } + + case *ast.FuncDecl: + name := d.Name.Name + obj := NewFunc(d.Name.Pos(), pkg, name, nil) + if d.Recv == nil { + // regular function + if name == "init" { + // don't declare init functions in the package scope - they are invisible + obj.parent = pkg.scope + check.recordDef(d.Name, obj) + // init functions must have a body + if d.Body == nil { + check.softErrorf(obj.pos, "missing function body") + } + } else { + check.declare(pkg.scope, d.Name, obj, token.NoPos) + } + } else { + // method + // (Methods with blank _ names are never found; no need to collect + // them for later type association. They will still be type-checked + // with all the other functions.) + if name != "_" { + methods = append(methods, obj) + } + check.recordDef(d.Name, obj) + } + info := &declInfo{file: fileScope, fdecl: d} + check.objMap[obj] = info + obj.setOrder(uint32(len(check.objMap))) + + default: + check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d) + } + } + } + + // verify that objects in package and file scopes have different names + for _, scope := range check.pkg.scope.children /* file scopes */ { + for _, obj := range scope.elems { + if alt := pkg.scope.Lookup(obj.Name()); alt != nil { + if pkg, ok := obj.(*PkgName); ok { + check.errorf(alt.Pos(), "%s already declared through import of %s", alt.Name(), pkg.Imported()) + check.reportAltDecl(pkg) + } else { + check.errorf(alt.Pos(), "%s already declared through dot-import of %s", alt.Name(), obj.Pkg()) + // TODO(gri) dot-imported objects don't have a position; reportAltDecl won't print anything + check.reportAltDecl(obj) + } + } + } + } + + // Now that we have all package scope objects and all methods, + // associate methods with receiver base type name where possible. + // Ignore methods that have an invalid receiver. They will be + // type-checked later, with regular functions. + if methods == nil { + return // nothing to do + } + check.methods = make(map[*TypeName][]*Func) + for _, f := range methods { + fdecl := check.objMap[f].fdecl + if list := fdecl.Recv.List; len(list) > 0 { + // f is a method + // receiver may be of the form T or *T, possibly with parentheses + typ := unparen(list[0].Type) + if ptr, _ := typ.(*ast.StarExpr); ptr != nil { + typ = unparen(ptr.X) + } + if base, _ := typ.(*ast.Ident); base != nil { + // base is a potential base type name; determine + // "underlying" defined type and associate f with it + if tname := check.resolveBaseTypeName(base); tname != nil { + check.methods[tname] = append(check.methods[tname], f) + } + } + } + } +} + +// resolveBaseTypeName returns the non-alias receiver base type name, +// explicitly declared in the package scope, for the given receiver +// type name; or nil. +func (check *Checker) resolveBaseTypeName(name *ast.Ident) *TypeName { + var path []*TypeName + for { + // name must denote an object found in the current package + // (it could be explicitly declared or dot-imported) + obj := check.pkg.scope.Lookup(name.Name) + if obj == nil { + return nil + } + // the object must be a type name... + tname, _ := obj.(*TypeName) + if tname == nil { + return nil + } + + // ... which we have not seen before + if check.cycle(tname, path, false) { + return nil + } + + // tname must have been explicitly declared + // (dot-imported objects are not in objMap) + tdecl := check.objMap[tname] + if tdecl == nil { + return nil + } + + // we're done if tdecl defined tname as a new type + // (rather than an alias) + if !tdecl.alias { + return tname + } + + // Otherwise, if tdecl defined an alias for a (possibly parenthesized) + // type which is not an (unqualified) named type, we're done because + // receiver base types must be named types declared in this package. + typ := unparen(tdecl.typ) // a type may be parenthesized + name, _ = typ.(*ast.Ident) + if name == nil { + return nil + } + + // continue resolving name + path = append(path, tname) + } +} + +// packageObjects typechecks all package objects, but not function bodies. +func (check *Checker) packageObjects() { + // process package objects in source order for reproducible results + objList := make([]Object, len(check.objMap)) + i := 0 + for obj := range check.objMap { + objList[i] = obj + i++ + } + sort.Sort(inSourceOrder(objList)) + + // add new methods to already type-checked types (from a prior Checker.Files call) + for _, obj := range objList { + if obj, _ := obj.(*TypeName); obj != nil && obj.typ != nil { + check.addMethodDecls(obj) + } + } + + // pre-allocate space for type declaration paths so that the underlying array is reused + typePath := make([]*TypeName, 0, 8) + + for _, obj := range objList { + check.objDecl(obj, nil, typePath) + } + + // At this point we may have a non-empty check.methods map; this means that not all + // entries were deleted at the end of typeDecl because the respective receiver base + // types were not found. In that case, an error was reported when declaring those + // methods. We can now safely discard this map. + check.methods = nil +} + +// inSourceOrder implements the sort.Sort interface. +type inSourceOrder []Object + +func (a inSourceOrder) Len() int { return len(a) } +func (a inSourceOrder) Less(i, j int) bool { return a[i].order() < a[j].order() } +func (a inSourceOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +// processDelayed processes all delayed actions pushed after top. +func (check *Checker) processDelayed(top int) { + for len(check.delayed) > top { + i := len(check.delayed) - 1 + f := check.delayed[i] + check.delayed = check.delayed[:i] + f() // may append to check.delayed + } +} + +// unusedImports checks for unused imports. +func (check *Checker) unusedImports() { + // if function bodies are not checked, packages' uses are likely missing - don't check + if check.conf.IgnoreFuncBodies { + return + } + + // spec: "It is illegal (...) to directly import a package without referring to + // any of its exported identifiers. To import a package solely for its side-effects + // (initialization), use the blank identifier as explicit package name." + + // check use of regular imported packages + for _, scope := range check.pkg.scope.children /* file scopes */ { + for _, obj := range scope.elems { + if obj, ok := obj.(*PkgName); ok { + // Unused "blank imports" are automatically ignored + // since _ identifiers are not entered into scopes. + if !obj.used { + path := obj.imported.path + base := pkgName(path) + if obj.name == base { + check.softErrorf(obj.pos, "%q imported but not used", path) + } else { + check.softErrorf(obj.pos, "%q imported but not used as %s", path, obj.name) + } + } + } + } + } + + // check use of dot-imported packages + for _, unusedDotImports := range check.unusedDotImports { + for pkg, pos := range unusedDotImports { + check.softErrorf(pos, "%q imported but not used", pkg.path) + } + } +} + +// pkgName returns the package name (last element) of an import path. +func pkgName(path string) string { + if i := strings.LastIndex(path, "/"); i >= 0 { + path = path[i+1:] + } + return path +} + +// dir makes a good-faith attempt to return the directory +// portion of path. If path is empty, the result is ".". +// (Per the go/build package dependency tests, we cannot import +// path/filepath and simply use filepath.Dir.) +func dir(path string) string { + if i := strings.LastIndexAny(path, `/\`); i > 0 { + return path[:i] + } + // i <= 0 + return "." +} diff --git a/vendor/go/types/return.go b/vendor/go/types/return.go new file mode 100644 index 000000000..2d34a70b9 --- /dev/null +++ b/vendor/go/types/return.go @@ -0,0 +1,184 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements isTerminating. + +package types + +import ( + "go/ast" + "go/token" +) + +// isTerminating reports if s is a terminating statement. +// If s is labeled, label is the label name; otherwise s +// is "". +func (check *Checker) isTerminating(s ast.Stmt, label string) bool { + switch s := s.(type) { + default: + unreachable() + + case *ast.BadStmt, *ast.DeclStmt, *ast.EmptyStmt, *ast.SendStmt, + *ast.IncDecStmt, *ast.AssignStmt, *ast.GoStmt, *ast.DeferStmt, + *ast.RangeStmt: + // no chance + + case *ast.LabeledStmt: + return check.isTerminating(s.Stmt, s.Label.Name) + + case *ast.ExprStmt: + // calling the predeclared (possibly parenthesized) panic() function is terminating + if call, ok := unparen(s.X).(*ast.CallExpr); ok && check.isPanic[call] { + return true + } + + case *ast.ReturnStmt: + return true + + case *ast.BranchStmt: + if s.Tok == token.GOTO || s.Tok == token.FALLTHROUGH { + return true + } + + case *ast.BlockStmt: + return check.isTerminatingList(s.List, "") + + case *ast.IfStmt: + if s.Else != nil && + check.isTerminating(s.Body, "") && + check.isTerminating(s.Else, "") { + return true + } + + case *ast.SwitchStmt: + return check.isTerminatingSwitch(s.Body, label) + + case *ast.TypeSwitchStmt: + return check.isTerminatingSwitch(s.Body, label) + + case *ast.SelectStmt: + for _, s := range s.Body.List { + cc := s.(*ast.CommClause) + if !check.isTerminatingList(cc.Body, "") || hasBreakList(cc.Body, label, true) { + return false + } + + } + return true + + case *ast.ForStmt: + if s.Cond == nil && !hasBreak(s.Body, label, true) { + return true + } + } + + return false +} + +func (check *Checker) isTerminatingList(list []ast.Stmt, label string) bool { + // trailing empty statements are permitted - skip them + for i := len(list) - 1; i >= 0; i-- { + if _, ok := list[i].(*ast.EmptyStmt); !ok { + return check.isTerminating(list[i], label) + } + } + return false // all statements are empty +} + +func (check *Checker) isTerminatingSwitch(body *ast.BlockStmt, label string) bool { + hasDefault := false + for _, s := range body.List { + cc := s.(*ast.CaseClause) + if cc.List == nil { + hasDefault = true + } + if !check.isTerminatingList(cc.Body, "") || hasBreakList(cc.Body, label, true) { + return false + } + } + return hasDefault +} + +// TODO(gri) For nested breakable statements, the current implementation of hasBreak +// will traverse the same subtree repeatedly, once for each label. Replace +// with a single-pass label/break matching phase. + +// hasBreak reports if s is or contains a break statement +// referring to the label-ed statement or implicit-ly the +// closest outer breakable statement. +func hasBreak(s ast.Stmt, label string, implicit bool) bool { + switch s := s.(type) { + default: + unreachable() + + case *ast.BadStmt, *ast.DeclStmt, *ast.EmptyStmt, *ast.ExprStmt, + *ast.SendStmt, *ast.IncDecStmt, *ast.AssignStmt, *ast.GoStmt, + *ast.DeferStmt, *ast.ReturnStmt: + // no chance + + case *ast.LabeledStmt: + return hasBreak(s.Stmt, label, implicit) + + case *ast.BranchStmt: + if s.Tok == token.BREAK { + if s.Label == nil { + return implicit + } + if s.Label.Name == label { + return true + } + } + + case *ast.BlockStmt: + return hasBreakList(s.List, label, implicit) + + case *ast.IfStmt: + if hasBreak(s.Body, label, implicit) || + s.Else != nil && hasBreak(s.Else, label, implicit) { + return true + } + + case *ast.CaseClause: + return hasBreakList(s.Body, label, implicit) + + case *ast.SwitchStmt: + if label != "" && hasBreak(s.Body, label, false) { + return true + } + + case *ast.TypeSwitchStmt: + if label != "" && hasBreak(s.Body, label, false) { + return true + } + + case *ast.CommClause: + return hasBreakList(s.Body, label, implicit) + + case *ast.SelectStmt: + if label != "" && hasBreak(s.Body, label, false) { + return true + } + + case *ast.ForStmt: + if label != "" && hasBreak(s.Body, label, false) { + return true + } + + case *ast.RangeStmt: + if label != "" && hasBreak(s.Body, label, false) { + return true + } + } + + return false +} + +func hasBreakList(list []ast.Stmt, label string, implicit bool) bool { + for _, s := range list { + if hasBreak(s, label, implicit) { + return true + } + } + return false +} diff --git a/vendor/go/types/scope.go b/vendor/go/types/scope.go new file mode 100644 index 000000000..39e42d758 --- /dev/null +++ b/vendor/go/types/scope.go @@ -0,0 +1,191 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements Scopes. + +package types + +import ( + "bytes" + "fmt" + "go/token" + "io" + "sort" + "strings" +) + +// TODO(gri) Provide scopes with a name or other mechanism so that +// objects can use that information for better printing. + +// A Scope maintains a set of objects and links to its containing +// (parent) and contained (children) scopes. Objects may be inserted +// and looked up by name. The zero value for Scope is a ready-to-use +// empty scope. +type Scope struct { + parent *Scope + children []*Scope + elems map[string]Object // lazily allocated + pos, end token.Pos // scope extent; may be invalid + comment string // for debugging only + isFunc bool // set if this is a function scope (internal use only) +} + +// NewScope returns a new, empty scope contained in the given parent +// scope, if any. The comment is for debugging only. +func NewScope(parent *Scope, pos, end token.Pos, comment string) *Scope { + s := &Scope{parent, nil, nil, pos, end, comment, false} + // don't add children to Universe scope! + if parent != nil && parent != Universe { + parent.children = append(parent.children, s) + } + return s +} + +// Parent returns the scope's containing (parent) scope. +func (s *Scope) Parent() *Scope { return s.parent } + +// Len() returns the number of scope elements. +func (s *Scope) Len() int { return len(s.elems) } + +// Names returns the scope's element names in sorted order. +func (s *Scope) Names() []string { + names := make([]string, len(s.elems)) + i := 0 + for name := range s.elems { + names[i] = name + i++ + } + sort.Strings(names) + return names +} + +// NumChildren() returns the number of scopes nested in s. +func (s *Scope) NumChildren() int { return len(s.children) } + +// Child returns the i'th child scope for 0 <= i < NumChildren(). +func (s *Scope) Child(i int) *Scope { return s.children[i] } + +// Lookup returns the object in scope s with the given name if such an +// object exists; otherwise the result is nil. +func (s *Scope) Lookup(name string) Object { + return s.elems[name] +} + +// LookupParent follows the parent chain of scopes starting with s until +// it finds a scope where Lookup(name) returns a non-nil object, and then +// returns that scope and object. If a valid position pos is provided, +// only objects that were declared at or before pos are considered. +// If no such scope and object exists, the result is (nil, nil). +// +// Note that obj.Parent() may be different from the returned scope if the +// object was inserted into the scope and already had a parent at that +// time (see Insert, below). This can only happen for dot-imported objects +// whose scope is the scope of the package that exported them. +func (s *Scope) LookupParent(name string, pos token.Pos) (*Scope, Object) { + for ; s != nil; s = s.parent { + if obj := s.elems[name]; obj != nil && (!pos.IsValid() || obj.scopePos() <= pos) { + return s, obj + } + } + return nil, nil +} + +// Insert attempts to insert an object obj into scope s. +// If s already contains an alternative object alt with +// the same name, Insert leaves s unchanged and returns alt. +// Otherwise it inserts obj, sets the object's parent scope +// if not already set, and returns nil. +func (s *Scope) Insert(obj Object) Object { + name := obj.Name() + if alt := s.elems[name]; alt != nil { + return alt + } + if s.elems == nil { + s.elems = make(map[string]Object) + } + s.elems[name] = obj + if obj.Parent() == nil { + obj.setParent(s) + } + return nil +} + +// Pos and End describe the scope's source code extent [pos, end). +// The results are guaranteed to be valid only if the type-checked +// AST has complete position information. The extent is undefined +// for Universe and package scopes. +func (s *Scope) Pos() token.Pos { return s.pos } +func (s *Scope) End() token.Pos { return s.end } + +// Contains returns true if pos is within the scope's extent. +// The result is guaranteed to be valid only if the type-checked +// AST has complete position information. +func (s *Scope) Contains(pos token.Pos) bool { + return s.pos <= pos && pos < s.end +} + +// Innermost returns the innermost (child) scope containing +// pos. If pos is not within any scope, the result is nil. +// The result is also nil for the Universe scope. +// The result is guaranteed to be valid only if the type-checked +// AST has complete position information. +func (s *Scope) Innermost(pos token.Pos) *Scope { + // Package scopes do not have extents since they may be + // discontiguous, so iterate over the package's files. + if s.parent == Universe { + for _, s := range s.children { + if inner := s.Innermost(pos); inner != nil { + return inner + } + } + } + + if s.Contains(pos) { + for _, s := range s.children { + if s.Contains(pos) { + return s.Innermost(pos) + } + } + return s + } + return nil +} + +// WriteTo writes a string representation of the scope to w, +// with the scope elements sorted by name. +// The level of indentation is controlled by n >= 0, with +// n == 0 for no indentation. +// If recurse is set, it also writes nested (children) scopes. +func (s *Scope) WriteTo(w io.Writer, n int, recurse bool) { + const ind = ". " + indn := strings.Repeat(ind, n) + + fmt.Fprintf(w, "%s%s scope %p {", indn, s.comment, s) + if len(s.elems) == 0 { + fmt.Fprintf(w, "}\n") + return + } + + fmt.Fprintln(w) + indn1 := indn + ind + for _, name := range s.Names() { + fmt.Fprintf(w, "%s%s\n", indn1, s.elems[name]) + } + + if recurse { + for _, s := range s.children { + fmt.Fprintln(w) + s.WriteTo(w, n+1, recurse) + } + } + + fmt.Fprintf(w, "%s}", indn) +} + +// String returns a string representation of the scope, for debugging. +func (s *Scope) String() string { + var buf bytes.Buffer + s.WriteTo(&buf, 0, false) + return buf.String() +} diff --git a/vendor/go/types/selection.go b/vendor/go/types/selection.go new file mode 100644 index 000000000..124e0d39f --- /dev/null +++ b/vendor/go/types/selection.go @@ -0,0 +1,143 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements Selections. + +package types + +import ( + "bytes" + "fmt" +) + +// SelectionKind describes the kind of a selector expression x.f +// (excluding qualified identifiers). +type SelectionKind int + +const ( + FieldVal SelectionKind = iota // x.f is a struct field selector + MethodVal // x.f is a method selector + MethodExpr // x.f is a method expression +) + +// A Selection describes a selector expression x.f. +// For the declarations: +// +// type T struct{ x int; E } +// type E struct{} +// func (e E) m() {} +// var p *T +// +// the following relations exist: +// +// Selector Kind Recv Obj Type Index Indirect +// +// p.x FieldVal T x int {0} true +// p.m MethodVal *T m func (e *T) m() {1, 0} true +// T.m MethodExpr T m func m(_ T) {1, 0} false +// +type Selection struct { + kind SelectionKind + recv Type // type of x + obj Object // object denoted by x.f + index []int // path from x to x.f + indirect bool // set if there was any pointer indirection on the path +} + +// Kind returns the selection kind. +func (s *Selection) Kind() SelectionKind { return s.kind } + +// Recv returns the type of x in x.f. +func (s *Selection) Recv() Type { return s.recv } + +// Obj returns the object denoted by x.f; a *Var for +// a field selection, and a *Func in all other cases. +func (s *Selection) Obj() Object { return s.obj } + +// Type returns the type of x.f, which may be different from the type of f. +// See Selection for more information. +func (s *Selection) Type() Type { + switch s.kind { + case MethodVal: + // The type of x.f is a method with its receiver type set + // to the type of x. + sig := *s.obj.(*Func).typ.(*Signature) + recv := *sig.recv + recv.typ = s.recv + sig.recv = &recv + return &sig + + case MethodExpr: + // The type of x.f is a function (without receiver) + // and an additional first argument with the same type as x. + // TODO(gri) Similar code is already in call.go - factor! + // TODO(gri) Compute this eagerly to avoid allocations. + sig := *s.obj.(*Func).typ.(*Signature) + arg0 := *sig.recv + sig.recv = nil + arg0.typ = s.recv + var params []*Var + if sig.params != nil { + params = sig.params.vars + } + sig.params = NewTuple(append([]*Var{&arg0}, params...)...) + return &sig + } + + // In all other cases, the type of x.f is the type of x. + return s.obj.Type() +} + +// Index describes the path from x to f in x.f. +// The last index entry is the field or method index of the type declaring f; +// either: +// +// 1) the list of declared methods of a named type; or +// 2) the list of methods of an interface type; or +// 3) the list of fields of a struct type. +// +// The earlier index entries are the indices of the embedded fields implicitly +// traversed to get from (the type of) x to f, starting at embedding depth 0. +func (s *Selection) Index() []int { return s.index } + +// Indirect reports whether any pointer indirection was required to get from +// x to f in x.f. +func (s *Selection) Indirect() bool { return s.indirect } + +func (s *Selection) String() string { return SelectionString(s, nil) } + +// SelectionString returns the string form of s. +// The Qualifier controls the printing of +// package-level objects, and may be nil. +// +// Examples: +// "field (T) f int" +// "method (T) f(X) Y" +// "method expr (T) f(X) Y" +// +func SelectionString(s *Selection, qf Qualifier) string { + var k string + switch s.kind { + case FieldVal: + k = "field " + case MethodVal: + k = "method " + case MethodExpr: + k = "method expr " + default: + unreachable() + } + var buf bytes.Buffer + buf.WriteString(k) + buf.WriteByte('(') + WriteType(&buf, s.Recv(), qf) + fmt.Fprintf(&buf, ") %s", s.obj.Name()) + if T := s.Type(); s.kind == FieldVal { + buf.WriteByte(' ') + WriteType(&buf, T, qf) + } else { + WriteSignature(&buf, T.(*Signature), qf) + } + return buf.String() +} diff --git a/vendor/go/types/sizes.go b/vendor/go/types/sizes.go new file mode 100644 index 000000000..fda0c9546 --- /dev/null +++ b/vendor/go/types/sizes.go @@ -0,0 +1,255 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements Sizes. + +package types + +// Sizes defines the sizing functions for package unsafe. +type Sizes interface { + // Alignof returns the alignment of a variable of type T. + // Alignof must implement the alignment guarantees required by the spec. + Alignof(T Type) int64 + + // Offsetsof returns the offsets of the given struct fields, in bytes. + // Offsetsof must implement the offset guarantees required by the spec. + Offsetsof(fields []*Var) []int64 + + // Sizeof returns the size of a variable of type T. + // Sizeof must implement the size guarantees required by the spec. + Sizeof(T Type) int64 +} + +// StdSizes is a convenience type for creating commonly used Sizes. +// It makes the following simplifying assumptions: +// +// - The size of explicitly sized basic types (int16, etc.) is the +// specified size. +// - The size of strings and interfaces is 2*WordSize. +// - The size of slices is 3*WordSize. +// - The size of an array of n elements corresponds to the size of +// a struct of n consecutive fields of the array's element type. +// - The size of a struct is the offset of the last field plus that +// field's size. As with all element types, if the struct is used +// in an array its size must first be aligned to a multiple of the +// struct's alignment. +// - All other types have size WordSize. +// - Arrays and structs are aligned per spec definition; all other +// types are naturally aligned with a maximum alignment MaxAlign. +// +// *StdSizes implements Sizes. +// +type StdSizes struct { + WordSize int64 // word size in bytes - must be >= 4 (32bits) + MaxAlign int64 // maximum alignment in bytes - must be >= 1 +} + +func (s *StdSizes) Alignof(T Type) int64 { + // For arrays and structs, alignment is defined in terms + // of alignment of the elements and fields, respectively. + switch t := T.Underlying().(type) { + case *Array: + // spec: "For a variable x of array type: unsafe.Alignof(x) + // is the same as unsafe.Alignof(x[0]), but at least 1." + return s.Alignof(t.elem) + case *Struct: + // spec: "For a variable x of struct type: unsafe.Alignof(x) + // is the largest of the values unsafe.Alignof(x.f) for each + // field f of x, but at least 1." + max := int64(1) + for _, f := range t.fields { + if a := s.Alignof(f.typ); a > max { + max = a + } + } + return max + case *Slice, *Interface: + // Multiword data structures are effectively structs + // in which each element has size WordSize. + return s.WordSize + case *Basic: + // Strings are like slices and interfaces. + if t.Info()&IsString != 0 { + return s.WordSize + } + } + a := s.Sizeof(T) // may be 0 + // spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1." + if a < 1 { + return 1 + } + // complex{64,128} are aligned like [2]float{32,64}. + if isComplex(T) { + a /= 2 + } + if a > s.MaxAlign { + return s.MaxAlign + } + return a +} + +func (s *StdSizes) Offsetsof(fields []*Var) []int64 { + offsets := make([]int64, len(fields)) + var o int64 + for i, f := range fields { + a := s.Alignof(f.typ) + o = align(o, a) + offsets[i] = o + o += s.Sizeof(f.typ) + } + return offsets +} + +var basicSizes = [...]byte{ + Bool: 1, + Int8: 1, + Int16: 2, + Int32: 4, + Int64: 8, + Uint8: 1, + Uint16: 2, + Uint32: 4, + Uint64: 8, + Float32: 4, + Float64: 8, + Complex64: 8, + Complex128: 16, +} + +func (s *StdSizes) Sizeof(T Type) int64 { + switch t := T.Underlying().(type) { + case *Basic: + assert(isTyped(T)) + k := t.kind + if int(k) < len(basicSizes) { + if s := basicSizes[k]; s > 0 { + return int64(s) + } + } + if k == String { + return s.WordSize * 2 + } + case *Array: + n := t.len + if n <= 0 { + return 0 + } + // n > 0 + a := s.Alignof(t.elem) + z := s.Sizeof(t.elem) + return align(z, a)*(n-1) + z + case *Slice: + return s.WordSize * 3 + case *Struct: + n := t.NumFields() + if n == 0 { + return 0 + } + offsets := s.Offsetsof(t.fields) + return offsets[n-1] + s.Sizeof(t.fields[n-1].typ) + case *Interface: + return s.WordSize * 2 + } + return s.WordSize // catch-all +} + +// common architecture word sizes and alignments +var gcArchSizes = map[string]*StdSizes{ + "386": {4, 4}, + "arm": {4, 4}, + "arm64": {8, 8}, + "amd64": {8, 8}, + "amd64p32": {4, 8}, + "mips": {4, 4}, + "mipsle": {4, 4}, + "mips64": {8, 8}, + "mips64le": {8, 8}, + "ppc64": {8, 8}, + "ppc64le": {8, 8}, + "s390x": {8, 8}, + "wasm": {8, 8}, + // When adding more architectures here, + // update the doc string of SizesFor below. +} + +// SizesFor returns the Sizes used by a compiler for an architecture. +// The result is nil if a compiler/architecture pair is not known. +// +// Supported architectures for compiler "gc": +// "386", "arm", "arm64", "amd64", "amd64p32", "mips", "mipsle", +// "mips64", "mips64le", "ppc64", "ppc64le", "s390x", "wasm". +func SizesFor(compiler, arch string) Sizes { + if compiler != "gc" { + return nil + } + s, ok := gcArchSizes[arch] + if !ok { + return nil + } + return s +} + +// stdSizes is used if Config.Sizes == nil. +var stdSizes = SizesFor("gc", "amd64") + +func (conf *Config) alignof(T Type) int64 { + if s := conf.Sizes; s != nil { + if a := s.Alignof(T); a >= 1 { + return a + } + panic("Config.Sizes.Alignof returned an alignment < 1") + } + return stdSizes.Alignof(T) +} + +func (conf *Config) offsetsof(T *Struct) []int64 { + var offsets []int64 + if T.NumFields() > 0 { + // compute offsets on demand + if s := conf.Sizes; s != nil { + offsets = s.Offsetsof(T.fields) + // sanity checks + if len(offsets) != T.NumFields() { + panic("Config.Sizes.Offsetsof returned the wrong number of offsets") + } + for _, o := range offsets { + if o < 0 { + panic("Config.Sizes.Offsetsof returned an offset < 0") + } + } + } else { + offsets = stdSizes.Offsetsof(T.fields) + } + } + return offsets +} + +// offsetof returns the offset of the field specified via +// the index sequence relative to typ. All embedded fields +// must be structs (rather than pointer to structs). +func (conf *Config) offsetof(typ Type, index []int) int64 { + var o int64 + for _, i := range index { + s := typ.Underlying().(*Struct) + o += conf.offsetsof(s)[i] + typ = s.fields[i].typ + } + return o +} + +func (conf *Config) sizeof(T Type) int64 { + if s := conf.Sizes; s != nil { + if z := s.Sizeof(T); z >= 0 { + return z + } + panic("Config.Sizes.Sizeof returned a size < 0") + } + return stdSizes.Sizeof(T) +} + +// align returns the smallest y >= x such that y % a == 0. +func align(x, a int64) int64 { + y := x + a - 1 + return y - y%a +} diff --git a/vendor/go/types/stmt.go b/vendor/go/types/stmt.go new file mode 100644 index 000000000..abd9d05ef --- /dev/null +++ b/vendor/go/types/stmt.go @@ -0,0 +1,866 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements typechecking of statements. + +package types + +import ( + "go/ast" + "go/constant" + "go/token" + "sort" +) + +func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body *ast.BlockStmt, iota constant.Value) { + if trace { + check.trace(body.Pos(), "--- %s: %s", name, sig) + defer func() { + check.trace(body.End(), "--- ") + }() + } + + // set function scope extent + sig.scope.pos = body.Pos() + sig.scope.end = body.End() + + // save/restore current context and setup function context + // (and use 0 indentation at function start) + defer func(ctxt context, indent int) { + check.context = ctxt + check.indent = indent + }(check.context, check.indent) + check.context = context{ + decl: decl, + scope: sig.scope, + iota: iota, + sig: sig, + } + check.indent = 0 + + check.stmtList(0, body.List) + + if check.hasLabel { + check.labels(body) + } + + if sig.results.Len() > 0 && !check.isTerminating(body, "") { + check.error(body.Rbrace, "missing return") + } + + // spec: "Implementation restriction: A compiler may make it illegal to + // declare a variable inside a function body if the variable is never used." + check.usage(sig.scope) +} + +func (check *Checker) usage(scope *Scope) { + var unused []*Var + for _, elem := range scope.elems { + if v, _ := elem.(*Var); v != nil && !v.used { + unused = append(unused, v) + } + } + sort.Slice(unused, func(i, j int) bool { + return unused[i].pos < unused[j].pos + }) + for _, v := range unused { + check.softErrorf(v.pos, "%s declared but not used", v.name) + } + + for _, scope := range scope.children { + // Don't go inside function literal scopes a second time; + // they are handled explicitly by funcBody. + if !scope.isFunc { + check.usage(scope) + } + } +} + +// stmtContext is a bitset describing which +// control-flow statements are permissible, +// and provides additional context information +// for better error messages. +type stmtContext uint + +const ( + // permissible control-flow statements + breakOk stmtContext = 1 << iota + continueOk + fallthroughOk + + // additional context information + finalSwitchCase +) + +func (check *Checker) simpleStmt(s ast.Stmt) { + if s != nil { + check.stmt(0, s) + } +} + +func trimTrailingEmptyStmts(list []ast.Stmt) []ast.Stmt { + for i := len(list); i > 0; i-- { + if _, ok := list[i-1].(*ast.EmptyStmt); !ok { + return list[:i] + } + } + return nil +} + +func (check *Checker) stmtList(ctxt stmtContext, list []ast.Stmt) { + ok := ctxt&fallthroughOk != 0 + inner := ctxt &^ fallthroughOk + list = trimTrailingEmptyStmts(list) // trailing empty statements are "invisible" to fallthrough analysis + for i, s := range list { + inner := inner + if ok && i+1 == len(list) { + inner |= fallthroughOk + } + check.stmt(inner, s) + } +} + +func (check *Checker) multipleDefaults(list []ast.Stmt) { + var first ast.Stmt + for _, s := range list { + var d ast.Stmt + switch c := s.(type) { + case *ast.CaseClause: + if len(c.List) == 0 { + d = s + } + case *ast.CommClause: + if c.Comm == nil { + d = s + } + default: + check.invalidAST(s.Pos(), "case/communication clause expected") + } + if d != nil { + if first != nil { + check.errorf(d.Pos(), "multiple defaults (first at %s)", check.fset.Position(first.Pos())) + } else { + first = d + } + } + } +} + +func (check *Checker) openScope(s ast.Stmt, comment string) { + scope := NewScope(check.scope, s.Pos(), s.End(), comment) + check.recordScope(s, scope) + check.scope = scope +} + +func (check *Checker) closeScope() { + check.scope = check.scope.Parent() +} + +func assignOp(op token.Token) token.Token { + // token_test.go verifies the token ordering this function relies on + if token.ADD_ASSIGN <= op && op <= token.AND_NOT_ASSIGN { + return op + (token.ADD - token.ADD_ASSIGN) + } + return token.ILLEGAL +} + +func (check *Checker) suspendedCall(keyword string, call *ast.CallExpr) { + var x operand + var msg string + switch check.rawExpr(&x, call, nil) { + case conversion: + msg = "requires function call, not conversion" + case expression: + msg = "discards result of" + case statement: + return + default: + unreachable() + } + check.errorf(x.pos(), "%s %s %s", keyword, msg, &x) +} + +// goVal returns the Go value for val, or nil. +func goVal(val constant.Value) interface{} { + // val should exist, but be conservative and check + if val == nil { + return nil + } + // Match implementation restriction of other compilers. + // gc only checks duplicates for integer, floating-point + // and string values, so only create Go values for these + // types. + switch val.Kind() { + case constant.Int: + if x, ok := constant.Int64Val(val); ok { + return x + } + if x, ok := constant.Uint64Val(val); ok { + return x + } + case constant.Float: + if x, ok := constant.Float64Val(val); ok { + return x + } + case constant.String: + return constant.StringVal(val) + } + return nil +} + +// A valueMap maps a case value (of a basic Go type) to a list of positions +// where the same case value appeared, together with the corresponding case +// types. +// Since two case values may have the same "underlying" value but different +// types we need to also check the value's types (e.g., byte(1) vs myByte(1)) +// when the switch expression is of interface type. +type ( + valueMap map[interface{}][]valueType // underlying Go value -> valueType + valueType struct { + pos token.Pos + typ Type + } +) + +func (check *Checker) caseValues(x *operand, values []ast.Expr, seen valueMap) { +L: + for _, e := range values { + var v operand + check.expr(&v, e) + if x.mode == invalid || v.mode == invalid { + continue L + } + check.convertUntyped(&v, x.typ) + if v.mode == invalid { + continue L + } + // Order matters: By comparing v against x, error positions are at the case values. + res := v // keep original v unchanged + check.comparison(&res, x, token.EQL) + if res.mode == invalid { + continue L + } + if v.mode != constant_ { + continue L // we're done + } + // look for duplicate values + if val := goVal(v.val); val != nil { + // look for duplicate types for a given value + // (quadratic algorithm, but these lists tend to be very short) + for _, vt := range seen[val] { + if Identical(v.typ, vt.typ) { + check.errorf(v.pos(), "duplicate case %s in expression switch", &v) + check.error(vt.pos, "\tprevious case") // secondary error, \t indented + continue L + } + } + seen[val] = append(seen[val], valueType{v.pos(), v.typ}) + } + } +} + +func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []ast.Expr, seen map[Type]token.Pos) (T Type) { +L: + for _, e := range types { + T = check.typOrNil(e) + if T == Typ[Invalid] { + continue L + } + // look for duplicate types + // (quadratic algorithm, but type switches tend to be reasonably small) + for t, pos := range seen { + if T == nil && t == nil || T != nil && t != nil && Identical(T, t) { + // talk about "case" rather than "type" because of nil case + Ts := "nil" + if T != nil { + Ts = T.String() + } + check.errorf(e.Pos(), "duplicate case %s in type switch", Ts) + check.error(pos, "\tprevious case") // secondary error, \t indented + continue L + } + } + seen[T] = e.Pos() + if T != nil { + check.typeAssertion(e.Pos(), x, xtyp, T) + } + } + return +} + +// stmt typechecks statement s. +func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { + // statements must end with the same top scope as they started with + if debug { + defer func(scope *Scope) { + // don't check if code is panicking + if p := recover(); p != nil { + panic(p) + } + assert(scope == check.scope) + }(check.scope) + } + + // process collected function literals before scope changes + defer check.processDelayed(len(check.delayed)) + + inner := ctxt &^ (fallthroughOk | finalSwitchCase) + switch s := s.(type) { + case *ast.BadStmt, *ast.EmptyStmt: + // ignore + + case *ast.DeclStmt: + check.declStmt(s.Decl) + + case *ast.LabeledStmt: + check.hasLabel = true + check.stmt(ctxt, s.Stmt) + + case *ast.ExprStmt: + // spec: "With the exception of specific built-in functions, + // function and method calls and receive operations can appear + // in statement context. Such statements may be parenthesized." + var x operand + kind := check.rawExpr(&x, s.X, nil) + var msg string + switch x.mode { + default: + if kind == statement { + return + } + msg = "is not used" + case builtin: + msg = "must be called" + case typexpr: + msg = "is not an expression" + } + check.errorf(x.pos(), "%s %s", &x, msg) + + case *ast.SendStmt: + var ch, x operand + check.expr(&ch, s.Chan) + check.expr(&x, s.Value) + if ch.mode == invalid || x.mode == invalid { + return + } + + tch, ok := ch.typ.Underlying().(*Chan) + if !ok { + check.invalidOp(s.Arrow, "cannot send to non-chan type %s", ch.typ) + return + } + + if tch.dir == RecvOnly { + check.invalidOp(s.Arrow, "cannot send to receive-only type %s", tch) + return + } + + check.assignment(&x, tch.elem, "send") + + case *ast.IncDecStmt: + var op token.Token + switch s.Tok { + case token.INC: + op = token.ADD + case token.DEC: + op = token.SUB + default: + check.invalidAST(s.TokPos, "unknown inc/dec operation %s", s.Tok) + return + } + + var x operand + check.expr(&x, s.X) + if x.mode == invalid { + return + } + if !isNumeric(x.typ) { + check.invalidOp(s.X.Pos(), "%s%s (non-numeric type %s)", s.X, s.Tok, x.typ) + return + } + + Y := &ast.BasicLit{ValuePos: s.X.Pos(), Kind: token.INT, Value: "1"} // use x's position + check.binary(&x, nil, s.X, Y, op) + if x.mode == invalid { + return + } + check.assignVar(s.X, &x) + + case *ast.AssignStmt: + switch s.Tok { + case token.ASSIGN, token.DEFINE: + if len(s.Lhs) == 0 { + check.invalidAST(s.Pos(), "missing lhs in assignment") + return + } + if s.Tok == token.DEFINE { + check.shortVarDecl(s.TokPos, s.Lhs, s.Rhs) + } else { + // regular assignment + check.assignVars(s.Lhs, s.Rhs) + } + + default: + // assignment operations + if len(s.Lhs) != 1 || len(s.Rhs) != 1 { + check.errorf(s.TokPos, "assignment operation %s requires single-valued expressions", s.Tok) + return + } + op := assignOp(s.Tok) + if op == token.ILLEGAL { + check.invalidAST(s.TokPos, "unknown assignment operation %s", s.Tok) + return + } + var x operand + check.binary(&x, nil, s.Lhs[0], s.Rhs[0], op) + if x.mode == invalid { + return + } + check.assignVar(s.Lhs[0], &x) + } + + case *ast.GoStmt: + check.suspendedCall("go", s.Call) + + case *ast.DeferStmt: + check.suspendedCall("defer", s.Call) + + case *ast.ReturnStmt: + res := check.sig.results + if res.Len() > 0 { + // function returns results + // (if one, say the first, result parameter is named, all of them are named) + if len(s.Results) == 0 && res.vars[0].name != "" { + // spec: "Implementation restriction: A compiler may disallow an empty expression + // list in a "return" statement if a different entity (constant, type, or variable) + // with the same name as a result parameter is in scope at the place of the return." + for _, obj := range res.vars { + if alt := check.lookup(obj.name); alt != nil && alt != obj { + check.errorf(s.Pos(), "result parameter %s not in scope at return", obj.name) + check.errorf(alt.Pos(), "\tinner declaration of %s", obj) + // ok to continue + } + } + } else { + // return has results or result parameters are unnamed + check.initVars(res.vars, s.Results, s.Return) + } + } else if len(s.Results) > 0 { + check.error(s.Results[0].Pos(), "no result values expected") + check.use(s.Results...) + } + + case *ast.BranchStmt: + if s.Label != nil { + check.hasLabel = true + return // checked in 2nd pass (check.labels) + } + switch s.Tok { + case token.BREAK: + if ctxt&breakOk == 0 { + check.error(s.Pos(), "break not in for, switch, or select statement") + } + case token.CONTINUE: + if ctxt&continueOk == 0 { + check.error(s.Pos(), "continue not in for statement") + } + case token.FALLTHROUGH: + if ctxt&fallthroughOk == 0 { + msg := "fallthrough statement out of place" + if ctxt&finalSwitchCase != 0 { + msg = "cannot fallthrough final case in switch" + } + check.error(s.Pos(), msg) + } + default: + check.invalidAST(s.Pos(), "branch statement: %s", s.Tok) + } + + case *ast.BlockStmt: + check.openScope(s, "block") + defer check.closeScope() + + check.stmtList(inner, s.List) + + case *ast.IfStmt: + check.openScope(s, "if") + defer check.closeScope() + + check.simpleStmt(s.Init) + var x operand + check.expr(&x, s.Cond) + if x.mode != invalid && !isBoolean(x.typ) { + check.error(s.Cond.Pos(), "non-boolean condition in if statement") + } + check.stmt(inner, s.Body) + // The parser produces a correct AST but if it was modified + // elsewhere the else branch may be invalid. Check again. + switch s.Else.(type) { + case nil, *ast.BadStmt: + // valid or error already reported + case *ast.IfStmt, *ast.BlockStmt: + check.stmt(inner, s.Else) + default: + check.error(s.Else.Pos(), "invalid else branch in if statement") + } + + case *ast.SwitchStmt: + inner |= breakOk + check.openScope(s, "switch") + defer check.closeScope() + + check.simpleStmt(s.Init) + var x operand + if s.Tag != nil { + check.expr(&x, s.Tag) + // By checking assignment of x to an invisible temporary + // (as a compiler would), we get all the relevant checks. + check.assignment(&x, nil, "switch expression") + } else { + // spec: "A missing switch expression is + // equivalent to the boolean value true." + x.mode = constant_ + x.typ = Typ[Bool] + x.val = constant.MakeBool(true) + x.expr = &ast.Ident{NamePos: s.Body.Lbrace, Name: "true"} + } + + check.multipleDefaults(s.Body.List) + + seen := make(valueMap) // map of seen case values to positions and types + for i, c := range s.Body.List { + clause, _ := c.(*ast.CaseClause) + if clause == nil { + check.invalidAST(c.Pos(), "incorrect expression switch case") + continue + } + check.caseValues(&x, clause.List, seen) + check.openScope(clause, "case") + inner := inner + if i+1 < len(s.Body.List) { + inner |= fallthroughOk + } else { + inner |= finalSwitchCase + } + check.stmtList(inner, clause.Body) + check.closeScope() + } + + case *ast.TypeSwitchStmt: + inner |= breakOk + check.openScope(s, "type switch") + defer check.closeScope() + + check.simpleStmt(s.Init) + + // A type switch guard must be of the form: + // + // TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" . + // + // The parser is checking syntactic correctness; + // remaining syntactic errors are considered AST errors here. + // TODO(gri) better factoring of error handling (invalid ASTs) + // + var lhs *ast.Ident // lhs identifier or nil + var rhs ast.Expr + switch guard := s.Assign.(type) { + case *ast.ExprStmt: + rhs = guard.X + case *ast.AssignStmt: + if len(guard.Lhs) != 1 || guard.Tok != token.DEFINE || len(guard.Rhs) != 1 { + check.invalidAST(s.Pos(), "incorrect form of type switch guard") + return + } + + lhs, _ = guard.Lhs[0].(*ast.Ident) + if lhs == nil { + check.invalidAST(s.Pos(), "incorrect form of type switch guard") + return + } + + if lhs.Name == "_" { + // _ := x.(type) is an invalid short variable declaration + check.softErrorf(lhs.Pos(), "no new variable on left side of :=") + lhs = nil // avoid declared but not used error below + } else { + check.recordDef(lhs, nil) // lhs variable is implicitly declared in each cause clause + } + + rhs = guard.Rhs[0] + + default: + check.invalidAST(s.Pos(), "incorrect form of type switch guard") + return + } + + // rhs must be of the form: expr.(type) and expr must be an interface + expr, _ := rhs.(*ast.TypeAssertExpr) + if expr == nil || expr.Type != nil { + check.invalidAST(s.Pos(), "incorrect form of type switch guard") + return + } + var x operand + check.expr(&x, expr.X) + if x.mode == invalid { + return + } + xtyp, _ := x.typ.Underlying().(*Interface) + if xtyp == nil { + check.errorf(x.pos(), "%s is not an interface", &x) + return + } + + check.multipleDefaults(s.Body.List) + + var lhsVars []*Var // list of implicitly declared lhs variables + seen := make(map[Type]token.Pos) // map of seen types to positions + for _, s := range s.Body.List { + clause, _ := s.(*ast.CaseClause) + if clause == nil { + check.invalidAST(s.Pos(), "incorrect type switch case") + continue + } + // Check each type in this type switch case. + T := check.caseTypes(&x, xtyp, clause.List, seen) + check.openScope(clause, "case") + // If lhs exists, declare a corresponding variable in the case-local scope. + if lhs != nil { + // spec: "The TypeSwitchGuard may include a short variable declaration. + // When that form is used, the variable is declared at the beginning of + // the implicit block in each clause. In clauses with a case listing + // exactly one type, the variable has that type; otherwise, the variable + // has the type of the expression in the TypeSwitchGuard." + if len(clause.List) != 1 || T == nil { + T = x.typ + } + obj := NewVar(lhs.Pos(), check.pkg, lhs.Name, T) + scopePos := clause.Pos() + token.Pos(len("default")) // for default clause (len(List) == 0) + if n := len(clause.List); n > 0 { + scopePos = clause.List[n-1].End() + } + check.declare(check.scope, nil, obj, scopePos) + check.recordImplicit(clause, obj) + // For the "declared but not used" error, all lhs variables act as + // one; i.e., if any one of them is 'used', all of them are 'used'. + // Collect them for later analysis. + lhsVars = append(lhsVars, obj) + } + check.stmtList(inner, clause.Body) + check.closeScope() + } + + // If lhs exists, we must have at least one lhs variable that was used. + if lhs != nil { + var used bool + for _, v := range lhsVars { + if v.used { + used = true + } + v.used = true // avoid usage error when checking entire function + } + if !used { + check.softErrorf(lhs.Pos(), "%s declared but not used", lhs.Name) + } + } + + case *ast.SelectStmt: + inner |= breakOk + + check.multipleDefaults(s.Body.List) + + for _, s := range s.Body.List { + clause, _ := s.(*ast.CommClause) + if clause == nil { + continue // error reported before + } + + // clause.Comm must be a SendStmt, RecvStmt, or default case + valid := false + var rhs ast.Expr // rhs of RecvStmt, or nil + switch s := clause.Comm.(type) { + case nil, *ast.SendStmt: + valid = true + case *ast.AssignStmt: + if len(s.Rhs) == 1 { + rhs = s.Rhs[0] + } + case *ast.ExprStmt: + rhs = s.X + } + + // if present, rhs must be a receive operation + if rhs != nil { + if x, _ := unparen(rhs).(*ast.UnaryExpr); x != nil && x.Op == token.ARROW { + valid = true + } + } + + if !valid { + check.error(clause.Comm.Pos(), "select case must be send or receive (possibly with assignment)") + continue + } + + check.openScope(s, "case") + if clause.Comm != nil { + check.stmt(inner, clause.Comm) + } + check.stmtList(inner, clause.Body) + check.closeScope() + } + + case *ast.ForStmt: + inner |= breakOk | continueOk + check.openScope(s, "for") + defer check.closeScope() + + check.simpleStmt(s.Init) + if s.Cond != nil { + var x operand + check.expr(&x, s.Cond) + if x.mode != invalid && !isBoolean(x.typ) { + check.error(s.Cond.Pos(), "non-boolean condition in for statement") + } + } + check.simpleStmt(s.Post) + // spec: "The init statement may be a short variable + // declaration, but the post statement must not." + if s, _ := s.Post.(*ast.AssignStmt); s != nil && s.Tok == token.DEFINE { + check.softErrorf(s.Pos(), "cannot declare in post statement") + // Don't call useLHS here because we want to use the lhs in + // this erroneous statement so that we don't get errors about + // these lhs variables being declared but not used. + check.use(s.Lhs...) // avoid follow-up errors + } + check.stmt(inner, s.Body) + + case *ast.RangeStmt: + inner |= breakOk | continueOk + check.openScope(s, "for") + defer check.closeScope() + + // check expression to iterate over + var x operand + check.expr(&x, s.X) + + // determine key/value types + var key, val Type + if x.mode != invalid { + switch typ := x.typ.Underlying().(type) { + case *Basic: + if isString(typ) { + key = Typ[Int] + val = universeRune // use 'rune' name + } + case *Array: + key = Typ[Int] + val = typ.elem + case *Slice: + key = Typ[Int] + val = typ.elem + case *Pointer: + if typ, _ := typ.base.Underlying().(*Array); typ != nil { + key = Typ[Int] + val = typ.elem + } + case *Map: + key = typ.key + val = typ.elem + case *Chan: + key = typ.elem + val = Typ[Invalid] + if typ.dir == SendOnly { + check.errorf(x.pos(), "cannot range over send-only channel %s", &x) + // ok to continue + } + if s.Value != nil { + check.errorf(s.Value.Pos(), "iteration over %s permits only one iteration variable", &x) + // ok to continue + } + } + } + + if key == nil { + check.errorf(x.pos(), "cannot range over %s", &x) + // ok to continue + } + + // check assignment to/declaration of iteration variables + // (irregular assignment, cannot easily map to existing assignment checks) + + // lhs expressions and initialization value (rhs) types + lhs := [2]ast.Expr{s.Key, s.Value} + rhs := [2]Type{key, val} // key, val may be nil + + if s.Tok == token.DEFINE { + // short variable declaration; variable scope starts after the range clause + // (the for loop opens a new scope, so variables on the lhs never redeclare + // previously declared variables) + var vars []*Var + for i, lhs := range lhs { + if lhs == nil { + continue + } + + // determine lhs variable + var obj *Var + if ident, _ := lhs.(*ast.Ident); ident != nil { + // declare new variable + name := ident.Name + obj = NewVar(ident.Pos(), check.pkg, name, nil) + check.recordDef(ident, obj) + // _ variables don't count as new variables + if name != "_" { + vars = append(vars, obj) + } + } else { + check.errorf(lhs.Pos(), "cannot declare %s", lhs) + obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable + } + + // initialize lhs variable + if typ := rhs[i]; typ != nil { + x.mode = value + x.expr = lhs // we don't have a better rhs expression to use here + x.typ = typ + check.initVar(obj, &x, "range clause") + } else { + obj.typ = Typ[Invalid] + obj.used = true // don't complain about unused variable + } + } + + // declare variables + if len(vars) > 0 { + scopePos := s.X.End() + for _, obj := range vars { + // spec: "The scope of a constant or variable identifier declared inside + // a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl + // for short variable declarations) and ends at the end of the innermost + // containing block." + check.declare(check.scope, nil /* recordDef already called */, obj, scopePos) + } + } else { + check.error(s.TokPos, "no new variables on left side of :=") + } + } else { + // ordinary assignment + for i, lhs := range lhs { + if lhs == nil { + continue + } + if typ := rhs[i]; typ != nil { + x.mode = value + x.expr = lhs // we don't have a better rhs expression to use here + x.typ = typ + check.assignVar(lhs, &x) + } + } + } + + check.stmt(inner, s.Body) + + default: + check.error(s.Pos(), "invalid statement") + } +} diff --git a/vendor/go/types/type.go b/vendor/go/types/type.go new file mode 100644 index 000000000..afdbb680f --- /dev/null +++ b/vendor/go/types/type.go @@ -0,0 +1,465 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package types + +import "sort" + +// A Type represents a type of Go. +// All types implement the Type interface. +type Type interface { + // Underlying returns the underlying type of a type. + Underlying() Type + + // String returns a string representation of a type. + String() string +} + +// BasicKind describes the kind of basic type. +type BasicKind int + +const ( + Invalid BasicKind = iota // type is invalid + + // predeclared types + Bool + Int + Int8 + Int16 + Int32 + Int64 + Uint + Uint8 + Uint16 + Uint32 + Uint64 + Uintptr + Float32 + Float64 + Complex64 + Complex128 + String + UnsafePointer + + // types for untyped values + UntypedBool + UntypedInt + UntypedRune + UntypedFloat + UntypedComplex + UntypedString + UntypedNil + + // aliases + Byte = Uint8 + Rune = Int32 +) + +// BasicInfo is a set of flags describing properties of a basic type. +type BasicInfo int + +// Properties of basic types. +const ( + IsBoolean BasicInfo = 1 << iota + IsInteger + IsUnsigned + IsFloat + IsComplex + IsString + IsUntyped + + IsOrdered = IsInteger | IsFloat | IsString + IsNumeric = IsInteger | IsFloat | IsComplex + IsConstType = IsBoolean | IsNumeric | IsString +) + +// A Basic represents a basic type. +type Basic struct { + kind BasicKind + info BasicInfo + name string +} + +// Kind returns the kind of basic type b. +func (b *Basic) Kind() BasicKind { return b.kind } + +// Info returns information about properties of basic type b. +func (b *Basic) Info() BasicInfo { return b.info } + +// Name returns the name of basic type b. +func (b *Basic) Name() string { return b.name } + +// An Array represents an array type. +type Array struct { + len int64 + elem Type +} + +// NewArray returns a new array type for the given element type and length. +// A negative length indicates an unknown length. +func NewArray(elem Type, len int64) *Array { return &Array{len, elem} } + +// Len returns the length of array a. +// A negative result indicates an unknown length. +func (a *Array) Len() int64 { return a.len } + +// Elem returns element type of array a. +func (a *Array) Elem() Type { return a.elem } + +// A Slice represents a slice type. +type Slice struct { + elem Type +} + +// NewSlice returns a new slice type for the given element type. +func NewSlice(elem Type) *Slice { return &Slice{elem} } + +// Elem returns the element type of slice s. +func (s *Slice) Elem() Type { return s.elem } + +// A Struct represents a struct type. +type Struct struct { + fields []*Var + tags []string // field tags; nil if there are no tags +} + +// NewStruct returns a new struct with the given fields and corresponding field tags. +// If a field with index i has a tag, tags[i] must be that tag, but len(tags) may be +// only as long as required to hold the tag with the largest index i. Consequently, +// if no field has a tag, tags may be nil. +func NewStruct(fields []*Var, tags []string) *Struct { + var fset objset + for _, f := range fields { + if f.name != "_" && fset.insert(f) != nil { + panic("multiple fields with the same name") + } + } + if len(tags) > len(fields) { + panic("more tags than fields") + } + return &Struct{fields: fields, tags: tags} +} + +// NumFields returns the number of fields in the struct (including blank and anonymous fields). +func (s *Struct) NumFields() int { return len(s.fields) } + +// Field returns the i'th field for 0 <= i < NumFields(). +func (s *Struct) Field(i int) *Var { return s.fields[i] } + +// Tag returns the i'th field tag for 0 <= i < NumFields(). +func (s *Struct) Tag(i int) string { + if i < len(s.tags) { + return s.tags[i] + } + return "" +} + +// A Pointer represents a pointer type. +type Pointer struct { + base Type // element type +} + +// NewPointer returns a new pointer type for the given element (base) type. +func NewPointer(elem Type) *Pointer { return &Pointer{base: elem} } + +// Elem returns the element type for the given pointer p. +func (p *Pointer) Elem() Type { return p.base } + +// A Tuple represents an ordered list of variables; a nil *Tuple is a valid (empty) tuple. +// Tuples are used as components of signatures and to represent the type of multiple +// assignments; they are not first class types of Go. +type Tuple struct { + vars []*Var +} + +// NewTuple returns a new tuple for the given variables. +func NewTuple(x ...*Var) *Tuple { + if len(x) > 0 { + return &Tuple{x} + } + return nil +} + +// Len returns the number variables of tuple t. +func (t *Tuple) Len() int { + if t != nil { + return len(t.vars) + } + return 0 +} + +// At returns the i'th variable of tuple t. +func (t *Tuple) At(i int) *Var { return t.vars[i] } + +// A Signature represents a (non-builtin) function or method type. +// The receiver is ignored when comparing signatures for identity. +type Signature struct { + // We need to keep the scope in Signature (rather than passing it around + // and store it in the Func Object) because when type-checking a function + // literal we call the general type checker which returns a general Type. + // We then unpack the *Signature and use the scope for the literal body. + scope *Scope // function scope, present for package-local signatures + recv *Var // nil if not a method + params *Tuple // (incoming) parameters from left to right; or nil + results *Tuple // (outgoing) results from left to right; or nil + variadic bool // true if the last parameter's type is of the form ...T (or string, for append built-in only) +} + +// NewSignature returns a new function type for the given receiver, parameters, +// and results, either of which may be nil. If variadic is set, the function +// is variadic, it must have at least one parameter, and the last parameter +// must be of unnamed slice type. +func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature { + if variadic { + n := params.Len() + if n == 0 { + panic("types.NewSignature: variadic function must have at least one parameter") + } + if _, ok := params.At(n - 1).typ.(*Slice); !ok { + panic("types.NewSignature: variadic parameter must be of unnamed slice type") + } + } + return &Signature{nil, recv, params, results, variadic} +} + +// Recv returns the receiver of signature s (if a method), or nil if a +// function. It is ignored when comparing signatures for identity. +// +// For an abstract method, Recv returns the enclosing interface either +// as a *Named or an *Interface. Due to embedding, an interface may +// contain methods whose receiver type is a different interface. +func (s *Signature) Recv() *Var { return s.recv } + +// Params returns the parameters of signature s, or nil. +func (s *Signature) Params() *Tuple { return s.params } + +// Results returns the results of signature s, or nil. +func (s *Signature) Results() *Tuple { return s.results } + +// Variadic reports whether the signature s is variadic. +func (s *Signature) Variadic() bool { return s.variadic } + +// An Interface represents an interface type. +type Interface struct { + methods []*Func // ordered list of explicitly declared methods + embeddeds []*Named // ordered list of explicitly embedded types + + allMethods []*Func // ordered list of methods declared with or embedded in this interface (TODO(gri): replace with mset) +} + +// emptyInterface represents the empty (completed) interface +var emptyInterface = Interface{allMethods: markComplete} + +// markComplete is used to mark an empty interface as completely +// set up by setting the allMethods field to a non-nil empty slice. +var markComplete = make([]*Func, 0) + +// NewInterface returns a new (incomplete) interface for the given methods and embedded types. +// NewInterface takes ownership of the provided methods and may modify their types by setting +// missing receivers. To compute the method set of the interface, Complete must be called. +func NewInterface(methods []*Func, embeddeds []*Named) *Interface { + typ := new(Interface) + + if len(methods) == 0 && len(embeddeds) == 0 { + return typ + } + + var mset objset + for _, m := range methods { + if mset.insert(m) != nil { + panic("multiple methods with the same name") + } + // set receiver if we don't have one + if sig := m.typ.(*Signature); sig.recv == nil { + sig.recv = NewVar(m.pos, m.pkg, "", typ) + } + } + sort.Sort(byUniqueMethodName(methods)) + + if embeddeds != nil { + sort.Sort(byUniqueTypeName(embeddeds)) + } + + typ.methods = methods + typ.embeddeds = embeddeds + return typ +} + +// NumExplicitMethods returns the number of explicitly declared methods of interface t. +func (t *Interface) NumExplicitMethods() int { return len(t.methods) } + +// ExplicitMethod returns the i'th explicitly declared method of interface t for 0 <= i < t.NumExplicitMethods(). +// The methods are ordered by their unique Id. +func (t *Interface) ExplicitMethod(i int) *Func { return t.methods[i] } + +// NumEmbeddeds returns the number of embedded types in interface t. +func (t *Interface) NumEmbeddeds() int { return len(t.embeddeds) } + +// Embedded returns the i'th embedded type of interface t for 0 <= i < t.NumEmbeddeds(). +// The types are ordered by the corresponding TypeName's unique Id. +func (t *Interface) Embedded(i int) *Named { return t.embeddeds[i] } + +// NumMethods returns the total number of methods of interface t. +func (t *Interface) NumMethods() int { return len(t.allMethods) } + +// Method returns the i'th method of interface t for 0 <= i < t.NumMethods(). +// The methods are ordered by their unique Id. +func (t *Interface) Method(i int) *Func { return t.allMethods[i] } + +// Empty returns true if t is the empty interface. +func (t *Interface) Empty() bool { return len(t.allMethods) == 0 } + +// Complete computes the interface's method set. It must be called by users of +// NewInterface after the interface's embedded types are fully defined and +// before using the interface type in any way other than to form other types. +// Complete returns the receiver. +func (t *Interface) Complete() *Interface { + if t.allMethods != nil { + return t + } + + var allMethods []*Func + if t.embeddeds == nil { + if t.methods == nil { + allMethods = make([]*Func, 0, 1) + } else { + allMethods = t.methods + } + } else { + allMethods = append(allMethods, t.methods...) + for _, et := range t.embeddeds { + it := et.Underlying().(*Interface) + it.Complete() + for _, tm := range it.allMethods { + // Make a copy of the method and adjust its receiver type. + newm := *tm + newmtyp := *tm.typ.(*Signature) + newm.typ = &newmtyp + newmtyp.recv = NewVar(newm.pos, newm.pkg, "", t) + allMethods = append(allMethods, &newm) + } + } + sort.Sort(byUniqueMethodName(allMethods)) + } + t.allMethods = allMethods + + return t +} + +// A Map represents a map type. +type Map struct { + key, elem Type +} + +// NewMap returns a new map for the given key and element types. +func NewMap(key, elem Type) *Map { + return &Map{key, elem} +} + +// Key returns the key type of map m. +func (m *Map) Key() Type { return m.key } + +// Elem returns the element type of map m. +func (m *Map) Elem() Type { return m.elem } + +// A Chan represents a channel type. +type Chan struct { + dir ChanDir + elem Type +} + +// A ChanDir value indicates a channel direction. +type ChanDir int + +// The direction of a channel is indicated by one of these constants. +const ( + SendRecv ChanDir = iota + SendOnly + RecvOnly +) + +// NewChan returns a new channel type for the given direction and element type. +func NewChan(dir ChanDir, elem Type) *Chan { + return &Chan{dir, elem} +} + +// Dir returns the direction of channel c. +func (c *Chan) Dir() ChanDir { return c.dir } + +// Elem returns the element type of channel c. +func (c *Chan) Elem() Type { return c.elem } + +// A Named represents a named type. +type Named struct { + obj *TypeName // corresponding declared object + underlying Type // possibly a *Named during setup; never a *Named once set up completely + methods []*Func // methods declared for this type (not the method set of this type) +} + +// NewNamed returns a new named type for the given type name, underlying type, and associated methods. +// If the given type name obj doesn't have a type yet, its type is set to the returned named type. +// The underlying type must not be a *Named. +func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named { + if _, ok := underlying.(*Named); ok { + panic("types.NewNamed: underlying type must not be *Named") + } + typ := &Named{obj: obj, underlying: underlying, methods: methods} + if obj.typ == nil { + obj.typ = typ + } + return typ +} + +// Obj returns the type name for the named type t. +func (t *Named) Obj() *TypeName { return t.obj } + +// NumMethods returns the number of explicit methods whose receiver is named type t. +func (t *Named) NumMethods() int { return len(t.methods) } + +// Method returns the i'th method of named type t for 0 <= i < t.NumMethods(). +func (t *Named) Method(i int) *Func { return t.methods[i] } + +// SetUnderlying sets the underlying type and marks t as complete. +func (t *Named) SetUnderlying(underlying Type) { + if underlying == nil { + panic("types.Named.SetUnderlying: underlying type must not be nil") + } + if _, ok := underlying.(*Named); ok { + panic("types.Named.SetUnderlying: underlying type must not be *Named") + } + t.underlying = underlying +} + +// AddMethod adds method m unless it is already in the method list. +func (t *Named) AddMethod(m *Func) { + if i, _ := lookupMethod(t.methods, m.pkg, m.name); i < 0 { + t.methods = append(t.methods, m) + } +} + +// Implementations for Type methods. + +func (b *Basic) Underlying() Type { return b } +func (a *Array) Underlying() Type { return a } +func (s *Slice) Underlying() Type { return s } +func (s *Struct) Underlying() Type { return s } +func (p *Pointer) Underlying() Type { return p } +func (t *Tuple) Underlying() Type { return t } +func (s *Signature) Underlying() Type { return s } +func (t *Interface) Underlying() Type { return t } +func (m *Map) Underlying() Type { return m } +func (c *Chan) Underlying() Type { return c } +func (t *Named) Underlying() Type { return t.underlying } + +func (b *Basic) String() string { return TypeString(b, nil) } +func (a *Array) String() string { return TypeString(a, nil) } +func (s *Slice) String() string { return TypeString(s, nil) } +func (s *Struct) String() string { return TypeString(s, nil) } +func (p *Pointer) String() string { return TypeString(p, nil) } +func (t *Tuple) String() string { return TypeString(t, nil) } +func (s *Signature) String() string { return TypeString(s, nil) } +func (t *Interface) String() string { return TypeString(t, nil) } +func (m *Map) String() string { return TypeString(m, nil) } +func (c *Chan) String() string { return TypeString(c, nil) } +func (t *Named) String() string { return TypeString(t, nil) } diff --git a/vendor/go/types/typestring.go b/vendor/go/types/typestring.go new file mode 100644 index 000000000..a9c0bfde1 --- /dev/null +++ b/vendor/go/types/typestring.go @@ -0,0 +1,307 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements printing of types. + +package types + +import ( + "bytes" + "fmt" +) + +// A Qualifier controls how named package-level objects are printed in +// calls to TypeString, ObjectString, and SelectionString. +// +// These three formatting routines call the Qualifier for each +// package-level object O, and if the Qualifier returns a non-empty +// string p, the object is printed in the form p.O. +// If it returns an empty string, only the object name O is printed. +// +// Using a nil Qualifier is equivalent to using (*Package).Path: the +// object is qualified by the import path, e.g., "encoding/json.Marshal". +// +type Qualifier func(*Package) string + +// RelativeTo(pkg) returns a Qualifier that fully qualifies members of +// all packages other than pkg. +func RelativeTo(pkg *Package) Qualifier { + if pkg == nil { + return nil + } + return func(other *Package) string { + if pkg == other { + return "" // same package; unqualified + } + return other.Path() + } +} + +// If gcCompatibilityMode is set, printing of types is modified +// to match the representation of some types in the gc compiler: +// +// - byte and rune lose their alias name and simply stand for +// uint8 and int32 respectively +// - embedded interfaces get flattened (the embedding info is lost, +// and certain recursive interface types cannot be printed anymore) +// +// This makes it easier to compare packages computed with the type- +// checker vs packages imported from gc export data. +// +// Caution: This flag affects all uses of WriteType, globally. +// It is only provided for testing in conjunction with +// gc-generated data. +// +// This flag is exported in the x/tools/go/types package. We don't +// need it at the moment in the std repo and so we don't export it +// anymore. We should eventually try to remove it altogether. +// TODO(gri) remove this +var gcCompatibilityMode bool + +// TypeString returns the string representation of typ. +// The Qualifier controls the printing of +// package-level objects, and may be nil. +func TypeString(typ Type, qf Qualifier) string { + var buf bytes.Buffer + WriteType(&buf, typ, qf) + return buf.String() +} + +// WriteType writes the string representation of typ to buf. +// The Qualifier controls the printing of +// package-level objects, and may be nil. +func WriteType(buf *bytes.Buffer, typ Type, qf Qualifier) { + writeType(buf, typ, qf, make([]Type, 0, 8)) +} + +func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) { + // Theoretically, this is a quadratic lookup algorithm, but in + // practice deeply nested composite types with unnamed component + // types are uncommon. This code is likely more efficient than + // using a map. + for _, t := range visited { + if t == typ { + fmt.Fprintf(buf, "○%T", typ) // cycle to typ + return + } + } + visited = append(visited, typ) + + switch t := typ.(type) { + case nil: + buf.WriteString("") + + case *Basic: + if t.kind == UnsafePointer { + buf.WriteString("unsafe.") + } + if gcCompatibilityMode { + // forget the alias names + switch t.kind { + case Byte: + t = Typ[Uint8] + case Rune: + t = Typ[Int32] + } + } + buf.WriteString(t.name) + + case *Array: + fmt.Fprintf(buf, "[%d]", t.len) + writeType(buf, t.elem, qf, visited) + + case *Slice: + buf.WriteString("[]") + writeType(buf, t.elem, qf, visited) + + case *Struct: + buf.WriteString("struct{") + for i, f := range t.fields { + if i > 0 { + buf.WriteString("; ") + } + if !f.anonymous { + buf.WriteString(f.name) + buf.WriteByte(' ') + } + writeType(buf, f.typ, qf, visited) + if tag := t.Tag(i); tag != "" { + fmt.Fprintf(buf, " %q", tag) + } + } + buf.WriteByte('}') + + case *Pointer: + buf.WriteByte('*') + writeType(buf, t.base, qf, visited) + + case *Tuple: + writeTuple(buf, t, false, qf, visited) + + case *Signature: + buf.WriteString("func") + writeSignature(buf, t, qf, visited) + + case *Interface: + // We write the source-level methods and embedded types rather + // than the actual method set since resolved method signatures + // may have non-printable cycles if parameters have anonymous + // interface types that (directly or indirectly) embed the + // current interface. For instance, consider the result type + // of m: + // + // type T interface{ + // m() interface{ T } + // } + // + buf.WriteString("interface{") + empty := true + if gcCompatibilityMode { + // print flattened interface + // (useful to compare against gc-generated interfaces) + for i, m := range t.allMethods { + if i > 0 { + buf.WriteString("; ") + } + buf.WriteString(m.name) + writeSignature(buf, m.typ.(*Signature), qf, visited) + empty = false + } + } else { + // print explicit interface methods and embedded types + for i, m := range t.methods { + if i > 0 { + buf.WriteString("; ") + } + buf.WriteString(m.name) + writeSignature(buf, m.typ.(*Signature), qf, visited) + empty = false + } + for i, typ := range t.embeddeds { + if i > 0 || len(t.methods) > 0 { + buf.WriteString("; ") + } + writeType(buf, typ, qf, visited) + empty = false + } + } + if t.allMethods == nil || len(t.methods) > len(t.allMethods) { + if !empty { + buf.WriteByte(' ') + } + buf.WriteString("/* incomplete */") + } + buf.WriteByte('}') + + case *Map: + buf.WriteString("map[") + writeType(buf, t.key, qf, visited) + buf.WriteByte(']') + writeType(buf, t.elem, qf, visited) + + case *Chan: + var s string + var parens bool + switch t.dir { + case SendRecv: + s = "chan " + // chan (<-chan T) requires parentheses + if c, _ := t.elem.(*Chan); c != nil && c.dir == RecvOnly { + parens = true + } + case SendOnly: + s = "chan<- " + case RecvOnly: + s = "<-chan " + default: + panic("unreachable") + } + buf.WriteString(s) + if parens { + buf.WriteByte('(') + } + writeType(buf, t.elem, qf, visited) + if parens { + buf.WriteByte(')') + } + + case *Named: + s := "" + if obj := t.obj; obj != nil { + if obj.pkg != nil { + writePackage(buf, obj.pkg, qf) + } + // TODO(gri): function-local named types should be displayed + // differently from named types at package level to avoid + // ambiguity. + s = obj.name + } + buf.WriteString(s) + + default: + // For externally defined implementations of Type. + buf.WriteString(t.String()) + } +} + +func writeTuple(buf *bytes.Buffer, tup *Tuple, variadic bool, qf Qualifier, visited []Type) { + buf.WriteByte('(') + if tup != nil { + for i, v := range tup.vars { + if i > 0 { + buf.WriteString(", ") + } + if v.name != "" { + buf.WriteString(v.name) + buf.WriteByte(' ') + } + typ := v.typ + if variadic && i == len(tup.vars)-1 { + if s, ok := typ.(*Slice); ok { + buf.WriteString("...") + typ = s.elem + } else { + // special case: + // append(s, "foo"...) leads to signature func([]byte, string...) + if t, ok := typ.Underlying().(*Basic); !ok || t.kind != String { + panic("internal error: string type expected") + } + writeType(buf, typ, qf, visited) + buf.WriteString("...") + continue + } + } + writeType(buf, typ, qf, visited) + } + } + buf.WriteByte(')') +} + +// WriteSignature writes the representation of the signature sig to buf, +// without a leading "func" keyword. +// The Qualifier controls the printing of +// package-level objects, and may be nil. +func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) { + writeSignature(buf, sig, qf, make([]Type, 0, 8)) +} + +func writeSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier, visited []Type) { + writeTuple(buf, sig.params, sig.variadic, qf, visited) + + n := sig.results.Len() + if n == 0 { + // no result + return + } + + buf.WriteByte(' ') + if n == 1 && sig.results.vars[0].name == "" { + // single unnamed result + writeType(buf, sig.results.vars[0].typ, qf, visited) + return + } + + // multiple or named result(s) + writeTuple(buf, sig.results, false, qf, visited) +} diff --git a/vendor/go/types/typexpr.go b/vendor/go/types/typexpr.go new file mode 100644 index 000000000..5e48edef7 --- /dev/null +++ b/vendor/go/types/typexpr.go @@ -0,0 +1,743 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements type-checking of identifiers and type expressions. + +package types + +import ( + "go/ast" + "go/constant" + "go/token" + "sort" + "strconv" +) + +// ident type-checks identifier e and initializes x with the value or type of e. +// If an error occurred, x.mode is set to invalid. +// For the meaning of def and path, see check.typ, below. +// +func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, path []*TypeName) { + x.mode = invalid + x.expr = e + + // Note that we cannot use check.lookup here because the returned scope + // may be different from obj.Parent(). See also Scope.LookupParent doc. + scope, obj := check.scope.LookupParent(e.Name, check.pos) + if obj == nil { + if e.Name == "_" { + check.errorf(e.Pos(), "cannot use _ as value or type") + } else { + check.errorf(e.Pos(), "undeclared name: %s", e.Name) + } + return + } + check.recordUse(e, obj) + + check.objDecl(obj, def, path) + typ := obj.Type() + assert(typ != nil) + + // The object may be dot-imported: If so, remove its package from + // the map of unused dot imports for the respective file scope. + // (This code is only needed for dot-imports. Without them, + // we only have to mark variables, see *Var case below). + if pkg := obj.Pkg(); pkg != check.pkg && pkg != nil { + delete(check.unusedDotImports[scope], pkg) + } + + switch obj := obj.(type) { + case *PkgName: + check.errorf(e.Pos(), "use of package %s not in selector", obj.name) + return + + case *Const: + check.addDeclDep(obj) + if typ == Typ[Invalid] { + return + } + if obj == universeIota { + if check.iota == nil { + check.errorf(e.Pos(), "cannot use iota outside constant declaration") + return + } + x.val = check.iota + } else { + x.val = obj.val + } + assert(x.val != nil) + x.mode = constant_ + + case *TypeName: + x.mode = typexpr + if check.cycle(obj, path, true) { + // maintain x.mode == typexpr despite error + typ = Typ[Invalid] + break + } + + case *Var: + // It's ok to mark non-local variables, but ignore variables + // from other packages to avoid potential race conditions with + // dot-imported variables. + if obj.pkg == check.pkg { + obj.used = true + } + check.addDeclDep(obj) + if typ == Typ[Invalid] { + return + } + x.mode = variable + + case *Func: + check.addDeclDep(obj) + x.mode = value + + case *Builtin: + x.id = obj.id + x.mode = builtin + + case *Nil: + x.mode = value + + default: + unreachable() + } + + x.typ = typ +} + +// cycle reports whether obj appears in path or not. +// If it does, and report is set, it also reports a cycle error. +func (check *Checker) cycle(obj *TypeName, path []*TypeName, report bool) bool { + // (it's ok to iterate forward because each named type appears at most once in path) + for i, prev := range path { + if prev == obj { + if report { + check.errorf(obj.pos, "illegal cycle in declaration of %s", obj.name) + // print cycle + for _, obj := range path[i:] { + check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented + } + check.errorf(obj.Pos(), "\t%s", obj.Name()) + } + return true + } + } + return false +} + +// typExpr type-checks the type expression e and returns its type, or Typ[Invalid]. +// If def != nil, e is the type specification for the named type def, declared +// in a type declaration, and def.underlying will be set to the type of e before +// any components of e are type-checked. Path contains the path of named types +// referring to this type. +// +func (check *Checker) typExpr(e ast.Expr, def *Named, path []*TypeName) (T Type) { + if trace { + check.trace(e.Pos(), "%s", e) + check.indent++ + defer func() { + check.indent-- + check.trace(e.Pos(), "=> %s", T) + }() + } + + T = check.typExprInternal(e, def, path) + assert(isTyped(T)) + check.recordTypeAndValue(e, typexpr, T, nil) + + return +} + +func (check *Checker) typ(e ast.Expr) Type { + return check.typExpr(e, nil, nil) +} + +// funcType type-checks a function or method type. +func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) { + scope := NewScope(check.scope, token.NoPos, token.NoPos, "function") + scope.isFunc = true + check.recordScope(ftyp, scope) + + recvList, _ := check.collectParams(scope, recvPar, false) + params, variadic := check.collectParams(scope, ftyp.Params, true) + results, _ := check.collectParams(scope, ftyp.Results, false) + + if recvPar != nil { + // recv parameter list present (may be empty) + // spec: "The receiver is specified via an extra parameter section preceding the + // method name. That parameter section must declare a single parameter, the receiver." + var recv *Var + switch len(recvList) { + case 0: + check.error(recvPar.Pos(), "method is missing receiver") + recv = NewParam(0, nil, "", Typ[Invalid]) // ignore recv below + default: + // more than one receiver + check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver") + fallthrough // continue with first receiver + case 1: + recv = recvList[0] + } + // spec: "The receiver type must be of the form T or *T where T is a type name." + // (ignore invalid types - error was reported before) + if t, _ := deref(recv.typ); t != Typ[Invalid] { + var err string + if T, _ := t.(*Named); T != nil { + // spec: "The type denoted by T is called the receiver base type; it must not + // be a pointer or interface type and it must be declared in the same package + // as the method." + if T.obj.pkg != check.pkg { + err = "type not defined in this package" + } else { + // TODO(gri) This is not correct if the underlying type is unknown yet. + switch u := T.underlying.(type) { + case *Basic: + // unsafe.Pointer is treated like a regular pointer + if u.kind == UnsafePointer { + err = "unsafe.Pointer" + } + case *Pointer, *Interface: + err = "pointer or interface type" + } + } + } else { + err = "basic or unnamed type" + } + if err != "" { + check.errorf(recv.pos, "invalid receiver %s (%s)", recv.typ, err) + // ok to continue + } + } + sig.recv = recv + } + + sig.scope = scope + sig.params = NewTuple(params...) + sig.results = NewTuple(results...) + sig.variadic = variadic +} + +// typExprInternal drives type checking of types. +// Must only be called by typExpr. +// +func (check *Checker) typExprInternal(e ast.Expr, def *Named, path []*TypeName) Type { + switch e := e.(type) { + case *ast.BadExpr: + // ignore - error reported before + + case *ast.Ident: + var x operand + check.ident(&x, e, def, path) + + switch x.mode { + case typexpr: + typ := x.typ + def.setUnderlying(typ) + return typ + case invalid: + // ignore - error reported before + case novalue: + check.errorf(x.pos(), "%s used as type", &x) + default: + check.errorf(x.pos(), "%s is not a type", &x) + } + + case *ast.SelectorExpr: + var x operand + check.selector(&x, e) + + switch x.mode { + case typexpr: + typ := x.typ + def.setUnderlying(typ) + return typ + case invalid: + // ignore - error reported before + case novalue: + check.errorf(x.pos(), "%s used as type", &x) + default: + check.errorf(x.pos(), "%s is not a type", &x) + } + + case *ast.ParenExpr: + return check.typExpr(e.X, def, path) + + case *ast.ArrayType: + if e.Len != nil { + typ := new(Array) + def.setUnderlying(typ) + typ.len = check.arrayLength(e.Len) + typ.elem = check.typExpr(e.Elt, nil, path) + return typ + + } else { + typ := new(Slice) + def.setUnderlying(typ) + typ.elem = check.typ(e.Elt) + return typ + } + + case *ast.StructType: + typ := new(Struct) + def.setUnderlying(typ) + check.structType(typ, e, path) + return typ + + case *ast.StarExpr: + typ := new(Pointer) + def.setUnderlying(typ) + typ.base = check.typ(e.X) + return typ + + case *ast.FuncType: + typ := new(Signature) + def.setUnderlying(typ) + check.funcType(typ, nil, e) + return typ + + case *ast.InterfaceType: + typ := new(Interface) + def.setUnderlying(typ) + check.interfaceType(typ, e, def, path) + return typ + + case *ast.MapType: + typ := new(Map) + def.setUnderlying(typ) + + typ.key = check.typ(e.Key) + typ.elem = check.typ(e.Value) + + // spec: "The comparison operators == and != must be fully defined + // for operands of the key type; thus the key type must not be a + // function, map, or slice." + // + // Delay this check because it requires fully setup types; + // it is safe to continue in any case (was issue 6667). + check.later(func() { + if !Comparable(typ.key) { + check.errorf(e.Key.Pos(), "invalid map key type %s", typ.key) + } + }) + + return typ + + case *ast.ChanType: + typ := new(Chan) + def.setUnderlying(typ) + + dir := SendRecv + switch e.Dir { + case ast.SEND | ast.RECV: + // nothing to do + case ast.SEND: + dir = SendOnly + case ast.RECV: + dir = RecvOnly + default: + check.invalidAST(e.Pos(), "unknown channel direction %d", e.Dir) + // ok to continue + } + + typ.dir = dir + typ.elem = check.typ(e.Value) + return typ + + default: + check.errorf(e.Pos(), "%s is not a type", e) + } + + typ := Typ[Invalid] + def.setUnderlying(typ) + return typ +} + +// typeOrNil type-checks the type expression (or nil value) e +// and returns the typ of e, or nil. +// If e is neither a type nor nil, typOrNil returns Typ[Invalid]. +// +func (check *Checker) typOrNil(e ast.Expr) Type { + var x operand + check.rawExpr(&x, e, nil) + switch x.mode { + case invalid: + // ignore - error reported before + case novalue: + check.errorf(x.pos(), "%s used as type", &x) + case typexpr: + return x.typ + case value: + if x.isNil() { + return nil + } + fallthrough + default: + check.errorf(x.pos(), "%s is not a type", &x) + } + return Typ[Invalid] +} + +// arrayLength type-checks the array length expression e +// and returns the constant length >= 0, or a value < 0 +// to indicate an error (and thus an unknown length). +func (check *Checker) arrayLength(e ast.Expr) int64 { + var x operand + check.expr(&x, e) + if x.mode != constant_ { + if x.mode != invalid { + check.errorf(x.pos(), "array length %s must be constant", &x) + } + return -1 + } + if isUntyped(x.typ) || isInteger(x.typ) { + if val := constant.ToInt(x.val); val.Kind() == constant.Int { + if representableConst(val, check.conf, Typ[Int], nil) { + if n, ok := constant.Int64Val(val); ok && n >= 0 { + return n + } + check.errorf(x.pos(), "invalid array length %s", &x) + return -1 + } + } + } + check.errorf(x.pos(), "array length %s must be integer", &x) + return -1 +} + +func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, variadic bool) { + if list == nil { + return + } + + var named, anonymous bool + for i, field := range list.List { + ftype := field.Type + if t, _ := ftype.(*ast.Ellipsis); t != nil { + ftype = t.Elt + if variadicOk && i == len(list.List)-1 { + variadic = true + } else { + check.invalidAST(field.Pos(), "... not permitted") + // ignore ... and continue + } + } + typ := check.typ(ftype) + // The parser ensures that f.Tag is nil and we don't + // care if a constructed AST contains a non-nil tag. + if len(field.Names) > 0 { + // named parameter + for _, name := range field.Names { + if name.Name == "" { + check.invalidAST(name.Pos(), "anonymous parameter") + // ok to continue + } + par := NewParam(name.Pos(), check.pkg, name.Name, typ) + check.declare(scope, name, par, scope.pos) + params = append(params, par) + } + named = true + } else { + // anonymous parameter + par := NewParam(ftype.Pos(), check.pkg, "", typ) + check.recordImplicit(field, par) + params = append(params, par) + anonymous = true + } + } + + if named && anonymous { + check.invalidAST(list.Pos(), "list contains both named and anonymous parameters") + // ok to continue + } + + // For a variadic function, change the last parameter's type from T to []T. + if variadic && len(params) > 0 { + last := params[len(params)-1] + last.typ = &Slice{elem: last.typ} + } + + return +} + +func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool { + if alt := oset.insert(obj); alt != nil { + check.errorf(pos, "%s redeclared", obj.Name()) + check.reportAltDecl(alt) + return false + } + return true +} + +func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *Named, path []*TypeName) { + // fast-track empty interface + if iface.Methods.List == nil { + ityp.allMethods = markComplete + return + } + + // collect embedded interfaces + // Only needed for printing and API. Delay collection + // to end of type-checking (for package-global interfaces) + // when all types are complete. Local interfaces are handled + // after each statement (as each statement processes delayed + // functions). + interfaceContext := check.context // capture for use in closure below + check.later(func() { + if trace { + check.trace(iface.Pos(), "-- delayed checking embedded interfaces of %v", iface) + check.indent++ + defer func() { + check.indent-- + }() + } + + // The context must be restored since for local interfaces + // delayed functions are processed after each statement + // (was issue #24140). + defer func(ctxt context) { + check.context = ctxt + }(check.context) + check.context = interfaceContext + + for _, f := range iface.Methods.List { + if len(f.Names) == 0 { + typ := check.typ(f.Type) + // typ should be a named type denoting an interface + // (the parser will make sure it's a named type but + // constructed ASTs may be wrong). + if typ == Typ[Invalid] { + continue // error reported before + } + if !isNamed(typ) { + check.invalidAST(f.Type.Pos(), "%s is not a named type", f.Type) + continue + } + embed, _ := typ.Underlying().(*Interface) + if embed == nil { + check.errorf(f.Type.Pos(), "%s is not an interface", typ) + continue + } + // Correct embedded interfaces must be complete - + // don't just assert, but report error since this + // used to be the underlying cause for issue #18395. + if embed.allMethods == nil { + check.dump("%v: incomplete embedded interface %s", f.Type.Pos(), typ) + unreachable() + } + // collect interface + // (at this point we know that typ must be a named, non-basic type) + ityp.embeddeds = append(ityp.embeddeds, typ.(*Named)) + } + } + // sort to match NewInterface + // TODO(gri) we may be able to switch to source order + sort.Sort(byUniqueTypeName(ityp.embeddeds)) + }) + + // compute method set + var tname *TypeName + if def != nil { + tname = def.obj + } + info := check.infoFromTypeLit(check.scope, iface, tname, path) + if info == nil || info == &emptyIfaceInfo { + // error or empty interface - exit early + ityp.allMethods = markComplete + return + } + + // use named receiver type if available (for better error messages) + var recvTyp Type = ityp + if def != nil { + recvTyp = def + } + + // collect methods + var sigfix []*methodInfo + for i, minfo := range info.methods { + fun := minfo.fun + if fun == nil { + name := minfo.src.Names[0] + pos := name.Pos() + // Don't type-check signature yet - use an + // empty signature now and update it later. + // Since we know the receiver, set it up now + // (required to avoid crash in ptrRecv; see + // e.g. test case for issue 6638). + // TODO(gri) Consider marking methods signatures + // as incomplete, for better error messages. See + // also the T4 and T5 tests in testdata/cycles2.src. + sig := new(Signature) + sig.recv = NewVar(pos, check.pkg, "", recvTyp) + fun = NewFunc(pos, check.pkg, name.Name, sig) + minfo.fun = fun + check.recordDef(name, fun) + sigfix = append(sigfix, minfo) + } + // fun != nil + if i < info.explicits { + ityp.methods = append(ityp.methods, fun) + } + ityp.allMethods = append(ityp.allMethods, fun) + } + + // fix signatures now that we have collected all methods + savedContext := check.context + for _, minfo := range sigfix { + // (possibly embedded) methods must be type-checked within their scope and + // type-checking them must not affect the current context (was issue #23914) + check.context = context{scope: minfo.scope} + typ := check.typ(minfo.src.Type) + sig, _ := typ.(*Signature) + if sig == nil { + if typ != Typ[Invalid] { + check.invalidAST(minfo.src.Type.Pos(), "%s is not a method signature", typ) + } + continue // keep method with empty method signature + } + // update signature, but keep recv that was set up before + old := minfo.fun.typ.(*Signature) + sig.recv = old.recv + *old = *sig // update signature (don't replace pointer!) + } + check.context = savedContext + + // sort to match NewInterface + // TODO(gri) we may be able to switch to source order + sort.Sort(byUniqueMethodName(ityp.methods)) + + if ityp.allMethods == nil { + ityp.allMethods = markComplete + } else { + sort.Sort(byUniqueMethodName(ityp.allMethods)) + } +} + +// byUniqueTypeName named type lists can be sorted by their unique type names. +type byUniqueTypeName []*Named + +func (a byUniqueTypeName) Len() int { return len(a) } +func (a byUniqueTypeName) Less(i, j int) bool { return a[i].obj.Id() < a[j].obj.Id() } +func (a byUniqueTypeName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +// byUniqueMethodName method lists can be sorted by their unique method names. +type byUniqueMethodName []*Func + +func (a byUniqueMethodName) Len() int { return len(a) } +func (a byUniqueMethodName) Less(i, j int) bool { return a[i].Id() < a[j].Id() } +func (a byUniqueMethodName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +func (check *Checker) tag(t *ast.BasicLit) string { + if t != nil { + if t.Kind == token.STRING { + if val, err := strconv.Unquote(t.Value); err == nil { + return val + } + } + check.invalidAST(t.Pos(), "incorrect tag syntax: %q", t.Value) + } + return "" +} + +func (check *Checker) structType(styp *Struct, e *ast.StructType, path []*TypeName) { + list := e.Fields + if list == nil { + return + } + + // struct fields and tags + var fields []*Var + var tags []string + + // for double-declaration checks + var fset objset + + // current field typ and tag + var typ Type + var tag string + add := func(ident *ast.Ident, anonymous bool, pos token.Pos) { + if tag != "" && tags == nil { + tags = make([]string, len(fields)) + } + if tags != nil { + tags = append(tags, tag) + } + + name := ident.Name + fld := NewField(pos, check.pkg, name, typ, anonymous) + // spec: "Within a struct, non-blank field names must be unique." + if name == "_" || check.declareInSet(&fset, pos, fld) { + fields = append(fields, fld) + check.recordDef(ident, fld) + } + } + + for _, f := range list.List { + typ = check.typExpr(f.Type, nil, path) + tag = check.tag(f.Tag) + if len(f.Names) > 0 { + // named fields + for _, name := range f.Names { + add(name, false, name.Pos()) + } + } else { + // anonymous field + // spec: "An embedded type must be specified as a type name T or as a pointer + // to a non-interface type name *T, and T itself may not be a pointer type." + pos := f.Type.Pos() + name := anonymousFieldIdent(f.Type) + if name == nil { + check.invalidAST(pos, "anonymous field type %s has no name", f.Type) + continue + } + t, isPtr := deref(typ) + // Because we have a name, typ must be of the form T or *T, where T is the name + // of a (named or alias) type, and t (= deref(typ)) must be the type of T. + switch t := t.Underlying().(type) { + case *Basic: + if t == Typ[Invalid] { + // error was reported before + continue + } + + // unsafe.Pointer is treated like a regular pointer + if t.kind == UnsafePointer { + check.errorf(pos, "anonymous field type cannot be unsafe.Pointer") + continue + } + + case *Pointer: + check.errorf(pos, "anonymous field type cannot be a pointer") + continue + + case *Interface: + if isPtr { + check.errorf(pos, "anonymous field type cannot be a pointer to an interface") + continue + } + } + add(name, true, pos) + } + } + + styp.fields = fields + styp.tags = tags +} + +func anonymousFieldIdent(e ast.Expr) *ast.Ident { + switch e := e.(type) { + case *ast.Ident: + return e + case *ast.StarExpr: + // *T is valid, but **T is not + if _, ok := e.X.(*ast.StarExpr); !ok { + return anonymousFieldIdent(e.X) + } + case *ast.SelectorExpr: + return e.Sel + } + return nil // invalid anonymous field +} diff --git a/vendor/go/types/universe.go b/vendor/go/types/universe.go new file mode 100644 index 000000000..07d7078ae --- /dev/null +++ b/vendor/go/types/universe.go @@ -0,0 +1,229 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file sets up the universe scope and the unsafe package. + +package types + +import ( + "go/constant" + "go/token" + "strings" +) + +var ( + Universe *Scope + Unsafe *Package + universeIota *Const + universeByte *Basic // uint8 alias, but has name "byte" + universeRune *Basic // int32 alias, but has name "rune" +) + +// Typ contains the predeclared *Basic types indexed by their +// corresponding BasicKind. +// +// The *Basic type for Typ[Byte] will have the name "uint8". +// Use Universe.Lookup("byte").Type() to obtain the specific +// alias basic type named "byte" (and analogous for "rune"). +var Typ = []*Basic{ + Invalid: {Invalid, 0, "invalid type"}, + + Bool: {Bool, IsBoolean, "bool"}, + Int: {Int, IsInteger, "int"}, + Int8: {Int8, IsInteger, "int8"}, + Int16: {Int16, IsInteger, "int16"}, + Int32: {Int32, IsInteger, "int32"}, + Int64: {Int64, IsInteger, "int64"}, + Uint: {Uint, IsInteger | IsUnsigned, "uint"}, + Uint8: {Uint8, IsInteger | IsUnsigned, "uint8"}, + Uint16: {Uint16, IsInteger | IsUnsigned, "uint16"}, + Uint32: {Uint32, IsInteger | IsUnsigned, "uint32"}, + Uint64: {Uint64, IsInteger | IsUnsigned, "uint64"}, + Uintptr: {Uintptr, IsInteger | IsUnsigned, "uintptr"}, + Float32: {Float32, IsFloat, "float32"}, + Float64: {Float64, IsFloat, "float64"}, + Complex64: {Complex64, IsComplex, "complex64"}, + Complex128: {Complex128, IsComplex, "complex128"}, + String: {String, IsString, "string"}, + UnsafePointer: {UnsafePointer, 0, "Pointer"}, + + UntypedBool: {UntypedBool, IsBoolean | IsUntyped, "untyped bool"}, + UntypedInt: {UntypedInt, IsInteger | IsUntyped, "untyped int"}, + UntypedRune: {UntypedRune, IsInteger | IsUntyped, "untyped rune"}, + UntypedFloat: {UntypedFloat, IsFloat | IsUntyped, "untyped float"}, + UntypedComplex: {UntypedComplex, IsComplex | IsUntyped, "untyped complex"}, + UntypedString: {UntypedString, IsString | IsUntyped, "untyped string"}, + UntypedNil: {UntypedNil, IsUntyped, "untyped nil"}, +} + +var aliases = [...]*Basic{ + {Byte, IsInteger | IsUnsigned, "byte"}, + {Rune, IsInteger, "rune"}, +} + +func defPredeclaredTypes() { + for _, t := range Typ { + def(NewTypeName(token.NoPos, nil, t.name, t)) + } + for _, t := range aliases { + def(NewTypeName(token.NoPos, nil, t.name, t)) + } + + // Error has a nil package in its qualified name since it is in no package + res := NewVar(token.NoPos, nil, "", Typ[String]) + sig := &Signature{results: NewTuple(res)} + err := NewFunc(token.NoPos, nil, "Error", sig) + typ := &Named{underlying: NewInterface([]*Func{err}, nil).Complete()} + sig.recv = NewVar(token.NoPos, nil, "", typ) + def(NewTypeName(token.NoPos, nil, "error", typ)) +} + +var predeclaredConsts = [...]struct { + name string + kind BasicKind + val constant.Value +}{ + {"true", UntypedBool, constant.MakeBool(true)}, + {"false", UntypedBool, constant.MakeBool(false)}, + {"iota", UntypedInt, constant.MakeInt64(0)}, +} + +func defPredeclaredConsts() { + for _, c := range predeclaredConsts { + def(NewConst(token.NoPos, nil, c.name, Typ[c.kind], c.val)) + } +} + +func defPredeclaredNil() { + def(&Nil{object{name: "nil", typ: Typ[UntypedNil]}}) +} + +// A builtinId is the id of a builtin function. +type builtinId int + +const ( + // universe scope + _Append builtinId = iota + _Cap + _Close + _Complex + _Copy + _Delete + _Imag + _Len + _Make + _New + _Panic + _Print + _Println + _Real + _Recover + + // package unsafe + _Alignof + _Offsetof + _Sizeof + + // testing support + _Assert + _Trace +) + +var predeclaredFuncs = [...]struct { + name string + nargs int + variadic bool + kind exprKind +}{ + _Append: {"append", 1, true, expression}, + _Cap: {"cap", 1, false, expression}, + _Close: {"close", 1, false, statement}, + _Complex: {"complex", 2, false, expression}, + _Copy: {"copy", 2, false, statement}, + _Delete: {"delete", 2, false, statement}, + _Imag: {"imag", 1, false, expression}, + _Len: {"len", 1, false, expression}, + _Make: {"make", 1, true, expression}, + _New: {"new", 1, false, expression}, + _Panic: {"panic", 1, false, statement}, + _Print: {"print", 0, true, statement}, + _Println: {"println", 0, true, statement}, + _Real: {"real", 1, false, expression}, + _Recover: {"recover", 0, false, statement}, + + _Alignof: {"Alignof", 1, false, expression}, + _Offsetof: {"Offsetof", 1, false, expression}, + _Sizeof: {"Sizeof", 1, false, expression}, + + _Assert: {"assert", 1, false, statement}, + _Trace: {"trace", 0, true, statement}, +} + +func defPredeclaredFuncs() { + for i := range predeclaredFuncs { + id := builtinId(i) + if id == _Assert || id == _Trace { + continue // only define these in testing environment + } + def(newBuiltin(id)) + } +} + +// DefPredeclaredTestFuncs defines the assert and trace built-ins. +// These built-ins are intended for debugging and testing of this +// package only. +func DefPredeclaredTestFuncs() { + if Universe.Lookup("assert") != nil { + return // already defined + } + def(newBuiltin(_Assert)) + def(newBuiltin(_Trace)) +} + +func init() { + Universe = NewScope(nil, token.NoPos, token.NoPos, "universe") + Unsafe = NewPackage("unsafe", "unsafe") + Unsafe.complete = true + + defPredeclaredTypes() + defPredeclaredConsts() + defPredeclaredNil() + defPredeclaredFuncs() + + universeIota = Universe.Lookup("iota").(*Const) + universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic) + universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic) +} + +// Objects with names containing blanks are internal and not entered into +// a scope. Objects with exported names are inserted in the unsafe package +// scope; other objects are inserted in the universe scope. +// +func def(obj Object) { + name := obj.Name() + if strings.Contains(name, " ") { + return // nothing to do + } + // fix Obj link for named types + if typ, ok := obj.Type().(*Named); ok { + typ.obj = obj.(*TypeName) + } + // exported identifiers go into package unsafe + scope := Universe + if obj.Exported() { + scope = Unsafe.scope + // set Pkg field + switch obj := obj.(type) { + case *TypeName: + obj.pkg = Unsafe + case *Builtin: + obj.pkg = Unsafe + default: + unreachable() + } + } + if scope.Insert(obj) != nil { + panic("internal error: double declaration") + } +} diff --git a/vendor/golang.org/x/tools/LICENSE b/vendor/golang.org/x/tools/LICENSE new file mode 100644 index 000000000..6a66aea5e --- /dev/null +++ b/vendor/golang.org/x/tools/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/tools/PATENTS b/vendor/golang.org/x/tools/PATENTS new file mode 100644 index 000000000..733099041 --- /dev/null +++ b/vendor/golang.org/x/tools/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go new file mode 100644 index 000000000..b44bdbfcf --- /dev/null +++ b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go @@ -0,0 +1,97 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package gcexportdata provides functions for locating, reading, and +// writing export data files containing type information produced by the +// gc compiler. This package supports go1.7 export data format and all +// later versions. +// +// Although it might seem convenient for this package to live alongside +// go/types in the standard library, this would cause version skew +// problems for developer tools that use it, since they must be able to +// consume the outputs of the gc compiler both before and after a Go +// update such as from Go 1.7 to Go 1.8. Because this package lives in +// golang.org/x/tools, sites can update their version of this repo some +// time before the Go 1.8 release and rebuild and redeploy their +// developer tools, which will then be able to consume both Go 1.7 and +// Go 1.8 export data files, so they will work before and after the +// Go update. (See discussion at https://github.com/golang/go/issues/15651.) +// +package gcexportdata // import "golang.org/x/tools/go/gcexportdata" + +import ( + "bufio" + "bytes" + "fmt" + "go/token" + "go/types" + "io" + "io/ioutil" + + "golang.org/x/tools/go/internal/gcimporter" +) + +// Find returns the name of an object (.o) or archive (.a) file +// containing type information for the specified import path, +// using the workspace layout conventions of go/build. +// If no file was found, an empty filename is returned. +// +// A relative srcDir is interpreted relative to the current working directory. +// +// Find also returns the package's resolved (canonical) import path, +// reflecting the effects of srcDir and vendoring on importPath. +func Find(importPath, srcDir string) (filename, path string) { + return gcimporter.FindPkg(importPath, srcDir) +} + +// NewReader returns a reader for the export data section of an object +// (.o) or archive (.a) file read from r. The new reader may provide +// additional trailing data beyond the end of the export data. +func NewReader(r io.Reader) (io.Reader, error) { + buf := bufio.NewReader(r) + _, err := gcimporter.FindExportData(buf) + // If we ever switch to a zip-like archive format with the ToC + // at the end, we can return the correct portion of export data, + // but for now we must return the entire rest of the file. + return buf, err +} + +// Read reads export data from in, decodes it, and returns type +// information for the package. +// The package name is specified by path. +// File position information is added to fset. +// +// Read may inspect and add to the imports map to ensure that references +// within the export data to other packages are consistent. The caller +// must ensure that imports[path] does not exist, or exists but is +// incomplete (see types.Package.Complete), and Read inserts the +// resulting package into this map entry. +// +// On return, the state of the reader is undefined. +func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) { + data, err := ioutil.ReadAll(in) + if err != nil { + return nil, fmt.Errorf("reading export data for %q: %v", path, err) + } + + if bytes.HasPrefix(data, []byte("!")) { + return nil, fmt.Errorf("can't read export data for %q directly from an archive file (call gcexportdata.NewReader first to extract export data)", path) + } + + // The App Engine Go runtime v1.6 uses the old export data format. + // TODO(adonovan): delete once v1.7 has been around for a while. + if bytes.HasPrefix(data, []byte("package ")) { + return gcimporter.ImportData(imports, path, path, bytes.NewReader(data)) + } + + _, pkg, err := gcimporter.BImportData(fset, imports, data, path) + return pkg, err +} + +// Write writes encoded type information for the specified package to out. +// The FileSet provides file position information for named objects. +func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error { + _, err := out.Write(gcimporter.BExportData(fset, pkg)) + return err +} diff --git a/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/vendor/golang.org/x/tools/go/gcexportdata/importer.go new file mode 100644 index 000000000..efe221e7e --- /dev/null +++ b/vendor/golang.org/x/tools/go/gcexportdata/importer.go @@ -0,0 +1,73 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gcexportdata + +import ( + "fmt" + "go/token" + "go/types" + "os" +) + +// NewImporter returns a new instance of the types.Importer interface +// that reads type information from export data files written by gc. +// The Importer also satisfies types.ImporterFrom. +// +// Export data files are located using "go build" workspace conventions +// and the build.Default context. +// +// Use this importer instead of go/importer.For("gc", ...) to avoid the +// version-skew problems described in the documentation of this package, +// or to control the FileSet or access the imports map populated during +// package loading. +// +func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { + return importer{fset, imports} +} + +type importer struct { + fset *token.FileSet + imports map[string]*types.Package +} + +func (imp importer) Import(importPath string) (*types.Package, error) { + return imp.ImportFrom(importPath, "", 0) +} + +func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) { + filename, path := Find(importPath, srcDir) + if filename == "" { + if importPath == "unsafe" { + // Even for unsafe, call Find first in case + // the package was vendored. + return types.Unsafe, nil + } + return nil, fmt.Errorf("can't find import: %s", importPath) + } + + if pkg, ok := imp.imports[path]; ok && pkg.Complete() { + return pkg, nil // cache hit + } + + // open file + f, err := os.Open(filename) + if err != nil { + return nil, err + } + defer func() { + f.Close() + if err != nil { + // add file name to error + err = fmt.Errorf("reading export data: %s: %v", filename, err) + } + }() + + r, err := NewReader(f) + if err != nil { + return nil, err + } + + return Read(r, imp.fset, imp.imports, path) +} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go new file mode 100644 index 000000000..cbf8bc00d --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go @@ -0,0 +1,828 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Binary package export. +// This file was derived from $GOROOT/src/cmd/compile/internal/gc/bexport.go; +// see that file for specification of the format. + +package gcimporter + +import ( + "bytes" + "encoding/binary" + "fmt" + "go/ast" + "go/constant" + "go/token" + "go/types" + "log" + "math" + "math/big" + "sort" + "strings" +) + +// If debugFormat is set, each integer and string value is preceded by a marker +// and position information in the encoding. This mechanism permits an importer +// to recognize immediately when it is out of sync. The importer recognizes this +// mode automatically (i.e., it can import export data produced with debugging +// support even if debugFormat is not set at the time of import). This mode will +// lead to massively larger export data (by a factor of 2 to 3) and should only +// be enabled during development and debugging. +// +// NOTE: This flag is the first flag to enable if importing dies because of +// (suspected) format errors, and whenever a change is made to the format. +const debugFormat = false // default: false + +// If trace is set, debugging output is printed to std out. +const trace = false // default: false + +// Current export format version. Increase with each format change. +// 4: type name objects support type aliases, uses aliasTag +// 3: Go1.8 encoding (same as version 2, aliasTag defined but never used) +// 2: removed unused bool in ODCL export (compiler only) +// 1: header format change (more regular), export package for _ struct fields +// 0: Go1.7 encoding +const exportVersion = 4 + +// trackAllTypes enables cycle tracking for all types, not just named +// types. The existing compiler invariants assume that unnamed types +// that are not completely set up are not used, or else there are spurious +// errors. +// If disabled, only named types are tracked, possibly leading to slightly +// less efficient encoding in rare cases. It also prevents the export of +// some corner-case type declarations (but those are not handled correctly +// with with the textual export format either). +// TODO(gri) enable and remove once issues caused by it are fixed +const trackAllTypes = false + +type exporter struct { + fset *token.FileSet + out bytes.Buffer + + // object -> index maps, indexed in order of serialization + strIndex map[string]int + pkgIndex map[*types.Package]int + typIndex map[types.Type]int + + // position encoding + posInfoFormat bool + prevFile string + prevLine int + + // debugging support + written int // bytes written + indent int // for trace +} + +// BExportData returns binary export data for pkg. +// If no file set is provided, position info will be missing. +func BExportData(fset *token.FileSet, pkg *types.Package) []byte { + p := exporter{ + fset: fset, + strIndex: map[string]int{"": 0}, // empty string is mapped to 0 + pkgIndex: make(map[*types.Package]int), + typIndex: make(map[types.Type]int), + posInfoFormat: true, // TODO(gri) might become a flag, eventually + } + + // write version info + // The version string must start with "version %d" where %d is the version + // number. Additional debugging information may follow after a blank; that + // text is ignored by the importer. + p.rawStringln(fmt.Sprintf("version %d", exportVersion)) + var debug string + if debugFormat { + debug = "debug" + } + p.rawStringln(debug) // cannot use p.bool since it's affected by debugFormat; also want to see this clearly + p.bool(trackAllTypes) + p.bool(p.posInfoFormat) + + // --- generic export data --- + + // populate type map with predeclared "known" types + for index, typ := range predeclared { + p.typIndex[typ] = index + } + if len(p.typIndex) != len(predeclared) { + log.Fatalf("gcimporter: duplicate entries in type map?") + } + + // write package data + p.pkg(pkg, true) + if trace { + p.tracef("\n") + } + + // write objects + objcount := 0 + scope := pkg.Scope() + for _, name := range scope.Names() { + if !ast.IsExported(name) { + continue + } + if trace { + p.tracef("\n") + } + p.obj(scope.Lookup(name)) + objcount++ + } + + // indicate end of list + if trace { + p.tracef("\n") + } + p.tag(endTag) + + // for self-verification only (redundant) + p.int(objcount) + + if trace { + p.tracef("\n") + } + + // --- end of export data --- + + return p.out.Bytes() +} + +func (p *exporter) pkg(pkg *types.Package, emptypath bool) { + if pkg == nil { + log.Fatalf("gcimporter: unexpected nil pkg") + } + + // if we saw the package before, write its index (>= 0) + if i, ok := p.pkgIndex[pkg]; ok { + p.index('P', i) + return + } + + // otherwise, remember the package, write the package tag (< 0) and package data + if trace { + p.tracef("P%d = { ", len(p.pkgIndex)) + defer p.tracef("} ") + } + p.pkgIndex[pkg] = len(p.pkgIndex) + + p.tag(packageTag) + p.string(pkg.Name()) + if emptypath { + p.string("") + } else { + p.string(pkg.Path()) + } +} + +func (p *exporter) obj(obj types.Object) { + switch obj := obj.(type) { + case *types.Const: + p.tag(constTag) + p.pos(obj) + p.qualifiedName(obj) + p.typ(obj.Type()) + p.value(obj.Val()) + + case *types.TypeName: + if isAlias(obj) { + p.tag(aliasTag) + p.pos(obj) + p.qualifiedName(obj) + } else { + p.tag(typeTag) + } + p.typ(obj.Type()) + + case *types.Var: + p.tag(varTag) + p.pos(obj) + p.qualifiedName(obj) + p.typ(obj.Type()) + + case *types.Func: + p.tag(funcTag) + p.pos(obj) + p.qualifiedName(obj) + sig := obj.Type().(*types.Signature) + p.paramList(sig.Params(), sig.Variadic()) + p.paramList(sig.Results(), false) + + default: + log.Fatalf("gcimporter: unexpected object %v (%T)", obj, obj) + } +} + +func (p *exporter) pos(obj types.Object) { + if !p.posInfoFormat { + return + } + + file, line := p.fileLine(obj) + if file == p.prevFile { + // common case: write line delta + // delta == 0 means different file or no line change + delta := line - p.prevLine + p.int(delta) + if delta == 0 { + p.int(-1) // -1 means no file change + } + } else { + // different file + p.int(0) + // Encode filename as length of common prefix with previous + // filename, followed by (possibly empty) suffix. Filenames + // frequently share path prefixes, so this can save a lot + // of space and make export data size less dependent on file + // path length. The suffix is unlikely to be empty because + // file names tend to end in ".go". + n := commonPrefixLen(p.prevFile, file) + p.int(n) // n >= 0 + p.string(file[n:]) // write suffix only + p.prevFile = file + p.int(line) + } + p.prevLine = line +} + +func (p *exporter) fileLine(obj types.Object) (file string, line int) { + if p.fset != nil { + pos := p.fset.Position(obj.Pos()) + file = pos.Filename + line = pos.Line + } + return +} + +func commonPrefixLen(a, b string) int { + if len(a) > len(b) { + a, b = b, a + } + // len(a) <= len(b) + i := 0 + for i < len(a) && a[i] == b[i] { + i++ + } + return i +} + +func (p *exporter) qualifiedName(obj types.Object) { + p.string(obj.Name()) + p.pkg(obj.Pkg(), false) +} + +func (p *exporter) typ(t types.Type) { + if t == nil { + log.Fatalf("gcimporter: nil type") + } + + // Possible optimization: Anonymous pointer types *T where + // T is a named type are common. We could canonicalize all + // such types *T to a single type PT = *T. This would lead + // to at most one *T entry in typIndex, and all future *T's + // would be encoded as the respective index directly. Would + // save 1 byte (pointerTag) per *T and reduce the typIndex + // size (at the cost of a canonicalization map). We can do + // this later, without encoding format change. + + // if we saw the type before, write its index (>= 0) + if i, ok := p.typIndex[t]; ok { + p.index('T', i) + return + } + + // otherwise, remember the type, write the type tag (< 0) and type data + if trackAllTypes { + if trace { + p.tracef("T%d = {>\n", len(p.typIndex)) + defer p.tracef("<\n} ") + } + p.typIndex[t] = len(p.typIndex) + } + + switch t := t.(type) { + case *types.Named: + if !trackAllTypes { + // if we don't track all types, track named types now + p.typIndex[t] = len(p.typIndex) + } + + p.tag(namedTag) + p.pos(t.Obj()) + p.qualifiedName(t.Obj()) + p.typ(t.Underlying()) + if !types.IsInterface(t) { + p.assocMethods(t) + } + + case *types.Array: + p.tag(arrayTag) + p.int64(t.Len()) + p.typ(t.Elem()) + + case *types.Slice: + p.tag(sliceTag) + p.typ(t.Elem()) + + case *dddSlice: + p.tag(dddTag) + p.typ(t.elem) + + case *types.Struct: + p.tag(structTag) + p.fieldList(t) + + case *types.Pointer: + p.tag(pointerTag) + p.typ(t.Elem()) + + case *types.Signature: + p.tag(signatureTag) + p.paramList(t.Params(), t.Variadic()) + p.paramList(t.Results(), false) + + case *types.Interface: + p.tag(interfaceTag) + p.iface(t) + + case *types.Map: + p.tag(mapTag) + p.typ(t.Key()) + p.typ(t.Elem()) + + case *types.Chan: + p.tag(chanTag) + p.int(int(3 - t.Dir())) // hack + p.typ(t.Elem()) + + default: + log.Fatalf("gcimporter: unexpected type %T: %s", t, t) + } +} + +func (p *exporter) assocMethods(named *types.Named) { + // Sort methods (for determinism). + var methods []*types.Func + for i := 0; i < named.NumMethods(); i++ { + methods = append(methods, named.Method(i)) + } + sort.Sort(methodsByName(methods)) + + p.int(len(methods)) + + if trace && methods != nil { + p.tracef("associated methods {>\n") + } + + for i, m := range methods { + if trace && i > 0 { + p.tracef("\n") + } + + p.pos(m) + name := m.Name() + p.string(name) + if !exported(name) { + p.pkg(m.Pkg(), false) + } + + sig := m.Type().(*types.Signature) + p.paramList(types.NewTuple(sig.Recv()), false) + p.paramList(sig.Params(), sig.Variadic()) + p.paramList(sig.Results(), false) + p.int(0) // dummy value for go:nointerface pragma - ignored by importer + } + + if trace && methods != nil { + p.tracef("<\n} ") + } +} + +type methodsByName []*types.Func + +func (x methodsByName) Len() int { return len(x) } +func (x methodsByName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x methodsByName) Less(i, j int) bool { return x[i].Name() < x[j].Name() } + +func (p *exporter) fieldList(t *types.Struct) { + if trace && t.NumFields() > 0 { + p.tracef("fields {>\n") + defer p.tracef("<\n} ") + } + + p.int(t.NumFields()) + for i := 0; i < t.NumFields(); i++ { + if trace && i > 0 { + p.tracef("\n") + } + p.field(t.Field(i)) + p.string(t.Tag(i)) + } +} + +func (p *exporter) field(f *types.Var) { + if !f.IsField() { + log.Fatalf("gcimporter: field expected") + } + + p.pos(f) + p.fieldName(f) + p.typ(f.Type()) +} + +func (p *exporter) iface(t *types.Interface) { + // TODO(gri): enable importer to load embedded interfaces, + // then emit Embeddeds and ExplicitMethods separately here. + p.int(0) + + n := t.NumMethods() + if trace && n > 0 { + p.tracef("methods {>\n") + defer p.tracef("<\n} ") + } + p.int(n) + for i := 0; i < n; i++ { + if trace && i > 0 { + p.tracef("\n") + } + p.method(t.Method(i)) + } +} + +func (p *exporter) method(m *types.Func) { + sig := m.Type().(*types.Signature) + if sig.Recv() == nil { + log.Fatalf("gcimporter: method expected") + } + + p.pos(m) + p.string(m.Name()) + if m.Name() != "_" && !ast.IsExported(m.Name()) { + p.pkg(m.Pkg(), false) + } + + // interface method; no need to encode receiver. + p.paramList(sig.Params(), sig.Variadic()) + p.paramList(sig.Results(), false) +} + +func (p *exporter) fieldName(f *types.Var) { + name := f.Name() + + if f.Anonymous() { + // anonymous field - we distinguish between 3 cases: + // 1) field name matches base type name and is exported + // 2) field name matches base type name and is not exported + // 3) field name doesn't match base type name (alias name) + bname := basetypeName(f.Type()) + if name == bname { + if ast.IsExported(name) { + name = "" // 1) we don't need to know the field name or package + } else { + name = "?" // 2) use unexported name "?" to force package export + } + } else { + // 3) indicate alias and export name as is + // (this requires an extra "@" but this is a rare case) + p.string("@") + } + } + + p.string(name) + if name != "" && !ast.IsExported(name) { + p.pkg(f.Pkg(), false) + } +} + +func basetypeName(typ types.Type) string { + switch typ := deref(typ).(type) { + case *types.Basic: + return typ.Name() + case *types.Named: + return typ.Obj().Name() + default: + return "" // unnamed type + } +} + +func (p *exporter) paramList(params *types.Tuple, variadic bool) { + // use negative length to indicate unnamed parameters + // (look at the first parameter only since either all + // names are present or all are absent) + n := params.Len() + if n > 0 && params.At(0).Name() == "" { + n = -n + } + p.int(n) + for i := 0; i < params.Len(); i++ { + q := params.At(i) + t := q.Type() + if variadic && i == params.Len()-1 { + t = &dddSlice{t.(*types.Slice).Elem()} + } + p.typ(t) + if n > 0 { + name := q.Name() + p.string(name) + if name != "_" { + p.pkg(q.Pkg(), false) + } + } + p.string("") // no compiler-specific info + } +} + +func (p *exporter) value(x constant.Value) { + if trace { + p.tracef("= ") + } + + switch x.Kind() { + case constant.Bool: + tag := falseTag + if constant.BoolVal(x) { + tag = trueTag + } + p.tag(tag) + + case constant.Int: + if v, exact := constant.Int64Val(x); exact { + // common case: x fits into an int64 - use compact encoding + p.tag(int64Tag) + p.int64(v) + return + } + // uncommon case: large x - use float encoding + // (powers of 2 will be encoded efficiently with exponent) + p.tag(floatTag) + p.float(constant.ToFloat(x)) + + case constant.Float: + p.tag(floatTag) + p.float(x) + + case constant.Complex: + p.tag(complexTag) + p.float(constant.Real(x)) + p.float(constant.Imag(x)) + + case constant.String: + p.tag(stringTag) + p.string(constant.StringVal(x)) + + case constant.Unknown: + // package contains type errors + p.tag(unknownTag) + + default: + log.Fatalf("gcimporter: unexpected value %v (%T)", x, x) + } +} + +func (p *exporter) float(x constant.Value) { + if x.Kind() != constant.Float { + log.Fatalf("gcimporter: unexpected constant %v, want float", x) + } + // extract sign (there is no -0) + sign := constant.Sign(x) + if sign == 0 { + // x == 0 + p.int(0) + return + } + // x != 0 + + var f big.Float + if v, exact := constant.Float64Val(x); exact { + // float64 + f.SetFloat64(v) + } else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int { + // TODO(gri): add big.Rat accessor to constant.Value. + r := valueToRat(num) + f.SetRat(r.Quo(r, valueToRat(denom))) + } else { + // Value too large to represent as a fraction => inaccessible. + // TODO(gri): add big.Float accessor to constant.Value. + f.SetFloat64(math.MaxFloat64) // FIXME + } + + // extract exponent such that 0.5 <= m < 1.0 + var m big.Float + exp := f.MantExp(&m) + + // extract mantissa as *big.Int + // - set exponent large enough so mant satisfies mant.IsInt() + // - get *big.Int from mant + m.SetMantExp(&m, int(m.MinPrec())) + mant, acc := m.Int(nil) + if acc != big.Exact { + log.Fatalf("gcimporter: internal error") + } + + p.int(sign) + p.int(exp) + p.string(string(mant.Bytes())) +} + +func valueToRat(x constant.Value) *big.Rat { + // Convert little-endian to big-endian. + // I can't believe this is necessary. + bytes := constant.Bytes(x) + for i := 0; i < len(bytes)/2; i++ { + bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i] + } + return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes)) +} + +func (p *exporter) bool(b bool) bool { + if trace { + p.tracef("[") + defer p.tracef("= %v] ", b) + } + + x := 0 + if b { + x = 1 + } + p.int(x) + return b +} + +// ---------------------------------------------------------------------------- +// Low-level encoders + +func (p *exporter) index(marker byte, index int) { + if index < 0 { + log.Fatalf("gcimporter: invalid index < 0") + } + if debugFormat { + p.marker('t') + } + if trace { + p.tracef("%c%d ", marker, index) + } + p.rawInt64(int64(index)) +} + +func (p *exporter) tag(tag int) { + if tag >= 0 { + log.Fatalf("gcimporter: invalid tag >= 0") + } + if debugFormat { + p.marker('t') + } + if trace { + p.tracef("%s ", tagString[-tag]) + } + p.rawInt64(int64(tag)) +} + +func (p *exporter) int(x int) { + p.int64(int64(x)) +} + +func (p *exporter) int64(x int64) { + if debugFormat { + p.marker('i') + } + if trace { + p.tracef("%d ", x) + } + p.rawInt64(x) +} + +func (p *exporter) string(s string) { + if debugFormat { + p.marker('s') + } + if trace { + p.tracef("%q ", s) + } + // if we saw the string before, write its index (>= 0) + // (the empty string is mapped to 0) + if i, ok := p.strIndex[s]; ok { + p.rawInt64(int64(i)) + return + } + // otherwise, remember string and write its negative length and bytes + p.strIndex[s] = len(p.strIndex) + p.rawInt64(-int64(len(s))) + for i := 0; i < len(s); i++ { + p.rawByte(s[i]) + } +} + +// marker emits a marker byte and position information which makes +// it easy for a reader to detect if it is "out of sync". Used for +// debugFormat format only. +func (p *exporter) marker(m byte) { + p.rawByte(m) + // Enable this for help tracking down the location + // of an incorrect marker when running in debugFormat. + if false && trace { + p.tracef("#%d ", p.written) + } + p.rawInt64(int64(p.written)) +} + +// rawInt64 should only be used by low-level encoders. +func (p *exporter) rawInt64(x int64) { + var tmp [binary.MaxVarintLen64]byte + n := binary.PutVarint(tmp[:], x) + for i := 0; i < n; i++ { + p.rawByte(tmp[i]) + } +} + +// rawStringln should only be used to emit the initial version string. +func (p *exporter) rawStringln(s string) { + for i := 0; i < len(s); i++ { + p.rawByte(s[i]) + } + p.rawByte('\n') +} + +// rawByte is the bottleneck interface to write to p.out. +// rawByte escapes b as follows (any encoding does that +// hides '$'): +// +// '$' => '|' 'S' +// '|' => '|' '|' +// +// Necessary so other tools can find the end of the +// export data by searching for "$$". +// rawByte should only be used by low-level encoders. +func (p *exporter) rawByte(b byte) { + switch b { + case '$': + // write '$' as '|' 'S' + b = 'S' + fallthrough + case '|': + // write '|' as '|' '|' + p.out.WriteByte('|') + p.written++ + } + p.out.WriteByte(b) + p.written++ +} + +// tracef is like fmt.Printf but it rewrites the format string +// to take care of indentation. +func (p *exporter) tracef(format string, args ...interface{}) { + if strings.ContainsAny(format, "<>\n") { + var buf bytes.Buffer + for i := 0; i < len(format); i++ { + // no need to deal with runes + ch := format[i] + switch ch { + case '>': + p.indent++ + continue + case '<': + p.indent-- + continue + } + buf.WriteByte(ch) + if ch == '\n' { + for j := p.indent; j > 0; j-- { + buf.WriteString(". ") + } + } + } + format = buf.String() + } + fmt.Printf(format, args...) +} + +// Debugging support. +// (tagString is only used when tracing is enabled) +var tagString = [...]string{ + // Packages + -packageTag: "package", + + // Types + -namedTag: "named type", + -arrayTag: "array", + -sliceTag: "slice", + -dddTag: "ddd", + -structTag: "struct", + -pointerTag: "pointer", + -signatureTag: "signature", + -interfaceTag: "interface", + -mapTag: "map", + -chanTag: "chan", + + // Values + -falseTag: "false", + -trueTag: "true", + -int64Tag: "int64", + -floatTag: "float", + -fractionTag: "fraction", + -complexTag: "complex", + -stringTag: "string", + -unknownTag: "unknown", + + // Type aliases + -aliasTag: "alias", +} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go new file mode 100644 index 000000000..3e845eafe --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go @@ -0,0 +1,1027 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file is a copy of $GOROOT/src/go/internal/gcimporter/bimport.go. + +package gcimporter + +import ( + "encoding/binary" + "fmt" + "go/constant" + "go/token" + "go/types" + "sort" + "strconv" + "strings" + "sync" + "unicode" + "unicode/utf8" +) + +type importer struct { + imports map[string]*types.Package + data []byte + importpath string + buf []byte // for reading strings + version int // export format version + + // object lists + strList []string // in order of appearance + pathList []string // in order of appearance + pkgList []*types.Package // in order of appearance + typList []types.Type // in order of appearance + interfaceList []*types.Interface // for delayed completion only + trackAllTypes bool + + // position encoding + posInfoFormat bool + prevFile string + prevLine int + fake fakeFileSet + + // debugging support + debugFormat bool + read int // bytes read +} + +// BImportData imports a package from the serialized package data +// and returns the number of bytes consumed and a reference to the package. +// If the export data version is not recognized or the format is otherwise +// compromised, an error is returned. +func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { + // catch panics and return them as errors + defer func() { + if e := recover(); e != nil { + // The package (filename) causing the problem is added to this + // error by a wrapper in the caller (Import in gcimporter.go). + // Return a (possibly nil or incomplete) package unchanged (see #16088). + err = fmt.Errorf("cannot import, possibly version skew (%v) - reinstall package", e) + } + }() + + if len(data) > 0 && data[0] == 'i' { + return iImportData(fset, imports, data[1:], path) + } + + p := importer{ + imports: imports, + data: data, + importpath: path, + version: -1, // unknown version + strList: []string{""}, // empty string is mapped to 0 + pathList: []string{""}, // empty string is mapped to 0 + fake: fakeFileSet{ + fset: fset, + files: make(map[string]*token.File), + }, + } + + // read version info + var versionstr string + if b := p.rawByte(); b == 'c' || b == 'd' { + // Go1.7 encoding; first byte encodes low-level + // encoding format (compact vs debug). + // For backward-compatibility only (avoid problems with + // old installed packages). Newly compiled packages use + // the extensible format string. + // TODO(gri) Remove this support eventually; after Go1.8. + if b == 'd' { + p.debugFormat = true + } + p.trackAllTypes = p.rawByte() == 'a' + p.posInfoFormat = p.int() != 0 + versionstr = p.string() + if versionstr == "v1" { + p.version = 0 + } + } else { + // Go1.8 extensible encoding + // read version string and extract version number (ignore anything after the version number) + versionstr = p.rawStringln(b) + if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" { + if v, err := strconv.Atoi(s[1]); err == nil && v > 0 { + p.version = v + } + } + } + + // read version specific flags - extend as necessary + switch p.version { + // case 7: + // ... + // fallthrough + case 6, 5, 4, 3, 2, 1: + p.debugFormat = p.rawStringln(p.rawByte()) == "debug" + p.trackAllTypes = p.int() != 0 + p.posInfoFormat = p.int() != 0 + case 0: + // Go1.7 encoding format - nothing to do here + default: + errorf("unknown export format version %d (%q)", p.version, versionstr) + } + + // --- generic export data --- + + // populate typList with predeclared "known" types + p.typList = append(p.typList, predeclared...) + + // read package data + pkg = p.pkg() + + // read objects of phase 1 only (see cmd/compile/internal/gc/bexport.go) + objcount := 0 + for { + tag := p.tagOrIndex() + if tag == endTag { + break + } + p.obj(tag) + objcount++ + } + + // self-verification + if count := p.int(); count != objcount { + errorf("got %d objects; want %d", objcount, count) + } + + // ignore compiler-specific import data + + // complete interfaces + // TODO(gri) re-investigate if we still need to do this in a delayed fashion + for _, typ := range p.interfaceList { + typ.Complete() + } + + // record all referenced packages as imports + list := append(([]*types.Package)(nil), p.pkgList[1:]...) + sort.Sort(byPath(list)) + pkg.SetImports(list) + + // package was imported completely and without errors + pkg.MarkComplete() + + return p.read, pkg, nil +} + +func errorf(format string, args ...interface{}) { + panic(fmt.Sprintf(format, args...)) +} + +func (p *importer) pkg() *types.Package { + // if the package was seen before, i is its index (>= 0) + i := p.tagOrIndex() + if i >= 0 { + return p.pkgList[i] + } + + // otherwise, i is the package tag (< 0) + if i != packageTag { + errorf("unexpected package tag %d version %d", i, p.version) + } + + // read package data + name := p.string() + var path string + if p.version >= 5 { + path = p.path() + } else { + path = p.string() + } + if p.version >= 6 { + p.int() // package height; unused by go/types + } + + // we should never see an empty package name + if name == "" { + errorf("empty package name in import") + } + + // an empty path denotes the package we are currently importing; + // it must be the first package we see + if (path == "") != (len(p.pkgList) == 0) { + errorf("package path %q for pkg index %d", path, len(p.pkgList)) + } + + // if the package was imported before, use that one; otherwise create a new one + if path == "" { + path = p.importpath + } + pkg := p.imports[path] + if pkg == nil { + pkg = types.NewPackage(path, name) + p.imports[path] = pkg + } else if pkg.Name() != name { + errorf("conflicting names %s and %s for package %q", pkg.Name(), name, path) + } + p.pkgList = append(p.pkgList, pkg) + + return pkg +} + +// objTag returns the tag value for each object kind. +func objTag(obj types.Object) int { + switch obj.(type) { + case *types.Const: + return constTag + case *types.TypeName: + return typeTag + case *types.Var: + return varTag + case *types.Func: + return funcTag + default: + errorf("unexpected object: %v (%T)", obj, obj) // panics + panic("unreachable") + } +} + +func sameObj(a, b types.Object) bool { + // Because unnamed types are not canonicalized, we cannot simply compare types for + // (pointer) identity. + // Ideally we'd check equality of constant values as well, but this is good enough. + return objTag(a) == objTag(b) && types.Identical(a.Type(), b.Type()) +} + +func (p *importer) declare(obj types.Object) { + pkg := obj.Pkg() + if alt := pkg.Scope().Insert(obj); alt != nil { + // This can only trigger if we import a (non-type) object a second time. + // Excluding type aliases, this cannot happen because 1) we only import a package + // once; and b) we ignore compiler-specific export data which may contain + // functions whose inlined function bodies refer to other functions that + // were already imported. + // However, type aliases require reexporting the original type, so we need + // to allow it (see also the comment in cmd/compile/internal/gc/bimport.go, + // method importer.obj, switch case importing functions). + // TODO(gri) review/update this comment once the gc compiler handles type aliases. + if !sameObj(obj, alt) { + errorf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", obj, alt) + } + } +} + +func (p *importer) obj(tag int) { + switch tag { + case constTag: + pos := p.pos() + pkg, name := p.qualifiedName() + typ := p.typ(nil, nil) + val := p.value() + p.declare(types.NewConst(pos, pkg, name, typ, val)) + + case aliasTag: + // TODO(gri) verify type alias hookup is correct + pos := p.pos() + pkg, name := p.qualifiedName() + typ := p.typ(nil, nil) + p.declare(types.NewTypeName(pos, pkg, name, typ)) + + case typeTag: + p.typ(nil, nil) + + case varTag: + pos := p.pos() + pkg, name := p.qualifiedName() + typ := p.typ(nil, nil) + p.declare(types.NewVar(pos, pkg, name, typ)) + + case funcTag: + pos := p.pos() + pkg, name := p.qualifiedName() + params, isddd := p.paramList() + result, _ := p.paramList() + sig := types.NewSignature(nil, params, result, isddd) + p.declare(types.NewFunc(pos, pkg, name, sig)) + + default: + errorf("unexpected object tag %d", tag) + } +} + +const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go + +func (p *importer) pos() token.Pos { + if !p.posInfoFormat { + return token.NoPos + } + + file := p.prevFile + line := p.prevLine + delta := p.int() + line += delta + if p.version >= 5 { + if delta == deltaNewFile { + if n := p.int(); n >= 0 { + // file changed + file = p.path() + line = n + } + } + } else { + if delta == 0 { + if n := p.int(); n >= 0 { + // file changed + file = p.prevFile[:n] + p.string() + line = p.int() + } + } + } + p.prevFile = file + p.prevLine = line + + return p.fake.pos(file, line) +} + +// Synthesize a token.Pos +type fakeFileSet struct { + fset *token.FileSet + files map[string]*token.File +} + +func (s *fakeFileSet) pos(file string, line int) token.Pos { + // Since we don't know the set of needed file positions, we + // reserve maxlines positions per file. + const maxlines = 64 * 1024 + f := s.files[file] + if f == nil { + f = s.fset.AddFile(file, -1, maxlines) + s.files[file] = f + // Allocate the fake linebreak indices on first use. + // TODO(adonovan): opt: save ~512KB using a more complex scheme? + fakeLinesOnce.Do(func() { + fakeLines = make([]int, maxlines) + for i := range fakeLines { + fakeLines[i] = i + } + }) + f.SetLines(fakeLines) + } + + if line > maxlines { + line = 1 + } + + // Treat the file as if it contained only newlines + // and column=1: use the line number as the offset. + return f.Pos(line - 1) +} + +var ( + fakeLines []int + fakeLinesOnce sync.Once +) + +func (p *importer) qualifiedName() (pkg *types.Package, name string) { + name = p.string() + pkg = p.pkg() + return +} + +func (p *importer) record(t types.Type) { + p.typList = append(p.typList, t) +} + +// A dddSlice is a types.Type representing ...T parameters. +// It only appears for parameter types and does not escape +// the importer. +type dddSlice struct { + elem types.Type +} + +func (t *dddSlice) Underlying() types.Type { return t } +func (t *dddSlice) String() string { return "..." + t.elem.String() } + +// parent is the package which declared the type; parent == nil means +// the package currently imported. The parent package is needed for +// exported struct fields and interface methods which don't contain +// explicit package information in the export data. +// +// A non-nil tname is used as the "owner" of the result type; i.e., +// the result type is the underlying type of tname. tname is used +// to give interface methods a named receiver type where possible. +func (p *importer) typ(parent *types.Package, tname *types.Named) types.Type { + // if the type was seen before, i is its index (>= 0) + i := p.tagOrIndex() + if i >= 0 { + return p.typList[i] + } + + // otherwise, i is the type tag (< 0) + switch i { + case namedTag: + // read type object + pos := p.pos() + parent, name := p.qualifiedName() + scope := parent.Scope() + obj := scope.Lookup(name) + + // if the object doesn't exist yet, create and insert it + if obj == nil { + obj = types.NewTypeName(pos, parent, name, nil) + scope.Insert(obj) + } + + if _, ok := obj.(*types.TypeName); !ok { + errorf("pkg = %s, name = %s => %s", parent, name, obj) + } + + // associate new named type with obj if it doesn't exist yet + t0 := types.NewNamed(obj.(*types.TypeName), nil, nil) + + // but record the existing type, if any + tname := obj.Type().(*types.Named) // tname is either t0 or the existing type + p.record(tname) + + // read underlying type + t0.SetUnderlying(p.typ(parent, t0)) + + // interfaces don't have associated methods + if types.IsInterface(t0) { + return tname + } + + // read associated methods + for i := p.int(); i > 0; i-- { + // TODO(gri) replace this with something closer to fieldName + pos := p.pos() + name := p.string() + if !exported(name) { + p.pkg() + } + + recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver? + params, isddd := p.paramList() + result, _ := p.paramList() + p.int() // go:nointerface pragma - discarded + + sig := types.NewSignature(recv.At(0), params, result, isddd) + t0.AddMethod(types.NewFunc(pos, parent, name, sig)) + } + + return tname + + case arrayTag: + t := new(types.Array) + if p.trackAllTypes { + p.record(t) + } + + n := p.int64() + *t = *types.NewArray(p.typ(parent, nil), n) + return t + + case sliceTag: + t := new(types.Slice) + if p.trackAllTypes { + p.record(t) + } + + *t = *types.NewSlice(p.typ(parent, nil)) + return t + + case dddTag: + t := new(dddSlice) + if p.trackAllTypes { + p.record(t) + } + + t.elem = p.typ(parent, nil) + return t + + case structTag: + t := new(types.Struct) + if p.trackAllTypes { + p.record(t) + } + + *t = *types.NewStruct(p.fieldList(parent)) + return t + + case pointerTag: + t := new(types.Pointer) + if p.trackAllTypes { + p.record(t) + } + + *t = *types.NewPointer(p.typ(parent, nil)) + return t + + case signatureTag: + t := new(types.Signature) + if p.trackAllTypes { + p.record(t) + } + + params, isddd := p.paramList() + result, _ := p.paramList() + *t = *types.NewSignature(nil, params, result, isddd) + return t + + case interfaceTag: + // Create a dummy entry in the type list. This is safe because we + // cannot expect the interface type to appear in a cycle, as any + // such cycle must contain a named type which would have been + // first defined earlier. + // TODO(gri) Is this still true now that we have type aliases? + // See issue #23225. + n := len(p.typList) + if p.trackAllTypes { + p.record(nil) + } + + var embeddeds []*types.Named + for n := p.int(); n > 0; n-- { + p.pos() + embeddeds = append(embeddeds, p.typ(parent, nil).(*types.Named)) + } + + t := types.NewInterface(p.methodList(parent, tname), embeddeds) + p.interfaceList = append(p.interfaceList, t) + if p.trackAllTypes { + p.typList[n] = t + } + return t + + case mapTag: + t := new(types.Map) + if p.trackAllTypes { + p.record(t) + } + + key := p.typ(parent, nil) + val := p.typ(parent, nil) + *t = *types.NewMap(key, val) + return t + + case chanTag: + t := new(types.Chan) + if p.trackAllTypes { + p.record(t) + } + + dir := chanDir(p.int()) + val := p.typ(parent, nil) + *t = *types.NewChan(dir, val) + return t + + default: + errorf("unexpected type tag %d", i) // panics + panic("unreachable") + } +} + +func chanDir(d int) types.ChanDir { + // tag values must match the constants in cmd/compile/internal/gc/go.go + switch d { + case 1 /* Crecv */ : + return types.RecvOnly + case 2 /* Csend */ : + return types.SendOnly + case 3 /* Cboth */ : + return types.SendRecv + default: + errorf("unexpected channel dir %d", d) + return 0 + } +} + +func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags []string) { + if n := p.int(); n > 0 { + fields = make([]*types.Var, n) + tags = make([]string, n) + for i := range fields { + fields[i], tags[i] = p.field(parent) + } + } + return +} + +func (p *importer) field(parent *types.Package) (*types.Var, string) { + pos := p.pos() + pkg, name, alias := p.fieldName(parent) + typ := p.typ(parent, nil) + tag := p.string() + + anonymous := false + if name == "" { + // anonymous field - typ must be T or *T and T must be a type name + switch typ := deref(typ).(type) { + case *types.Basic: // basic types are named types + pkg = nil // // objects defined in Universe scope have no package + name = typ.Name() + case *types.Named: + name = typ.Obj().Name() + default: + errorf("named base type expected") + } + anonymous = true + } else if alias { + // anonymous field: we have an explicit name because it's an alias + anonymous = true + } + + return types.NewField(pos, pkg, name, typ, anonymous), tag +} + +func (p *importer) methodList(parent *types.Package, baseType *types.Named) (methods []*types.Func) { + if n := p.int(); n > 0 { + methods = make([]*types.Func, n) + for i := range methods { + methods[i] = p.method(parent, baseType) + } + } + return +} + +func (p *importer) method(parent *types.Package, baseType *types.Named) *types.Func { + pos := p.pos() + pkg, name, _ := p.fieldName(parent) + // If we don't have a baseType, use a nil receiver. + // A receiver using the actual interface type (which + // we don't know yet) will be filled in when we call + // types.Interface.Complete. + var recv *types.Var + if baseType != nil { + recv = types.NewVar(token.NoPos, parent, "", baseType) + } + params, isddd := p.paramList() + result, _ := p.paramList() + sig := types.NewSignature(recv, params, result, isddd) + return types.NewFunc(pos, pkg, name, sig) +} + +func (p *importer) fieldName(parent *types.Package) (pkg *types.Package, name string, alias bool) { + name = p.string() + pkg = parent + if pkg == nil { + // use the imported package instead + pkg = p.pkgList[0] + } + if p.version == 0 && name == "_" { + // version 0 didn't export a package for _ fields + return + } + switch name { + case "": + // 1) field name matches base type name and is exported: nothing to do + case "?": + // 2) field name matches base type name and is not exported: need package + name = "" + pkg = p.pkg() + case "@": + // 3) field name doesn't match type name (alias) + name = p.string() + alias = true + fallthrough + default: + if !exported(name) { + pkg = p.pkg() + } + } + return +} + +func (p *importer) paramList() (*types.Tuple, bool) { + n := p.int() + if n == 0 { + return nil, false + } + // negative length indicates unnamed parameters + named := true + if n < 0 { + n = -n + named = false + } + // n > 0 + params := make([]*types.Var, n) + isddd := false + for i := range params { + params[i], isddd = p.param(named) + } + return types.NewTuple(params...), isddd +} + +func (p *importer) param(named bool) (*types.Var, bool) { + t := p.typ(nil, nil) + td, isddd := t.(*dddSlice) + if isddd { + t = types.NewSlice(td.elem) + } + + var pkg *types.Package + var name string + if named { + name = p.string() + if name == "" { + errorf("expected named parameter") + } + if name != "_" { + pkg = p.pkg() + } + if i := strings.Index(name, "·"); i > 0 { + name = name[:i] // cut off gc-specific parameter numbering + } + } + + // read and discard compiler-specific info + p.string() + + return types.NewVar(token.NoPos, pkg, name, t), isddd +} + +func exported(name string) bool { + ch, _ := utf8.DecodeRuneInString(name) + return unicode.IsUpper(ch) +} + +func (p *importer) value() constant.Value { + switch tag := p.tagOrIndex(); tag { + case falseTag: + return constant.MakeBool(false) + case trueTag: + return constant.MakeBool(true) + case int64Tag: + return constant.MakeInt64(p.int64()) + case floatTag: + return p.float() + case complexTag: + re := p.float() + im := p.float() + return constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) + case stringTag: + return constant.MakeString(p.string()) + case unknownTag: + return constant.MakeUnknown() + default: + errorf("unexpected value tag %d", tag) // panics + panic("unreachable") + } +} + +func (p *importer) float() constant.Value { + sign := p.int() + if sign == 0 { + return constant.MakeInt64(0) + } + + exp := p.int() + mant := []byte(p.string()) // big endian + + // remove leading 0's if any + for len(mant) > 0 && mant[0] == 0 { + mant = mant[1:] + } + + // convert to little endian + // TODO(gri) go/constant should have a more direct conversion function + // (e.g., once it supports a big.Float based implementation) + for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 { + mant[i], mant[j] = mant[j], mant[i] + } + + // adjust exponent (constant.MakeFromBytes creates an integer value, + // but mant represents the mantissa bits such that 0.5 <= mant < 1.0) + exp -= len(mant) << 3 + if len(mant) > 0 { + for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 { + exp++ + } + } + + x := constant.MakeFromBytes(mant) + switch { + case exp < 0: + d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp)) + x = constant.BinaryOp(x, token.QUO, d) + case exp > 0: + x = constant.Shift(x, token.SHL, uint(exp)) + } + + if sign < 0 { + x = constant.UnaryOp(token.SUB, x, 0) + } + return x +} + +// ---------------------------------------------------------------------------- +// Low-level decoders + +func (p *importer) tagOrIndex() int { + if p.debugFormat { + p.marker('t') + } + + return int(p.rawInt64()) +} + +func (p *importer) int() int { + x := p.int64() + if int64(int(x)) != x { + errorf("exported integer too large") + } + return int(x) +} + +func (p *importer) int64() int64 { + if p.debugFormat { + p.marker('i') + } + + return p.rawInt64() +} + +func (p *importer) path() string { + if p.debugFormat { + p.marker('p') + } + // if the path was seen before, i is its index (>= 0) + // (the empty string is at index 0) + i := p.rawInt64() + if i >= 0 { + return p.pathList[i] + } + // otherwise, i is the negative path length (< 0) + a := make([]string, -i) + for n := range a { + a[n] = p.string() + } + s := strings.Join(a, "/") + p.pathList = append(p.pathList, s) + return s +} + +func (p *importer) string() string { + if p.debugFormat { + p.marker('s') + } + // if the string was seen before, i is its index (>= 0) + // (the empty string is at index 0) + i := p.rawInt64() + if i >= 0 { + return p.strList[i] + } + // otherwise, i is the negative string length (< 0) + if n := int(-i); n <= cap(p.buf) { + p.buf = p.buf[:n] + } else { + p.buf = make([]byte, n) + } + for i := range p.buf { + p.buf[i] = p.rawByte() + } + s := string(p.buf) + p.strList = append(p.strList, s) + return s +} + +func (p *importer) marker(want byte) { + if got := p.rawByte(); got != want { + errorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read) + } + + pos := p.read + if n := int(p.rawInt64()); n != pos { + errorf("incorrect position: got %d; want %d", n, pos) + } +} + +// rawInt64 should only be used by low-level decoders. +func (p *importer) rawInt64() int64 { + i, err := binary.ReadVarint(p) + if err != nil { + errorf("read error: %v", err) + } + return i +} + +// rawStringln should only be used to read the initial version string. +func (p *importer) rawStringln(b byte) string { + p.buf = p.buf[:0] + for b != '\n' { + p.buf = append(p.buf, b) + b = p.rawByte() + } + return string(p.buf) +} + +// needed for binary.ReadVarint in rawInt64 +func (p *importer) ReadByte() (byte, error) { + return p.rawByte(), nil +} + +// byte is the bottleneck interface for reading p.data. +// It unescapes '|' 'S' to '$' and '|' '|' to '|'. +// rawByte should only be used by low-level decoders. +func (p *importer) rawByte() byte { + b := p.data[0] + r := 1 + if b == '|' { + b = p.data[1] + r = 2 + switch b { + case 'S': + b = '$' + case '|': + // nothing to do + default: + errorf("unexpected escape sequence in export data") + } + } + p.data = p.data[r:] + p.read += r + return b + +} + +// ---------------------------------------------------------------------------- +// Export format + +// Tags. Must be < 0. +const ( + // Objects + packageTag = -(iota + 1) + constTag + typeTag + varTag + funcTag + endTag + + // Types + namedTag + arrayTag + sliceTag + dddTag + structTag + pointerTag + signatureTag + interfaceTag + mapTag + chanTag + + // Values + falseTag + trueTag + int64Tag + floatTag + fractionTag // not used by gc + complexTag + stringTag + nilTag // only used by gc (appears in exported inlined function bodies) + unknownTag // not used by gc (only appears in packages with errors) + + // Type aliases + aliasTag +) + +var predeclared = []types.Type{ + // basic types + types.Typ[types.Bool], + types.Typ[types.Int], + types.Typ[types.Int8], + types.Typ[types.Int16], + types.Typ[types.Int32], + types.Typ[types.Int64], + types.Typ[types.Uint], + types.Typ[types.Uint8], + types.Typ[types.Uint16], + types.Typ[types.Uint32], + types.Typ[types.Uint64], + types.Typ[types.Uintptr], + types.Typ[types.Float32], + types.Typ[types.Float64], + types.Typ[types.Complex64], + types.Typ[types.Complex128], + types.Typ[types.String], + + // basic type aliases + types.Universe.Lookup("byte").Type(), + types.Universe.Lookup("rune").Type(), + + // error + types.Universe.Lookup("error").Type(), + + // untyped types + types.Typ[types.UntypedBool], + types.Typ[types.UntypedInt], + types.Typ[types.UntypedRune], + types.Typ[types.UntypedFloat], + types.Typ[types.UntypedComplex], + types.Typ[types.UntypedString], + types.Typ[types.UntypedNil], + + // package unsafe + types.Typ[types.UnsafePointer], + + // invalid type + types.Typ[types.Invalid], // only appears in packages with errors + + // used internally by gc; never used by this package or in .a files + anyType{}, +} + +type anyType struct{} + +func (t anyType) Underlying() types.Type { return t } +func (t anyType) String() string { return "any" } diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go b/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go new file mode 100644 index 000000000..f33dc5613 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go @@ -0,0 +1,93 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go. + +// This file implements FindExportData. + +package gcimporter + +import ( + "bufio" + "fmt" + "io" + "strconv" + "strings" +) + +func readGopackHeader(r *bufio.Reader) (name string, size int, err error) { + // See $GOROOT/include/ar.h. + hdr := make([]byte, 16+12+6+6+8+10+2) + _, err = io.ReadFull(r, hdr) + if err != nil { + return + } + // leave for debugging + if false { + fmt.Printf("header: %s", hdr) + } + s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10])) + size, err = strconv.Atoi(s) + if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' { + err = fmt.Errorf("invalid archive header") + return + } + name = strings.TrimSpace(string(hdr[:16])) + return +} + +// FindExportData positions the reader r at the beginning of the +// export data section of an underlying GC-created object/archive +// file by reading from it. The reader must be positioned at the +// start of the file before calling this function. The hdr result +// is the string before the export data, either "$$" or "$$B". +// +func FindExportData(r *bufio.Reader) (hdr string, err error) { + // Read first line to make sure this is an object file. + line, err := r.ReadSlice('\n') + if err != nil { + err = fmt.Errorf("can't find export data (%v)", err) + return + } + + if string(line) == "!\n" { + // Archive file. Scan to __.PKGDEF. + var name string + if name, _, err = readGopackHeader(r); err != nil { + return + } + + // First entry should be __.PKGDEF. + if name != "__.PKGDEF" { + err = fmt.Errorf("go archive is missing __.PKGDEF") + return + } + + // Read first line of __.PKGDEF data, so that line + // is once again the first line of the input. + if line, err = r.ReadSlice('\n'); err != nil { + err = fmt.Errorf("can't find export data (%v)", err) + return + } + } + + // Now at __.PKGDEF in archive or still at beginning of file. + // Either way, line should begin with "go object ". + if !strings.HasPrefix(string(line), "go object ") { + err = fmt.Errorf("not a Go object file") + return + } + + // Skip over object header to export data. + // Begins after first line starting with $$. + for line[0] != '$' { + if line, err = r.ReadSlice('\n'); err != nil { + err = fmt.Errorf("can't find export data (%v)", err) + return + } + } + hdr = string(line) + + return +} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go new file mode 100644 index 000000000..58e558c95 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go @@ -0,0 +1,1037 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file is a copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go, +// but it also contains the original source-based importer code for Go1.6. +// Once we stop supporting 1.6, we can remove that code. + +// Package gcimporter provides various functions for reading +// gc-generated object files that can be used to implement the +// Importer interface defined by the Go 1.5 standard library package. +package gcimporter // import "golang.org/x/tools/go/internal/gcimporter" + +import ( + "bufio" + "errors" + "fmt" + "go/build" + exact "go/constant" + "go/token" + "go/types" + "io" + "io/ioutil" + "os" + "path/filepath" + "sort" + "strconv" + "strings" + "text/scanner" +) + +// debugging/development support +const debug = false + +var pkgExts = [...]string{".a", ".o"} + +// FindPkg returns the filename and unique package id for an import +// path based on package information provided by build.Import (using +// the build.Default build.Context). A relative srcDir is interpreted +// relative to the current working directory. +// If no file was found, an empty filename is returned. +// +func FindPkg(path, srcDir string) (filename, id string) { + if path == "" { + return + } + + var noext string + switch { + default: + // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" + // Don't require the source files to be present. + if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282 + srcDir = abs + } + bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary) + if bp.PkgObj == "" { + return + } + noext = strings.TrimSuffix(bp.PkgObj, ".a") + id = bp.ImportPath + + case build.IsLocalImport(path): + // "./x" -> "/this/directory/x.ext", "/this/directory/x" + noext = filepath.Join(srcDir, path) + id = noext + + case filepath.IsAbs(path): + // for completeness only - go/build.Import + // does not support absolute imports + // "/x" -> "/x.ext", "/x" + noext = path + id = path + } + + if false { // for debugging + if path != id { + fmt.Printf("%s -> %s\n", path, id) + } + } + + // try extensions + for _, ext := range pkgExts { + filename = noext + ext + if f, err := os.Stat(filename); err == nil && !f.IsDir() { + return + } + } + + filename = "" // not found + return +} + +// ImportData imports a package by reading the gc-generated export data, +// adds the corresponding package object to the packages map indexed by id, +// and returns the object. +// +// The packages map must contains all packages already imported. The data +// reader position must be the beginning of the export data section. The +// filename is only used in error messages. +// +// If packages[id] contains the completely imported package, that package +// can be used directly, and there is no need to call this function (but +// there is also no harm but for extra time used). +// +func ImportData(packages map[string]*types.Package, filename, id string, data io.Reader) (pkg *types.Package, err error) { + // support for parser error handling + defer func() { + switch r := recover().(type) { + case nil: + // nothing to do + case importError: + err = r + default: + panic(r) // internal error + } + }() + + var p parser + p.init(filename, id, data, packages) + pkg = p.parseExport() + + return +} + +// Import imports a gc-generated package given its import path and srcDir, adds +// the corresponding package object to the packages map, and returns the object. +// The packages map must contain all packages already imported. +// +func Import(packages map[string]*types.Package, path, srcDir string) (pkg *types.Package, err error) { + filename, id := FindPkg(path, srcDir) + if filename == "" { + if path == "unsafe" { + return types.Unsafe, nil + } + err = fmt.Errorf("can't find import: %s", id) + return + } + + // no need to re-import if the package was imported completely before + if pkg = packages[id]; pkg != nil && pkg.Complete() { + return + } + + // open file + f, err := os.Open(filename) + if err != nil { + return + } + defer func() { + f.Close() + if err != nil { + // add file name to error + err = fmt.Errorf("reading export data: %s: %v", filename, err) + } + }() + + var hdr string + buf := bufio.NewReader(f) + if hdr, err = FindExportData(buf); err != nil { + return + } + + switch hdr { + case "$$\n": + return ImportData(packages, filename, id, buf) + case "$$B\n": + var data []byte + data, err = ioutil.ReadAll(buf) + if err == nil { + fset := token.NewFileSet() + _, pkg, err = BImportData(fset, packages, data, id) + return + } + default: + err = fmt.Errorf("unknown export data header: %q", hdr) + } + + return +} + +// ---------------------------------------------------------------------------- +// Parser + +// TODO(gri) Imported objects don't have position information. +// Ideally use the debug table line info; alternatively +// create some fake position (or the position of the +// import). That way error messages referring to imported +// objects can print meaningful information. + +// parser parses the exports inside a gc compiler-produced +// object/archive file and populates its scope with the results. +type parser struct { + scanner scanner.Scanner + tok rune // current token + lit string // literal string; only valid for Ident, Int, String tokens + id string // package id of imported package + sharedPkgs map[string]*types.Package // package id -> package object (across importer) + localPkgs map[string]*types.Package // package id -> package object (just this package) +} + +func (p *parser) init(filename, id string, src io.Reader, packages map[string]*types.Package) { + p.scanner.Init(src) + p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) } + p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments + p.scanner.Whitespace = 1<<'\t' | 1<<' ' + p.scanner.Filename = filename // for good error messages + p.next() + p.id = id + p.sharedPkgs = packages + if debug { + // check consistency of packages map + for _, pkg := range packages { + if pkg.Name() == "" { + fmt.Printf("no package name for %s\n", pkg.Path()) + } + } + } +} + +func (p *parser) next() { + p.tok = p.scanner.Scan() + switch p.tok { + case scanner.Ident, scanner.Int, scanner.Char, scanner.String, '·': + p.lit = p.scanner.TokenText() + default: + p.lit = "" + } + if debug { + fmt.Printf("%s: %q -> %q\n", scanner.TokenString(p.tok), p.scanner.TokenText(), p.lit) + } +} + +func declTypeName(pkg *types.Package, name string) *types.TypeName { + scope := pkg.Scope() + if obj := scope.Lookup(name); obj != nil { + return obj.(*types.TypeName) + } + obj := types.NewTypeName(token.NoPos, pkg, name, nil) + // a named type may be referred to before the underlying type + // is known - set it up + types.NewNamed(obj, nil, nil) + scope.Insert(obj) + return obj +} + +// ---------------------------------------------------------------------------- +// Error handling + +// Internal errors are boxed as importErrors. +type importError struct { + pos scanner.Position + err error +} + +func (e importError) Error() string { + return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err) +} + +func (p *parser) error(err interface{}) { + if s, ok := err.(string); ok { + err = errors.New(s) + } + // panic with a runtime.Error if err is not an error + panic(importError{p.scanner.Pos(), err.(error)}) +} + +func (p *parser) errorf(format string, args ...interface{}) { + p.error(fmt.Sprintf(format, args...)) +} + +func (p *parser) expect(tok rune) string { + lit := p.lit + if p.tok != tok { + p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit) + } + p.next() + return lit +} + +func (p *parser) expectSpecial(tok string) { + sep := 'x' // not white space + i := 0 + for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' { + sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token + p.next() + i++ + } + if i < len(tok) { + p.errorf("expected %q, got %q", tok, tok[0:i]) + } +} + +func (p *parser) expectKeyword(keyword string) { + lit := p.expect(scanner.Ident) + if lit != keyword { + p.errorf("expected keyword %s, got %q", keyword, lit) + } +} + +// ---------------------------------------------------------------------------- +// Qualified and unqualified names + +// PackageId = string_lit . +// +func (p *parser) parsePackageId() string { + id, err := strconv.Unquote(p.expect(scanner.String)) + if err != nil { + p.error(err) + } + // id == "" stands for the imported package id + // (only known at time of package installation) + if id == "" { + id = p.id + } + return id +} + +// PackageName = ident . +// +func (p *parser) parsePackageName() string { + return p.expect(scanner.Ident) +} + +// dotIdentifier = ( ident | '·' ) { ident | int | '·' } . +func (p *parser) parseDotIdent() string { + ident := "" + if p.tok != scanner.Int { + sep := 'x' // not white space + for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' { + ident += p.lit + sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token + p.next() + } + } + if ident == "" { + p.expect(scanner.Ident) // use expect() for error handling + } + return ident +} + +// QualifiedName = "@" PackageId "." ( "?" | dotIdentifier ) . +// +func (p *parser) parseQualifiedName() (id, name string) { + p.expect('@') + id = p.parsePackageId() + p.expect('.') + // Per rev f280b8a485fd (10/2/2013), qualified names may be used for anonymous fields. + if p.tok == '?' { + p.next() + } else { + name = p.parseDotIdent() + } + return +} + +// getPkg returns the package for a given id. If the package is +// not found, create the package and add it to the p.localPkgs +// and p.sharedPkgs maps. name is the (expected) name of the +// package. If name == "", the package name is expected to be +// set later via an import clause in the export data. +// +// id identifies a package, usually by a canonical package path like +// "encoding/json" but possibly by a non-canonical import path like +// "./json". +// +func (p *parser) getPkg(id, name string) *types.Package { + // package unsafe is not in the packages maps - handle explicitly + if id == "unsafe" { + return types.Unsafe + } + + pkg := p.localPkgs[id] + if pkg == nil { + // first import of id from this package + pkg = p.sharedPkgs[id] + if pkg == nil { + // first import of id by this importer; + // add (possibly unnamed) pkg to shared packages + pkg = types.NewPackage(id, name) + p.sharedPkgs[id] = pkg + } + // add (possibly unnamed) pkg to local packages + if p.localPkgs == nil { + p.localPkgs = make(map[string]*types.Package) + } + p.localPkgs[id] = pkg + } else if name != "" { + // package exists already and we have an expected package name; + // make sure names match or set package name if necessary + if pname := pkg.Name(); pname == "" { + pkg.SetName(name) + } else if pname != name { + p.errorf("%s package name mismatch: %s (given) vs %s (expected)", id, pname, name) + } + } + return pkg +} + +// parseExportedName is like parseQualifiedName, but +// the package id is resolved to an imported *types.Package. +// +func (p *parser) parseExportedName() (pkg *types.Package, name string) { + id, name := p.parseQualifiedName() + pkg = p.getPkg(id, "") + return +} + +// ---------------------------------------------------------------------------- +// Types + +// BasicType = identifier . +// +func (p *parser) parseBasicType() types.Type { + id := p.expect(scanner.Ident) + obj := types.Universe.Lookup(id) + if obj, ok := obj.(*types.TypeName); ok { + return obj.Type() + } + p.errorf("not a basic type: %s", id) + return nil +} + +// ArrayType = "[" int_lit "]" Type . +// +func (p *parser) parseArrayType(parent *types.Package) types.Type { + // "[" already consumed and lookahead known not to be "]" + lit := p.expect(scanner.Int) + p.expect(']') + elem := p.parseType(parent) + n, err := strconv.ParseInt(lit, 10, 64) + if err != nil { + p.error(err) + } + return types.NewArray(elem, n) +} + +// MapType = "map" "[" Type "]" Type . +// +func (p *parser) parseMapType(parent *types.Package) types.Type { + p.expectKeyword("map") + p.expect('[') + key := p.parseType(parent) + p.expect(']') + elem := p.parseType(parent) + return types.NewMap(key, elem) +} + +// Name = identifier | "?" | QualifiedName . +// +// For unqualified and anonymous names, the returned package is the parent +// package unless parent == nil, in which case the returned package is the +// package being imported. (The parent package is not nil if the the name +// is an unqualified struct field or interface method name belonging to a +// type declared in another package.) +// +// For qualified names, the returned package is nil (and not created if +// it doesn't exist yet) unless materializePkg is set (which creates an +// unnamed package with valid package path). In the latter case, a +// subsequent import clause is expected to provide a name for the package. +// +func (p *parser) parseName(parent *types.Package, materializePkg bool) (pkg *types.Package, name string) { + pkg = parent + if pkg == nil { + pkg = p.sharedPkgs[p.id] + } + switch p.tok { + case scanner.Ident: + name = p.lit + p.next() + case '?': + // anonymous + p.next() + case '@': + // exported name prefixed with package path + pkg = nil + var id string + id, name = p.parseQualifiedName() + if materializePkg { + pkg = p.getPkg(id, "") + } + default: + p.error("name expected") + } + return +} + +func deref(typ types.Type) types.Type { + if p, _ := typ.(*types.Pointer); p != nil { + return p.Elem() + } + return typ +} + +// Field = Name Type [ string_lit ] . +// +func (p *parser) parseField(parent *types.Package) (*types.Var, string) { + pkg, name := p.parseName(parent, true) + + if name == "_" { + // Blank fields should be package-qualified because they + // are unexported identifiers, but gc does not qualify them. + // Assuming that the ident belongs to the current package + // causes types to change during re-exporting, leading + // to spurious "can't assign A to B" errors from go/types. + // As a workaround, pretend all blank fields belong + // to the same unique dummy package. + const blankpkg = "<_>" + pkg = p.getPkg(blankpkg, blankpkg) + } + + typ := p.parseType(parent) + anonymous := false + if name == "" { + // anonymous field - typ must be T or *T and T must be a type name + switch typ := deref(typ).(type) { + case *types.Basic: // basic types are named types + pkg = nil // objects defined in Universe scope have no package + name = typ.Name() + case *types.Named: + name = typ.Obj().Name() + default: + p.errorf("anonymous field expected") + } + anonymous = true + } + tag := "" + if p.tok == scanner.String { + s := p.expect(scanner.String) + var err error + tag, err = strconv.Unquote(s) + if err != nil { + p.errorf("invalid struct tag %s: %s", s, err) + } + } + return types.NewField(token.NoPos, pkg, name, typ, anonymous), tag +} + +// StructType = "struct" "{" [ FieldList ] "}" . +// FieldList = Field { ";" Field } . +// +func (p *parser) parseStructType(parent *types.Package) types.Type { + var fields []*types.Var + var tags []string + + p.expectKeyword("struct") + p.expect('{') + for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ { + if i > 0 { + p.expect(';') + } + fld, tag := p.parseField(parent) + if tag != "" && tags == nil { + tags = make([]string, i) + } + if tags != nil { + tags = append(tags, tag) + } + fields = append(fields, fld) + } + p.expect('}') + + return types.NewStruct(fields, tags) +} + +// Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] . +// +func (p *parser) parseParameter() (par *types.Var, isVariadic bool) { + _, name := p.parseName(nil, false) + // remove gc-specific parameter numbering + if i := strings.Index(name, "·"); i >= 0 { + name = name[:i] + } + if p.tok == '.' { + p.expectSpecial("...") + isVariadic = true + } + typ := p.parseType(nil) + if isVariadic { + typ = types.NewSlice(typ) + } + // ignore argument tag (e.g. "noescape") + if p.tok == scanner.String { + p.next() + } + // TODO(gri) should we provide a package? + par = types.NewVar(token.NoPos, nil, name, typ) + return +} + +// Parameters = "(" [ ParameterList ] ")" . +// ParameterList = { Parameter "," } Parameter . +// +func (p *parser) parseParameters() (list []*types.Var, isVariadic bool) { + p.expect('(') + for p.tok != ')' && p.tok != scanner.EOF { + if len(list) > 0 { + p.expect(',') + } + par, variadic := p.parseParameter() + list = append(list, par) + if variadic { + if isVariadic { + p.error("... not on final argument") + } + isVariadic = true + } + } + p.expect(')') + + return +} + +// Signature = Parameters [ Result ] . +// Result = Type | Parameters . +// +func (p *parser) parseSignature(recv *types.Var) *types.Signature { + params, isVariadic := p.parseParameters() + + // optional result type + var results []*types.Var + if p.tok == '(' { + var variadic bool + results, variadic = p.parseParameters() + if variadic { + p.error("... not permitted on result type") + } + } + + return types.NewSignature(recv, types.NewTuple(params...), types.NewTuple(results...), isVariadic) +} + +// InterfaceType = "interface" "{" [ MethodList ] "}" . +// MethodList = Method { ";" Method } . +// Method = Name Signature . +// +// The methods of embedded interfaces are always "inlined" +// by the compiler and thus embedded interfaces are never +// visible in the export data. +// +func (p *parser) parseInterfaceType(parent *types.Package) types.Type { + var methods []*types.Func + + p.expectKeyword("interface") + p.expect('{') + for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ { + if i > 0 { + p.expect(';') + } + pkg, name := p.parseName(parent, true) + sig := p.parseSignature(nil) + methods = append(methods, types.NewFunc(token.NoPos, pkg, name, sig)) + } + p.expect('}') + + // Complete requires the type's embedded interfaces to be fully defined, + // but we do not define any + return types.NewInterface(methods, nil).Complete() +} + +// ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type . +// +func (p *parser) parseChanType(parent *types.Package) types.Type { + dir := types.SendRecv + if p.tok == scanner.Ident { + p.expectKeyword("chan") + if p.tok == '<' { + p.expectSpecial("<-") + dir = types.SendOnly + } + } else { + p.expectSpecial("<-") + p.expectKeyword("chan") + dir = types.RecvOnly + } + elem := p.parseType(parent) + return types.NewChan(dir, elem) +} + +// Type = +// BasicType | TypeName | ArrayType | SliceType | StructType | +// PointerType | FuncType | InterfaceType | MapType | ChanType | +// "(" Type ")" . +// +// BasicType = ident . +// TypeName = ExportedName . +// SliceType = "[" "]" Type . +// PointerType = "*" Type . +// FuncType = "func" Signature . +// +func (p *parser) parseType(parent *types.Package) types.Type { + switch p.tok { + case scanner.Ident: + switch p.lit { + default: + return p.parseBasicType() + case "struct": + return p.parseStructType(parent) + case "func": + // FuncType + p.next() + return p.parseSignature(nil) + case "interface": + return p.parseInterfaceType(parent) + case "map": + return p.parseMapType(parent) + case "chan": + return p.parseChanType(parent) + } + case '@': + // TypeName + pkg, name := p.parseExportedName() + return declTypeName(pkg, name).Type() + case '[': + p.next() // look ahead + if p.tok == ']' { + // SliceType + p.next() + return types.NewSlice(p.parseType(parent)) + } + return p.parseArrayType(parent) + case '*': + // PointerType + p.next() + return types.NewPointer(p.parseType(parent)) + case '<': + return p.parseChanType(parent) + case '(': + // "(" Type ")" + p.next() + typ := p.parseType(parent) + p.expect(')') + return typ + } + p.errorf("expected type, got %s (%q)", scanner.TokenString(p.tok), p.lit) + return nil +} + +// ---------------------------------------------------------------------------- +// Declarations + +// ImportDecl = "import" PackageName PackageId . +// +func (p *parser) parseImportDecl() { + p.expectKeyword("import") + name := p.parsePackageName() + p.getPkg(p.parsePackageId(), name) +} + +// int_lit = [ "+" | "-" ] { "0" ... "9" } . +// +func (p *parser) parseInt() string { + s := "" + switch p.tok { + case '-': + s = "-" + p.next() + case '+': + p.next() + } + return s + p.expect(scanner.Int) +} + +// number = int_lit [ "p" int_lit ] . +// +func (p *parser) parseNumber() (typ *types.Basic, val exact.Value) { + // mantissa + mant := exact.MakeFromLiteral(p.parseInt(), token.INT, 0) + if mant == nil { + panic("invalid mantissa") + } + + if p.lit == "p" { + // exponent (base 2) + p.next() + exp, err := strconv.ParseInt(p.parseInt(), 10, 0) + if err != nil { + p.error(err) + } + if exp < 0 { + denom := exact.MakeInt64(1) + denom = exact.Shift(denom, token.SHL, uint(-exp)) + typ = types.Typ[types.UntypedFloat] + val = exact.BinaryOp(mant, token.QUO, denom) + return + } + if exp > 0 { + mant = exact.Shift(mant, token.SHL, uint(exp)) + } + typ = types.Typ[types.UntypedFloat] + val = mant + return + } + + typ = types.Typ[types.UntypedInt] + val = mant + return +} + +// ConstDecl = "const" ExportedName [ Type ] "=" Literal . +// Literal = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit . +// bool_lit = "true" | "false" . +// complex_lit = "(" float_lit "+" float_lit "i" ")" . +// rune_lit = "(" int_lit "+" int_lit ")" . +// string_lit = `"` { unicode_char } `"` . +// +func (p *parser) parseConstDecl() { + p.expectKeyword("const") + pkg, name := p.parseExportedName() + + var typ0 types.Type + if p.tok != '=' { + // constant types are never structured - no need for parent type + typ0 = p.parseType(nil) + } + + p.expect('=') + var typ types.Type + var val exact.Value + switch p.tok { + case scanner.Ident: + // bool_lit + if p.lit != "true" && p.lit != "false" { + p.error("expected true or false") + } + typ = types.Typ[types.UntypedBool] + val = exact.MakeBool(p.lit == "true") + p.next() + + case '-', scanner.Int: + // int_lit + typ, val = p.parseNumber() + + case '(': + // complex_lit or rune_lit + p.next() + if p.tok == scanner.Char { + p.next() + p.expect('+') + typ = types.Typ[types.UntypedRune] + _, val = p.parseNumber() + p.expect(')') + break + } + _, re := p.parseNumber() + p.expect('+') + _, im := p.parseNumber() + p.expectKeyword("i") + p.expect(')') + typ = types.Typ[types.UntypedComplex] + val = exact.BinaryOp(re, token.ADD, exact.MakeImag(im)) + + case scanner.Char: + // rune_lit + typ = types.Typ[types.UntypedRune] + val = exact.MakeFromLiteral(p.lit, token.CHAR, 0) + p.next() + + case scanner.String: + // string_lit + typ = types.Typ[types.UntypedString] + val = exact.MakeFromLiteral(p.lit, token.STRING, 0) + p.next() + + default: + p.errorf("expected literal got %s", scanner.TokenString(p.tok)) + } + + if typ0 == nil { + typ0 = typ + } + + pkg.Scope().Insert(types.NewConst(token.NoPos, pkg, name, typ0, val)) +} + +// TypeDecl = "type" ExportedName Type . +// +func (p *parser) parseTypeDecl() { + p.expectKeyword("type") + pkg, name := p.parseExportedName() + obj := declTypeName(pkg, name) + + // The type object may have been imported before and thus already + // have a type associated with it. We still need to parse the type + // structure, but throw it away if the object already has a type. + // This ensures that all imports refer to the same type object for + // a given type declaration. + typ := p.parseType(pkg) + + if name := obj.Type().(*types.Named); name.Underlying() == nil { + name.SetUnderlying(typ) + } +} + +// VarDecl = "var" ExportedName Type . +// +func (p *parser) parseVarDecl() { + p.expectKeyword("var") + pkg, name := p.parseExportedName() + typ := p.parseType(pkg) + pkg.Scope().Insert(types.NewVar(token.NoPos, pkg, name, typ)) +} + +// Func = Signature [ Body ] . +// Body = "{" ... "}" . +// +func (p *parser) parseFunc(recv *types.Var) *types.Signature { + sig := p.parseSignature(recv) + if p.tok == '{' { + p.next() + for i := 1; i > 0; p.next() { + switch p.tok { + case '{': + i++ + case '}': + i-- + } + } + } + return sig +} + +// MethodDecl = "func" Receiver Name Func . +// Receiver = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" . +// +func (p *parser) parseMethodDecl() { + // "func" already consumed + p.expect('(') + recv, _ := p.parseParameter() // receiver + p.expect(')') + + // determine receiver base type object + base := deref(recv.Type()).(*types.Named) + + // parse method name, signature, and possibly inlined body + _, name := p.parseName(nil, false) + sig := p.parseFunc(recv) + + // methods always belong to the same package as the base type object + pkg := base.Obj().Pkg() + + // add method to type unless type was imported before + // and method exists already + // TODO(gri) This leads to a quadratic algorithm - ok for now because method counts are small. + base.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig)) +} + +// FuncDecl = "func" ExportedName Func . +// +func (p *parser) parseFuncDecl() { + // "func" already consumed + pkg, name := p.parseExportedName() + typ := p.parseFunc(nil) + pkg.Scope().Insert(types.NewFunc(token.NoPos, pkg, name, typ)) +} + +// Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" . +// +func (p *parser) parseDecl() { + if p.tok == scanner.Ident { + switch p.lit { + case "import": + p.parseImportDecl() + case "const": + p.parseConstDecl() + case "type": + p.parseTypeDecl() + case "var": + p.parseVarDecl() + case "func": + p.next() // look ahead + if p.tok == '(' { + p.parseMethodDecl() + } else { + p.parseFuncDecl() + } + } + } + p.expect('\n') +} + +// ---------------------------------------------------------------------------- +// Export + +// Export = "PackageClause { Decl } "$$" . +// PackageClause = "package" PackageName [ "safe" ] "\n" . +// +func (p *parser) parseExport() *types.Package { + p.expectKeyword("package") + name := p.parsePackageName() + if p.tok == scanner.Ident && p.lit == "safe" { + // package was compiled with -u option - ignore + p.next() + } + p.expect('\n') + + pkg := p.getPkg(p.id, name) + + for p.tok != '$' && p.tok != scanner.EOF { + p.parseDecl() + } + + if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' { + // don't call next()/expect() since reading past the + // export data may cause scanner errors (e.g. NUL chars) + p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch) + } + + if n := p.scanner.ErrorCount; n != 0 { + p.errorf("expected no scanner errors, got %d", n) + } + + // Record all locally referenced packages as imports. + var imports []*types.Package + for id, pkg2 := range p.localPkgs { + if pkg2.Name() == "" { + p.errorf("%s package has no name", id) + } + if id == p.id { + continue // avoid self-edge + } + imports = append(imports, pkg2) + } + sort.Sort(byPath(imports)) + pkg.SetImports(imports) + + // package was imported completely and without errors + pkg.MarkComplete() + + return pkg +} + +type byPath []*types.Package + +func (a byPath) Len() int { return len(a) } +func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() } diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go new file mode 100644 index 000000000..dfc00a332 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go @@ -0,0 +1,585 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Indexed package import. +// See cmd/compile/internal/gc/iexport.go for the export data format. + +// This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go. + +package gcimporter + +import ( + "bytes" + "encoding/binary" + "go/constant" + "go/token" + "go/types" + "io" + "sort" +) + +type intReader struct { + *bytes.Reader + path string +} + +func (r *intReader) int64() int64 { + i, err := binary.ReadVarint(r.Reader) + if err != nil { + errorf("import %q: read varint error: %v", r.path, err) + } + return i +} + +func (r *intReader) uint64() uint64 { + i, err := binary.ReadUvarint(r.Reader) + if err != nil { + errorf("import %q: read varint error: %v", r.path, err) + } + return i +} + +const predeclReserved = 32 + +type itag uint64 + +const ( + // Types + definedType itag = iota + pointerType + sliceType + arrayType + chanType + mapType + signatureType + structType + interfaceType +) + +// iImportData imports a package from the serialized package data +// and returns the number of bytes consumed and a reference to the package. +// If the export data version is not recognized or the format is otherwise +// compromised, an error is returned. +func iImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { + r := &intReader{bytes.NewReader(data), path} + + version := r.uint64() + switch version { + case 0: + default: + errorf("cannot import %q: unknown iexport format version %d", path, version) + } + + sLen := int64(r.uint64()) + dLen := int64(r.uint64()) + + whence, _ := r.Seek(0, io.SeekCurrent) + stringData := data[whence : whence+sLen] + declData := data[whence+sLen : whence+sLen+dLen] + r.Seek(sLen+dLen, io.SeekCurrent) + + p := iimporter{ + ipath: path, + + stringData: stringData, + stringCache: make(map[uint64]string), + pkgCache: make(map[uint64]*types.Package), + + declData: declData, + pkgIndex: make(map[*types.Package]map[string]uint64), + typCache: make(map[uint64]types.Type), + + fake: fakeFileSet{ + fset: fset, + files: make(map[string]*token.File), + }, + } + + for i, pt := range predeclared { + p.typCache[uint64(i)] = pt + } + + pkgList := make([]*types.Package, r.uint64()) + for i := range pkgList { + pkgPathOff := r.uint64() + pkgPath := p.stringAt(pkgPathOff) + pkgName := p.stringAt(r.uint64()) + _ = r.uint64() // package height; unused by go/types + + if pkgPath == "" { + pkgPath = path + } + pkg := imports[pkgPath] + if pkg == nil { + pkg = types.NewPackage(pkgPath, pkgName) + imports[pkgPath] = pkg + } else if pkg.Name() != pkgName { + errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path) + } + + p.pkgCache[pkgPathOff] = pkg + + nameIndex := make(map[string]uint64) + for nSyms := r.uint64(); nSyms > 0; nSyms-- { + name := p.stringAt(r.uint64()) + nameIndex[name] = r.uint64() + } + + p.pkgIndex[pkg] = nameIndex + pkgList[i] = pkg + } + + localpkg := pkgList[0] + + names := make([]string, 0, len(p.pkgIndex[localpkg])) + for name := range p.pkgIndex[localpkg] { + names = append(names, name) + } + sort.Strings(names) + for _, name := range names { + p.doDecl(localpkg, name) + } + + for _, typ := range p.interfaceList { + typ.Complete() + } + + // record all referenced packages as imports + list := append(([]*types.Package)(nil), pkgList[1:]...) + sort.Sort(byPath(list)) + localpkg.SetImports(list) + + // package was imported completely and without errors + localpkg.MarkComplete() + + consumed, _ := r.Seek(0, io.SeekCurrent) + return int(consumed), localpkg, nil +} + +type iimporter struct { + ipath string + + stringData []byte + stringCache map[uint64]string + pkgCache map[uint64]*types.Package + + declData []byte + pkgIndex map[*types.Package]map[string]uint64 + typCache map[uint64]types.Type + + fake fakeFileSet + interfaceList []*types.Interface +} + +func (p *iimporter) doDecl(pkg *types.Package, name string) { + // See if we've already imported this declaration. + if obj := pkg.Scope().Lookup(name); obj != nil { + return + } + + off, ok := p.pkgIndex[pkg][name] + if !ok { + errorf("%v.%v not in index", pkg, name) + } + + r := &importReader{p: p, currPkg: pkg} + r.declReader.Reset(p.declData[off:]) + + r.obj(name) +} + +func (p *iimporter) stringAt(off uint64) string { + if s, ok := p.stringCache[off]; ok { + return s + } + + slen, n := binary.Uvarint(p.stringData[off:]) + if n <= 0 { + errorf("varint failed") + } + spos := off + uint64(n) + s := string(p.stringData[spos : spos+slen]) + p.stringCache[off] = s + return s +} + +func (p *iimporter) pkgAt(off uint64) *types.Package { + if pkg, ok := p.pkgCache[off]; ok { + return pkg + } + path := p.stringAt(off) + errorf("missing package %q in %q", path, p.ipath) + return nil +} + +func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { + if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) { + return t + } + + if off < predeclReserved { + errorf("predeclared type missing from cache: %v", off) + } + + r := &importReader{p: p} + r.declReader.Reset(p.declData[off-predeclReserved:]) + t := r.doType(base) + + if base == nil || !isInterface(t) { + p.typCache[off] = t + } + return t +} + +type importReader struct { + p *iimporter + declReader bytes.Reader + currPkg *types.Package + prevFile string + prevLine int64 +} + +func (r *importReader) obj(name string) { + tag := r.byte() + pos := r.pos() + + switch tag { + case 'A': + typ := r.typ() + + r.declare(types.NewTypeName(pos, r.currPkg, name, typ)) + + case 'C': + typ, val := r.value() + + r.declare(types.NewConst(pos, r.currPkg, name, typ, val)) + + case 'F': + sig := r.signature(nil) + + r.declare(types.NewFunc(pos, r.currPkg, name, sig)) + + case 'T': + // Types can be recursive. We need to setup a stub + // declaration before recursing. + obj := types.NewTypeName(pos, r.currPkg, name, nil) + named := types.NewNamed(obj, nil, nil) + r.declare(obj) + + underlying := r.p.typAt(r.uint64(), named).Underlying() + named.SetUnderlying(underlying) + + if !isInterface(underlying) { + for n := r.uint64(); n > 0; n-- { + mpos := r.pos() + mname := r.ident() + recv := r.param() + msig := r.signature(recv) + + named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig)) + } + } + + case 'V': + typ := r.typ() + + r.declare(types.NewVar(pos, r.currPkg, name, typ)) + + default: + errorf("unexpected tag: %v", tag) + } +} + +func (r *importReader) declare(obj types.Object) { + obj.Pkg().Scope().Insert(obj) +} + +func (r *importReader) value() (typ types.Type, val constant.Value) { + typ = r.typ() + + switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { + case types.IsBoolean: + val = constant.MakeBool(r.bool()) + + case types.IsString: + val = constant.MakeString(r.string()) + + case types.IsInteger: + val = r.mpint(b) + + case types.IsFloat: + val = r.mpfloat(b) + + case types.IsComplex: + re := r.mpfloat(b) + im := r.mpfloat(b) + val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) + + default: + errorf("unexpected type %v", typ) // panics + panic("unreachable") + } + + return +} + +func intSize(b *types.Basic) (signed bool, maxBytes uint) { + if (b.Info() & types.IsUntyped) != 0 { + return true, 64 + } + + switch b.Kind() { + case types.Float32, types.Complex64: + return true, 3 + case types.Float64, types.Complex128: + return true, 7 + } + + signed = (b.Info() & types.IsUnsigned) == 0 + switch b.Kind() { + case types.Int8, types.Uint8: + maxBytes = 1 + case types.Int16, types.Uint16: + maxBytes = 2 + case types.Int32, types.Uint32: + maxBytes = 4 + default: + maxBytes = 8 + } + + return +} + +func (r *importReader) mpint(b *types.Basic) constant.Value { + signed, maxBytes := intSize(b) + + maxSmall := 256 - maxBytes + if signed { + maxSmall = 256 - 2*maxBytes + } + if maxBytes == 1 { + maxSmall = 256 + } + + n, _ := r.declReader.ReadByte() + if uint(n) < maxSmall { + v := int64(n) + if signed { + v >>= 1 + if n&1 != 0 { + v = ^v + } + } + return constant.MakeInt64(v) + } + + v := -n + if signed { + v = -(n &^ 1) >> 1 + } + if v < 1 || uint(v) > maxBytes { + errorf("weird decoding: %v, %v => %v", n, signed, v) + } + + buf := make([]byte, v) + io.ReadFull(&r.declReader, buf) + + // convert to little endian + // TODO(gri) go/constant should have a more direct conversion function + // (e.g., once it supports a big.Float based implementation) + for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 { + buf[i], buf[j] = buf[j], buf[i] + } + + x := constant.MakeFromBytes(buf) + if signed && n&1 != 0 { + x = constant.UnaryOp(token.SUB, x, 0) + } + return x +} + +func (r *importReader) mpfloat(b *types.Basic) constant.Value { + x := r.mpint(b) + if constant.Sign(x) == 0 { + return x + } + + exp := r.int64() + switch { + case exp > 0: + x = constant.Shift(x, token.SHL, uint(exp)) + case exp < 0: + d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp)) + x = constant.BinaryOp(x, token.QUO, d) + } + return x +} + +func (r *importReader) ident() string { + return r.string() +} + +func (r *importReader) qualifiedIdent() (*types.Package, string) { + name := r.string() + pkg := r.pkg() + return pkg, name +} + +func (r *importReader) pos() token.Pos { + delta := r.int64() + if delta != deltaNewFile { + r.prevLine += delta + } else if l := r.int64(); l == -1 { + r.prevLine += deltaNewFile + } else { + r.prevFile = r.string() + r.prevLine = l + } + + if r.prevFile == "" && r.prevLine == 0 { + return token.NoPos + } + + return r.p.fake.pos(r.prevFile, int(r.prevLine)) +} + +func (r *importReader) typ() types.Type { + return r.p.typAt(r.uint64(), nil) +} + +func isInterface(t types.Type) bool { + _, ok := t.(*types.Interface) + return ok +} + +func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) } +func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } + +func (r *importReader) doType(base *types.Named) types.Type { + switch k := r.kind(); k { + default: + errorf("unexpected kind tag in %q: %v", r.p.ipath, k) + return nil + + case definedType: + pkg, name := r.qualifiedIdent() + r.p.doDecl(pkg, name) + return pkg.Scope().Lookup(name).(*types.TypeName).Type() + case pointerType: + return types.NewPointer(r.typ()) + case sliceType: + return types.NewSlice(r.typ()) + case arrayType: + n := r.uint64() + return types.NewArray(r.typ(), int64(n)) + case chanType: + dir := chanDir(int(r.uint64())) + return types.NewChan(dir, r.typ()) + case mapType: + return types.NewMap(r.typ(), r.typ()) + case signatureType: + r.currPkg = r.pkg() + return r.signature(nil) + + case structType: + r.currPkg = r.pkg() + + fields := make([]*types.Var, r.uint64()) + tags := make([]string, len(fields)) + for i := range fields { + fpos := r.pos() + fname := r.ident() + ftyp := r.typ() + emb := r.bool() + tag := r.string() + + fields[i] = types.NewField(fpos, r.currPkg, fname, ftyp, emb) + tags[i] = tag + } + return types.NewStruct(fields, tags) + + case interfaceType: + r.currPkg = r.pkg() + + embeddeds := make([]*types.Named, r.uint64()) + for i := range embeddeds { + _ = r.pos() + embeddeds[i] = r.typ().(*types.Named) + } + + methods := make([]*types.Func, r.uint64()) + for i := range methods { + mpos := r.pos() + mname := r.ident() + + // TODO(mdempsky): Matches bimport.go, but I + // don't agree with this. + var recv *types.Var + if base != nil { + recv = types.NewVar(token.NoPos, r.currPkg, "", base) + } + + msig := r.signature(recv) + methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig) + } + + typ := types.NewInterface(methods, embeddeds) + r.p.interfaceList = append(r.p.interfaceList, typ) + return typ + } +} + +func (r *importReader) kind() itag { + return itag(r.uint64()) +} + +func (r *importReader) signature(recv *types.Var) *types.Signature { + params := r.paramList() + results := r.paramList() + variadic := params.Len() > 0 && r.bool() + return types.NewSignature(recv, params, results, variadic) +} + +func (r *importReader) paramList() *types.Tuple { + xs := make([]*types.Var, r.uint64()) + for i := range xs { + xs[i] = r.param() + } + return types.NewTuple(xs...) +} + +func (r *importReader) param() *types.Var { + pos := r.pos() + name := r.ident() + typ := r.typ() + return types.NewParam(pos, r.currPkg, name, typ) +} + +func (r *importReader) bool() bool { + return r.uint64() != 0 +} + +func (r *importReader) int64() int64 { + n, err := binary.ReadVarint(&r.declReader) + if err != nil { + errorf("readVarint: %v", err) + } + return n +} + +func (r *importReader) uint64() uint64 { + n, err := binary.ReadUvarint(&r.declReader) + if err != nil { + errorf("readUvarint: %v", err) + } + return n +} + +func (r *importReader) byte() byte { + x, err := r.declReader.ReadByte() + if err != nil { + errorf("declReader.ReadByte: %v", err) + } + return x +} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/isAlias18.go b/vendor/golang.org/x/tools/go/internal/gcimporter/isAlias18.go new file mode 100644 index 000000000..225ffeedf --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/isAlias18.go @@ -0,0 +1,13 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.9 + +package gcimporter + +import "go/types" + +func isAlias(obj *types.TypeName) bool { + return false // there are no type aliases before Go 1.9 +} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/isAlias19.go b/vendor/golang.org/x/tools/go/internal/gcimporter/isAlias19.go new file mode 100644 index 000000000..c2025d84a --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/isAlias19.go @@ -0,0 +1,13 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.9 + +package gcimporter + +import "go/types" + +func isAlias(obj *types.TypeName) bool { + return obj.IsAlias() +} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/imports.go b/vendor/golang.org/x/tools/go/types/typeutil/imports.go new file mode 100644 index 000000000..9c441dba9 --- /dev/null +++ b/vendor/golang.org/x/tools/go/types/typeutil/imports.go @@ -0,0 +1,31 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typeutil + +import "go/types" + +// Dependencies returns all dependencies of the specified packages. +// +// Dependent packages appear in topological order: if package P imports +// package Q, Q appears earlier than P in the result. +// The algorithm follows import statements in the order they +// appear in the source code, so the result is a total order. +// +func Dependencies(pkgs ...*types.Package) []*types.Package { + var result []*types.Package + seen := make(map[*types.Package]bool) + var visit func(pkgs []*types.Package) + visit = func(pkgs []*types.Package) { + for _, p := range pkgs { + if !seen[p] { + seen[p] = true + visit(p.Imports()) + result = append(result, p) + } + } + } + visit(pkgs) + return result +} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/map.go b/vendor/golang.org/x/tools/go/types/typeutil/map.go new file mode 100644 index 000000000..c7f754500 --- /dev/null +++ b/vendor/golang.org/x/tools/go/types/typeutil/map.go @@ -0,0 +1,313 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package typeutil defines various utilities for types, such as Map, +// a mapping from types.Type to interface{} values. +package typeutil // import "golang.org/x/tools/go/types/typeutil" + +import ( + "bytes" + "fmt" + "go/types" + "reflect" +) + +// Map is a hash-table-based mapping from types (types.Type) to +// arbitrary interface{} values. The concrete types that implement +// the Type interface are pointers. Since they are not canonicalized, +// == cannot be used to check for equivalence, and thus we cannot +// simply use a Go map. +// +// Just as with map[K]V, a nil *Map is a valid empty map. +// +// Not thread-safe. +// +type Map struct { + hasher Hasher // shared by many Maps + table map[uint32][]entry // maps hash to bucket; entry.key==nil means unused + length int // number of map entries +} + +// entry is an entry (key/value association) in a hash bucket. +type entry struct { + key types.Type + value interface{} +} + +// SetHasher sets the hasher used by Map. +// +// All Hashers are functionally equivalent but contain internal state +// used to cache the results of hashing previously seen types. +// +// A single Hasher created by MakeHasher() may be shared among many +// Maps. This is recommended if the instances have many keys in +// common, as it will amortize the cost of hash computation. +// +// A Hasher may grow without bound as new types are seen. Even when a +// type is deleted from the map, the Hasher never shrinks, since other +// types in the map may reference the deleted type indirectly. +// +// Hashers are not thread-safe, and read-only operations such as +// Map.Lookup require updates to the hasher, so a full Mutex lock (not a +// read-lock) is require around all Map operations if a shared +// hasher is accessed from multiple threads. +// +// If SetHasher is not called, the Map will create a private hasher at +// the first call to Insert. +// +func (m *Map) SetHasher(hasher Hasher) { + m.hasher = hasher +} + +// Delete removes the entry with the given key, if any. +// It returns true if the entry was found. +// +func (m *Map) Delete(key types.Type) bool { + if m != nil && m.table != nil { + hash := m.hasher.Hash(key) + bucket := m.table[hash] + for i, e := range bucket { + if e.key != nil && types.Identical(key, e.key) { + // We can't compact the bucket as it + // would disturb iterators. + bucket[i] = entry{} + m.length-- + return true + } + } + } + return false +} + +// At returns the map entry for the given key. +// The result is nil if the entry is not present. +// +func (m *Map) At(key types.Type) interface{} { + if m != nil && m.table != nil { + for _, e := range m.table[m.hasher.Hash(key)] { + if e.key != nil && types.Identical(key, e.key) { + return e.value + } + } + } + return nil +} + +// Set sets the map entry for key to val, +// and returns the previous entry, if any. +func (m *Map) Set(key types.Type, value interface{}) (prev interface{}) { + if m.table != nil { + hash := m.hasher.Hash(key) + bucket := m.table[hash] + var hole *entry + for i, e := range bucket { + if e.key == nil { + hole = &bucket[i] + } else if types.Identical(key, e.key) { + prev = e.value + bucket[i].value = value + return + } + } + + if hole != nil { + *hole = entry{key, value} // overwrite deleted entry + } else { + m.table[hash] = append(bucket, entry{key, value}) + } + } else { + if m.hasher.memo == nil { + m.hasher = MakeHasher() + } + hash := m.hasher.Hash(key) + m.table = map[uint32][]entry{hash: {entry{key, value}}} + } + + m.length++ + return +} + +// Len returns the number of map entries. +func (m *Map) Len() int { + if m != nil { + return m.length + } + return 0 +} + +// Iterate calls function f on each entry in the map in unspecified order. +// +// If f should mutate the map, Iterate provides the same guarantees as +// Go maps: if f deletes a map entry that Iterate has not yet reached, +// f will not be invoked for it, but if f inserts a map entry that +// Iterate has not yet reached, whether or not f will be invoked for +// it is unspecified. +// +func (m *Map) Iterate(f func(key types.Type, value interface{})) { + if m != nil { + for _, bucket := range m.table { + for _, e := range bucket { + if e.key != nil { + f(e.key, e.value) + } + } + } + } +} + +// Keys returns a new slice containing the set of map keys. +// The order is unspecified. +func (m *Map) Keys() []types.Type { + keys := make([]types.Type, 0, m.Len()) + m.Iterate(func(key types.Type, _ interface{}) { + keys = append(keys, key) + }) + return keys +} + +func (m *Map) toString(values bool) string { + if m == nil { + return "{}" + } + var buf bytes.Buffer + fmt.Fprint(&buf, "{") + sep := "" + m.Iterate(func(key types.Type, value interface{}) { + fmt.Fprint(&buf, sep) + sep = ", " + fmt.Fprint(&buf, key) + if values { + fmt.Fprintf(&buf, ": %q", value) + } + }) + fmt.Fprint(&buf, "}") + return buf.String() +} + +// String returns a string representation of the map's entries. +// Values are printed using fmt.Sprintf("%v", v). +// Order is unspecified. +// +func (m *Map) String() string { + return m.toString(true) +} + +// KeysString returns a string representation of the map's key set. +// Order is unspecified. +// +func (m *Map) KeysString() string { + return m.toString(false) +} + +//////////////////////////////////////////////////////////////////////// +// Hasher + +// A Hasher maps each type to its hash value. +// For efficiency, a hasher uses memoization; thus its memory +// footprint grows monotonically over time. +// Hashers are not thread-safe. +// Hashers have reference semantics. +// Call MakeHasher to create a Hasher. +type Hasher struct { + memo map[types.Type]uint32 +} + +// MakeHasher returns a new Hasher instance. +func MakeHasher() Hasher { + return Hasher{make(map[types.Type]uint32)} +} + +// Hash computes a hash value for the given type t such that +// Identical(t, t') => Hash(t) == Hash(t'). +func (h Hasher) Hash(t types.Type) uint32 { + hash, ok := h.memo[t] + if !ok { + hash = h.hashFor(t) + h.memo[t] = hash + } + return hash +} + +// hashString computes the Fowler–Noll–Vo hash of s. +func hashString(s string) uint32 { + var h uint32 + for i := 0; i < len(s); i++ { + h ^= uint32(s[i]) + h *= 16777619 + } + return h +} + +// hashFor computes the hash of t. +func (h Hasher) hashFor(t types.Type) uint32 { + // See Identical for rationale. + switch t := t.(type) { + case *types.Basic: + return uint32(t.Kind()) + + case *types.Array: + return 9043 + 2*uint32(t.Len()) + 3*h.Hash(t.Elem()) + + case *types.Slice: + return 9049 + 2*h.Hash(t.Elem()) + + case *types.Struct: + var hash uint32 = 9059 + for i, n := 0, t.NumFields(); i < n; i++ { + f := t.Field(i) + if f.Anonymous() { + hash += 8861 + } + hash += hashString(t.Tag(i)) + hash += hashString(f.Name()) // (ignore f.Pkg) + hash += h.Hash(f.Type()) + } + return hash + + case *types.Pointer: + return 9067 + 2*h.Hash(t.Elem()) + + case *types.Signature: + var hash uint32 = 9091 + if t.Variadic() { + hash *= 8863 + } + return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results()) + + case *types.Interface: + var hash uint32 = 9103 + for i, n := 0, t.NumMethods(); i < n; i++ { + // See go/types.identicalMethods for rationale. + // Method order is not significant. + // Ignore m.Pkg(). + m := t.Method(i) + hash += 3*hashString(m.Name()) + 5*h.Hash(m.Type()) + } + return hash + + case *types.Map: + return 9109 + 2*h.Hash(t.Key()) + 3*h.Hash(t.Elem()) + + case *types.Chan: + return 9127 + 2*uint32(t.Dir()) + 3*h.Hash(t.Elem()) + + case *types.Named: + // Not safe with a copying GC; objects may move. + return uint32(reflect.ValueOf(t.Obj()).Pointer()) + + case *types.Tuple: + return h.hashTuple(t) + } + panic(t) +} + +func (h Hasher) hashTuple(tuple *types.Tuple) uint32 { + // See go/types.identicalTypes for rationale. + n := tuple.Len() + var hash uint32 = 9137 + 2*uint32(n) + for i := 0; i < n; i++ { + hash += 3 * h.Hash(tuple.At(i).Type()) + } + return hash +} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go b/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go new file mode 100644 index 000000000..32084610f --- /dev/null +++ b/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go @@ -0,0 +1,72 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements a cache of method sets. + +package typeutil + +import ( + "go/types" + "sync" +) + +// A MethodSetCache records the method set of each type T for which +// MethodSet(T) is called so that repeat queries are fast. +// The zero value is a ready-to-use cache instance. +type MethodSetCache struct { + mu sync.Mutex + named map[*types.Named]struct{ value, pointer *types.MethodSet } // method sets for named N and *N + others map[types.Type]*types.MethodSet // all other types +} + +// MethodSet returns the method set of type T. It is thread-safe. +// +// If cache is nil, this function is equivalent to types.NewMethodSet(T). +// Utility functions can thus expose an optional *MethodSetCache +// parameter to clients that care about performance. +// +func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet { + if cache == nil { + return types.NewMethodSet(T) + } + cache.mu.Lock() + defer cache.mu.Unlock() + + switch T := T.(type) { + case *types.Named: + return cache.lookupNamed(T).value + + case *types.Pointer: + if N, ok := T.Elem().(*types.Named); ok { + return cache.lookupNamed(N).pointer + } + } + + // all other types + // (The map uses pointer equivalence, not type identity.) + mset := cache.others[T] + if mset == nil { + mset = types.NewMethodSet(T) + if cache.others == nil { + cache.others = make(map[types.Type]*types.MethodSet) + } + cache.others[T] = mset + } + return mset +} + +func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } { + if cache.named == nil { + cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet }) + } + // Avoid recomputing mset(*T) for each distinct Pointer + // instance whose underlying type is a named type. + msets, ok := cache.named[named] + if !ok { + msets.value = types.NewMethodSet(named) + msets.pointer = types.NewMethodSet(types.NewPointer(named)) + cache.named[named] = msets + } + return msets +} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/ui.go b/vendor/golang.org/x/tools/go/types/typeutil/ui.go new file mode 100644 index 000000000..9849c24ce --- /dev/null +++ b/vendor/golang.org/x/tools/go/types/typeutil/ui.go @@ -0,0 +1,52 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typeutil + +// This file defines utilities for user interfaces that display types. + +import "go/types" + +// IntuitiveMethodSet returns the intuitive method set of a type T, +// which is the set of methods you can call on an addressable value of +// that type. +// +// The result always contains MethodSet(T), and is exactly MethodSet(T) +// for interface types and for pointer-to-concrete types. +// For all other concrete types T, the result additionally +// contains each method belonging to *T if there is no identically +// named method on T itself. +// +// This corresponds to user intuition about method sets; +// this function is intended only for user interfaces. +// +// The order of the result is as for types.MethodSet(T). +// +func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection { + isPointerToConcrete := func(T types.Type) bool { + ptr, ok := T.(*types.Pointer) + return ok && !types.IsInterface(ptr.Elem()) + } + + var result []*types.Selection + mset := msets.MethodSet(T) + if types.IsInterface(T) || isPointerToConcrete(T) { + for i, n := 0, mset.Len(); i < n; i++ { + result = append(result, mset.At(i)) + } + } else { + // T is some other concrete type. + // Report methods of T and *T, preferring those of T. + pmset := msets.MethodSet(types.NewPointer(T)) + for i, n := 0, pmset.Len(); i < n; i++ { + meth := pmset.At(i) + if m := mset.Lookup(meth.Obj().Pkg(), meth.Obj().Name()); m != nil { + meth = m + } + result = append(result, meth) + } + + } + return result +} diff --git a/vendor/vendor.json b/vendor/vendor.json new file mode 100644 index 000000000..8a2c0b060 --- /dev/null +++ b/vendor/vendor.json @@ -0,0 +1,35 @@ +{ + "comment": "", + "ignore": "test", + "package": [ + { + "checksumSHA1": "CaUaJLLnql96d2JGRgCpYsKomxw=", + "path": "github.com/neelance/astrewrite", + "revision": "99348263ae862cc230986ce88deaddbf7edcc034", + "revisionTime": "2016-05-11T09:36:45Z" + }, + { + "path": "go/types", + "revision": "030ac2c719e14925830de5e97d4ef86b3ab5826f" + }, + { + "checksumSHA1": "ba80UZ0mLHlMRtyMQXLo2rqkISY=", + "path": "golang.org/x/tools/go/gcexportdata", + "revision": "836e0f611e69f12657ca7b4ff1d5747865308e2d", + "revisionTime": "2018-04-30T23:40:03Z" + }, + { + "checksumSHA1": "4fHLwo8NkpTrPdtOezgBMFqnWz4=", + "path": "golang.org/x/tools/go/internal/gcimporter", + "revision": "836e0f611e69f12657ca7b4ff1d5747865308e2d", + "revisionTime": "2018-04-30T23:40:03Z" + }, + { + "checksumSHA1": "QKvPv3TJ+ZnOLkUeUkT8Wm8eCV0=", + "path": "golang.org/x/tools/go/types/typeutil", + "revision": "836e0f611e69f12657ca7b4ff1d5747865308e2d", + "revisionTime": "2018-04-30T23:40:03Z" + } + ], + "rootPath": "github.com/gopherjs/gopherjs" +} From 75a0cb90261ce7f2e658b2e8abfd6f68ca09855d Mon Sep 17 00:00:00 2001 From: Paul Jolly Date: Sat, 7 Jul 2018 09:53:42 +0100 Subject: [PATCH 08/10] js: add MakeFullWrapper to expose exported methods and struct fields. (#8) Currently the documentation for js.MakeWrapper is: > "MakeWrapper creates a JavaScript object which has wrappers for the exported methods of i. Use explicit getter and setter methods to expose struct fields to JavaScript." Where the value a struct value (or more interestingly a pointer to a struct value) we can actually auto-generate getters and setters for exported fields in the JavaScript world, rather than requiring explicit getters and setters to be defined on the Go side. We do this via a new MakeFullWrapper method. --- compiler/gopherjspkg/fs_vfsdata.go | 20 +-- compiler/natives/fs_vfsdata.go | 194 ++++++++++++++--------------- compiler/prelude/jsmapping.js | 74 ++++++----- compiler/prelude/jspmapping.js | 0 compiler/prelude/prelude.go | 2 +- compiler/prelude/prelude_min.go | 2 +- js/js.go | 99 ++++++++++++++- tests/js_test.go | 167 ++++++++++++++++++++++++- 8 files changed, 417 insertions(+), 141 deletions(-) delete mode 100644 compiler/prelude/jspmapping.js diff --git a/compiler/gopherjspkg/fs_vfsdata.go b/compiler/gopherjspkg/fs_vfsdata.go index fde74dd82..3a25a90fd 100644 --- a/compiler/gopherjspkg/fs_vfsdata.go +++ b/compiler/gopherjspkg/fs_vfsdata.go @@ -21,47 +21,47 @@ var FS = func() http.FileSystem { fs := vfsgen۰FS{ "/": &vfsgen۰DirInfo{ name: "/", - modTime: time.Date(2018, 4, 20, 21, 15, 55, 808735181, time.UTC), + modTime: time.Date(2018, 7, 7, 8, 29, 15, 490982724, time.UTC), }, "/js": &vfsgen۰DirInfo{ name: "js", - modTime: time.Date(2018, 4, 20, 21, 5, 10, 645618320, time.UTC), + modTime: time.Date(2018, 7, 7, 8, 21, 7, 523593061, time.UTC), }, "/js/js.go": &vfsgen۰CompressedFileInfo{ name: "js.go", - modTime: time.Date(2017, 10, 12, 19, 45, 13, 330964900, time.UTC), - uncompressedSize: 8002, + modTime: time.Date(2018, 7, 7, 8, 21, 7, 523593061, time.UTC), + uncompressedSize: 10926, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x59\x5f\x6f\xdc\x36\x12\x7f\x5e\x7d\x8a\x39\xa1\x40\x56\xcd\x56\xbe\xb6\x86\x51\x38\xe7\x87\xa4\xb9\xfa\xdc\x4b\xdc\x00\x6e\xd0\x07\x23\x30\xb8\xd2\x68\x97\xb1\x44\xea\x48\x6a\x37\x7b\xb6\xbf\xfb\x61\xf8\x47\x2b\xad\xa4\xc4\xbe\x24\x2f\x75\xc5\xe1\x6f\x7e\x9c\x19\xce\x1f\xee\xd1\x11\xbc\x63\xd9\x2d\x5b\x21\x7c\xd4\x50\x2b\xb9\xe1\x39\x6a\x28\x1a\x91\x19\x2e\x85\x86\x42\x2a\xe0\xc2\xa0\x62\x99\xe1\x62\x05\x5b\x6e\xd6\x20\x98\xe1\x1b\x84\xdf\xd9\x86\x5d\x65\x8a\xd7\x06\x5e\xbe\xbb\xd0\x29\xfc\xca\xca\x52\x83\x91\x60\xd6\xa8\xb1\x83\xc2\x14\x82\x51\xc8\x0c\xe6\xa0\x6b\xcc\x38\x2b\xcb\x1d\x2c\x77\x70\x2e\xeb\x35\xaa\xdf\xaf\x80\x89\x1c\x8c\x62\x42\x97\x56\x28\xe7\x0a\x33\x53\xee\x3c\x18\x57\x90\x49\xa5\x50\xd7\x52\xe4\x44\xa3\xa3\x5a\xef\x84\x61\x9f\xd2\xe8\xe8\x28\x3a\x3a\x82\xf7\x1a\xe1\x2d\xbb\xc5\xbf\x14\xab\x6b\x54\xb4\x1f\x3f\xd5\x52\x23\x54\x68\xd6\x32\xb7\xf4\xf6\xbb\x53\xf8\x6b\x8d\x02\x6a\xa6\x35\xc1\x6e\x58\xd9\xa0\x6e\xb5\x2f\x48\x37\x14\xb2\x2c\xe5\x96\x96\xcd\xae\x46\xc8\xa4\xd8\xa0\xd2\xed\xb9\x6a\x54\x85\x54\x15\xe6\xa7\x9e\x02\xdc\xc3\xb9\x74\xb2\xfd\x7f\xf7\x5d\xda\x9d\xf5\x7b\xf8\xb5\x83\xb9\x64\xd9\x2d\x91\xb4\x56\x2f\x58\x86\x77\x0f\x70\xef\x71\x7f\x18\xfb\xf7\xd4\xef\x5d\x09\x8f\xbb\x94\xb2\x84\xc1\xbf\x7b\x78\x25\x65\x89\x4c\x0c\xbe\x8f\xcb\x77\x24\x3c\x2e\x9d\x61\x85\x4a\x5b\xf7\x16\xa5\x64\x46\xdb\xfd\x97\x4d\xb5\x44\x35\xd4\x67\x45\x4e\x8e\xbf\x88\xab\x8d\x22\x7f\x0c\xf6\x5f\x4d\x7c\x1f\x97\x1f\xe2\x5e\x7f\xe0\xc2\xfc\x32\xdc\x7f\x21\xcc\x2f\x2f\x95\x62\xbb\x83\xef\xe3\xf2\x13\xb8\x3f\x9e\x8c\xe1\xfe\x78\x32\x00\x9e\x92\x9f\xc0\xfd\xf9\xa7\x85\xfb\xa3\x87\xfb\xf3\x4f\x53\xb8\xd3\x74\x3b\xb8\xcd\xc8\xc1\xee\xe1\x3d\x1f\x33\xc4\x94\xfc\x14\xee\xe1\xc1\x1c\xee\xd0\x10\x53\xf2\x53\xb8\xce\x10\x4d\x7b\x44\x87\x3b\x34\xc4\x7d\x4f\xea\xf3\xb8\x36\x22\x7f\xfe\xe9\x80\xef\x6f\xee\xeb\x01\xf0\x94\xfc\x24\xee\x41\xa4\x7b\xdc\x93\xe3\x29\xdc\xc9\x9b\x11\x70\x59\x59\x82\x34\x6b\x54\xa0\x4b\x9e\xa1\x0e\xfb\x87\xb1\x0b\xfb\x78\x68\xb3\xcc\x67\x70\x69\xbf\x1e\xee\xd7\x88\x4e\x53\x2f\xdd\x4d\x7d\x1f\xe2\xee\x2b\xc4\x81\x1d\xfc\xf7\x43\x7d\x24\x3f\x4f\xd3\xb4\xc3\x3a\x81\xef\x3f\xea\xf4\x8f\xe5\x47\xcc\x4c\x8b\x6b\x78\x85\xe9\x9f\xbc\xc2\x83\xfd\xaf\x99\x19\x63\x33\x21\x3f\xe4\xfb\xc3\xf8\x2a\x70\xa1\x0d\x13\x19\xca\x02\x2e\x65\xbe\xcf\xeb\x1d\x6a\x9f\xc5\xad\x58\xad\x17\x94\xa5\x9a\xcc\xe8\x71\xdc\x0e\x8c\x95\xbf\x76\x39\x6d\xdc\x81\xf7\xbe\x14\xbd\xcc\x73\x4e\x76\xa4\x72\xbb\xb0\xb5\x9c\x79\x2d\x54\xc6\x0c\xe3\x82\xd2\x22\xeb\xf2\x2c\x38\x96\xf9\x02\xa4\xa0\xe2\xbb\xb6\xe5\xce\xa0\x30\x20\x0b\x57\x0c\x69\x19\xb6\xbc\x2c\x61\x89\xb6\x6e\x62\xde\x2f\xa9\x36\xd7\x6f\xc8\xf7\x54\xd2\x58\x1a\xd5\x6d\x83\x11\x11\x27\xaf\x87\x6b\x60\x81\x04\x2a\xcf\x6d\xd8\x58\x48\x2b\xdd\x69\x2d\xb8\xd1\x6d\x29\xff\x06\x6d\xc5\xb0\x91\x80\x97\x20\x78\x09\xb5\xb4\x96\x25\xc9\x3d\x63\xfc\x4f\xc3\xca\xfe\x71\x9f\x69\x88\x45\x53\x96\x71\x1a\xe4\x32\x26\x40\x48\x43\xf6\x69\xc8\x3a\x8c\x4e\x5a\xb1\x1a\x6e\x71\x97\x46\xf6\x42\x78\x49\xe7\x8a\x3b\x7f\x48\xf8\xde\x7f\x7e\xb0\x76\x3a\x47\x03\x0a\x4d\xa3\x84\xb6\x96\x77\x42\xcf\x6c\x97\x56\xa3\x32\x3b\xd7\x8b\xd1\xd2\x8a\x6f\x50\x38\x78\xba\x21\x30\x97\x01\x2b\x21\x98\xf9\x2d\xee\x7c\x09\x4c\x5a\x25\x77\x1e\x1c\x64\xea\x6d\xec\x25\x13\xaf\xff\x0a\x0d\x50\x5b\xb4\xf2\xfa\x6d\x6f\xe4\x0d\xf7\xff\x92\xb9\xea\x91\x59\x78\xcc\xde\x6d\xbe\xdb\x13\xf2\xd2\x5e\x2c\xf0\x7a\x8d\x25\x1a\x04\x85\x95\xdc\xe0\x57\x99\xc6\x21\xf5\xac\xd3\xd1\xbe\x5f\x0d\x9a\xdf\xa0\x58\x99\xf5\xb8\x53\xe2\xd2\x2e\xc6\x2d\x85\x85\x6f\x14\x8d\xbb\x1f\x5c\x98\x11\x06\x0e\x71\x9e\xd0\xf2\x88\x47\xda\x65\xa7\xff\x42\xe4\xf8\xa9\xa7\x9e\x3f\x33\x6b\xc0\x12\x2b\x7f\x43\x99\x70\xa9\x7a\x44\x95\xdd\x3c\xe7\xa4\xe9\x73\x41\xe0\xc5\x3a\x41\xe0\xb4\x6a\x34\x4f\x56\x19\x36\x3b\xad\x8f\xf0\xb6\x97\x3e\x70\x38\x5d\x7d\xc8\xdc\xfd\xef\x9a\xdc\x65\x81\x43\x57\x0b\x56\xe1\x08\x17\x02\x99\xd3\x5a\x1b\x7b\x4c\xad\x34\x0c\x6a\xc9\xa4\x61\x5a\x00\xb7\x33\x4d\xd3\xbd\x5b\x36\xf2\x16\x07\x0c\x29\x53\x61\x59\xa4\xf0\xe7\x9a\x6b\x97\x31\x0b\xc6\x4b\xe0\x05\x70\x9b\x4c\x28\x47\xb0\xb6\x04\x8e\xba\x8c\x80\xe7\x4f\x24\xda\xd9\xd5\x21\x79\x89\x5b\xc8\x6c\xaa\xa4\x6c\x24\x70\xdb\xd6\x16\x97\xd9\xb9\x76\xa5\x3a\xe4\xdb\x51\xd2\x7d\xc6\x30\xcf\xa4\x70\x29\x4c\xaa\x64\x84\xff\x25\x6e\x9f\x4a\x3e\x6c\xe9\x30\xa7\x19\x64\xe4\xce\xf5\xaf\x97\x1d\x48\x58\x96\x49\x65\xc7\xc3\x7e\x41\x3a\x1c\xdb\x46\xa8\x92\x92\x79\xe2\x60\x86\xac\xfc\xaa\xbf\x12\x6e\x96\xf8\x12\x23\x3f\x72\x7c\x05\x27\xa7\x68\x9e\x04\xa8\x21\xaf\x56\x22\x04\xe2\x58\xc5\x18\xe4\xa1\x47\x73\x82\x79\xcd\x94\xc6\x0b\x61\xc6\xbc\x7b\x21\xcc\x64\xe2\x72\x6b\x2d\xab\x93\xe3\xc7\xf0\x3a\x39\xfe\x76\xcc\x4e\x8e\x1d\xb7\x93\xe3\x71\x76\x76\xdd\xf1\x7b\xcf\x1f\x45\xb0\xf9\x96\x0c\x9d\xce\x79\x12\x50\x87\x1c\x5b\x09\x47\xd2\x0e\x06\x5f\xe4\x18\x86\x84\x27\x92\xb4\xe0\x63\x34\xed\xc2\x3c\x69\x71\x87\x34\x83\x44\xeb\x6a\x77\xc9\x1f\xe3\xee\x90\x0e\x52\xb8\x42\x04\xc3\x96\x25\xd5\x06\x08\xdd\x62\x26\x2b\x5b\x62\xa8\x31\xcc\xd1\x30\x5e\x8e\xdd\x91\x56\xa3\x73\x77\xdb\x09\x8f\x3a\xbd\x95\xf4\x8e\x17\x9a\x15\xa3\x54\xa9\x63\x13\xd6\x37\xb5\x51\x0b\xd8\xae\x79\xb6\xb6\x6d\xdd\x12\x3b\xc7\xd8\x70\x06\x8d\xc5\x48\xdf\xb9\x66\x31\x85\x4b\x69\x2c\x0f\x91\x63\x6e\xa9\xd7\xcd\xb2\xe4\x19\x35\x82\x63\x61\x60\x77\xfb\x30\xa8\x8d\x1a\x8b\x83\x20\xe2\x38\xff\x53\x29\xa9\x00\x45\xc6\x6a\xdd\x94\x36\x9b\x77\xfc\x8b\xb4\xaa\x29\x79\x4b\x8d\xae\x3b\x6e\x94\xc0\x9c\x28\x49\x60\x70\x2e\xa1\x66\x82\x67\xb6\x2d\xae\xd8\x8e\xce\xa3\x30\x93\x1b\x54\x98\x2f\xa8\x80\xda\x94\x25\xe0\x7b\xa7\xc7\xac\x99\x81\xb5\x2c\x73\x67\x9d\x43\x4d\xa1\x58\xb8\x9e\xd6\x6d\xf1\xd3\xc5\x5d\x34\xf3\xa7\x8c\xba\xc4\xbb\xb6\xae\x50\x6b\x72\xb4\x1f\x2c\x3a\x67\xca\xa7\x35\x39\x13\xa2\x52\x9e\x62\xe2\x80\x3b\x49\x32\x9a\x79\x13\xc6\x87\x20\xa7\x10\xc3\x73\xfa\xd3\x76\xba\xb1\xd7\x1f\x27\x6d\x1a\x8d\x42\x82\x67\xd9\x6d\x8f\xaa\xb6\x5f\xda\xe6\xf2\x2b\x19\x5b\xfc\x31\xc6\x2d\x35\xab\x6f\x48\xec\xbc\x94\x4b\x56\xda\x3e\x47\xf7\x27\x90\x95\x5b\xf1\xe1\x3b\x8f\xb7\x5c\xe4\x72\x1b\xdb\x08\x5c\x2a\xb9\xd5\xe1\x0d\x2e\x3e\x7f\xf3\xc7\xab\x97\x6f\xdc\x0a\x8d\xaa\xe9\x47\x9d\xa4\xd1\x86\xa9\x80\x1e\xdc\x46\x0a\xdf\xca\xbc\x29\xd1\x2b\xdc\xcf\x00\xfe\xfc\x71\x65\x97\x63\xd8\x30\xc5\xed\xf5\xd5\x68\x68\xfa\xf2\xb8\x29\xfc\x8b\x0b\x73\xea\x06\x09\x70\xc2\xf6\x31\x56\x19\xd7\xb4\x3d\xfb\xa8\x53\xa7\xc2\x1d\xdb\xad\x69\x3a\xf8\xfe\x7f\x2f\x59\x85\xf1\x82\x5a\x88\xe4\x99\x23\xea\x59\x75\x89\xbe\x17\x39\x16\x9c\x22\x7d\xcf\xb5\xe3\x11\x47\x3b\x6e\x82\x54\xec\x80\xf6\xbb\xba\x58\xaf\x71\xd9\xac\x56\xa8\x60\x45\x2d\x6f\x26\xab\x9a\x97\x87\x33\x2e\x35\xfc\xb9\x97\x7b\x11\x53\x7c\x18\xdb\x10\x7b\x77\x07\x88\x79\x02\x77\x9d\xcc\x28\x58\xe9\x1b\x9f\x5e\x0f\xef\x97\x86\x53\xaf\xbb\x7f\x0a\x6b\x85\x1a\x85\xd1\xc0\x1f\x93\x60\xfa\xaa\x5c\xef\x3d\xd2\x7a\xb5\x51\x27\x78\xe9\xe3\xeb\x2d\xbb\xc5\xdf\x08\x62\xab\x58\xad\xbb\x9d\x1e\x85\x8e\xb3\x2c\xcb\x32\xd4\xe1\x8d\x3f\xbc\x97\xcb\xe2\xc0\x36\xd4\x4f\xc6\x2e\xe0\x98\x5a\x35\x64\x1a\x1d\xd3\x14\xb6\x95\x2a\x0f\x79\x3c\xa8\x9b\x17\xc2\x3d\xec\xd8\x2e\xd4\x13\xb4\x5d\xb6\xdb\x08\xd7\x1f\xda\x8c\xf9\x85\xb3\xb8\x18\x76\xbd\x7a\xfc\x5d\xe5\x15\xc4\x8b\x43\xa3\x14\x22\x09\x97\xea\xdf\xb8\xd3\x3d\x7f\xdc\xd2\x07\x1f\xe2\x6e\xa4\x18\x3e\x47\xb8\x03\xd0\xd6\x6e\x3a\xbf\xfe\xb0\xbf\xd2\xbc\x00\x09\x67\x67\xf6\x29\xe1\xfe\xde\xfd\xbd\x8f\xb7\xbb\x68\xd6\x35\xff\xec\x21\x9a\x31\x38\x3d\x0b\xfc\xed\x6d\x70\xa8\x71\xe2\x4f\x43\xb4\xe2\x05\xc8\x24\x9a\x69\x12\xa5\xc3\xcd\x83\xc6\x05\xb0\x76\x58\x4c\xa2\x99\xfd\xd1\x86\x84\xfe\xfe\x02\x38\xfc\xa3\xb3\xf8\x02\xf8\xf3\xe7\x56\xbd\xbe\xe6\x1f\xe0\x0c\x58\x3b\xf1\xed\xb3\x0d\xd1\xf1\xec\x74\x27\x34\xc2\x4f\x2a\xfb\x31\x62\x18\xb1\xae\x54\xae\x99\xb6\x31\x54\x53\xda\x29\x6c\x21\x09\x37\x1f\xf3\xf6\xf5\x46\x16\x14\xd0\xef\xb5\x5d\x2a\x79\xc6\x0d\x5d\x39\x83\xca\x06\x8e\x76\x7f\x76\x7e\xb5\xf1\xbf\xe3\xf8\x0a\x63\x1f\xa2\x0e\x7f\xcd\xd9\x07\x96\x27\xfb\x99\xf0\xdf\x90\x81\x0e\x2f\x4b\x12\xcd\xe4\xa4\x23\x68\x38\x21\x01\x97\x9e\x6e\x6e\xc2\xcd\xbd\x71\x87\xbf\xb9\x89\x17\xb0\x49\xa2\x59\xe0\x7c\x7a\x06\x1b\x07\xd1\x19\x94\xe2\x24\x94\x1f\x2b\x14\x8f\xb8\xcb\x2f\x8d\x38\xad\xb2\x9e\xf7\xcb\xc1\x71\xd1\x8c\xa2\xad\x72\xb0\xf5\xed\xaa\x53\x38\xe0\x6f\x67\x10\xc7\x70\x07\x47\x47\x76\x78\x0b\x3e\x88\x66\xb3\x59\x26\x85\xe1\xa2\xc1\x68\x46\xfe\xf6\xa7\xf2\x28\x34\xe7\x76\x60\x16\xee\x7e\x86\x59\xae\x0d\xf8\x8e\x35\x67\xe3\x57\x10\x3f\x39\x13\xf1\xff\x62\x78\xd3\x25\x23\x59\x2d\x81\xb1\x92\x75\x47\x57\xb2\x08\x47\x31\xbb\x3a\x4e\x16\x60\x54\x83\xe1\x12\xb0\xba\x2e\x77\x04\xe0\x86\x70\x3a\xfa\x43\x2f\x5e\x65\xd4\x8e\xbb\xf6\xcd\xfb\x55\x53\x14\x53\x21\xdb\x15\x28\x94\xac\x80\xc1\x72\x67\xfc\xc3\xb5\x0f\xa5\x3e\xce\x7c\x09\xd7\x1f\x48\xa6\x77\x74\xf7\xd0\x3d\x0c\xa6\x25\xc5\x4a\x51\x50\x51\x3c\x3d\xf3\xa8\xf6\x60\xdf\xb9\xaf\x71\xe2\xe6\xa4\x68\xe6\xde\x8e\x0e\xa5\xfc\x8b\x52\x2b\x15\xae\x64\x47\xc4\xbe\xbc\x84\x88\x5a\x5a\x8e\x6d\xc2\xb0\x72\x94\x31\xac\xb2\xf0\xdf\xe7\x0e\x35\x64\xbf\xb7\xee\x1d\x56\xf3\xaa\x2e\xd1\x3e\x52\x52\x2f\x97\xc2\x85\x7d\xa1\x68\x0b\x8d\x7d\xc2\xd4\x6b\xa9\xcc\xda\xfe\x92\x27\xd5\xf0\xee\x6b\x98\x2f\xb1\x90\xaa\x3b\x61\x24\xbe\x37\x7c\x3b\xf1\x62\xed\xfa\xad\x1e\x87\xfd\xcf\x06\x4f\x64\xe1\x7f\xa3\x98\x26\x71\xd5\xff\xb9\x23\x72\x1e\xe6\x82\xd3\x00\x73\x17\xcd\x8e\x8e\x80\x6d\x24\xcf\x21\x47\x96\x43\x26\x73\x04\x2c\x79\xc5\x05\xa3\xb0\x8d\x66\xd6\xc7\xb6\x87\xbb\x7b\x88\x66\x37\x70\x06\x18\x3d\x44\xff\x0b\x00\x00\xff\xff\x72\x0d\xcb\x80\x42\x1f\x00\x00"), + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x5a\x5f\x73\xdb\x36\x90\x7f\x16\x3f\xc5\x96\xd3\x19\x8b\x89\x22\xf5\x4f\xc6\xd3\x71\xce\x0f\x69\x73\xcd\xa5\xd7\xb8\x99\xba\xb9\x3e\x64\x32\x1e\x88\x5c\x4a\x88\x29\x80\x05\x20\x29\xaa\xed\xef\x7e\xb3\x58\x80\x22\x45\x2a\x76\x9a\xde\xcc\xf9\xc5\x12\xb1\xf8\xed\x0f\xbb\x8b\xdd\x05\xa8\xd9\x0c\xde\x88\xfc\x5a\x2c\x10\x3e\x58\xa8\x8d\xde\xc8\x02\x2d\x94\x6b\x95\x3b\xa9\x95\x85\x52\x1b\x90\xca\xa1\x11\xb9\x93\x6a\x01\x5b\xe9\x96\xa0\x84\x93\x1b\x84\x5f\xc4\x46\x5c\xe6\x46\xd6\x0e\x9e\xbf\x79\x65\xa7\xf0\x93\xa8\x2a\x0b\x4e\x83\x5b\xa2\xc5\x16\x8a\x30\x08\xce\xa0\x70\x58\x80\xad\x31\x97\xa2\xaa\x76\x30\xdf\xc1\x4b\x5d\x2f\xd1\xfc\x72\x09\x42\x15\xe0\x8c\x50\xb6\xf2\x42\x85\x34\x98\xbb\x6a\x17\xc0\xa4\x81\x5c\x1b\x83\xb6\xd6\xaa\x20\x1a\x2d\xd5\x76\xa7\x9c\xf8\x38\x4d\x66\xb3\x64\x36\x83\xb7\x16\xe1\xb5\xb8\xc6\x3f\x8d\xa8\x6b\x34\x34\x1f\x3f\xd6\xda\x22\xac\xd0\x2d\x75\xe1\xe9\xed\x67\x4f\x9b\x09\x3f\xaf\xab\xea\xf8\xa4\xe7\x17\x2f\xa0\x94\x58\xf5\xe7\xff\xb9\x44\x05\xb5\xb0\x96\x68\x6d\x44\xb5\x46\xdb\xb0\x9f\x10\x77\x28\x75\x55\xe9\x2d\x0d\xbb\x5d\x8d\x90\x6b\xb5\x41\x63\x1b\xbb\xd4\x68\x4a\x6d\x56\x58\x9c\x85\x25\xc0\x2d\xbc\xd4\x2c\xdb\xfd\xbb\x6d\x2f\xbb\x35\x7e\x0b\x3f\xb5\x30\xe7\x22\xbf\x26\x92\xde\x6b\xa5\xc8\xf1\xe6\x0e\x6e\x03\xee\x93\xa1\xbf\xcf\x7d\xde\x96\x08\xb8\x73\xad\x2b\xe8\xfd\xdd\xc2\x8f\x5a\x57\x28\x54\xef\xf9\xb0\x7c\x4b\x22\xe0\xd2\x1a\x16\x68\xac\x0f\x8f\xb2\xd2\xc2\x59\x3f\xff\x62\xbd\x9a\xa3\xe9\xeb\xf3\x22\xa7\x4f\xef\xc5\xb5\xce\x90\x3f\x7a\xf3\x2f\x8f\x3c\x1f\x96\xef\xe3\xbe\x7b\x2f\x95\xfb\xa1\x3f\xff\x95\x72\x3f\x3c\x37\x46\xec\x0e\x9e\x0f\xcb\x1f\xc1\xfd\xf6\x74\x08\xf7\xdb\xd3\x1e\xf0\x31\xf9\x23\xb8\xdf\x7f\x37\xe1\x0f\x1d\xdc\xef\xbf\x3b\x86\x7b\x9c\x6e\x0b\x77\x3d\xb0\xb0\x5b\x78\x2b\x87\x0c\x71\x4c\xfe\x18\xee\xe1\xc2\x18\xb7\x6f\x88\x63\xf2\xc7\x70\xd9\x10\xeb\x66\x89\x8c\xdb\x37\xc4\x6d\x47\xea\xd3\xb8\x3e\x22\xbf\xff\xee\x80\xef\xcf\xfc\xf4\x00\xf8\x98\xfc\x51\xdc\x83\x48\x0f\xb8\xa7\x4f\x8f\xe1\x1e\xdd\x19\x11\x57\x54\x15\x68\xb7\x44\x03\xb6\x92\x39\xda\x38\xbf\x1f\xbb\xb0\x8f\x87\x26\xcb\x7c\x02\x97\xe6\xdb\xfe\x7c\x8b\xc8\x9a\x3a\xe9\xee\xd8\xf3\x3e\xee\xbe\xc2\x1c\xd8\x21\x3c\x3f\xd4\x47\xf2\xe3\xe9\x74\xda\x62\x9d\xc1\xa3\x0f\x76\xfa\xdb\xfc\x03\xe6\xae\xc1\x75\x72\x85\xd3\x3f\xe4\x0a\x0f\xe6\xbf\x10\x6e\x88\xcd\x11\xf9\x3e\xdf\x27\xc3\xa3\x20\x95\x75\x42\xe5\xa8\x4b\xb8\xd0\xc5\x3e\xaf\xb7\xa8\x7d\x12\x77\x25\x6a\x3b\xa1\x2c\xb5\xce\x9d\x1d\xc6\x6d\xc1\x78\xf9\x77\x9c\xd3\x86\x1d\x78\x1b\x4a\xd1\xf3\xa2\x90\x64\x47\x2a\xd7\x13\xdf\x0b\x88\xa0\x85\xca\x98\x13\x52\x51\x5a\x14\x6d\x9e\xbe\x4a\x4e\x40\x2b\x2a\xde\x4b\x5f\xee\x1c\x2a\x07\xba\xe4\x62\x48\xc3\xb0\x95\x55\x05\x73\xf4\x75\x13\x8b\x6e\x49\xf5\xb9\x7e\x43\xbe\xa7\x92\x26\xa6\x49\xdd\x34\x28\x09\x71\x0a\x7a\xa4\x05\x11\x49\xa0\x09\xdc\xfa\x8d\x89\xf6\xd2\xad\xd6\x44\x3a\xdb\x54\xf5\x7f\xa1\x2d\xe9\x37\x22\xf0\x1c\x94\xac\xa0\xd6\xde\xb2\x24\xb9\x67\x8c\x7f\xad\x45\xd5\x5d\xee\x89\x85\x54\xad\xab\x2a\x9d\x46\xb9\x5c\x28\x50\xda\x91\x7d\xd6\x64\x1d\x41\x2b\x5d\x89\x1a\xae\x71\x37\x4d\xfc\x86\x08\x92\xec\x8a\x9b\xb0\x48\x78\x14\x1e\xdf\x79\x3b\xbd\x44\x07\x06\xdd\xda\x28\xeb\x2d\xcf\x42\x27\xbe\xcb\xab\xd1\xb8\x1d\xf7\x72\x34\xb4\x90\x1b\x54\x0c\x4f\x3b\x04\xc6\x3a\x62\x65\x04\x33\xbe\xc6\x5d\x28\x81\x59\xa3\xe4\x26\x80\x83\x9e\x06\x1b\x07\xc9\x2c\xe8\xbf\x44\x07\xd4\x16\x2d\x82\x7e\xdf\x1b\x05\xc3\xfd\x53\x32\x97\x1d\x32\x93\x80\xd9\xd9\xcd\x37\x7b\x42\x41\x3a\x88\x45\x5e\x2f\xb0\x42\x87\x60\x70\xa5\x37\xf8\x45\xa6\x61\xa4\x8e\x75\x5a\xda\xf7\xa3\x51\xf3\xaf\xa8\x16\x6e\x39\xec\x94\xb4\xf2\x83\x69\x43\x61\x12\x1a\x45\xc7\xfb\x43\x2a\x37\xc0\x80\x11\xc7\x19\x0d\x0f\x78\xa4\x19\x66\xfd\xaf\x54\x81\x1f\x3b\xea\xe5\x89\x5b\x02\x56\xb8\x0a\x3b\x54\x28\x4e\xd5\x03\xaa\xfc\xe4\xb1\x24\x4d\x9f\x0a\x82\x20\xd6\x0a\x02\xd6\x6a\xd1\x7d\xb6\xca\x38\x99\xb5\x3e\xc0\xdb\x41\xfa\xc0\xe1\xb4\xf5\x21\xe7\xfd\xdf\x36\x39\x67\x81\x43\x57\x2b\xb1\xc2\x01\x2e\x04\x32\xa6\xb1\x26\xf6\x84\x59\x58\xe8\xd5\x92\xa3\x86\x69\x00\x78\xe6\x74\x3a\xdd\xbb\x65\xa3\xaf\xb1\xc7\x90\x32\x15\x56\xe5\x14\xfe\x58\x4a\xcb\x19\xb3\x14\xb2\x02\x59\x82\xf4\xc9\x84\x72\x84\x68\x4a\xe0\xa0\xcb\x08\x78\xfc\x99\x44\x5b\xb3\x5a\x24\x2f\x70\x0b\xb9\x4f\x95\x94\x8d\x14\x6e\x9b\xda\xc2\x99\x5d\x5a\x2e\xd5\x31\xdf\x0e\x92\xee\x32\x86\x71\xae\x15\xa7\x30\x6d\xb2\x01\xfe\x17\xb8\xfd\x5c\xf2\x71\x4a\x8b\x39\x9d\x41\x06\xf6\x5c\x77\x7b\xf9\x03\x89\xc8\x73\x6d\xfc\xf1\xb2\x5b\x90\x0e\x8f\x6d\x03\x54\x49\xc9\x38\x63\x98\x3e\xab\x30\x1a\xb6\x04\x9f\x25\xee\x63\x14\x8e\x1c\x5f\xc0\x89\x15\x8d\xb3\x08\xd5\xe7\xd5\x48\xc4\x40\x1c\xaa\x18\xbd\x3c\xf4\x60\x4e\x30\xae\x85\xb1\xf8\x4a\xb9\x21\xef\xbe\x52\xee\x68\xe2\xe2\xb1\x86\xd5\xe9\xd3\x87\xf0\x3a\x7d\xfa\xef\x31\x3b\x7d\xca\xdc\x4e\x9f\x0e\xb3\xf3\xe3\xcc\xef\xad\x7c\x10\xc1\xf5\xbf\xc9\x90\x75\x8e\xb3\x88\xda\xe7\xd8\x48\x30\x49\x7f\x30\xb8\x97\x63\x3c\x24\x7c\x26\x49\x0f\x3e\x44\xd3\x0f\x8c\xb3\x06\xb7\x4f\x33\x4a\x34\xae\xe6\x4d\xfe\x10\x77\xc7\x74\x30\x85\x4b\x44\x70\x62\x5e\x51\x6d\x80\xd8\x2d\xe6\x7a\xe5\x4b\x0c\x35\x86\x05\x3a\x21\xab\xa1\x3d\xd2\x68\x64\x77\x37\x9d\xf0\xa0\xd3\x1b\xc9\xe0\x78\x65\x45\x39\x48\x95\x3a\x36\xe5\x7d\x53\x3b\x33\x81\xed\x52\xe6\x4b\xdf\xd6\xcd\xb1\xb5\x8c\x8d\x14\xb0\xf6\x18\xd3\x37\xdc\x2c\x4e\xe1\x42\x3b\xcf\x43\x15\x58\x78\xea\xf5\x7a\x5e\xc9\x9c\x1a\xc1\xa1\x30\xf0\xb3\x43\x18\xd4\xce\x0c\xc5\x41\x14\x61\xce\xff\x69\x8c\x36\x80\x2a\x17\xb5\x5d\x57\x3e\x9b\xb7\xfc\x8b\x34\x6a\x29\x79\x6b\x8b\xdc\x1d\xaf\x8d\xc2\x82\x28\x69\x10\xf0\x52\x43\x2d\x94\xcc\x7d\x5b\xbc\x12\x3b\x5a\x8f\xc1\x5c\x6f\xd0\x60\x31\xa1\x02\xea\x53\x96\x82\x47\xac\xc7\x2d\x85\x83\xa5\xf6\xb7\x66\x4b\xec\x69\x8a\xc5\x82\x7b\x5a\x9e\x12\x4e\x17\x37\xc9\x28\xac\x32\x69\x13\x6f\xdb\x7a\x85\xd6\x92\xa3\xc3\xc1\xa2\xb5\xa6\xe2\xb8\x26\x36\x21\x1a\x13\x28\x66\x0c\xdc\x4a\x92\xc9\x28\x98\x30\x3d\x04\x39\x83\x14\x1e\xd3\x47\xdf\xe9\xa6\x41\x7f\x9a\x35\x69\x34\x89\x09\x5e\xe4\xd7\x1d\xaa\xd6\x3f\x69\x9a\xcb\x2f\x64\xec\xf1\x87\x18\x37\xd4\xbc\xbe\x3e\xb1\x97\x95\x9e\x8b\xca\xf7\x39\xb6\x7b\x02\x59\xf0\x48\x08\xdf\x71\xba\x95\xaa\xd0\xdb\xd4\x47\xe0\xdc\xe8\xad\x8d\x77\x70\xe9\xcb\x5f\x7f\xfb\xf1\xf9\xaf\x3c\x42\x47\xd5\xe9\x07\x9b\x4d\x93\x8d\x30\x11\x3d\xba\x8d\x14\xbe\xd6\xc5\xba\xc2\xa0\x70\x7f\x06\x08\xeb\x4f\x57\x7e\x38\x85\x8d\x30\xd2\x6f\x5f\x8b\x8e\x4e\x5f\x01\x77\x0a\xff\x25\x95\x3b\xe3\x83\x04\xb0\xb0\xbf\x97\x35\x8e\x9b\xb6\x93\x0f\x76\xca\x2a\x78\xd9\x3c\x66\x69\xe1\xfb\xaf\x17\x62\x85\xe9\x84\x5a\x88\xec\x84\x89\x06\x56\x6d\xa2\x6f\x55\x81\xa5\xa4\x48\xdf\x73\x6d\x79\x84\x69\xa7\xeb\x28\x95\x32\xd0\x7e\x56\x1b\xeb\x05\xce\xd7\x8b\x05\x1a\x58\x50\xcb\x9b\xeb\x55\x2d\xab\xc3\x33\x2e\x35\xfc\x45\x90\x7b\x96\x52\x7c\x38\xdf\x10\x07\x77\x47\x88\x71\x06\x37\xad\xcc\xa8\x44\x15\x1a\x9f\x4e\x0f\x1f\x86\xfa\xa7\x5e\xde\x7f\x06\x6b\x83\x16\x95\xb3\x20\x1f\x92\x60\xba\xaa\xb8\xf7\x1e\x68\xbd\x9a\xa8\x53\xb2\x0a\xf1\xc5\xd7\xe8\x2a\x87\xad\x11\xb5\x6d\x77\x7a\x14\x3a\x6c\x59\x91\xe7\x68\xe3\x3b\x82\x78\x5f\xae\xcb\x03\xdb\x50\x3f\x99\x72\xc0\x09\xb3\x58\x93\x69\x6c\x4a\xa7\xb0\xad\x36\x45\xcc\xe3\x51\xdd\xb8\x54\x7c\xb1\xe3\xbb\xd0\x40\xd0\x77\xd9\x3c\x11\xde\xbd\x6f\x32\xe6\x3d\x6b\xe1\x18\xe6\x5e\x3d\xfd\x7a\x15\x14\xa4\x93\x43\xa3\x94\x2a\x8b\x9b\xea\xbf\x71\x67\x3b\xfe\xb8\xa6\x07\x21\xc4\xf9\x48\xd1\xbf\x8e\xe0\x05\xd0\xd4\x76\x3a\x7f\xf7\x7e\xbf\xa5\x65\x09\x1a\xce\xcf\xfd\x55\xc2\xed\x2d\x7f\xde\xc7\xdb\x4d\x32\x6a\x9b\x7f\x74\x97\x8c\x04\x9c\x9d\x47\xfe\x7e\x37\x30\x6a\x9a\x85\xd5\x10\xad\x74\x02\x3a\x4b\x46\x96\x44\x69\x71\xe3\xa8\x71\x02\xa2\x39\x2c\x66\xc9\xc8\xbf\xf4\x21\xa1\x6f\x9e\x81\x84\xff\x68\x0d\x3e\x03\xf9\xf8\xb1\x57\x6f\xdf\xc9\xf7\x70\x0e\xa2\x39\xf1\xed\xb3\x0d\xd1\x09\xec\x6c\x2b\x34\xe2\xdb\x95\xfd\x31\xa2\x1f\xb1\x5c\x2a\x97\xc2\xfa\x18\xaa\x29\xed\x94\xbe\x90\xc4\x9d\x8f\x45\x73\x7b\xa3\x4b\x0a\xe8\xb7\xd6\x0f\x55\x32\x97\x8e\xb6\x9c\x43\xe3\x03\xc7\xf2\xc7\xd6\x5b\x9f\xf0\x4a\x27\x54\x98\xc1\xb7\x39\xfb\xc0\x0a\x64\x3f\x11\xfe\x1b\x32\xd0\xe1\x66\xc9\x92\x91\x3e\xea\x08\x3a\x9c\x90\x00\xa7\xa7\xab\xab\xb8\x73\xaf\x78\xf1\x57\x57\xe9\x04\x36\x59\x32\x8a\x9c\xcf\xce\x61\xc3\x10\xad\x83\x52\x9a\xc5\xf2\xe3\x85\xd2\x01\x77\x85\xa1\x01\xa7\xad\xbc\xe7\xc3\x70\x74\x5c\x32\xa2\x68\x5b\x31\x6c\x7d\xbd\x68\x15\x0e\xf8\xea\x1c\xd2\x14\x6e\x60\x36\xf3\x87\xb7\xe8\x83\x64\x34\x1a\xe5\x5a\x39\xa9\xd6\x98\x8c\xc8\xdf\x61\x55\x01\x85\xce\xb9\x2d\x98\x09\xef\xcf\x78\x96\x6b\x02\xbe\x65\xcd\xd1\xf0\x16\xc4\x8f\x6c\x22\xf9\x37\xc6\x3b\x5d\x32\x92\xd7\x12\x19\x1b\x5d\xb7\x74\x65\x93\xb8\x14\xb7\xab\xd3\x6c\x02\xce\xac\x31\x6e\x02\x51\xd7\xd5\x8e\x00\xf8\x10\x4e\x4b\xbf\xeb\xc4\xab\xee\xa4\xb2\xfd\x1b\xc1\x2f\x8c\x59\x82\x6c\x87\xed\x84\x42\x94\x1a\x43\x34\x08\x92\xef\x32\xc7\xad\x1b\x43\x91\xc5\x30\xf5\x19\x72\x12\x90\x8b\x10\xe0\x96\xf0\xf6\x41\xee\xbf\x8e\x97\xce\xd5\xf6\x6c\x36\x2b\x70\x83\x15\x75\x1a\xd3\x95\xfe\x5b\x56\x95\x98\x6a\xb3\x98\xa1\x7a\xf2\xf6\x72\x56\xe8\xdc\xce\xfe\xc4\xf9\x6c\xbf\x8a\xd9\xef\x58\xa2\x41\x95\xe3\x8c\x4d\x7f\xc5\x4e\xb1\x33\xfe\x3f\xe3\x9c\xf3\x26\x34\x2f\x19\xe9\x8a\xcb\x53\x5a\x3d\xc1\xd5\x1c\x0b\x2a\x26\xcd\xfe\x0c\x3b\x8b\xb7\xe7\xff\x70\x86\xe7\xb4\x1f\x9a\x5e\x7e\x3b\x1c\xec\x11\x97\x12\x56\xc6\x5d\xe7\x12\x57\x16\x37\x15\xda\x66\xe1\xdb\x25\xaa\x06\x65\x02\xf3\xb5\xa3\x3e\x53\xae\x48\xa7\x50\x8e\xaf\x5b\xc1\xe9\x84\x23\x15\xc9\xa6\xbe\xfc\xf1\x65\x45\x84\x09\x57\x48\x36\x38\xb4\x00\xad\x00\x45\xbe\x0c\xd0\x9d\xca\xd2\x78\xff\x1f\x24\x81\xfc\xd8\xe6\x4d\xee\x4f\x10\xc9\xa8\x6b\x72\x12\xf7\xfb\xe7\xba\xb9\x7b\x2a\x95\xdf\x48\xfe\x69\xdc\x4d\x99\xdf\x46\xba\xbe\x2f\xfd\xf8\x74\x71\x35\x81\x92\x04\x8d\x50\x0b\xf4\x70\x7e\x0f\x96\x63\x5d\x67\x61\x43\x7f\xa2\x96\x74\xf9\x51\x55\x99\xc0\xf5\x04\xfc\xdc\xbb\x1e\xff\x63\xa9\xce\xb3\xd7\xf5\xbe\xfe\x31\x7f\xce\x8e\xde\x51\x21\x1f\xde\x91\x4d\x68\x70\x36\x83\x5c\xe4\xbe\x63\x06\x01\x16\x95\x95\xd4\x36\xfa\xe3\x03\x9b\x26\x61\xa9\x2d\x42\xa1\xd5\x89\x83\xad\xf0\x51\x11\x02\x05\x84\xda\xc5\x03\xa2\xa5\xc3\xa2\xef\x18\xc2\x03\x9e\x69\x35\x4f\x06\xab\x9b\xbb\x3e\xa0\x75\x08\x7e\xcf\x34\xdf\xc1\x52\xa8\x82\xf4\xb8\x9d\xb7\x75\x1e\x7b\x6e\x12\x6d\x37\xdd\xa3\x51\x7d\xbd\x68\x49\x74\x53\x2b\x21\xd0\x91\xed\x8c\x32\x2c\xa7\x60\xb7\xab\xdf\x7d\xf3\x9e\x2a\xfd\xc9\xa3\x13\x76\x08\x49\x9c\x43\xfa\x28\xf5\x4e\x09\xce\x6b\xe7\xfa\x0a\xd5\xd8\xed\xea\x56\x8e\x8f\x48\x92\x91\xa6\x01\xc9\xd3\x3d\xe7\x91\xc7\xdf\x9e\xbd\xf7\xcf\xe6\x06\xc5\x35\x7d\xba\x8b\xf8\xf5\xf5\xe2\x0f\x5e\x17\x91\x7f\x0c\xe9\x94\x0e\x3d\x44\xe3\x31\xcd\x4d\x46\x3d\xe7\x7e\x4d\xe6\x3f\xe6\xce\x9e\x3f\x19\x7f\x9f\x78\x93\x11\x75\xd2\x21\x65\xc4\x36\xba\x5d\x01\xdb\x61\xe8\x5f\x43\xee\x23\x99\xaa\x96\x6d\x19\xb8\x29\x89\xcf\xe8\xf9\x57\x87\x0d\x53\x04\xdd\x57\x40\x8e\xe6\x5c\xab\x5c\xb8\x74\x02\x2b\xcb\xb5\x60\x36\x03\x59\x52\x18\x50\x2e\x12\xcd\x9b\x9c\xf0\x02\xc3\x27\xa2\xa2\x49\x73\xa5\xd1\xab\x78\x9f\xed\xa7\x62\x65\x31\xbe\xf9\x8a\xfb\x3e\xdc\xe5\xf2\x85\xe8\x52\x6c\x38\xc5\xf9\x15\x60\x6b\x01\x04\x43\xec\xb1\x4f\x3e\x68\x3b\x87\x70\xd6\xe1\xef\x54\xfd\xef\x5f\x17\x1e\x98\x87\x56\xc9\x34\x3b\xc8\xf9\x21\xf2\xdd\xff\x93\xd6\xe2\x20\xe2\x86\xeb\xfe\x43\x03\xf0\x01\x9d\xc8\xff\x69\x2b\xd2\x3b\x4b\x1c\x14\x9b\xec\x13\xbd\x8a\xdf\x33\xb1\x63\x91\x65\x0c\xc1\x7e\xb0\x1c\x78\x8d\xe5\x06\x9c\x36\xf2\x45\x20\x0c\xb7\x9c\x46\xe0\x5f\x95\xed\x53\x35\x16\x69\x16\xef\xb1\xd9\x48\x2d\x27\x79\x2f\x1d\xba\xa9\xfc\x2c\x37\x35\x7e\x5a\xa0\x8b\x5e\x3a\x74\xcb\x68\x93\xb7\x32\x42\x70\x4b\xae\xeb\xdd\xab\xf2\x77\xfc\x6b\x2d\x0d\x16\x8d\x47\xd2\xaf\x37\xa2\x0a\xbd\xf2\x30\x13\xa2\xd2\xf2\x4e\xc6\x2a\xee\x73\x3d\x29\xc8\xbb\x33\xef\xf7\xa8\x87\xbe\xcb\x3a\xeb\xb4\xfb\x75\x7e\xd8\x1c\x1a\x63\xb4\xd8\xf4\x57\x1a\x6b\x28\xb3\xf8\xb0\xf9\x47\x2c\x46\x5d\xf3\x5c\x1e\x35\xcf\x04\x16\x9b\x36\xf1\xbb\xd0\x17\xf4\x7b\xe5\x0b\xdc\xfa\xc4\xfc\xe3\xba\x2c\x8f\xb5\xca\x6d\x01\x9f\x31\x05\xcc\x77\x2e\xfc\xc8\x23\x74\x5d\x5d\x9c\xf1\x1c\xde\xbd\x27\x99\x4e\x14\xf0\x8f\x42\xfa\x3d\xd7\x9c\xce\x55\x65\x69\xd1\xd1\x20\xa3\xf2\x3a\xf9\x69\x9a\xf1\x3b\x85\x64\xc4\xef\x59\x0f\xa5\xc2\xdb\xd7\x46\x2a\x1e\x5f\x5b\x22\x22\x14\x1f\xff\x6d\xee\x39\x36\x0d\x91\x97\xa3\x3e\xc8\x2b\x8b\xff\x1f\x33\x6a\xbc\x29\x78\xcd\x7d\xbe\x95\xab\xba\x42\xff\x42\x9f\x2a\xe7\x14\x5e\xf9\xb7\x79\xcd\xa5\x8c\x7f\xdd\x6f\x97\xda\xb8\xa5\xff\xd5\x9b\x36\xfd\x33\x87\x85\xf1\x1c\x4b\x6d\xda\xb7\xf1\x59\xb8\x47\x7d\x7d\xe4\xd7\x1d\x7c\x37\xd9\xe1\xb0\xff\x89\xcd\x67\xb2\x08\xbf\xe7\x39\x4e\xe2\xb2\xfb\xd3\xa0\x84\x3d\x2c\x95\x74\x9c\x3f\xa8\xe9\xdf\x68\x59\x40\x81\xa2\x80\x5c\x17\x08\x58\xc9\x95\x54\xbe\xcd\x4a\x46\xde\xc7\xfe\xbe\xf3\xe6\x2e\x19\x5d\x51\xdd\x4b\xee\x92\xff\x0d\x00\x00\xff\xff\x14\x03\x9e\xa4\xae\x2a\x00\x00"), }, "/nosync": &vfsgen۰DirInfo{ name: "nosync", - modTime: time.Date(2018, 4, 16, 1, 47, 43, 780377829, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 120920376, time.UTC), }, "/nosync/map.go": &vfsgen۰CompressedFileInfo{ name: "map.go", - modTime: time.Date(2017, 10, 12, 19, 45, 13, 333389591, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 120920376, time.UTC), uncompressedSize: 1958, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x55\x4d\x8f\xdb\x46\x0c\x3d\x5b\xbf\x82\x3d\x55\x2e\x14\xe7\x9e\x62\x0f\x05\x7a\x29\xd0\x34\x40\xdb\x5b\x90\x03\x2d\x71\xac\x81\xe7\x43\x1d\x52\xeb\x2a\x8b\xfd\xef\x05\x39\xb2\x57\xde\x24\x45\x0f\xbd\xd9\x23\x0e\xf9\xf8\xde\x23\x67\xc2\xfe\x8c\x27\x82\x94\x79\x49\x7d\xd3\xbc\x7d\x0b\xef\x71\x02\xcf\x80\xd0\xe7\xd4\xcf\xa5\x50\x12\x88\x38\xc1\xc5\xcb\x08\x18\x73\x11\xff\x99\x86\x37\x7d\x4e\x2c\x98\xe4\x8d\xf8\x48\x10\x32\x0e\xdc\x01\x4b\x2e\xc4\x1d\x60\x1a\x60\xa0\x40\x42\x7c\xd0\x9c\xbf\x88\xa6\x64\x74\x04\x2e\x17\x88\x73\x10\x3f\x05\x82\x53\x2e\x79\x16\x9f\x88\x41\x32\xf4\x18\x02\xa0\x02\xf8\x9e\x21\x92\x8c\x79\xe0\x0d\x8a\xb0\x68\x2e\x4d\xf7\xe7\x48\xf0\x99\x4a\xbe\x62\x7d\xc4\xe0\x07\x2b\x4a\x71\x92\x5b\xd8\x4f\xf6\x3d\xce\x2c\x90\xb2\xc0\x91\xa0\xcf\x93\xa7\x01\xd0\x09\x15\x70\xbe\xb0\xc0\xcc\x74\x68\x64\x99\xc8\x82\x59\xca\xdc\x0b\x3c\x35\xbb\xa8\x4d\x7f\xf4\x49\xa8\x38\xec\xe9\xe9\xf9\xd3\xe6\x77\xf3\x6c\x54\xfd\x9a\x71\x80\x42\x32\x97\xc4\x20\x23\x29\x90\x99\x2a\x0b\x03\xf8\x64\x67\xca\x9d\x36\x8d\x70\xa6\xa5\x83\x5c\x20\xf9\x00\xde\x41\xca\x9a\xa3\x5e\xf1\x0c\x53\x21\xa6\x24\x87\x6b\x83\xf9\x0c\x85\x78\x0e\x02\x3e\x0d\xbe\x47\x21\x86\xcb\x48\x32\x52\x59\x2f\x5d\x90\xc1\xe5\x39\x6d\x4b\x1d\x1a\x37\xa7\x1e\xda\x08\x3f\xbc\xc7\x69\x6f\x10\xdb\x33\x2d\xb0\x41\xbf\x87\x76\xad\xfa\x72\xd6\x69\xbd\x63\xce\x61\xaf\xcd\xdb\x67\x3b\x7a\x80\x78\x88\x1f\xcf\xb4\x7c\x6a\x76\xb5\x53\xb8\x7d\x5c\x59\xf8\x43\xdb\x05\x26\xd9\x72\x70\xeb\xf8\x35\x20\x8b\x6e\x8d\x8a\x2f\x40\x58\x6d\xef\xb4\x24\x3c\x3c\x18\x4f\x4f\xcd\x6e\x67\x7f\x21\xe2\x99\xda\x7f\xd1\x64\xdf\xec\x9e\x9b\xdd\x15\x2d\x3c\xd4\xf4\x1b\xa5\x3e\x94\x8a\x74\x2b\x18\xfd\xed\x59\x7c\x3a\x6d\x50\xeb\xb1\x11\xe6\xee\x24\xf9\xa0\xc4\x5f\x3c\x53\x07\x5e\x56\xa3\x9b\xe5\xb6\xe9\x4e\xfe\x91\x56\x82\x6e\x3a\xea\x68\xd0\x70\xd3\x92\x41\x8a\x76\xed\x36\x64\xa9\x90\x35\xac\x03\x87\x81\xed\x73\x75\xd1\xd7\xf4\x5c\x1b\xf9\x26\x89\x2d\xf6\x32\x63\xb8\x97\x77\x85\x71\x93\xd8\xbb\x17\x21\xe1\xdd\x8b\xcc\x3f\xea\x7f\x65\xfd\x5e\x6d\x05\x6d\x04\xff\xcf\xf2\xbc\x2a\x63\xdd\xaf\x9a\xfd\x6c\x0b\xe4\xba\x47\xfe\x8b\xb7\xea\x8d\x2f\xed\xfe\x55\x57\xd5\xc2\x86\xaa\x96\x68\xe3\x21\x76\x9a\x76\xbf\x02\xf8\x1d\xd3\x89\x6c\x2b\x31\x38\x60\xfa\x6b\xa6\x24\x1e\x43\x58\x0c\x02\x61\x3f\x9a\x53\xd4\x05\x15\xd9\x6a\x98\xbb\x79\xd4\xf5\xe7\xc0\xdd\x7c\x62\x2d\x76\x50\x2c\x39\x4b\x9e\x6a\x6b\x5e\xa8\xa0\xf8\x9c\xae\xdb\xab\x56\x1f\x32\xb1\x6d\xaf\x44\x3d\x31\x63\xf1\x61\x81\x3e\x97\x42\x3c\xe5\x34\xe8\xda\xc4\xa4\x27\x89\x3d\x8b\xd6\xe6\x84\x13\x8f\x59\x20\x57\x8b\xd9\x3a\xd5\x84\x7d\x4e\x1a\xc0\xef\x20\x65\xc3\x7d\xf1\x21\xe8\x56\x7c\xf4\xec\x85\x06\x88\x3a\x1d\x32\x62\x82\x9c\x7a\xea\xe0\x38\xcb\xbd\x4f\x8d\xf8\xb4\xe8\x65\x4d\xa8\x2b\xbd\xae\xba\x5c\x56\x99\x86\xbb\x7d\xdd\xad\x4d\x44\x5c\xa0\x90\x0b\xd4\x8b\xdd\x8f\x38\x4d\x3a\x74\x75\xdc\x50\xae\x09\x5d\xc9\xd1\x02\xa6\xec\x93\xc0\x30\x17\x8d\xd2\xfa\x2f\x52\xdc\xd3\xa3\x99\x8f\x04\x1f\xda\xdf\xf6\xf5\x81\xd2\xe0\x34\xc7\x23\x15\xed\x9f\x02\x45\x6d\x79\xbb\x8b\x49\x47\xd4\x6f\x14\xb1\xca\x36\x75\xf5\x5d\xb0\x97\xcf\xde\xb6\x4d\x26\x73\xc1\x6b\xbf\x19\x86\xd6\x81\x9e\x7e\x73\x1a\x6f\x13\xa7\xdd\x9e\x3b\x78\xd4\x69\xab\xea\xab\x23\xd5\x8a\xde\xc1\x77\xae\xd5\x6f\x16\xb8\xdb\x1d\x0b\xe1\xb9\xd9\xa9\x37\xf5\xad\xf9\x27\x00\x00\xff\xff\xe8\x19\x65\x16\xa6\x07\x00\x00"), }, "/nosync/mutex.go": &vfsgen۰CompressedFileInfo{ name: "mutex.go", - modTime: time.Date(2014, 12, 8, 0, 47, 30, 0, time.UTC), + modTime: time.Date(2015, 7, 29, 17, 18, 1, 240870824, time.UTC), uncompressedSize: 2073, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x54\xcb\x6e\xdb\x30\x10\x3c\x4b\x5f\xb1\xc9\xc9\x4e\x62\xa5\xbd\xb6\xf5\xa1\x68\x81\x22\x40\x7a\x09\x50\xe4\x4c\x53\x2b\x99\xb0\x44\x1a\x24\x55\xd5\x4d\xf2\xef\xc5\xf2\x21\xcb\x92\xec\xc4\x2d\xaa\x93\xb0\xe4\xce\xce\xec\x0c\xb8\x65\x7c\xc3\x4a\x04\xa9\xcc\x4e\xf2\x34\xbd\xbd\x85\xef\x8d\xc5\x5f\x20\x0c\x30\xc8\x9b\xba\xde\x41\xbb\x16\x7c\x4d\x05\xa9\xe4\x62\x55\x29\xbe\x11\xb2\xcc\x52\xbb\xdb\x62\xb8\x6c\xac\x6e\xb8\x85\xa7\x34\xa1\x53\xcc\x61\xa5\x54\x95\xbe\x38\xb8\x7b\xc5\x37\x40\x65\x03\x75\x06\x77\xd6\x23\xeb\x46\x2e\xac\xa8\x11\x50\x6b\xa5\x41\x14\x50\xbb\x83\x4a\x23\xcb\x77\xe0\x61\xb2\xb4\x68\x24\x87\x59\x0d\x57\x6e\xce\xdc\x81\xcd\xe6\x34\x88\x3a\xb2\x30\xed\x29\x4d\x92\x2d\x93\x82\xcf\x2e\xbd\x8e\x0f\x50\x77\x22\x0e\x10\x2f\xe7\x69\xf2\x92\x26\x5d\xe7\x12\xac\x6e\x30\x30\xfd\x21\xa9\x0a\x8d\x7c\x2b\x5b\xa9\xec\x51\xa6\x1e\xac\xe3\x7a\x71\x8a\xac\x9f\x08\xaa\x08\x7f\x98\x7b\xfe\x63\xb6\x05\xab\x4c\xa4\xfb\xf0\x78\x96\x53\xf1\xfa\xde\xab\x56\x0b\x8b\xf7\x1e\x9a\x3e\x67\x5a\x42\xeb\xa2\xe2\x17\xd5\x48\x8b\x1a\x84\xb4\x13\x4e\x42\xa1\x34\x10\x00\x0d\x38\xb1\x27\xdd\x8e\x4d\x70\xbd\x54\x10\xb2\x84\x1e\x4c\xd8\xa1\x6e\xe1\x2a\x90\x1d\x18\xae\xdb\x6c\xc8\xee\x62\x09\xef\xe0\xf9\x99\x8e\xfa\x72\xce\x4e\xc4\xa0\xff\x54\x2e\x74\x7b\x9e\xf8\x7d\x4a\x0e\xfa\xa6\xd4\x0e\x43\xf3\xba\xaa\x57\xa2\x33\x92\x75\x10\xa0\x91\xa1\xc1\x94\xff\x69\xe8\xc3\xd0\xd1\x7f\xb5\x6d\x90\x88\xeb\xeb\xa8\xae\xb3\x2d\x57\x48\x5a\x8c\x90\x65\x85\x41\x35\x67\x55\xf5\x11\x84\x05\x77\x48\x16\xb1\xa2\x40\x6e\x41\xd9\x35\x6a\x30\xa2\x6e\x2a\xcb\x24\xaa\xc6\x38\x65\xa8\xcd\xd9\x4e\xc7\x6d\x4e\xae\x61\x60\xf5\x44\xb4\x97\x14\xed\xbf\xb2\x7c\x80\xb4\x58\x84\x95\x3c\x32\x61\xbf\x69\xd5\x6c\xdf\xfa\x66\xec\x1b\xf6\xaf\x06\x1f\xbd\x0b\x9f\xf3\x1c\x58\x9e\x1b\xc8\xb1\xb2\xec\x26\x20\xd6\x6c\x07\x2b\x04\x89\x25\xb3\xe2\x27\xde\x80\x55\x60\xd7\x7d\xcc\xbb\xc2\x15\x22\x60\xe9\x9c\xe8\xae\x13\xaa\x53\x6e\xe2\x02\xdb\x12\xae\xba\xee\x39\x5d\x98\xb9\x89\x44\xc5\xed\xb1\x2d\xb3\x08\x76\xbd\xf4\x6c\xdc\x72\x7b\xf5\x4f\x87\x3b\xf5\x1b\x8d\x43\x7b\xdc\xc2\x7d\xbf\x53\x2f\xf3\xab\x92\x08\x39\x72\x8d\x35\x4a\x6b\x06\x62\x42\xc3\x11\xae\xd4\x3b\x8b\x1c\x89\xf8\xe2\xfd\xbc\x67\x4a\x10\x4a\x49\x9a\x44\x8d\xe1\xfa\x8d\x5a\x1d\x99\x40\xbf\x5d\x9a\x7a\x82\x2f\x96\x53\x8a\xc7\x13\x22\x7c\x54\xfc\x27\x00\x00\xff\xff\xec\x95\x29\x83\x19\x08\x00\x00"), }, "/nosync/once.go": &vfsgen۰CompressedFileInfo{ name: "once.go", - modTime: time.Date(2014, 12, 8, 0, 47, 30, 0, time.UTC), + modTime: time.Date(2015, 7, 29, 17, 18, 1, 240870824, time.UTC), uncompressedSize: 1072, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x53\xcb\x92\xda\x40\x0c\x3c\xdb\x5f\xd1\xb5\x27\x9c\xa2\xe0\xbe\xa9\x1c\x52\xc5\x65\x4f\x39\xe4\x0b\xc4\x58\x03\xca\x0e\x1a\x32\x0f\x58\x67\x8b\x7f\x4f\x69\x6c\x08\xb9\xd9\x92\xba\xd5\x6a\x69\xce\xe4\xde\xe9\xc0\xd0\x98\x27\x75\x7d\xbf\xdd\xe2\x87\x3a\x86\x64\x90\x22\xee\x7f\xb1\x2b\x28\x47\x2a\xb8\x4a\x08\x38\x73\xf2\x31\x9d\xc0\x1f\xe4\x4a\x98\x10\x95\x41\xae\x48\xd4\x4d\x5f\xa6\x33\xcf\xe0\x5c\x52\x75\x05\x9f\x7d\x37\x46\xd1\x03\xf6\x31\x06\xfb\x56\xc6\xfc\x7d\x6b\x8d\x76\x11\x8e\x42\xc8\x28\x47\x86\xaf\xda\x78\xe0\x21\x1e\xa4\x23\xa2\x86\xc9\xbe\x77\xd1\xd4\xec\xd9\x98\xac\x9e\x47\xf8\x98\x0c\x64\x24\x5e\x52\x2e\x28\x72\xe2\x25\x2a\x19\xa2\xb9\x90\x09\x89\xbe\x09\xda\xe0\x4d\x11\xcb\x91\x13\xae\x31\x8d\x79\x8d\x83\x5c\x58\x0d\xde\x5d\x28\x21\x5a\xad\x15\x5a\x44\x7c\xfb\xdf\xec\xe2\xca\x0f\xd6\x79\xe9\x79\xaa\xa1\xc8\x39\x70\xeb\x95\xd7\xb3\xbc\xa6\xbc\x29\xb0\xaa\xd9\x23\xd1\x4b\x7c\x67\xf8\xb5\xb1\xf1\x85\xd5\x28\x3d\x8e\x94\x41\x18\xc5\x7b\x4e\xac\x05\x17\x0a\x95\x21\x0a\x26\x77\x6c\x20\x47\xcd\x48\xe0\x3b\x94\xaf\xcf\x53\x3c\xaf\x25\xf1\xef\x2a\x69\x31\xa1\x61\x1f\xd6\x95\x08\xfe\x60\x57\x0b\x6f\xfa\xed\x76\xb1\xb8\xf9\x51\x58\xc7\x05\x22\x2a\x45\x28\xc8\x1f\x9a\x31\xb6\xdb\x53\xcd\x05\x7b\x46\xaa\xfa\xb4\x5a\x33\x0e\x3f\xc5\xfa\x36\x05\x92\xa1\x12\x68\x14\xb7\x86\x14\x9c\x68\x32\x8c\xb2\xe3\x9c\x29\x4d\xd6\xbe\x66\x06\xfd\x13\x14\xa4\x70\xa2\x60\x19\x47\xe7\x52\x13\xdf\xd7\x46\xe9\x50\x4f\xac\x25\x5b\x8e\xfe\x1b\x61\xcf\x8b\x85\x23\xf6\x13\x76\xf1\xb5\xed\xc9\x45\xf5\x72\xd8\x3c\x56\x53\xd5\xad\x06\x7c\x62\x89\xdb\x54\x2b\x2f\x81\x95\x4e\x3c\xe0\x36\x2c\x06\xbc\x99\xf5\x8e\x6a\xe6\x6c\x66\xcc\xf4\xf3\x46\xdb\x10\xf3\x55\x93\x8a\xdb\x3c\x23\x5a\x24\xaf\xdb\x89\x46\xcd\x32\x72\xca\x56\x5e\x22\x8e\x74\x61\x24\x2e\x35\x29\x8f\x5f\xe1\x6b\x1b\x6b\x3e\xe4\xd8\xae\x75\x4e\x1a\xd7\x55\xca\x31\xd6\xf9\x38\xec\x7c\x7d\x6b\x62\xda\xb1\x8a\xf8\x62\x2b\x1d\x60\xd3\x60\x9e\x67\xb0\x37\x63\x07\xb8\x69\x8f\xe5\xb3\xef\xba\x85\xac\xbb\x3d\x12\x46\x64\x99\xa6\x71\xf5\x32\xbf\xdc\xd7\xfb\x6b\xe2\xb1\x75\x15\x85\x7f\x19\x1a\xec\x8e\xf9\x86\x92\x2a\xf7\xdd\xc8\x9e\x13\xee\x06\xf6\xdd\x53\x81\xa7\x90\x79\x89\x28\x3f\x10\xb7\xd5\xd0\x77\x7e\x35\xf4\xb7\xfe\x6f\x00\x00\x00\xff\xff\xf9\x72\xbe\xa9\x30\x04\x00\x00"), }, "/nosync/pool.go": &vfsgen۰CompressedFileInfo{ name: "pool.go", - modTime: time.Date(2014, 12, 8, 0, 47, 30, 0, time.UTC), + modTime: time.Date(2015, 7, 29, 17, 18, 1, 240870824, time.UTC), uncompressedSize: 2130, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\x55\x3f\x93\xdb\xc6\x0f\xad\x4f\x9f\x02\xbf\xea\x77\xca\xe8\x74\x49\xeb\x99\x2b\x32\x29\x1c\x37\x89\x8b\x74\x1e\x17\x10\x09\x8a\x88\x97\x0b\x06\xc0\x4a\xa2\x3d\xf7\xdd\x33\x58\xfe\x39\x39\xee\x44\xee\xf2\xe1\xe1\xbd\x07\x68\xc4\xe6\x0b\x9e\x09\xb2\xd8\x94\x9b\xdd\xee\xf9\x19\x7e\x85\x8f\x22\x09\xd8\x00\xc1\xc8\x41\x3a\x70\x1a\x46\x51\xd4\x09\xe4\xf4\x37\x35\x6e\xe0\x3d\x3a\x0c\x38\xc1\x89\x80\x73\xcb\x17\x6e\x0b\xa6\x34\x81\xe1\x85\x5a\xc0\xdc\x06\x94\x92\x2b\xd3\x85\xda\xe3\xee\xf9\xb9\x62\xe7\x09\xd8\x69\x00\x73\x51\x6a\x81\x33\x78\x4f\x73\xc1\x05\x4d\x69\x90\x0a\x51\x5c\x06\x74\x6e\x2a\x2c\x3a\x60\x9e\xc0\x79\x20\xb8\xb2\xf7\x52\x3c\xf0\xb2\x38\x77\xdc\xa0\xb3\xe4\x23\x7c\xe8\xde\xd0\x7a\x49\xad\xd5\x47\xc9\x69\x02\xa5\x8e\x94\x72\x43\x70\xed\x29\x8a\xb2\x41\x8f\xe3\x48\xd9\x0e\x71\x2b\xc0\x2a\xb1\x81\xcf\xbd\x07\x8f\x96\x30\x25\x69\xd0\xef\xd8\x6f\xca\x18\x76\x04\x9d\x28\x14\x23\x38\x4d\x30\x94\xe4\x3c\x26\x82\xb3\xa8\x14\xe7\x4c\x06\xc6\xf1\x16\x33\x49\xb1\x34\xad\x18\x81\xf0\x7f\x83\xb1\xe8\x28\x46\x81\xe5\x02\x0d\x36\x3d\xc1\x56\x0f\x4e\xc5\xa1\xe4\x62\xa1\x90\xd3\x60\xb5\x54\x42\x27\x05\xa5\x62\x74\x98\xc5\x4d\x4c\x17\xce\x67\x18\x95\xcc\x8a\x46\xab\xb5\xe3\x33\xea\x29\x4c\x6d\x24\x25\x6a\x5c\xf4\x08\x7f\x85\x5f\x6c\x07\xe0\xb0\xed\x0b\x59\xfc\x20\xb4\x09\x5c\x02\xec\x54\x38\xb5\x40\x5d\xc7\x0d\x53\xf6\xd0\x44\x09\xdb\xa7\xb9\x51\x25\x82\xc4\xe6\x76\x84\xdf\xe5\x4a\x17\xd2\x0a\xc4\x16\x06\x80\x15\x76\x3c\xa5\x59\x10\x4c\x29\xf0\xee\x3e\xd9\xac\x07\x1c\x47\x95\x51\x19\x9d\xaa\x70\xd2\x01\x6e\x92\xba\xc0\x80\x39\x68\x23\x9c\x55\xca\xf8\x7d\xf0\xaa\x0e\x81\x63\x9c\x28\x7b\x24\xad\xc7\x88\x10\x0e\x92\xcf\x11\x38\x18\xc5\x29\x3b\xd7\xbc\x54\x99\xda\xb0\xa6\x91\xdc\x14\x55\xca\x1e\x41\xa5\x91\x72\x4b\xb9\x86\xa7\x49\xd1\xaa\xcd\x34\x96\x41\x38\xce\x7c\x46\x95\x0b\xb7\x14\x23\x70\xc5\xd0\x28\xca\xa8\xf3\xd7\xcd\x25\x96\x0c\x72\x21\xed\x09\x6b\xd4\xb1\x51\x31\x8b\x16\xa6\x15\xf8\xae\x73\xba\xe1\x10\xf1\x90\x0e\xce\x22\xed\x8f\xdd\x2f\x83\xd0\x0d\xbe\x32\x39\xc0\xb5\xe7\xa6\x87\x01\x39\x3b\x72\x36\xc0\x00\x6b\xa7\x8c\xc3\x3c\x14\x4f\xc6\x5f\xa9\x9d\x47\xe9\x3f\x53\x5a\x7c\x2c\x0e\xa7\xd2\x75\xa4\x16\xee\xd3\x72\xcd\x1a\x4c\x64\x50\x72\x4b\x1a\x70\x49\xb0\x85\xc7\x3a\x13\x95\xfa\x5d\x7e\x51\x09\xb0\x71\xbe\x50\x9a\x60\x54\xce\xce\xf9\xbc\xaf\x4a\x5b\xaf\x9c\xbf\x58\x9d\xa5\x40\xf9\xa7\x30\x59\x43\xd9\xd7\x96\xff\x9c\xdb\x11\xef\x49\xa1\xc7\xdc\x1e\x00\xdf\x32\xb1\xf5\x14\xf6\x19\x8c\xa8\x3e\xab\x61\xbd\xa8\x3f\x25\x8e\xf9\x9f\x37\x0d\xb0\x2d\x73\x1e\xc7\x6b\xd0\x42\xbe\x1a\xb6\xaa\xdf\x01\x8c\x63\xb2\x6b\xc5\xc5\x12\x68\x85\xe6\x74\x6e\xc6\x5d\x29\x25\xe0\xca\xb7\x6e\xaf\x20\x8c\xca\x72\x84\x0f\x35\xca\x43\xe8\xb3\x4d\x40\x78\xde\xe3\x85\xc0\x4a\xd3\x6f\x6b\x8f\xc3\xc5\xa1\x1e\xf7\xc4\x0a\x72\xcd\xdf\xa5\xbd\xf6\xef\xd3\xb8\x2c\x21\x73\x2d\x8d\xc3\xb7\xdd\xc3\xac\xfe\xa7\xcf\x9c\x9d\xb4\xc3\x86\xbe\xbd\xee\x1e\xfe\xa0\x2b\x00\x74\x25\x37\x8f\x7b\xb8\x3f\x79\xad\x8b\xf8\x3d\x39\x18\xa5\x5a\x18\x33\xa0\x9e\xd8\xb7\x59\x80\x4e\x65\xd8\xd6\xdd\x61\x59\x9b\x75\xac\xd7\x93\x75\xdd\x1c\xaa\x67\x4a\x5e\x34\xd7\x0b\x2e\xf5\xc3\x08\x11\xe9\x71\x2d\x15\xfb\xb7\xe9\x25\xb6\x92\x0b\xf0\x39\x07\xe3\xb8\x37\x46\x2b\x01\xe1\x4a\xb1\x45\x3c\x4c\xa3\x61\xf4\xba\xd4\xe0\xb7\x0a\x63\x61\x5e\x49\xed\xac\xb9\x59\x19\xa8\x6e\x6c\xa5\x34\x0f\xcb\x89\xfc\x4a\x94\xe1\x82\xa9\x50\x98\x6e\x31\xa0\x2e\xf0\xb1\xf8\xfa\x7f\x11\xd5\x96\xf3\x99\xee\x3c\xc2\xef\x69\x0b\xd6\x87\xae\x72\xbd\xd6\x52\x35\x5e\x57\x36\x5a\x6e\x43\xe6\x99\xe8\x78\x0c\x69\xeb\x7a\xca\x4f\x99\xd3\xa1\x7e\xb4\x28\xb0\x16\x52\xb2\x92\x6a\xf0\x42\x88\xba\x47\xe3\xb3\xe3\x2e\x0c\x81\xc7\x11\x7e\x0a\xf1\xf6\xf1\xe9\xf7\xf6\x84\x9f\xdc\x41\xa2\xfc\x38\x1e\xab\xb1\x7b\x78\x79\x81\x9f\xe3\x7d\x1c\xcc\xd5\xff\xf7\x52\xe9\xc4\xbb\x87\x85\x5e\x3d\x78\xdc\xef\x1e\x1e\x5e\x77\xdb\xcb\xcc\x69\x17\xcf\x37\x78\xf7\x02\x0b\xde\xa7\x7b\xec\xa7\x5f\x3e\xef\x1e\x96\x07\x78\xbb\xf2\xee\x87\x3b\x0b\xe0\x6d\x89\x4f\xd5\xb5\x6d\x0d\x6e\xab\xe1\x61\xe4\x0f\xed\x7d\x2c\xfe\x78\xbb\x6f\x6f\xbf\xf4\x77\x8b\xa6\xd6\x16\x66\xec\x4a\xf4\x8d\x4a\xfd\xff\x6c\x57\x12\x07\xb8\xed\x77\xaf\xbb\x7f\x03\x00\x00\xff\xff\x07\xba\x3e\x57\x52\x08\x00\x00"), diff --git a/compiler/natives/fs_vfsdata.go b/compiler/natives/fs_vfsdata.go index e357b8d2f..8df56ef4f 100644 --- a/compiler/natives/fs_vfsdata.go +++ b/compiler/natives/fs_vfsdata.go @@ -21,532 +21,532 @@ var FS = func() http.FileSystem { fs := vfsgen۰FS{ "/": &vfsgen۰DirInfo{ name: "/", - modTime: time.Date(2018, 4, 4, 21, 17, 1, 613289444, time.UTC), + modTime: time.Date(2018, 7, 7, 8, 21, 7, 519593188, time.UTC), }, "/src": &vfsgen۰DirInfo{ name: "src", - modTime: time.Date(2018, 4, 4, 21, 34, 44, 576967800, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/bytes": &vfsgen۰DirInfo{ name: "bytes", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 218527662, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/bytes/bytes.go": &vfsgen۰CompressedFileInfo{ name: "bytes.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 218527662, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), uncompressedSize: 508, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x90\xcd\x4e\xc3\x30\x10\x84\xcf\xde\xa7\x18\x6e\x8d\x68\x55\x72\x45\x4d\x0f\x20\x0e\x3c\x43\xd5\xc3\xda\xdd\x54\x86\xe0\x14\x27\x91\xa8\x50\xde\x1d\xd9\x71\x1a\x19\x55\xca\x21\xde\x9f\x99\x6f\x67\xbb\xc5\xa3\x1e\x6c\x73\xc2\x47\x47\x74\x61\xf3\xc9\x67\x81\xbe\xf6\xd2\x11\xd5\x83\x33\x78\x77\x27\xf9\x79\xb9\xf6\xb2\xea\x70\x38\x86\xce\x1a\x26\x4e\x14\xb0\xae\xc7\x2f\xa9\xba\xf5\xb0\x6b\x68\x3c\x57\xf0\xec\xce\x82\x2e\x94\x95\xad\xa1\x51\x55\x30\xf1\xa5\xbc\xf4\x83\x77\xb0\xa4\xd4\x48\xe1\x4b\x85\x4d\x49\x63\x32\x7b\xfb\x1e\xb8\x59\x71\xd0\x9a\xbc\x0a\xe8\xb6\x6d\xc2\xbe\xad\xd1\x88\x5b\x71\x81\x87\x2a\xfe\xe9\x22\xca\x26\x91\x9a\x9b\x4e\xa2\x6a\xa2\x31\x0b\x0d\xcf\x34\x26\xec\xea\x83\x3d\x66\x40\x69\x35\x87\xea\xfd\x20\x37\xac\xd7\xf6\xeb\xc2\x5e\x72\xb0\xfc\x78\xc3\x77\xfc\x2c\xf6\x19\xeb\x2c\x5e\x4e\x6e\xca\xc4\xc8\x02\x50\xe2\x63\xec\x60\x74\x36\xbb\x99\x87\xa7\xfe\xfe\x7f\xbf\xbc\x91\x2f\x09\xed\xee\x04\x14\x74\x96\xf3\x9e\x68\xa4\xbf\x00\x00\x00\xff\xff\x23\x2d\xfc\x5d\xfc\x01\x00\x00"), }, "/src/bytes/bytes_test.go": &vfsgen۰CompressedFileInfo{ name: "bytes_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 218527662, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 215, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\xcc\xc1\x4a\xc4\x30\x10\x87\xf1\x73\xe7\x29\x86\x5c\x6c\x55\xba\x8f\xb1\xe0\xb5\xde\x44\x24\x4d\xff\xb6\xe3\xa6\x93\x90\x99\x22\xab\xf8\xee\xb2\xe0\xc5\xeb\xc7\x8f\xef\x74\xe2\x87\xf9\x90\xbc\xf0\x87\x11\xd5\x98\x2e\x71\x05\xcf\x57\x87\xbd\x39\xcc\x89\x64\xaf\xa5\x39\xf7\xd4\x85\x5b\x10\x5d\x03\x0d\x44\xef\x87\x26\x5e\xa2\xae\x68\xe5\xb0\x29\x4b\x42\xef\x7c\xff\x47\xc6\xe7\x81\x5f\x5e\x6f\x1b\xfe\xa6\xce\xc7\xe9\x22\xb5\x0f\xff\x39\x37\x64\x81\x71\x51\xb6\xab\xa5\x98\xf3\x78\x86\xd7\xb8\xc2\xe4\x0b\x8f\xfc\xb9\x49\xda\xf8\x5c\xea\x86\xf6\x34\xf1\x52\x60\x7a\xe7\x2c\x7b\xcd\xd8\xa1\x1e\x06\xa2\xae\x46\x95\xd4\x87\x43\x1b\x62\xda\xe2\x9c\x11\x06\xfa\xa1\xdf\x00\x00\x00\xff\xff\x25\x40\x6e\x83\xd7\x00\x00\x00"), }, "/src/crypto": &vfsgen۰DirInfo{ name: "crypto", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), }, "/src/crypto/rand": &vfsgen۰DirInfo{ name: "rand", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), }, "/src/crypto/rand/rand.go": &vfsgen۰CompressedFileInfo{ name: "rand.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), uncompressedSize: 1175, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x53\x4b\x6f\x9b\x40\x10\x3e\x7b\x7f\xc5\x94\x56\x15\xdb\x38\x50\x29\x4a\x0e\xa9\x5c\x29\x8d\xa2\x28\x97\xb4\x8d\xfa\x38\x54\x3d\x2c\x30\xc0\x3a\x30\x4b\x77\x07\x53\x2b\xe2\xbf\x57\xb0\xe0\xb8\x89\xab\x5e\x0c\xeb\xef\xb5\xf3\x20\x8e\xe1\x28\x69\x75\x95\xc1\xda\x09\xd1\xa8\xf4\x5e\x15\x08\x56\x51\x26\x84\xae\x1b\x63\x19\x42\xb1\x08\xd0\x5a\x63\x5d\x20\xc4\x22\x28\x34\x97\x6d\x12\xa5\xa6\x8e\x0b\xd3\x94\x68\xd7\xee\xf1\x65\xed\x02\x21\x85\xc8\x5b\x4a\x41\x93\xe6\x50\xc2\x83\x58\xdc\xa1\xca\xd0\xc2\x0a\x5e\x5b\x2a\xfc\xe1\xa1\x17\xbd\x10\xbc\x6d\x10\x76\xff\x81\x63\xdb\xa6\xfc\xd0\x4f\x06\xa1\x85\x37\x3b\x50\xc2\xf0\x0c\x13\xf8\xf1\x33\xd9\x32\x4a\x08\x09\x34\xf1\x12\xd0\x5a\x18\xaf\x37\x46\x29\x6b\xd5\x16\xce\x57\xb0\x76\xd1\x0d\x31\x5a\x52\xd5\xc7\x64\x8d\x29\x87\x89\x8c\xae\x91\xc3\xe0\xd5\xc8\x09\xa4\x58\x98\x3c\x77\xc8\xff\x61\x7b\x52\x20\x07\x42\x28\x85\x58\xc4\x31\x24\xd6\x74\x0e\xad\x58\xa4\x76\xdb\xb0\x99\x1c\xae\x2b\x93\xa8\xca\xcb\x3c\x30\x84\xe8\x1c\x26\xd6\x6a\x64\x7d\xa5\x0c\x73\x4d\x98\x0d\xd7\x9d\x0d\x9e\xe9\x6b\x77\xb9\x73\xe8\xf7\x4d\x5e\x1c\x30\xd9\xa1\x5e\x5b\x20\xdf\x29\xca\x4c\xfd\x4d\x55\x2d\xba\x40\x1e\x14\x2d\x08\x56\x50\x21\x85\x89\x1c\x4e\x3a\x07\x82\xf7\x70\x76\x7a\x7a\x72\xe6\xf1\xa1\xd0\x8b\x8d\xd1\x19\x7c\x6e\x0d\xab\xab\xdf\x29\x62\x86\xd9\xd5\xd0\x6b\xe0\xd2\x9a\x8e\x20\xd9\xc2\x93\xb4\x59\xd9\x95\x48\x83\x7d\xc1\x25\x68\x07\xb5\xb1\x08\x5c\x2a\xf2\x09\x4b\x50\x0e\x5c\x83\xa9\xce\x35\x66\xa0\x69\x96\x95\xcc\xcd\x79\x1c\x77\x5d\x17\x75\x27\x91\xb1\x45\xfc\xe5\x2e\xfe\x8e\x89\xef\xc6\xc5\xa7\x9b\xf8\xa5\x7f\x3d\xae\x91\x4b\x93\x1d\x1f\x8a\x1f\x2a\x1b\x63\x86\x53\x3f\xfc\x4c\xed\xb9\x54\x55\xf5\xbc\x3f\x4b\x18\x37\x62\x42\x5d\x9b\xf8\x05\x59\x82\x1f\xfd\xfc\x3c\x22\x39\x76\xca\x22\xb7\x96\x80\x96\x40\xba\x12\x63\x40\xef\xd7\xe2\xd6\x64\x18\xad\xdd\x38\x2e\x8b\xbf\x5a\x6d\xf1\xc0\x6a\x4c\x48\x20\xdf\xed\x48\xff\x18\xaa\x1d\x6f\xf9\x61\xcb\xe8\x06\x9f\x89\x1d\xdd\xd0\xc6\xdc\xe3\xe3\x8e\x4d\xb6\x8f\xe4\xd1\x7a\x4f\x7b\x70\xfc\x7f\xd5\x8c\x1c\x2c\xf7\x25\x73\x86\xdf\x0f\x39\xb7\x60\xbf\x7e\x0f\x3d\x69\xc2\x84\xbd\x5d\xfa\x4f\xd2\x45\xb7\xd8\xcd\x17\x8d\x07\x7f\x20\xc3\xa0\x36\x4a\x57\x2a\xa9\x10\x34\x01\x97\xda\x01\xd2\x46\x5b\x43\x35\x12\x07\x52\xf4\xe2\x4f\x00\x00\x00\xff\xff\xe9\xf9\x0b\x94\x97\x04\x00\x00"), }, "/src/crypto/x509": &vfsgen۰DirInfo{ name: "x509", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/crypto/x509/x509.go": &vfsgen۰CompressedFileInfo{ name: "x509.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 177, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x34\x8d\xb1\x6e\xc2\x40\x10\x05\xeb\xec\x57\x3c\x5d\x65\x27\x51\x9c\x26\x45\xd2\xa6\x88\x94\x02\x21\xfc\x05\x67\x7b\x81\x83\xf3\xed\x69\x6f\x0d\x58\x88\x7f\x47\x58\xa2\x1d\x8d\x66\x9a\x06\x6f\xdd\x14\xe2\x80\x43\x21\xca\xbe\x3f\xfa\x1d\xe3\xf2\xf5\xf9\x4d\x14\xc6\x2c\x6a\x70\xac\x2a\x5a\x1c\xd1\x76\x4a\x3d\xa2\xf8\xa1\x9d\x8b\xf1\xb8\x11\xb1\x52\xd5\xa8\x5e\x7f\x59\x6d\x2d\x12\xdf\xb1\xb8\x35\xae\xf4\xa2\x6c\x93\x26\xa4\xf0\xa4\xe5\x63\xc5\xe7\xca\xf5\x3a\x67\x93\xe6\xb1\xf8\x41\x59\x42\x50\x11\x43\x16\x89\x08\x05\x49\x0c\xfe\xe4\x43\xf4\x5d\x64\x84\x84\x3f\xc9\x7b\xd6\xff\xd6\xd5\x74\xa3\x7b\x00\x00\x00\xff\xff\xa1\x8b\x91\x39\xb1\x00\x00\x00"), }, "/src/crypto/x509/x509_test.go": &vfsgen۰CompressedFileInfo{ name: "x509_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 364, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x90\xb1\x0e\x82\x40\x0c\x40\x67\xfb\x15\xcd\x4d\xa0\x09\xb8\x38\x38\x1b\x07\x37\x23\x84\x1d\xb1\x90\x13\xb8\x92\x6b\x31\x12\xe3\xbf\x1b\xd1\x49\x17\xc2\xdc\xf7\x5e\x9b\xc6\x31\xae\xce\xbd\x6d\x2e\x78\x15\x80\x2e\x2f\xea\xbc\x22\xbc\x6f\xd6\x5b\x00\xdb\x76\xec\x15\x8d\x92\xa8\x75\x95\x01\x28\x7b\x57\x60\x4a\xa2\xc9\x20\x4a\xed\x8e\xbc\x1e\x99\x9b\x40\x71\xf9\x85\xa2\x34\xc4\x07\x2c\x34\x4a\x6a\xdb\x05\xc6\x31\xca\x88\xa2\x67\x56\x31\x21\x3c\xff\x2a\xa7\xf7\x64\x6e\x62\xef\x6e\x59\xee\x67\xeb\x9f\x0b\x32\xf2\xb6\x1c\x26\x34\x7e\xec\xc3\xf8\xa0\x29\xcb\x47\xf1\x15\x00\x00\xff\xff\xa4\x46\xbd\x49\x6c\x01\x00\x00"), }, "/src/database": &vfsgen۰DirInfo{ name: "database", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/database/sql": &vfsgen۰DirInfo{ name: "sql", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/database/sql/driver": &vfsgen۰DirInfo{ name: "driver", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/database/sql/driver/driver_test.go": &vfsgen۰CompressedFileInfo{ name: "driver_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 1185, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x53\x4d\x8f\xd3\x30\x10\x3d\x93\x5f\x31\x9a\x03\x38\x60\x35\xc9\x0a\xad\x44\x24\x2e\xb0\xe2\xba\x1c\x7a\xdb\xf6\xe0\x24\x0e\x32\x18\x3b\xf8\x23\xa5\xaa\xfa\xdf\x91\xe3\x06\xa4\xd6\x6d\xc3\x25\x9e\xcc\x9b\x79\xf3\xe4\x79\x2e\x0a\x78\xd7\x78\x21\x3b\xf8\x6e\xb3\x6c\x60\xed\x0f\xf6\x8d\x43\x67\xc4\xc8\x4d\x96\x8d\xcc\xc0\xc8\xa4\xe7\x9f\xb5\x1a\xb9\x71\xdc\xac\xb9\x75\x16\x3e\xc2\xcb\xf6\x32\x7f\xc8\x5e\x1d\x3e\x69\x2d\x29\xa0\x33\x9e\x23\x85\x70\x50\x40\x3c\xd2\x7f\xd0\xfa\x2a\xf4\xb2\x6d\xf6\x8e\x13\x74\x98\x27\xf1\x98\x4a\x71\x56\x69\xc2\x2a\x99\x15\xca\x3d\xbe\x27\x55\x7a\x86\x17\xca\x55\x8f\xd7\x50\xec\x99\xb4\x41\xfd\x74\x9e\x81\xa7\x5c\x0a\xc2\xf2\x4a\x4f\x99\x4e\x47\x89\x65\x9e\x46\x4f\x1a\x2f\xe1\xb6\x86\xb9\xbf\x06\xec\xb5\x46\x0a\xdc\x98\x1a\xd0\xfe\x92\x45\x5c\x6a\x0d\xad\xf6\xb2\x53\x6f\x1c\xb4\x71\x79\xb0\x09\xa5\x1b\x0c\x53\x35\xb8\xfd\xc0\xa1\xd1\x5a\x26\x28\x1f\x16\xd1\x3d\x24\x89\x9e\x78\xcf\xbc\x74\x5f\x99\x61\x3f\xb9\xe3\xe6\xaf\x73\x28\x28\xbd\x3b\x7d\xf0\x6e\x2d\x79\x3b\xdd\x4d\x4e\x94\x90\x39\x05\x25\xe4\x92\xae\xd7\x4c\xd9\x5d\x08\xe6\x73\x41\xcb\xb9\xaa\xa2\xb8\x55\x2e\xc8\x87\x7c\xde\x5b\x88\x42\x0f\x14\x05\xac\x9f\x9f\x9e\x6b\xf8\x22\x7e\xaf\x6e\x8f\xeb\x49\xb9\x0a\xa6\xeb\xa5\x66\xd3\xee\xa7\xbf\xfb\x32\x1b\x12\x6c\x7a\xe6\xd6\xdb\x52\x1b\x7b\xa8\x8e\xf3\x6b\x9b\xc2\xff\x15\x6b\x09\xb2\xf0\x46\x91\xe1\x12\x8d\x22\x0e\x8c\xbb\xf2\xca\xfa\x61\xd0\xc6\xf1\x2e\x5a\x24\xfa\x68\x25\x2c\x05\x06\x56\x8a\x96\x83\xee\xc3\x4d\x06\xde\x63\xf6\x27\x00\x00\xff\xff\x8d\xf2\x41\x9a\xa1\x04\x00\x00"), }, "/src/debug": &vfsgen۰DirInfo{ name: "debug", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), }, "/src/debug/elf": &vfsgen۰DirInfo{ name: "elf", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), }, "/src/debug/elf/elf_test.go": &vfsgen۰FileInfo{ name: "elf_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x65\x6c\x66\x0a\x0a\x69\x6d\x70\x6f\x72\x74\x20\x22\x74\x65\x73\x74\x69\x6e\x67\x22\x0a\x0a\x66\x75\x6e\x63\x20\x54\x65\x73\x74\x4e\x6f\x53\x65\x63\x74\x69\x6f\x6e\x4f\x76\x65\x72\x6c\x61\x70\x73\x28\x74\x20\x2a\x74\x65\x73\x74\x69\x6e\x67\x2e\x54\x29\x20\x7b\x0a\x09\x74\x2e\x53\x6b\x69\x70\x28\x22\x6e\x6f\x74\x20\x36\x6c\x22\x29\x0a\x7d\x0a"), }, "/src/encoding": &vfsgen۰DirInfo{ name: "encoding", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/encoding/gob": &vfsgen۰DirInfo{ name: "gob", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/encoding/gob/gob_test.go": &vfsgen۰CompressedFileInfo{ name: "gob_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 2598, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x56\x51\x6f\xdb\x3e\x0e\x7f\xb6\x3e\x05\x67\xdc\x0a\xa7\xe7\x39\x95\x93\xae\x9d\x81\x3e\xac\x5b\x77\xd8\x43\x3b\x60\x33\x70\xdb\x8a\x62\x70\x6c\x26\xd1\xea\x48\x3e\x49\x6e\x1a\x04\xf9\xee\x07\x4a\x76\x9c\xae\xff\x0d\x2b\xd0\x56\xa4\x7e\xfc\x91\xa2\x48\xca\xe3\x31\xfc\x7b\xd6\x8a\xba\x82\x9f\x86\xb1\xa6\x28\xef\x8b\x05\xc2\x42\xcd\x18\x13\xab\x46\x69\x0b\x11\x0b\xc2\xd9\xc6\xa2\x09\x59\x10\x6a\x9c\xd7\x58\x5a\x5a\x5a\x34\x56\xc8\x45\xc8\x46\x8c\x8d\xc7\x90\x7f\x7a\xff\x29\x83\x1c\x8d\xbd\x92\x55\xae\xae\x64\x05\xea\x01\xb5\x16\x15\x42\x59\x48\x98\x21\x68\x5c\xa9\x07\xac\x40\xc9\x12\xc1\x2e\x11\x66\xed\x02\xd6\xc2\x2e\xe1\xba\xd0\x1a\xe6\x02\xeb\x0a\x84\x81\xb9\x78\xc4\x2a\x61\xf3\x56\x96\x4f\x08\x23\x0b\xc7\x9d\xd7\x24\x1f\xc1\x96\x05\x76\xd3\x20\xe4\x29\x18\xab\xdb\xd2\x92\x26\xc8\x49\x10\x72\xc1\x82\x5d\xbf\x3f\x39\xdc\xff\x0a\xf3\x5a\x15\xf6\xf5\x94\x05\xc1\x77\x38\x16\xd2\x1e\x20\xf9\x21\xf2\x6d\x0c\x97\x31\xbc\x03\x70\x98\xe0\x1a\xba\x9f\x55\xd1\xdc\x7a\x1f\x77\xc7\x03\xd7\x75\x7a\xb0\x2d\xa4\xbd\xcb\x27\xa4\xf5\xc0\x27\x46\x7d\x7c\xc1\xb5\x90\xb6\xb1\x7a\x30\x39\xee\x3c\x95\x6a\xd5\xf4\x54\xb4\xae\xf1\x91\xa7\xe7\x77\xc3\x92\x40\x94\xb2\x1e\x74\x9b\x76\xac\x77\xb7\xe9\x61\x50\x57\xab\xc6\x6e\xae\x8b\xe6\xd0\xbd\x90\x16\xc6\x63\xb0\x0a\xca\x25\x96\xf7\x60\x97\x85\x85\x35\xdd\x4e\x89\xe2\x01\xa1\x00\xa9\xe4\x2b\x29\x6a\x32\x4a\x58\x10\xdc\xf4\x07\x3f\xbe\x9d\xdc\x0d\xdc\x5f\xac\x36\x9d\x3a\x1d\xce\xf4\x51\xda\xd7\x53\xe3\xb4\xe4\xc9\x21\x3f\x7f\xec\x08\xba\x03\x78\xf3\x9e\x75\x6f\xfa\xad\xd7\xdc\xde\x51\xbd\xb9\xbb\xec\x3d\xe7\xa9\xbb\xa5\x46\x40\x76\x01\x93\x84\x4f\xf9\xe9\x1b\x16\x20\x49\x69\x72\xc6\xcf\x29\x25\x76\xad\xbc\x7c\xc2\x82\x15\x16\x92\xf2\x9e\x5d\xc0\x34\x65\xc1\x5c\xc8\x05\x6a\x43\xe2\x29\x0b\x0c\xa7\x45\xe8\x1d\xf3\x90\x05\x26\x3d\x50\xa4\x21\x0b\x1e\x0a\xed\x82\xe5\x30\xe4\x1c\x2e\x7a\x21\xe2\xc9\x49\x0c\x3c\x39\x19\x0d\xc8\xf4\xaf\x90\x85\xd6\x1c\x0e\xd2\x45\xf2\xed\xc9\x1d\x5c\x80\xe1\x9d\xc4\x9d\x94\xee\xf1\xe9\x2f\xf8\xb4\xc3\xa7\x9d\xc4\x7b\x6b\xc2\xbb\xdb\x79\xdb\x39\x19\xea\x60\xaf\xf6\xb6\x47\x8d\x38\xd4\x39\x86\x23\x7c\xca\x90\xfe\x33\x43\xe7\x9d\xd0\x83\xca\x13\xd8\xb5\x62\x81\x75\xa9\x3d\xca\xb9\x6b\xa0\xac\xbb\x3e\x7e\x16\xb3\x20\xb8\xdc\x8b\xe7\x24\xbe\xeb\xc5\x57\xa7\x24\x5e\x67\xbf\x6f\xaf\x6d\xd8\x88\x30\xa3\xb8\x63\x08\x91\x56\xb8\x73\x36\x69\xf6\x6b\xcf\x6d\xa7\x19\xe4\x93\xed\xd7\x0c\x08\xfc\x3d\x83\xa3\xae\x14\x76\x31\xf0\x93\x7e\x0f\xfd\x56\x57\x16\x3b\x4f\xe6\x9d\x66\xcf\x5b\xb5\x73\x1f\x52\xdd\x85\x5d\x04\x21\x95\x5d\xe8\x0d\x7d\x1b\x67\x4f\xda\x78\xdb\xb9\x1d\xbc\xc4\xd0\x2d\x0e\x63\xea\xbb\x3d\xfb\x53\xb7\x6f\x5d\x29\x66\xbe\xce\x62\xff\xcf\x4b\xdc\x31\xec\xa7\xef\x07\xf1\x08\x76\x29\x0c\x34\x5a\xcd\x6a\x5c\x65\x7e\x33\xc8\x37\x0d\x5e\x69\xad\x74\x06\x95\xb1\xc9\xbf\x0c\x5a\x9a\xb3\x52\x59\x28\x80\xc6\xac\x15\x4a\x76\x58\x4a\x67\x61\x81\xe6\x61\xb5\xc2\x15\x4d\x6c\x88\xc6\x0b\x61\x97\xed\x2c\x29\xd5\x6a\xbc\x50\xcd\x12\xf5\x4f\x33\x2c\xba\x47\x21\x59\xa8\x6c\x7a\x7e\x96\x4d\x46\x8e\x8a\x06\x54\xf6\xe7\x09\xb5\xa5\x8a\xcf\x86\xaa\x8d\x5d\xc1\x0f\x8a\xd4\x1d\xaf\x1f\x62\x94\xe0\x7b\x8c\x9e\x8e\xb2\x11\x21\x6e\xfa\xda\x81\xa3\x61\x44\x6d\x79\x72\x1a\x43\x4a\x7f\x26\xc9\xa9\x63\xa2\x91\x95\x75\xb8\x3e\x9e\xad\xe1\x31\x18\xef\xc9\x0f\xaf\xcc\xed\xfb\xe9\xb5\x3d\x3b\x8b\xe1\xfc\x4d\x0c\x3c\x9d\x4c\xe9\x37\xe5\x93\xa9\xc3\x7e\xfe\x38\x54\x37\xbc\x82\x74\x22\x9c\x87\x7d\x24\xe1\x8d\x5a\x53\x92\xe9\x9d\xb3\x62\x85\x21\x6d\x7f\xcb\x9e\xce\xb8\x28\x5c\x62\x5d\xab\x18\x4c\x21\x6a\xa5\x43\x77\x9a\x7c\x38\x4d\x9e\x6e\x43\x77\xa1\xc2\x40\x9e\xba\x72\xdb\xb1\x60\x46\x3d\x26\x71\x1d\xb9\x67\x39\xb9\x6c\xe7\x73\xd4\x23\x16\xa0\xd6\xb4\x73\x83\xeb\x2b\x59\xaa\x0a\x75\x34\x1b\x25\x7e\x19\x59\x3e\x62\x81\x98\x03\x61\x5e\x5c\x00\x8d\x77\x6a\x51\x9b\xb8\xba\x88\x42\x74\xb0\x2c\x8c\x09\x31\x72\x6e\x68\x1c\xfc\xb0\x1c\x72\xee\xa9\x1d\xf3\x7b\xdc\x33\xfb\x65\x74\xf4\xe3\xb7\xdc\x1f\x0a\x5b\xd4\x51\x58\xe1\x33\x6e\x31\x87\x17\x7d\xd9\xbc\x47\x6c\xae\xfe\xd7\x16\x75\x64\x79\x0c\x8e\xee\x30\xb6\x79\x1f\x1c\xe0\x63\x83\xa5\xc5\x0a\x5e\x3e\xc0\x42\x59\x78\xf9\x10\xc6\x70\x4c\x46\x3e\x84\x1d\xa3\x0a\xbe\x44\x28\x66\x46\xd5\xad\xc5\x7a\x03\xa6\xd5\xfe\x5b\xa3\x7b\xde\x2a\xaa\x46\x5f\xfc\xee\x91\x4b\x5c\x2c\x96\x27\xfb\xa7\xf2\xe2\x59\x76\xe6\x51\xd8\x3d\x87\x60\x50\xda\x70\x7f\x84\x1f\x7f\x6d\xd7\x7b\xf7\xb6\x3b\x36\x7c\xdc\x50\x6f\x7e\x2e\x4a\x7c\xfe\x71\x33\x1e\x83\x3b\xb8\x90\x8b\xf1\x42\xcd\xa0\x6c\xb5\x46\x69\xeb\x0d\xb4\x06\xe9\x00\x66\x23\xcb\x04\x72\xaa\x0f\xb2\xf4\x6a\xa7\xfc\x6f\x21\xec\x7f\xb4\x6a\x1b\x28\x64\xe5\x98\xca\x42\x52\xbb\x9b\xb6\x2c\x11\x2b\x58\x2f\x51\x76\x0c\x94\x8c\xd6\xd0\x07\x57\x60\x93\x2f\xf7\xa2\x89\xc2\xd6\xd0\xdb\xe9\xb7\xc3\x11\xdb\xb1\xff\x07\x00\x00\xff\xff\x9b\x7c\x41\xd0\x26\x0a\x00\x00"), }, "/src/encoding/json": &vfsgen۰DirInfo{ name: "json", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), }, "/src/encoding/json/stream_test.go": &vfsgen۰FileInfo{ name: "stream_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x6a\x73\x6f\x6e\x0a\x0a\x69\x6d\x70\x6f\x72\x74\x20\x22\x74\x65\x73\x74\x69\x6e\x67\x22\x0a\x0a\x66\x75\x6e\x63\x20\x54\x65\x73\x74\x48\x54\x54\x50\x44\x65\x63\x6f\x64\x69\x6e\x67\x28\x74\x20\x2a\x74\x65\x73\x74\x69\x6e\x67\x2e\x54\x29\x20\x7b\x0a\x09\x74\x2e\x53\x6b\x69\x70\x28\x22\x6e\x65\x74\x77\x6f\x72\x6b\x20\x61\x63\x63\x65\x73\x73\x20\x69\x73\x20\x6e\x6f\x74\x20\x73\x75\x70\x70\x6f\x72\x74\x65\x64\x20\x62\x79\x20\x47\x6f\x70\x68\x65\x72\x4a\x53\x22\x29\x0a\x7d\x0a"), }, "/src/fmt": &vfsgen۰DirInfo{ name: "fmt", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), }, "/src/fmt/fmt_test.go": &vfsgen۰FileInfo{ name: "fmt_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x66\x6d\x74\x5f\x74\x65\x73\x74\x0a\x0a\x63\x6f\x6e\x73\x74\x20\x69\x6e\x74\x43\x6f\x75\x6e\x74\x20\x3d\x20\x31\x30\x30\x0a"), }, "/src/go": &vfsgen۰DirInfo{ name: "go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), }, "/src/go/token": &vfsgen۰DirInfo{ name: "token", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), }, "/src/go/token/token_test.go": &vfsgen۰FileInfo{ name: "token_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x74\x6f\x6b\x65\x6e\x0a\x0a\x69\x6d\x70\x6f\x72\x74\x20\x28\x0a\x09\x22\x74\x65\x73\x74\x69\x6e\x67\x22\x0a\x29\x0a\x0a\x66\x75\x6e\x63\x20\x54\x65\x73\x74\x46\x69\x6c\x65\x53\x65\x74\x52\x61\x63\x65\x28\x74\x20\x2a\x74\x65\x73\x74\x69\x6e\x67\x2e\x54\x29\x20\x7b\x0a\x09\x74\x2e\x53\x6b\x69\x70\x28\x29\x0a\x7d\x0a"), }, "/src/internal": &vfsgen۰DirInfo{ name: "internal", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/internal/poll": &vfsgen۰DirInfo{ name: "poll", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/internal/poll/fd_poll_js.go": &vfsgen۰CompressedFileInfo{ name: "fd_poll_js.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 1931, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x54\x41\x6f\x2a\x37\x10\x3e\xaf\x7f\xc5\x28\x97\xec\x12\xd8\x4d\xdb\x5b\x14\x0e\x15\x69\xd2\x48\x55\xa9\x92\x48\x39\x20\x1a\x19\x7b\x80\x49\xbc\xb6\x6b\x7b\x83\x10\xca\x7f\xaf\xbc\xbb\x04\x48\xe0\x85\xf7\xa4\x77\x02\x79\x66\xbe\xf9\xbe\x6f\x67\xa6\x28\xe0\x6c\x52\x91\x92\xf0\xec\x19\xb3\x5c\xbc\xf0\x19\x82\x35\x4a\x31\x46\xa5\x35\x2e\xc0\x49\xa0\x12\x4f\x18\x2b\x8a\xfa\xfd\x0a\xbd\x00\xf2\xc0\x41\x9b\x9e\xb1\x40\xa5\x55\x58\xa2\x0e\x3c\x90\xd1\x60\xa6\xc0\x35\xdc\x16\xc3\x3a\x19\x1d\x4c\x8d\x83\x9b\xe1\xef\x77\x83\x3f\xfb\xcf\x3e\x67\x45\x11\x81\x6e\x83\xff\x58\x48\x1e\x26\xdc\xa3\x04\xa3\xe1\x6f\x3e\xf8\x0b\x48\xc3\x4c\x80\x30\xa5\xa5\x88\x93\x7a\x44\xb8\x19\xde\x0d\x87\x0f\x85\x77\xa2\x20\x1d\xd0\x69\xae\x8a\xd8\xa7\x98\xca\xa7\xf8\xfb\xa4\xb9\x50\xf9\xcc\x64\xdd\xd8\x65\x52\x05\xa0\x00\xd2\xa0\x07\x7c\x45\x0d\x0a\xbd\xcf\x59\x58\x5a\xdc\x48\xf1\xc1\x55\x22\xc0\x8a\x25\x42\x19\x4f\x7a\x06\x13\x63\x14\x7b\x63\x6c\x5a\x69\x01\xa9\x95\xd0\x59\x27\x67\x40\x9a\x42\x3a\x95\xd0\xb9\xbe\xca\x00\x9d\x33\x0e\x56\xe0\x30\x54\x4e\x83\x26\x05\x07\xca\x22\x34\xa6\x19\xac\x0e\xc4\xf1\x95\x44\x88\x71\xb0\x32\x5f\xf3\xe8\x43\x70\x15\x1e\x82\xb4\x0e\x2d\x77\x98\x96\x46\x22\x90\x0e\x5d\x20\x7f\x4d\x0a\x6b\xfa\xef\xdc\x58\x42\xd3\x6d\xcc\x15\x4b\x92\x96\x2e\x3a\x37\x68\x5e\xd3\xa6\x32\x63\xc9\x1b\x4b\x36\x62\x0e\x79\xd0\x76\xbe\x43\x2e\xd3\x7d\x3d\xd7\x7e\x58\x99\xaf\x49\x9e\xba\xd3\x35\xbf\xec\x0b\x41\x8f\x8e\x02\x1e\x8d\xbb\xf8\x1a\x77\xc1\x29\xfc\x2c\x97\xfe\x70\xee\x81\x4a\x34\x55\x38\x64\x56\xec\x7e\x8c\x53\x35\xcb\x63\x6c\x8a\x89\x47\x79\xd4\x20\xee\x35\xe8\x03\xdc\x80\x6b\x81\x0a\xe5\xbb\x4b\xdb\x83\xba\xfd\x85\x8c\x52\x7c\xa2\xe2\x20\xc7\xa6\x9b\x6e\xbb\x73\x5a\xef\xc6\x3d\x86\x2b\xe4\x52\x91\xc6\x34\x40\x3c\x21\x79\x74\xea\xdb\x4b\xb3\xae\x8c\x86\xfd\x78\x75\xed\xce\xf7\x94\x17\x05\xfc\xd3\x8a\x74\x64\x83\x71\x6d\xdc\x43\x98\x23\xc8\xcd\xf3\x04\xe3\x74\x54\xf1\x4a\x4d\x96\x75\xb0\x39\x72\xf5\xb5\x31\x0e\xfe\xad\x48\x07\x1b\x5c\x7a\x9e\x01\x4d\x63\x82\x43\x20\xaf\x4f\x03\x18\x8d\x39\x3c\xcc\xc9\xc7\x43\x67\xb4\x5a\x36\x30\xf1\x3a\x06\xf4\x81\xf4\x2c\x6f\x64\xec\x32\x49\x33\x68\x31\xe3\x50\xb6\xb4\xb7\xda\xb0\x86\xfe\xc0\xd8\x65\x3c\xbd\x7e\xa9\x45\xee\x2a\x1d\x25\x3f\xdd\x63\xc9\xc5\x7f\x15\x39\x6c\xa1\x3f\x07\x52\x0f\x9d\x08\xf6\xdb\xaf\x59\xbb\x05\x1d\x0f\xfd\x3e\x9c\xd7\x2b\x20\xe6\x70\xd1\x87\x92\xbf\x60\x2a\xe6\x5c\x37\x93\xc6\x92\xc4\x63\xf9\xc8\x29\xa0\xf3\x23\x3f\x86\x3e\x70\x6b\x51\xcb\x74\xe7\xb9\x0b\x62\x1e\x73\x2f\x7b\x62\x5e\x6f\x4c\xc7\xf7\x7a\x5f\xb0\x75\xa8\x90\xfb\x3d\x6c\xdb\xc0\x07\xb6\x1d\x7f\x76\xc6\x58\xb2\x88\x24\x77\x7a\xd7\x42\x14\xea\x74\x91\x6d\xc4\x34\xde\x45\x2a\xac\x15\xb6\x18\x9d\x8f\x63\x79\xfc\xf7\xcb\xc5\x98\x7d\xd2\xb5\xd8\x0b\x24\x51\x61\xc0\x2d\xb5\x5d\xf0\xd9\x3b\xee\x65\xaf\xde\x86\xa8\xf4\x95\xbb\x2d\x5e\xd0\x3a\x59\x72\x3b\x6a\x55\x8c\x47\xe3\x2d\x5f\xff\x0f\x00\x00\xff\xff\x9e\x79\xbb\x91\x8b\x07\x00\x00"), }, "/src/internal/testenv": &vfsgen۰DirInfo{ name: "testenv", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/internal/testenv/testenv.go": &vfsgen۰CompressedFileInfo{ name: "testenv.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 424, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x8f\xc1\x6a\xc3\x30\x0c\x86\xcf\xd1\x53\x08\x9f\x12\x36\x92\xfb\x6e\xa3\x8c\xf5\xd6\xb2\x3e\x81\xeb\x2a\x8d\xbb\x58\x2e\x92\xb2\xb4\x8c\xbe\xfb\xf0\xd6\x52\xd8\x06\x3e\xfd\x9f\xfd\xf1\xb9\xeb\xf0\x61\x3b\xc5\x71\x87\x07\x05\x38\xfa\xf0\xee\xf7\x84\x46\x6a\xc4\x1f\x00\x31\x1d\xb3\x18\xd6\x50\x39\x99\xd8\x62\x22\x07\x95\x53\x93\xc8\x7b\x75\xd0\x00\x74\x1d\x2e\xbd\xbe\x9c\x28\xa0\x50\xb9\xac\x38\x0f\x64\x03\x09\xda\x40\x18\x26\x11\x62\x43\x3d\xab\x51\xc2\xe0\x19\xd5\xbc\x18\x32\xcd\x78\x94\x1c\x48\x95\xb4\x58\x26\x8d\xbc\xc7\xac\xed\xa6\xf0\xf5\x0f\xc2\x2c\x58\xa7\x2c\x84\x21\xa7\x94\x79\x3c\x37\x48\x27\x0a\xed\x22\xa7\xe4\x79\xd7\x42\x3f\x71\xb8\x15\xd4\x0d\x6e\x73\x1e\xf1\x13\x2a\x9d\xa3\x85\x01\xaf\xd1\xed\xeb\x6a\xb5\x29\x73\xf0\x4a\xe8\xd8\x87\xd1\x3d\x41\x55\x09\xd9\x24\x8c\xbd\x1f\x95\x6e\x70\xe7\x65\x8e\xfc\x8d\x63\x8f\xd7\xaf\xb6\x4b\xaf\x6b\xa1\x3e\x9e\xea\xbb\xf2\xf9\x6d\xb1\x7c\x44\xe7\x25\xb9\xa6\xc8\x7f\xfb\xaa\x0b\x94\xf3\x27\xa5\xbc\xbb\xc7\x1c\xf4\x9f\x94\x0b\xdc\x06\x93\x89\xe0\x02\x5f\x01\x00\x00\xff\xff\xdc\xf8\xeb\x9e\xa8\x01\x00\x00"), }, "/src/io": &vfsgen۰DirInfo{ name: "io", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/io/io_test.go": &vfsgen۰CompressedFileInfo{ name: "io_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 574, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\xd0\x41\x4b\xfb\x40\x10\x05\xf0\x73\xf7\x53\x0c\xbd\xfc\x9b\xbf\x92\x7e\x06\x29\x46\x10\xbc\x98\x82\xc7\xb2\x26\xcf\x64\xec\x66\x76\x99\x9d\x45\x51\xfc\xee\xd2\xa6\xa7\x52\x0f\xde\x3c\x2d\x3c\x78\xcb\xef\xcd\x7a\x4d\x57\xcf\x85\x43\x4f\xaf\xd9\xb9\xe4\xbb\xbd\x1f\x40\x1c\x77\x86\x6c\xce\xf1\x94\xa2\x1a\xad\xdc\x62\x79\x08\x58\x86\xa5\xab\x9c\x7b\x29\xd2\xd1\x16\xd9\x1e\x4a\x30\x7e\x52\x36\xe8\xee\xf8\xb4\xa6\x2c\x43\xcb\x32\x04\xdc\x84\x10\xbb\x95\xd1\xff\x53\xb5\xde\x56\xf4\xe9\x16\x56\xb7\x7b\x4e\xab\xca\x7d\x9d\x7f\xf4\x08\xdf\x43\x9b\xe0\xcd\x20\x3f\x16\x8f\x12\x52\x04\x46\xa6\x28\xa4\x45\x8c\x27\xd4\x1b\x1f\x02\x34\x93\x97\xfe\x3c\x6b\xd4\x4f\xc8\xd7\xf4\x36\x72\x37\xd2\x5d\x4c\x23\xf4\xbe\xa5\x3e\x22\xcb\x3f\xa3\x5c\xd2\x61\xe6\xf2\x02\x69\xde\x36\xef\xd9\x8c\x9e\xe5\x4f\xe9\x4e\x07\x53\x20\xdf\xbe\x8f\xbe\x64\x43\x3f\x67\xf9\xd7\xc0\x16\xd6\xb0\xf8\xc0\x1f\xd0\x8b\x16\x92\x68\xc4\x53\x0a\x98\x20\x33\xe7\x3b\x00\x00\xff\xff\x75\x6f\xe1\xab\x3e\x02\x00\x00"), }, "/src/math": &vfsgen۰DirInfo{ name: "math", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/math/big": &vfsgen۰DirInfo{ name: "big", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/math/big/big.go": &vfsgen۰CompressedFileInfo{ name: "big.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 174, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x44\x8d\xbd\xaa\xc3\x30\x0c\x46\x77\x3f\x85\xf6\x0b\x11\x5c\x68\x87\xcc\xdd\x03\x25\xd0\xd9\x89\x15\xdb\xf9\x93\x91\xe4\x94\xbe\x7d\x49\x3b\xf4\x9b\xbe\xe1\x70\x0e\x22\xfc\x0d\x35\xaf\x01\x66\x75\xae\xf8\x71\xf1\x91\x60\xc8\xd1\x39\x44\xe8\xbb\x5b\xd7\x42\x9f\xb2\x42\x56\xf0\xf0\x64\x59\xbc\x70\xdd\x03\x4c\x2c\x90\xcc\x8a\xb6\x88\x31\x5b\xaa\x43\x33\xf2\x86\x91\x4b\x22\x99\xf5\x77\xb2\x6a\x25\xc5\xeb\xe5\xbf\x39\x95\xdf\xdd\x69\xe3\x83\xc0\x4f\x46\x02\x96\xbc\xc1\x07\x3b\x2b\x42\xca\xeb\x41\xa1\x71\xf6\x2a\x04\x0f\x96\x00\x35\xef\x56\x4c\xdc\x3b\x00\x00\xff\xff\x55\xc0\x14\x01\xae\x00\x00\x00"), }, "/src/math/big/big_test.go": &vfsgen۰CompressedFileInfo{ name: "big_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), uncompressedSize: 148, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd2\xd7\x57\xd0\x4e\x2a\xcd\xcc\x49\x51\xc8\x2a\xe6\xe2\x2a\x48\x4c\xce\x4e\x4c\x4f\x55\x48\xca\x4c\xe7\xe2\xca\xcc\x2d\xc8\x2f\x2a\x51\x50\x2a\x49\x2d\x2e\xc9\xcc\x4b\x57\xe2\xe2\x4a\x2b\xcd\x4b\x56\x08\x49\x2d\x2e\x71\xaa\x2c\x49\x2d\xd6\x28\x51\xd0\x82\xca\xe9\x85\x68\x2a\x54\x73\x71\x96\xe8\x05\x67\x67\x16\x68\x28\x25\x15\xe5\x67\xa7\xe6\x29\x69\x72\xd5\x22\xe9\xf1\xcd\x4f\x09\x2e\x2c\x2a\xc1\xad\xab\x38\x27\xbf\x1c\xac\x07\x10\x00\x00\xff\xff\x9b\x59\x2d\xf0\x94\x00\x00\x00"), }, "/src/math/math.go": &vfsgen۰CompressedFileInfo{ name: "math.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 4655, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x57\xdd\x6e\xdb\x38\x13\xbd\xb6\x9e\x62\x3e\xe3\x43\x21\x6d\xe5\x1f\x29\x41\x50\x14\x71\x80\x6e\xb0\xe9\x16\x68\xb3\x8b\x4d\x76\x6f\x02\x5f\x50\x32\x69\xd3\x95\x49\x85\xa2\x1a\xb9\x49\xde\x7d\x41\xea\x8f\x92\xcd\xd8\xde\x3b\x8b\x3c\x73\xe6\xcc\x70\x86\x1c\x4f\x26\xf0\x3e\xca\x69\xb2\x80\x75\xe6\x38\x29\x8a\xbf\xa3\x25\x86\x0d\x92\x2b\xc7\xa1\x9b\x94\x0b\x09\xae\x33\x18\x2e\xa9\x5c\xe5\xd1\x38\xe6\x9b\xc9\x92\xa7\x2b\x2c\xd6\x59\xfb\x63\x9d\x0d\x1d\xcf\x71\x7e\x20\xa1\x0d\x61\x06\xeb\x6c\xfc\x39\xe1\x11\x4a\xc6\x9f\xb1\x74\x87\xdf\x90\x5c\x0d\x3d\x0d\xf8\x89\x05\x07\x92\x70\x24\x2f\xce\x61\x06\x53\xbd\x98\xf2\xec\x0b\x23\x30\x83\x00\x26\x1a\xa1\x57\x19\x5e\x96\xab\xa3\xee\x32\x62\xca\xb0\x5e\x72\x48\xce\x62\xf8\x14\xf3\xcc\x2d\x6a\x62\xaf\xf1\xf0\xec\x0c\x04\x96\xb9\x60\x5a\xd9\xf8\x1a\x25\x89\x3b\x44\x31\xcf\x86\x3e\x14\xde\xf8\x46\xc1\x5c\xcf\x79\x35\x68\x56\x27\xf1\xac\x2c\x44\x19\x65\xc7\xf3\x64\x94\xd9\x69\x4e\xd0\xa3\xd0\x16\x22\x89\x4e\xd0\x23\x91\x4d\x8f\x44\xa7\xe8\x51\x68\x3b\x51\xe8\x6e\x7d\x38\x85\x2b\x1c\xfa\xb0\xdd\x4b\x77\x1d\x09\x79\xb4\xac\x38\x12\x72\xbf\xaa\x6b\x4c\x93\xe3\x69\x30\x4d\x2c\x34\x3c\xdd\x66\x74\xc9\xdc\xc2\x87\xed\x5e\x36\x4a\xc0\x2d\xe0\x12\xa6\xf0\xf2\x02\xc1\xa4\x80\xd9\xac\x2a\x77\x0f\xfe\x37\x03\x77\xdb\xee\x6d\xcd\xbd\x67\x67\x50\x2b\x19\x15\xce\xe0\xb5\xd1\x55\x18\xce\x8f\x6f\x04\x6b\x1f\x5c\x9f\xd2\x06\xf6\x2e\xf8\x4d\x90\xb7\x59\xb0\x02\x74\xf0\xf1\x41\x83\xb8\x63\x51\xa4\x47\xeb\xc4\x45\x6a\x91\x59\xa4\xe1\xd1\x2c\x29\x7f\x1a\xfa\x10\xda\x88\x36\xc1\x81\x00\x4a\x48\x6b\x73\x93\x70\x2e\x8e\xf6\x4e\x14\x7a\x7f\x14\x37\x02\x17\xa9\x4b\x5a\x22\x97\x08\x14\xd7\x9f\xbe\xf2\x0c\x94\x49\xcf\x20\x26\xa5\x49\xcb\xf1\xfb\x36\xe5\xd2\x4d\x7d\x78\x7c\x4b\xcf\xaa\x41\xb5\x96\x5f\x18\x71\x55\xcd\x97\x2e\x0c\x9b\xec\x89\xca\x78\xa5\x7e\xc5\x28\xc3\xa0\x31\x57\x33\x98\x7e\x6c\x4b\xb9\xbc\xfe\x9d\xc1\x02\x13\x94\x27\xd2\xd8\x29\xeb\x5e\x15\x7a\xe3\x47\x41\xdb\x28\x7d\x68\x9d\x46\x9c\x27\x55\x73\x11\xd5\x34\xd5\xab\x62\xf4\x4c\xe3\x5c\xb7\x4e\x8d\xab\xde\x99\x3e\xee\xb2\xc6\xd5\xc9\x42\x49\x86\x0d\x1d\xb7\xe8\xb6\x93\x6d\x9a\x69\x05\x9d\xfc\xaa\x66\x26\x8d\xcd\xd7\x85\x4e\xf7\xfe\x53\xe9\xde\x0e\x1a\x34\x53\xcf\x9c\x21\x4b\x2d\xd6\xca\x95\xdd\xd5\x0c\x82\x69\x78\xde\x87\xc0\x2f\x7b\xeb\x35\x98\x86\x67\x4d\xd5\x58\x30\xb8\x48\x47\x1d\x9c\xe9\xee\x52\xbd\xc4\xc7\xfb\x1b\x1d\xe9\xf0\xfd\xae\xc3\xc3\xe4\xb8\x48\x77\x3b\xe0\x2b\x5f\x5a\x1a\x89\x12\x28\xd4\x59\x14\xf0\x0c\x93\x09\x3c\x71\xf1\x1d\x09\x9e\xb3\x05\x10\x2e\x80\xa7\x92\x6e\xe8\x4f\x2c\x20\xca\x97\x40\x19\xfc\xf3\xc1\x07\x81\x37\xfc\x07\x06\x24\x21\xe3\x1b\x0c\x29\xa7\x4c\x1a\x85\x89\x98\xa9\xd4\x90\x98\xf0\xe5\xfe\xfe\xfc\xca\x97\xc1\xf4\xed\x46\x4f\x4a\x48\xd7\xe6\xc0\x05\x97\x94\x90\x8e\xcd\x81\xdb\x2c\xd1\x88\xd6\xe2\x1b\x2a\xec\x4f\x55\x13\x61\x89\x31\xac\xe8\x1b\x0f\x5c\x6d\x55\x61\x0c\x2b\xbe\x38\x68\xd5\x4e\x8f\x65\x4a\xff\xbf\xe1\x0b\x95\x53\x45\xb4\x93\xd6\x6f\x7c\x41\xba\xb7\x5e\xdd\x5a\xcd\xd2\xee\x9d\xf0\xf2\x62\x6b\x7d\xe2\x37\x67\x4b\x09\x04\x13\x3b\x4c\x5f\x4b\x03\x5d\xa3\x1f\x67\x3a\x2e\xe2\x43\xe0\x19\xcd\x3f\xd2\x15\xec\x97\x7d\x5b\xeb\x55\xd7\xc6\xbe\xa0\x95\xd7\x1a\xf3\x27\x7f\x7a\x73\x76\xd0\xf3\x42\xa0\xa2\x70\xf5\xcf\x51\x00\xef\xde\xa9\xa9\xa1\x13\xa1\x39\x39\x74\x46\x87\xc0\x52\xba\x65\x77\xed\x4f\xf3\x5f\x78\x83\x28\x5b\x60\x71\xf0\xf4\x44\x07\xd9\x32\xdc\xd1\x25\x8b\x68\x67\x4c\xab\x6f\xec\x7a\x88\xd9\x3b\x11\x19\x04\xc7\x8f\xb0\xd6\x89\xfa\xee\x94\x81\xda\x3e\x4f\xdf\x51\xd6\xfb\xc7\xe1\x66\x94\xf9\x10\xf3\xac\x53\x77\x15\xa7\x96\xee\xf9\xe5\x70\x66\xb0\x3c\x9e\x30\xb6\x66\x8f\xb6\xb1\xf5\xfe\x84\xd9\xde\x3a\xda\xdf\x9f\x32\xd9\xdb\x07\xfb\x7b\x91\x33\xdb\x0c\x57\x57\x6e\x5b\xa2\xc6\x31\x97\x9f\xfa\x8e\xee\x57\x80\x59\xbb\x9d\xa9\xb7\xe2\x76\x29\x93\x6e\xe1\x69\x11\xea\x1f\x62\x94\x13\xc8\xa4\xc8\x63\xa9\x2c\x73\xca\xe4\x59\x88\x84\x40\x5b\x80\x87\x70\x5e\x7e\x3b\x03\x6d\x5c\x6f\x3c\x84\xf3\xea\xbb\xda\xb8\x38\xaf\x36\x82\x79\xf5\xdd\x84\x48\x19\x55\x0f\xda\xb3\x33\x40\x91\x6a\xfd\xde\x9f\xdd\x4f\xca\xee\xd7\x9c\x10\x2c\x86\xde\xf8\x16\x3f\xb9\x1f\x3c\x67\xb0\xce\xc6\x5f\x98\xc4\x82\xa1\xe4\x8f\x68\x8d\x63\xe9\x46\x39\xf1\xc6\x77\xca\xc2\x50\x38\xf4\xfb\x74\x7f\xeb\x4d\x4d\x5a\xd1\xa1\xc8\x3b\x40\x68\x86\xb6\xcb\x78\x53\xee\xfe\x07\xca\x2a\x29\x16\xca\x8b\xf3\x1d\x4a\x63\xc8\x55\x2e\x23\x2a\xb3\xfa\xae\x3e\x0b\x3d\x28\x03\x57\x99\x8c\x72\x32\x36\x55\x3f\x4c\xe7\xa0\x46\xa7\xfa\xa4\xd5\xbe\x91\xa6\x87\xe9\xbc\xcf\x4d\x04\xdf\x68\xfe\xa8\xa2\xf5\x6a\x3f\x35\x7f\xd7\x1e\x66\x10\x75\xe8\x7b\xee\xbb\xfc\x17\xe7\xa6\x76\x55\xd7\x8a\xad\x2c\xeb\xc6\xb8\x4a\x4f\x5f\x7b\x89\x74\xfb\x12\x82\xb9\x77\x79\x79\x16\xc2\x7b\x1b\x60\x3a\xf7\xfa\x22\x7a\x41\xf6\xfa\x6b\x6f\x90\xe5\x82\x1b\x79\xbb\xfb\x81\xb9\x0f\x57\x57\x70\x16\x7a\xbb\x29\x69\xa3\x72\x5e\x9d\x7f\x03\x00\x00\xff\xff\x2d\x84\x8c\x5b\x2f\x12\x00\x00"), }, "/src/math/math_test.go": &vfsgen۰CompressedFileInfo{ name: "math_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 587, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x90\x31\x6b\xdc\x40\x10\x85\x7b\xfd\x8a\xd7\x39\x26\x77\x27\x0c\x17\x17\x69\xae\x09\x04\x17\xe1\x02\x71\x1f\x46\xab\xd1\xed\x24\xab\xdd\xcb\xcc\xc8\xb2\x08\xf9\xef\x41\x92\x41\x6e\x6e\xbb\x85\xf7\xbe\xf7\xe6\xd5\x35\x3e\x36\x83\xa4\x16\xbf\xac\xaa\xae\x14\x7e\xd3\x85\xd1\x93\xc7\x9f\xce\xe6\x55\x55\xd7\xf8\x91\xe4\x12\xd3\x84\x28\x97\xc8\x0a\x2f\x89\x95\x72\x60\x83\x47\xca\x18\xae\xe6\xca\xd4\xef\x50\x3c\xb2\x8e\x62\x8c\x67\x36\xff\x4a\x7d\x4f\xe8\x48\x92\x1d\x66\xcc\xf3\xf9\xcb\xf9\x33\x9e\x66\x17\x2b\x83\xd0\xb0\x3b\x2b\x46\x9a\xe0\x05\x9d\xbc\x6e\xb6\x13\x9e\xfc\xce\x30\xb2\x68\x3b\xa7\x38\x4a\x4e\x13\x4a\x66\x2c\xb5\xea\x1a\xeb\x53\xfe\x33\x88\xb2\x41\x72\x50\x26\x93\x7c\x79\x57\xf0\x80\xef\xac\x91\xae\x6f\x99\x77\xb6\xa5\x76\xf2\x7a\xc2\x37\x9a\x1a\xc6\xc8\x1b\xcf\x62\x19\x52\x8b\xf2\xc2\xaa\xd2\xbe\x3f\xc4\xae\x1c\xa4\x93\x40\x29\x4d\xa0\xdc\x22\x17\x9f\xb1\x78\x1b\x6d\x3f\xce\xfa\x2d\x7b\xb7\x41\x1b\x0e\x34\x18\xc3\xa3\x18\x46\x49\x09\xeb\xbf\xa7\x3c\xad\xa3\x2d\x57\xd9\x3c\x43\xc3\x48\x6c\x06\x0a\x61\x50\x72\x3e\xe0\xac\xe8\x97\x9e\xb3\x7d\x83\x8a\xa1\x93\xcc\xa7\xaa\x1b\x72\x40\x48\xc5\xf8\x03\xed\xd0\xa0\x4b\x85\xfc\xf1\x78\x8f\xa6\x94\xb4\x48\xff\x42\xd9\x07\xcd\x5b\xbb\x45\xb9\xc3\x91\xf7\x0f\xc7\x7b\xfc\x5b\x19\x2f\xac\xd3\x4d\xce\x4d\xc6\x23\xef\x1f\x3e\xcd\x8c\xff\x01\x00\x00\xff\xff\xc7\x9d\xb5\x9f\x4b\x02\x00\x00"), }, "/src/math/rand": &vfsgen۰DirInfo{ name: "rand", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), }, "/src/math/rand/rand_test.go": &vfsgen۰CompressedFileInfo{ name: "rand_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), uncompressedSize: 160, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\xcb\x51\x0a\xc2\x30\x0c\x00\xd0\x6f\x73\x8a\xd0\xaf\x4d\x61\x03\x3d\x82\xe0\x05\xdc\x05\x6a\x57\x4b\x5c\x4d\x4a\x93\x22\x22\xde\x5d\x10\x3f\xfc\xd9\xf7\xe3\x8d\x23\xee\x2e\x8d\xf2\x8c\x37\x05\x28\x3e\x2c\x3e\x45\xac\x9e\x67\x00\xba\x17\xa9\x86\xce\xa2\x1a\x71\x72\x00\xd7\xc6\x01\xa7\xa8\x76\xca\xe2\xed\xb0\xef\x0c\xb7\x3f\x1d\xa6\x1e\x5f\xb0\xb1\xe1\xbc\x50\xe9\x9c\x66\x79\xb8\x1e\xde\x7f\xe7\x28\x1c\x5a\xad\x91\x6d\xbd\x35\x25\x4e\xc8\xa2\x4f\x0e\xdf\xfe\x09\x00\x00\xff\xff\x3d\xb4\x3b\xb8\xa0\x00\x00\x00"), }, "/src/net": &vfsgen۰DirInfo{ name: "net", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/net/http": &vfsgen۰DirInfo{ name: "http", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/net/http/cookiejar": &vfsgen۰DirInfo{ name: "cookiejar", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/net/http/cookiejar/example_test.go": &vfsgen۰CompressedFileInfo{ name: "example_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 269, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\xcc\x41\x4e\xc3\x30\x10\x85\xe1\x75\xe7\x14\x4f\x5d\xb5\x02\x35\x82\x65\x77\xa8\x02\x24\x16\x05\xd1\x03\xd0\xa9\x3d\x21\x6e\x1c\xdb\x78\x26\x0d\x08\x71\x77\x14\xb1\x65\xfb\xf4\xbd\xbf\x69\x70\x75\x1a\x43\xf4\x38\x2b\x51\x61\xd7\xf3\xbb\xc0\xe5\xdc\x07\x39\x73\x7d\x33\x51\x23\x0a\x43\xc9\xd5\xb0\x6c\x07\x5b\x12\xb5\x63\x72\xb8\xff\xe4\xa1\x44\xd9\xcb\xb4\x5a\xe3\x9b\x16\x4d\x83\x24\x36\xe5\xda\x83\x9d\x13\x55\xa4\x6c\xd0\xb1\xcc\x4f\xf1\x38\x7d\xe1\x31\x97\x4e\xea\xd3\xe1\x1a\x9c\x3c\xac\x0b\x8a\x39\x0f\x2f\x45\x92\x57\xe4\x84\xce\xac\xcc\xdb\x66\x2f\xd3\x41\xea\x45\x2a\xd1\xa2\x1d\x6c\xf3\x52\x43\xb2\x98\x56\xc7\xbb\xd6\xa4\xe2\x46\x0d\x55\x3e\x46\x51\xdb\x12\xf0\x10\xf9\x92\xeb\x16\xbb\x2e\xbb\x1c\xd9\x04\xbb\x2e\x14\xfa\xb3\xb7\xc9\xff\x67\x9f\xd9\x06\xe1\x88\x57\x0e\x1a\xd2\x71\x4d\x3f\xf4\x1b\x00\x00\xff\xff\x4a\xaa\xb1\x5a\x0d\x01\x00\x00"), }, "/src/net/http/fetch.go": &vfsgen۰CompressedFileInfo{ name: "fetch.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 3551, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x56\x5f\x6f\xdb\x36\x10\x7f\x16\x3f\xc5\x4d\xc3\x3a\x29\xb5\xa5\x16\x28\xfa\xe0\xc5\x0f\xa9\x9b\x76\xc1\xda\xa5\x48\xb2\xa7\x20\x18\x68\xe9\x24\x31\x91\x48\x85\xa4\x92\x18\x81\xbf\xfb\x70\xa4\x24\xcb\x49\xda\x62\x01\xea\x4a\xe2\xf1\xee\x77\x77\xbf\xfb\x93\xa6\xf0\x7a\xdd\x89\x3a\x87\x6b\xc3\x58\xcb\xb3\x1b\x5e\x22\x54\xd6\xb6\x8c\x89\xa6\x55\xda\x42\xc4\x82\x10\xb5\x56\xda\x84\x2c\x08\x8b\xc6\xd2\x7f\x42\xf9\xdf\x54\xa8\xce\x8a\x9a\x5e\x8c\xd5\x99\x92\x77\x21\x63\x41\x58\x0a\x5b\x75\xeb\x24\x53\x4d\x5a\xaa\xb6\x42\x7d\x6d\x76\x0f\xd7\x26\x64\x31\x63\x69\x0a\xc6\x6a\xe4\xcd\x19\xf2\x1c\x35\x88\xa6\xad\xb1\x41\x69\x0d\x70\x09\x42\x25\xf4\x7d\x55\x2b\x83\x1a\xee\x35\x6f\x5b\xd4\x50\x28\x0d\xf4\x99\xaf\x6b\x3c\x77\x97\x41\x15\x0e\xae\x59\xa4\x69\x81\x36\xab\x12\xd3\x62\x96\xdc\x57\xdc\xde\x97\x89\xd2\x65\x9a\x30\xbb\x69\x71\xdf\x96\xb1\xba\xcb\x2c\x3c\xb2\xa0\x45\x99\x0b\x59\xc2\xe5\xd5\x7a\x63\x91\x05\x5e\x0c\xe0\xe0\xda\x24\xa7\xeb\x6b\xcc\x2c\xdb\x32\x56\x74\x32\x83\x48\xc3\xc1\x54\x4b\xec\xa0\x44\x6d\x7f\x37\x86\x48\x82\x90\x76\x06\xa8\x35\xb8\x88\xc5\x64\x41\x14\x50\xa3\x8c\x74\xd2\x9b\x8a\x61\xb9\x84\x37\x74\x12\xdc\x71\x4d\xe1\x0d\x82\xf5\xaa\x02\x80\x25\x34\xfc\x06\xa3\xac\xe2\x72\xd0\x49\x87\xa8\xf5\xaa\xda\x3b\xf4\xca\x59\x10\xd0\x3f\x9d\x78\x50\xc9\x8a\xd7\x75\x14\x6a\xe4\x79\x18\xf7\x2f\xb6\x42\x19\xce\x48\x09\x79\x10\x69\x34\x5d\x6d\x27\xbe\x39\x80\x41\x40\x18\xfd\x59\xf2\x19\x6d\x14\xe6\x4a\x62\x18\x27\x1f\x94\xaa\xa3\x41\xa4\x87\x71\x38\xa7\xd4\x1c\x9f\x7e\xf2\x1f\x35\xda\x4e\x4b\xf7\xbc\x75\xbf\x6b\x2f\x33\xd5\x76\xc7\xeb\x8e\xd4\x9d\x48\x8b\xba\xe0\x19\x46\x71\x12\x4d\xfc\xdb\x4e\x01\x72\xa3\xe4\x0b\x00\xd3\x14\x8e\x8c\xe9\x1a\x34\x20\xec\xef\x06\x38\x7c\x3c\xfd\x7a\xfc\x90\x61\x6b\x85\x92\x09\xdb\x03\xe8\xd9\x9a\xfc\x8d\xf7\xbd\x42\x8f\xa3\x41\x63\x78\x49\x48\xce\xad\x16\xb2\x8c\xe2\x9d\x79\x7a\x32\x58\xa3\x27\x45\x90\x71\x83\xb0\x86\xc5\x12\x0e\xe7\xeb\x55\xb5\x20\xb9\x31\x81\xb0\x84\xf5\x20\x43\xa9\x76\x52\xce\xb8\x97\x73\x21\x81\x37\x8e\x07\xcc\xc5\x65\xcb\x02\x09\x4b\xc8\x54\xbb\x89\xda\x19\xec\xa8\xc0\xf6\xb4\x8e\xcf\x97\x72\x71\xc5\x06\x45\x72\x06\x52\xd4\x3f\x60\xa1\xab\x91\x28\xf6\x6e\x13\xfc\x34\x85\x8b\x4a\x18\x10\xa5\x54\x1a\xa9\x9c\x36\xfd\xa1\x57\x89\x39\x14\x5a\x35\x90\x71\x99\x61\x0d\x0d\xda\x4a\xe5\x09\x9c\x2b\x28\xb8\x9e\xc1\x09\xe4\x22\x07\xa9\x2c\xa0\xcc\x54\x47\x59\x73\x2a\x32\x25\x33\x8d\x54\x24\x54\xba\xc2\x76\x9c\x62\x0f\xf7\x15\x6a\x04\x8d\xd4\x2c\xc8\x0f\x5b\x61\x6f\x4d\x18\x68\x90\x4b\x21\xcb\xa2\xab\x13\xf8\xaa\x8c\x85\xce\xa0\x1e\x90\xf5\x62\x0e\x8b\x46\xd3\x26\x1f\x54\xbe\x49\x7a\x77\x12\x67\xe6\xa4\x20\x7d\x1a\x5d\xca\x25\x62\x0e\x56\xf5\xb6\xfa\xdb\x74\x3a\x03\x61\xc9\x1b\x58\xe3\xae\x8d\x60\x0e\x5c\xe6\x60\xd1\xd0\xe3\x7d\x85\x12\x6c\xc5\xad\xd7\x92\x29\xa2\x52\xd7\x26\xec\x69\xfd\xf8\xa0\x84\xf1\x2e\xfe\x3e\xf8\x69\x0a\xae\xbf\x5c\x68\x2e\x8d\xb3\x2f\x08\xd3\x99\xea\x64\x7e\xa1\x85\x6b\x4f\x4e\x3f\x05\x7e\x82\xa1\x33\x14\x94\x4f\x74\x15\x8e\xbe\x9d\x24\x70\x62\xc1\x74\x2d\x69\x30\x7d\x53\x12\xb2\x24\xf5\x14\x02\x25\x89\x78\x2a\x17\x68\xfa\xbe\xf5\xc4\xa8\xef\x5c\x8f\x23\x1b\x2c\x1c\xec\x4b\xc4\x3b\x48\x91\xc6\x5b\x38\x38\xc3\xdb\x0e\x8d\x8d\x21\x3a\x38\xeb\x2d\xcc\x26\xed\xa9\x72\x2c\x32\xc4\xe2\x6b\x93\x7c\xae\xd5\x9a\xd7\xbe\x5e\xfe\xf4\x27\x61\xec\x2a\x29\x66\x01\x75\xdf\x1b\xdc\xcc\xc0\x55\xb4\xbb\xa2\xb9\x2c\x29\xf9\xb7\x89\x97\x76\xd5\x43\x72\xff\xf6\x52\x3b\xa1\xfe\x92\xab\xe7\xde\x68\x1f\x72\xea\xed\x32\x0f\x67\x13\xe5\xf1\x58\x38\xaa\xb5\xa4\xa3\xe1\xed\xa5\x71\x65\x7b\x25\x86\x3e\xf2\xb8\x25\x65\xa1\xe7\x6f\xb8\x00\xf7\x47\x58\xbe\xba\x2f\x54\xd7\x61\x6f\xa9\x3f\xed\xdf\xdc\x49\xa6\x31\x47\x69\x05\xaf\xe9\x34\x34\xbc\xc1\xb9\xd2\xa2\x14\xae\x63\x6e\x99\x6f\x8a\xb7\x8e\x94\xf0\xcb\x92\x78\xe0\xc0\x53\x75\x9d\x7e\x3c\x5d\xc0\x27\x21\x73\x50\x9d\x05\x2f\x48\x41\xa6\xd4\x6d\x06\x26\xfa\xe4\x62\x4e\x43\x41\xb9\xb2\x70\x99\x1a\x65\x35\x27\x6a\x13\x69\x68\x6e\x00\xcf\xef\x88\x7a\x8e\xd0\x89\xb7\xe3\xff\xce\x11\xe1\x43\x57\x14\xa8\xcf\x55\xa7\x33\x04\x6e\x7f\x32\xf2\x7e\x25\x18\xf3\x46\x3c\x08\xd7\x1a\xe9\x6d\x36\xb4\x2a\x3f\xb0\xdd\x70\x3d\xaa\xeb\x68\xf0\x90\x02\x2e\x0a\x27\x34\xf1\x35\x18\x8e\x87\xaa\x84\x34\xdd\xf1\x0b\x9a\xce\x58\xe0\xf5\x3d\xdf\x18\xc8\x48\xc0\x79\xe9\xcd\x09\x99\xd5\x9d\x6b\x6c\x4a\x0e\x1d\x79\xd2\x1e\xa5\xa8\x27\x0d\xf2\x99\x1d\x16\x50\xe2\x2f\x43\xd2\x15\x5e\x51\xc7\x55\xf9\xc6\x65\x85\xaa\xe4\x9b\x56\x8d\x30\xb8\xcf\x59\xcf\x25\x17\x90\x70\xe6\x32\xf7\xcf\xd9\x97\xb1\xd5\xcf\x40\xb5\x36\x66\x6c\x9c\xb9\xa4\xe7\xc9\x58\x1d\xeb\x83\xcc\xfb\x69\xf2\xe2\xd8\x8d\xf7\x50\x3c\x1d\xb5\x3f\x9c\xb4\x9e\x80\x04\xdc\xd7\xcb\xe3\xd6\xc7\x64\x37\x2d\xab\xb1\xea\x7a\x87\x94\x3e\xe6\xce\x25\xa7\xd8\x55\x87\xab\x94\x17\xa6\x64\x76\x43\x9a\x57\x5c\x2a\x29\x32\x5e\x7b\x13\x7f\xe1\x26\xba\xc1\xcd\xfe\xd0\xeb\x81\x5c\x66\x37\x14\x5c\x5f\x80\xd1\xee\x5b\x5f\x85\x4f\x06\x25\x85\x2f\x08\x32\x25\x2d\x4a\xfb\x05\x65\x69\x2b\xc7\x28\x69\xdf\xbf\x8b\xe6\x6f\x9d\x90\x28\x20\xab\x47\xb2\xf5\x3b\x61\xf2\x8d\x6b\x83\x27\xd2\xf6\x26\xbc\xa7\x2b\xaf\x68\xee\x35\x85\xf1\x0c\xde\xbe\x99\xc1\xfb\x77\xf1\x1f\xee\xfa\x72\x42\xc3\x27\x46\x97\x90\xd5\x0e\x91\x03\x34\x99\xdb\x7e\x28\xf7\xa9\x3d\x9c\xc3\xab\x21\xa3\x5e\xcb\xb9\xe5\xb6\x33\x7d\xa3\x80\xbd\x25\xc5\xb8\xa3\xc9\x6e\x00\xaf\x21\x84\x10\x5e\x83\xbf\x74\x81\x0f\x36\x7a\xf1\x02\xb9\x15\xc7\xb3\x89\x81\x95\xca\x71\xf1\x5d\x03\x4e\xde\x8b\xfb\x04\x8d\x78\x7c\x70\xfc\xd1\x6a\xea\xf0\x02\xf6\xfc\xf7\x12\x54\x2e\xe3\x55\x80\x57\xd3\xa5\xe0\xd1\xbf\x2c\xf6\x10\xb8\x5a\x1a\x68\x55\xa2\xf5\xa2\x61\xec\xf7\xaf\xa0\x9f\x13\x8b\x31\x38\xb7\xee\xfb\x76\x31\xc6\xf5\x70\x4e\x55\xe5\x90\x3d\xd8\x28\x4e\x3e\x2a\x89\x51\xbc\x60\xfd\xf2\xb7\x9d\xb0\xff\xe5\x35\xee\x59\xa6\xc6\x95\xad\x68\x6c\x72\x4c\xe5\x55\x44\xa1\x44\x9b\x52\x7f\x5b\xf8\x7e\x19\xc5\x50\x70\x51\x63\xbe\x80\xdf\x8c\xab\x6c\xb7\xd2\x8d\xd4\xfc\x5f\xf8\x62\x36\x01\xf1\x93\x4b\x63\xa3\x3f\x5a\xd3\xe4\x1d\xda\xb6\x28\xa0\x55\xc6\x88\x75\x8d\xcf\x86\x3b\x7b\xd6\xdf\x86\x45\x74\xe2\xd5\xa0\xc8\x6f\x1a\x98\xd3\xae\x31\xf2\xd6\x6f\x93\x9e\xc1\x8b\x9d\x3a\xfa\xe0\xf7\xc0\xef\xed\x9d\xcf\xfa\xea\x96\x6d\xd9\x7f\x01\x00\x00\xff\xff\xcd\xea\xf8\xb6\xdf\x0d\x00\x00"), }, "/src/net/http/http.go": &vfsgen۰CompressedFileInfo{ name: "http.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 2998, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x56\x61\x6f\xdb\x36\x10\xfd\x2c\xfe\x8a\xab\x06\x04\x52\xaa\xc8\x0d\x50\x74\x43\x1a\x63\xc8\xd2\xae\x09\xd0\x74\x85\x93\x02\x05\xba\xa2\xa0\xa5\x93\xc4\x84\x26\x15\x92\x8a\xe3\x15\xfe\xef\xc3\x91\xb2\x22\x3b\xe9\x86\x2d\x5f\x42\x93\xc7\xbb\x7b\x8f\xef\xee\x34\x99\xc0\xf3\x79\x27\x64\x09\xd7\x96\xb1\x96\x17\x37\xbc\x46\x68\x9c\x6b\x19\x13\x8b\x56\x1b\x07\x09\x8b\xe2\x79\x57\x09\x1d\xd3\x62\xe5\xd0\xd2\x02\x8d\xd1\xc6\xaf\x84\x9e\x08\xdd\x39\x21\xe9\x87\x42\x37\x71\x78\xef\x5a\xa3\x9d\xbf\x60\x9d\x29\xb4\xba\x8b\x19\x8b\xe2\x5a\xb8\xa6\x9b\xe7\x85\x5e\x4c\x6a\xdd\x36\x68\xae\xed\xc3\xe2\xda\xc6\x2c\x65\xec\x8e\x1b\x78\x83\x15\xef\xa4\xbb\x32\x5c\x59\x9f\xc2\x14\xaa\x4e\x15\x49\x0a\x33\xdd\xa9\xf2\xca\x88\xb6\x45\x03\xdf\x59\x64\x97\xc2\x15\x0d\xad\x0a\x6e\x11\xae\x6d\xfe\x4e\xea\x39\x97\xf9\x3b\x74\x49\x5c\xa1\x2b\x9a\x38\x85\x67\x53\x3a\xf9\xa4\x4a\xac\x84\xc2\x12\xf6\xf6\x76\x2d\x67\xc8\x4b\x3e\x97\x78\xe9\x0c\xf2\xc5\xe3\x2b\x47\x30\x99\xc0\xb6\x11\x08\x0b\x9d\xc5\x12\xb8\x05\x0e\x45\x83\xc5\x0d\x54\xda\x80\xed\x5a\x9f\xb3\xae\xc0\x7a\x43\xa1\x6a\x30\x68\x5b\xad\x2c\xc2\x5c\x97\x02\x6d\x06\x16\x03\xcb\xf6\x68\x32\xf1\x69\xe6\xb6\xc5\x22\x5f\x36\xdc\x2d\xeb\x5c\x9b\x7a\xf2\x53\xb8\x6d\x73\x16\x45\x06\x5d\x67\x14\xec\x79\xcb\x81\x96\xef\xeb\xa7\x61\x7f\xbe\x78\x7f\xe6\x5c\x3b\xc3\xdb\x0e\xad\x7b\x02\xcc\xc8\xe3\xe7\xb3\xd9\x96\xbf\x32\x50\x3f\x32\x51\x7a\xcb\x60\xcd\xd6\x49\xca\xd8\x64\x32\x3e\x18\xb8\x58\x36\xa8\x40\xa1\x70\x0d\x1a\xf8\x9d\xb2\x85\x93\x8f\xe7\xa0\xb4\x81\xed\xac\xfc\x36\x37\x08\xfc\x8e\x0b\x49\xac\xe6\x70\xee\x80\xcb\x25\x5f\x59\xa8\xb8\x90\x36\x67\x6e\xd5\xe2\x56\x18\xeb\x4c\x57\x50\x1a\x8c\xf4\x00\xc9\xe8\x6c\xa4\x8d\xc4\xe0\x2d\xec\xf7\x81\x52\x48\xf6\x67\x3d\xfb\x19\x78\xd5\xa6\xa4\x97\x0d\x3a\x21\xfb\x5d\x9b\x7f\xc0\x65\xe2\x05\x4c\x0f\x73\x34\xc0\xd0\x55\x8f\xe4\x69\x14\x96\xc0\x0f\x28\xe2\x94\xad\x59\x48\x7c\x4c\x6d\x9f\x39\x05\x16\xaa\x92\xa2\x6e\x1c\x2c\x78\xfb\x65\x93\xe5\xd7\xfd\x6b\x9b\xff\x31\xbf\xc6\xc2\xb1\x01\x9d\x83\xfd\xb1\x8f\xff\x8a\xf0\xbe\x31\x70\x34\xfd\x37\x71\x78\xd4\x29\x63\x91\xa8\xc0\xe5\x43\x72\xd3\x29\x51\x43\x6e\xa2\xf1\xee\x8f\x92\x0e\xca\x18\x99\x7e\x31\x78\xfb\x15\xa6\x70\xdf\x18\x2f\x2a\x34\x50\xa2\x44\x87\xc9\x83\x4d\x06\x06\x6f\x29\x34\x55\xc7\x69\x43\xc9\x2e\xf8\x0d\x26\x45\xc3\x15\x0c\x90\x52\x16\xa1\x31\xbb\xc7\x01\x26\xf3\x28\xf3\x4b\x02\xa6\x95\xd4\xbc\x8c\xb3\x4d\xab\xa0\xd4\x1b\xe4\x25\x9a\x0c\xbe\xd1\xe5\xa1\x2d\x11\xe4\x99\x3f\x49\x7c\x5f\x1b\xff\xa6\xf6\x36\xfa\xfd\xe5\x2b\xed\x24\x14\xe4\x94\x4b\x99\xc4\x35\xba\x13\x29\x37\xb9\x9d\x79\x2b\x1b\xa7\xf9\xa5\x33\x42\xd5\x49\x0a\xcf\x21\xfe\x53\xc5\x69\x9a\xa6\x39\xf9\xb8\x38\xbf\x78\x1b\xac\x92\x94\x45\xd1\x5c\x97\xab\x27\x1e\xe5\x93\x50\xee\x97\x13\x63\xf8\xaa\x7f\x10\x0a\xe8\x4f\x36\x8d\x23\x4e\xd3\xfc\x5c\x39\x34\x15\x2f\x30\x49\xf3\x3e\x33\x62\x20\x2a\xb4\x72\xa8\xdc\x7b\x54\xb5\xf3\x34\x09\xe5\x5e\xbd\x4c\x0e\x0e\x29\x62\xdf\x21\x0d\xde\xe6\x17\xe8\x1a\x5d\x7a\x62\x7c\xdb\x88\xcf\xde\x9e\xbc\x89\xa9\xd4\xe9\xf1\x43\x1d\xd0\xf5\xbe\x65\xe7\x1f\xb9\xb1\x78\xae\x5c\x12\x68\x0c\x09\x9d\x86\x60\x07\x21\x5a\x9c\x66\x70\xf8\x22\x83\x57\x2f\xd3\xd7\xfe\xfa\x48\x37\xbb\x89\x4d\x41\xd2\xee\x9a\x45\xe3\x2e\xf3\xc8\x28\x24\x2f\x51\x25\x44\x56\x4a\x18\xd6\xcc\xb7\x23\x2f\x92\xe3\x03\xd8\xdb\xd0\xef\xa3\x5c\x3a\xee\x3a\x7b\x04\xfd\xdf\xc0\x9c\xf5\xfb\x3b\x4f\x03\x31\x3c\xdf\x35\xb9\xc2\x7b\x37\x32\xcb\x1e\x9c\x9e\xea\x12\x8f\x9e\x76\x4a\xb4\x04\xd3\xf0\xba\x43\xfc\xfe\xb1\x03\x65\xc1\xe2\x74\x8c\xf0\x08\xb6\x00\x7b\x83\xdf\x74\xb9\x1a\x1c\x00\x84\x69\x9a\x7f\xd0\xed\xa9\xd4\xf6\x09\x55\x06\x62\xfc\xd5\xbe\x14\x37\xb7\x0d\xde\x66\x9e\xb0\x68\xbd\x53\x1c\xbe\x60\x36\xd5\x81\xf0\x50\xba\xa1\x52\x42\x89\x1d\x1f\xfc\xa0\x17\xee\xb4\x3d\xea\xcf\x58\xc6\xe9\xe3\x30\x7c\xae\x8d\xfb\xdf\x61\x4c\xef\xbf\xe0\xaa\xc0\xdd\x08\xa1\x00\x75\x8b\x2a\xce\x46\x7a\x0e\xeb\x4f\xb3\xf7\xc3\x0b\xa6\xa3\x8c\x36\xf5\x73\xb5\x6a\x31\xce\x20\xe6\x54\x64\xf3\xae\xaa\xd0\xc4\x29\x0d\xf5\x86\x5b\x70\x1a\xe6\x08\xbc\x72\x68\x20\x04\x80\x4e\x39\x21\x87\x09\x3d\xef\xea\xbf\x84\x94\x3c\x5f\xe8\xf0\x9f\x06\xb4\x6d\xf4\xf2\xdb\xbc\xab\xf3\xa2\x16\xbf\x8a\x72\x7a\x78\x78\xf8\xe2\xe7\x57\x87\x34\x0e\x0c\x5a\x2d\xef\xb0\x64\x11\x7d\x11\xdc\xe0\x2a\x83\x3b\x2e\x3b\xb4\x54\x5e\x86\xab\x1a\x7d\xd2\x41\x2b\x9e\x18\xb2\xfb\xd6\x5b\x3d\x18\xf5\x97\xbc\xce\x1f\x28\xb0\xe8\xfa\x87\x08\x0e\xe2\x6c\x14\x22\xed\x9f\xdf\x37\x74\x0a\x42\xe2\x1a\x97\xe5\xd8\x8f\x0a\x0c\x03\x4a\x8b\xfe\x90\x94\x35\xf4\x81\x5e\x87\x24\xba\x13\x29\x93\x8d\x33\x8a\x20\x2a\x6f\xf4\x6c\x54\xed\x9b\xe3\xdc\x8b\x36\xf1\xe4\x0e\x03\x0b\x16\x9d\x1d\xa6\x7b\x41\x06\xe0\x1a\xff\x35\xb4\xca\x40\xa8\x42\x76\x25\x7d\x26\x69\xb5\x11\x46\xf0\xb8\x35\xa2\x03\xb0\x47\x71\x1e\x43\xca\xbc\x5f\x02\xc6\x58\x64\x51\x62\x18\xbc\xbe\xe7\x91\x1e\x08\xdb\xf1\x41\xe8\x27\xa3\x0f\x1d\xda\xc8\x28\x5a\x6f\xda\xb3\x70\x7c\xe0\x45\x3b\xfe\x22\x1a\x12\x5a\xff\xc3\xb0\x3e\xf5\x1a\xee\x1f\x6a\x67\x60\x7f\xf7\xaf\x73\xdf\x98\x0c\xf4\x8d\x9f\x4d\xdb\x83\xf3\x35\x6d\x6f\x3f\x56\x28\xac\x34\xc4\xfc\x3b\x00\x00\xff\xff\x05\x0b\xbb\x60\xb6\x0b\x00\x00"), }, "/src/net/net.go": &vfsgen۰CompressedFileInfo{ name: "net.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 1122, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x92\x41\x6f\x1a\x3d\x10\x86\xcf\xf8\x57\xcc\xe7\x93\xfd\x75\xbb\xa8\x52\xd4\x43\x25\x0e\x0d\xad\x22\xaa\x36\x44\x42\x6a\x2b\x45\x39\x78\xbd\xb3\x1b\x83\xb1\xb7\x1e\x6f\xc3\xaa\xe2\xbf\x57\x5e\x76\x49\x02\x5c\x7b\xc2\x0c\x33\xcf\xfb\x68\x86\xe9\x14\xde\x14\xad\xb1\x25\xac\x89\xb1\x46\xe9\x8d\xaa\x11\x1c\x46\xc6\xcc\xb6\xf1\x21\x82\x60\x13\x8e\x21\xf8\x40\x9c\x4d\x38\x75\xa4\x95\xb5\x9c\xb1\x09\xaf\x4d\x7c\x6c\x8b\x5c\xfb\xed\xb4\xf6\xcd\x23\x86\x35\x3d\x3f\xd6\xc4\x99\x64\xac\x6a\x9d\x86\xaf\x86\x22\x3a\xe1\x30\x66\x60\x55\x59\x06\xa0\x18\x8c\xab\x25\x88\xc3\x4f\x18\x32\xe8\x33\x24\xfc\x61\x93\x46\x39\xa3\xc5\x21\x33\xbf\xc5\x27\xc1\x1d\xc6\x27\x1f\x36\xa0\xb4\x46\x22\x30\x04\xce\x47\xa0\xb6\x49\x86\x58\x42\xd1\xc1\x4d\x1f\xfc\x65\xc5\xa5\x64\xfb\x21\x57\x94\xf0\xff\x27\xa3\x2c\x06\x09\xe9\x53\x0c\x9c\x0c\x92\x44\x22\x1d\x3d\xe6\xde\xb9\x7f\xe2\x40\x1d\x2d\x9c\x89\x22\x51\xc7\x5a\x13\x7c\x81\x8b\xbb\xdf\x57\xab\xa8\xf4\x46\x48\x28\xbc\xb7\x29\x35\x60\x6c\x83\x83\x4a\x59\xc2\xb3\xee\xf7\x63\xb7\x18\x42\x29\x15\x33\x78\xf1\xed\x6a\xab\x9a\x1e\x26\x4f\x69\xd9\x25\xe8\x0f\xe3\x4a\xff\x44\x8b\xbb\x33\xf2\x77\x43\x51\x2d\xee\x2e\xb3\x8e\x90\xad\xda\x8d\xf7\xbb\x56\x7a\x63\x7d\x2d\x24\x18\x17\x5f\x0c\x0c\xff\x97\x7c\xb5\xfc\xf6\xf1\xe7\x7c\x79\x7b\x9b\x86\xa7\x53\x98\xfb\xa6\x03\x5f\x0d\x07\xa0\x7c\xe1\x4a\xdc\x5d\x77\x11\xf3\x03\xba\xe8\x22\xf6\x35\x31\x1e\x29\x83\x43\xf5\x34\x61\x9d\x86\x23\x06\xa7\xec\xb2\x58\xa3\x8e\x82\x64\x3e\x57\xd6\x0a\x6e\x12\x60\x59\xf1\x2c\x35\xdd\x58\x5f\x28\x9b\xdf\x60\x14\x7c\xd5\x13\xf9\xd8\x57\x05\xbf\x9d\x3f\xaa\x30\xf7\x25\xf2\x0c\xb4\x94\x09\x29\xe4\x89\x6b\x4a\xa7\xfc\xf3\xaf\x56\xd9\x17\x96\xd4\x17\xc4\x2e\x83\x0e\xee\x1f\x0e\x86\xe3\x3d\x4d\x05\x16\x9d\xd8\x49\xf8\x6f\xd6\xbf\xba\x7e\x99\xaf\xb7\x39\xd9\xb3\x49\xe5\x03\x98\x0c\x0a\xf8\x30\x83\xa0\x5c\x8d\xb0\xeb\x1b\x4d\x05\x45\x9a\xed\xee\xcd\x43\x5f\x38\x19\x4d\xb3\xfb\xe3\x2a\x62\x68\xf1\xa2\xf3\xa5\xed\xd2\xb1\x28\x68\x10\x3f\x5b\xf1\xb9\x16\x3d\x6b\xcd\x66\xa0\x5f\x39\x99\x53\x9f\xb7\xef\xd8\x9e\xfd\x0d\x00\x00\xff\xff\x93\x28\xa9\x7f\x62\x04\x00\x00"), }, "/src/os": &vfsgen۰DirInfo{ name: "os", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/os/os.go": &vfsgen۰CompressedFileInfo{ name: "os.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 581, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x91\x4f\x6b\xdc\x30\x10\xc5\xcf\x9e\x4f\x31\xd5\x49\x62\x5b\x3b\xb9\x76\x6b\x4a\x28\x61\x5b\x28\x2d\xb4\x94\x1e\x42\x28\xfe\x33\xd6\x8e\x23\x4b\x46\x92\x9b\x85\x65\xbf\x7b\x91\xd6\x4e\x21\xe0\x83\xd1\xfc\xde\x9b\x99\x37\x55\x85\xbb\x76\x61\xd3\xe3\x18\x00\xe6\xa6\x7b\x6a\x34\xa1\x0b\x00\x3c\xcd\xce\x47\x94\x50\x08\xf2\xde\xf9\x20\x00\x0a\xa1\x39\x1e\x97\xb6\xec\xdc\x54\x69\x37\x1f\xc9\x8f\xe1\xff\xcf\x18\x04\x28\x80\x61\xb1\x1d\xfa\xc5\x46\x9e\xe8\x4f\xe3\x75\x90\x0a\x1f\x1e\x43\xf4\x6c\x35\x9e\xb1\xaa\xd0\xba\x88\x5d\x63\x0c\xf5\xe8\x2c\xfe\x66\xdb\xbb\xe7\x00\x85\xa7\xb8\x78\x8b\x77\x5e\x07\xb8\xac\x3e\x6c\x39\x4a\x85\x67\x28\x78\xc0\xd9\xbb\x8e\x42\xc0\xf7\x35\x8e\xa1\x3c\x18\xd7\x36\xa6\x3c\x50\x94\x62\xad\x08\xb5\x7f\x81\xde\x64\xe8\x97\xed\x69\x60\x4b\x7d\xb2\x28\x1a\xaf\xff\x26\xf5\xca\x5c\xb5\xe9\x51\x28\x28\x8a\xd4\x18\x6b\x9c\x9a\x27\x92\xdb\xc0\x6f\x31\x95\xcb\xaf\x64\x75\x3c\x4a\xf5\xee\x36\x81\x83\xf3\xc8\xc9\xe7\x66\x8f\x8c\x1f\x5e\x23\x7b\xe4\xdd\x2e\xf7\xcb\x96\x0f\xfc\x88\xf5\x95\xf9\x62\x7b\x3a\x49\xc6\x1d\xde\xaa\xf2\x67\x6e\x20\x93\xe1\x05\xd2\xc7\x03\x1a\xb2\x32\x69\x14\xd6\x35\xde\x64\x8f\x75\xaa\x6d\xa0\xb3\xf8\x28\x32\x7e\x79\x95\x74\x4b\x83\xf3\x74\x7f\xba\xe6\xb5\x55\xe9\x44\xdd\x12\x9b\xd6\x90\x54\x28\xb7\x9d\xf2\x45\x73\xaa\x6b\xe6\x42\xac\x8f\xa1\xfc\x46\xcf\x52\xdc\xbf\xc8\xf2\xb1\x78\x9a\x0d\x4d\x64\x23\xf5\x98\x96\x3f\x7c\xbf\xfb\xf1\xe9\x73\x3d\x06\xa1\xe0\x02\xff\x02\x00\x00\xff\xff\x55\xfc\x3a\xb3\x45\x02\x00\x00"), }, "/src/os/signal": &vfsgen۰DirInfo{ name: "signal", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/os/signal/signal.go": &vfsgen۰CompressedFileInfo{ name: "signal.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 233, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\xce\xbf\xca\xc2\x40\x10\x04\xf0\x7e\x9f\x62\xca\x84\x0f\xbe\x13\xad\x2d\xc4\x42\x3b\xc5\x17\x90\x4b\xb2\x09\x1b\x2f\x7b\xe1\xfe\xd8\x84\xbc\xbb\xa0\x69\x22\xd8\xce\x6f\x60\xc6\x18\xfc\x55\x59\x5c\x83\x3e\x12\x8d\xb6\x7e\xd8\x8e\x11\xa5\x53\xeb\x88\x8c\xc1\x75\x15\x41\x22\xd4\x27\xc8\x30\x3a\x1e\x58\x13\x37\x68\x7d\xc0\xe9\x72\xb8\x1d\xcf\xfb\x3e\xfe\x13\xb5\x59\xeb\xa5\x7e\x6f\x24\xda\xca\x71\x91\x45\xd3\x6e\x5b\x62\x9a\x57\xcc\xba\xd2\x6f\x96\x4e\x7d\xf8\xcd\x81\xeb\x67\x51\xe2\xc3\x00\x26\x04\x4e\x39\x28\x36\x98\x97\x1b\xce\xfb\xb1\x78\xcf\xbe\x02\x00\x00\xff\xff\x29\x0b\xd3\x08\xe9\x00\x00\x00"), }, "/src/reflect": &vfsgen۰DirInfo{ name: "reflect", - modTime: time.Date(2018, 4, 4, 21, 34, 44, 576967800, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/reflect/example_test.go": &vfsgen۰CompressedFileInfo{ name: "example_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 311, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x8d\xcf\x4a\x33\x31\x14\xc5\xd7\xbd\x4f\x71\xc9\xe2\xa3\xe5\x93\xa4\x95\xba\xe8\xec\x5c\x88\xe2\xa6\x62\x1f\xc0\xa6\x93\x9b\x3f\x75\x92\x0c\xc9\x8d\x08\xa5\xef\x2e\x33\x22\x82\xbb\x03\xbf\x73\xce\x4f\x29\xfc\x7f\x6a\x61\x30\x78\xae\x00\xa3\xee\xdf\xb5\x23\x2c\x64\x07\xea\xf9\x8d\xa9\x32\x40\x88\x63\x2e\x8c\xc2\x46\x16\x00\xb6\xa5\x1e\x1f\x3e\x75\x1c\x07\x3a\x70\x69\x3d\xef\xed\x72\x85\x17\x58\x28\x85\x8f\x79\xf4\x54\x9e\x0f\x68\x32\x55\x4c\x99\x31\x4c\xbd\x48\x89\x7f\x4e\xa5\x36\xe6\xf5\x3b\xee\xad\xc5\x44\x64\xc8\xa0\xcd\x05\xd9\x87\x8a\x93\x52\xce\x5f\x07\x22\xf4\xcc\x63\xed\x94\x72\x81\x7d\x3b\xc9\x3e\x47\xe5\x66\xc5\xb9\xfe\x86\x50\x6b\xa3\xaa\xb6\xbb\x1d\xc0\xc2\x46\x96\x2f\x25\x24\x1e\xd2\xf2\xf8\xa1\x87\x46\x1d\xfe\xbb\x3c\x51\x70\x9e\xbb\xb5\xdc\xe2\xbd\xa3\xee\xf6\x0a\xe7\x9a\x53\x87\x78\x11\x7e\x46\x62\x62\x37\x42\x3b\x12\x13\xfd\x3b\xdc\xc8\xbb\x79\xb8\x59\x5f\x8f\x2b\xb8\xc2\x57\x00\x00\x00\xff\xff\x0d\x48\xa9\x1a\x37\x01\x00\x00"), }, "/src/reflect/reflect.go": &vfsgen۰CompressedFileInfo{ name: "reflect.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 37718, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\xef\x73\x1b\x37\x92\xe8\x67\xf2\xaf\x80\x59\x5b\xba\x19\x6b\x42\x59\xca\xbe\x54\x4a\x89\x72\x95\x38\xc9\x3e\xef\xc6\x56\x2a\x5a\xe7\xbd\x7a\x3a\x95\x0f\x22\x31\x14\xc4\x21\x66\x76\x06\xa4\xc5\x48\xfa\xdf\x5f\xa1\x1b\xbf\x07\x43\x4a\x4e\xf6\x6e\x3f\x9c\x3f\x58\xe4\x0c\xd0\x68\x34\xba\x1b\xfd\x0b\xe0\xd1\x11\x39\xbc\x5e\xf3\x6a\x4e\x6e\xbb\xf1\xb8\xa1\xb3\x25\x5d\x30\xd2\xb2\xb2\x62\x33\x39\x1e\xf3\x55\x53\xb7\x92\x64\xe3\xd1\x84\xb5\x6d\xdd\x76\x93\xf1\x68\xd2\xc9\x76\x56\x8b\x8d\xfa\xb8\x16\x1d\x2d\xd9\x64\x3c\x1e\x4d\x16\x5c\xde\xac\xaf\xa7\xb3\x7a\x75\xb4\xa8\x9b\x1b\xd6\xde\x76\xee\xc3\x6d\x37\x19\xe7\xe3\xf1\x86\xb6\x84\x0b\x2e\x39\xad\xf8\x6f\x6c\x4e\xce\x48\x49\xab\x8e\x8d\xc7\xe5\x5a\xcc\xe0\x4d\x96\x93\xfb\xf1\xe8\xe8\x88\xd0\x4d\xcd\xe7\x64\xce\xe8\x9c\xcc\xea\x39\x23\xac\xe2\x2b\x2e\xa8\xe4\xb5\x18\x8f\xd6\x1d\x9b\x93\xd3\x33\xa2\xba\x65\x9c\x70\x21\x59\x5b\xd2\x19\xbb\x7f\xcc\xc9\xfd\x23\xbe\xcf\x5a\xb9\x6d\xd4\x13\xfd\x75\x2d\x66\xf5\x6a\x55\x8b\xbf\x07\x4f\x57\x4c\xde\xd4\x73\xf7\x9d\xb6\x2d\xdd\x86\x4d\x66\x37\x34\xea\xa4\x86\x0d\x9f\x58\x0c\x22\xe8\xb4\x09\x1f\x34\xb2\x0d\x1f\x74\x15\x8f\x3b\x75\xb2\x5d\xcf\x64\x04\x3f\xc6\x13\x1b\xfd\xc8\x59\x05\x0f\xc7\xa3\x90\xac\xb2\x5d\xb3\xf1\x68\xcd\x85\xfc\x52\x01\x22\x67\x44\xfd\x39\x2f\x33\x78\x94\xbd\xca\xf3\x69\xf6\x12\x08\x94\x93\xa3\x23\xd2\x31\x49\xca\xba\x25\x2d\xa3\xd5\xf8\x51\x2f\xc7\x6d\xa7\xfa\x64\x72\xdb\x40\xe7\x9c\xbc\xbc\xed\xa6\xe7\xd7\xb7\x6c\x26\xd5\x1a\xb5\x4c\xae\x5b\x41\x6e\xbb\xe9\x1b\x35\x79\x41\x2b\x7c\xa7\x3a\xe4\xd3\xbf\x30\x99\x4d\x10\xc2\x24\xb7\x20\x35\x5f\x59\xb8\x0e\x62\x4e\x10\x1d\x05\x99\x97\x44\x6e\x1b\x04\xe1\xf5\x98\xe4\xe4\xec\x4c\x8d\xf7\x5e\xcc\x59\xc9\x05\x9b\xab\xc6\xa3\x56\x2a\x4e\x38\xc0\xd5\x1e\x8f\x46\xa3\x8e\xff\xc6\x4e\x89\x9a\x68\x23\xdb\xcc\x42\x52\x8f\x27\xb9\x42\x36\xcb\xf3\x42\x35\x5c\x72\x31\xc7\x86\x5f\xba\x66\xea\x61\xd8\xac\x93\xed\x29\x21\x82\x7d\x7c\x47\x57\xec\xbc\x2c\x33\xfd\x11\x17\x5d\xd0\xea\x22\x18\x46\xb6\x5c\x2c\x26\x79\x5e\x90\xc9\xa4\x70\x13\x61\x77\x4a\x92\x98\x82\xfd\x5d\x5d\x57\x59\x8e\xd0\x1f\xc7\xa3\x51\x9f\x84\xad\xcc\xa7\x17\x1e\x05\x01\x4e\x3e\x1e\x8d\x14\xb8\x8b\x98\x2e\x45\x62\x11\x5a\x99\x2b\xae\x18\x21\xdf\x5c\x30\x20\xd2\x6d\x37\xfd\x4b\x55\x5f\xd3\x6a\xfa\x9a\x56\x55\x36\xf9\x93\x7d\xeb\x46\xe0\x25\xb1\x4f\xa7\x3f\x31\xb1\x90\x37\x59\x4e\x5e\x9c\x91\x57\xe4\xe1\xc1\x4d\x47\xd0\x95\x37\x17\x58\x88\x51\x2b\xa7\xb2\xac\xe8\x82\x3c\x9c\x11\xf8\xf0\x5e\x8b\x9c\x7a\xe9\x2f\x6a\xaa\x73\xbf\xb7\xa2\xf1\x5c\xbd\x7a\x04\xe0\x38\xe1\xb7\x80\x5b\xa7\x66\xb3\xa2\x4b\x96\x5d\x5e\x21\xb6\x45\x02\x6b\x35\x9d\x91\x62\x6b\xae\x9a\xb7\x54\x38\xcd\x66\xc0\xe0\xd0\x2b\x00\x67\xfb\xbf\x11\x73\x76\x97\xf1\x1c\xd1\x0a\x3a\x5c\xf2\x2b\x62\x9a\x62\xdf\x91\x9a\xcc\xe9\x3e\xf6\x58\xb9\x89\x5b\xd6\x48\xbc\x6f\x96\x8a\x73\x14\x9b\x4f\x26\x9a\xfb\x46\xa3\x95\xdc\x36\x30\x00\x8a\x70\x99\xf9\x52\xa4\x3b\xca\x6d\x33\xc9\x4d\x8f\x47\x4b\xb4\x35\xca\x46\xa0\xfa\xa0\x49\xb3\x5c\xfc\x4c\xe5\xcd\x33\xf8\x1a\x51\x43\xcc\x41\x69\x9b\xd1\x56\xb3\x7a\x2d\xe4\x29\x21\x20\x49\xc7\x5f\x64\x89\x85\xc0\x96\x1f\xf0\x4d\x77\x1a\xad\x42\xe1\xf0\xf5\x10\x7d\x4b\x9b\xcb\x56\x2a\x72\xaf\xa5\x7a\xd7\xe7\xf1\xf5\x90\x94\x3c\x2a\xce\xef\x3e\x72\x39\xbb\x21\xad\x9c\xfe\x8d\x8b\xb9\x66\xb3\x19\xed\x18\xf9\x56\xe9\xf8\x53\x10\x6d\x26\xd5\x4b\xa0\x64\x2b\x0b\x72\xe0\xd4\x3f\x60\xcc\x2a\xb6\x3a\x8d\xb5\x96\x96\xe7\x8a\xad\xec\x1a\x55\x4c\x9c\x92\xbe\xca\xa9\x98\x08\x55\x89\x52\xdf\x88\xc3\xeb\x1b\x2a\x00\x85\x39\x6f\xd5\x1a\x7d\x57\xcb\x9b\xef\x79\x1b\x4b\x4a\xc7\xc4\xfc\x5c\x54\xdb\x58\x58\x54\xaf\x33\x72\xc1\xc4\x5c\x77\x7a\x8c\x7b\xb6\x6c\xb6\x19\xee\xf9\x0b\x9b\x6d\xfc\x9e\x3d\x42\xd8\x4d\xef\x59\x74\x98\xf3\xd6\xa3\xc3\x9c\xb7\xf1\xb4\x7f\x5c\x8b\x19\x4c\xbb\xa1\x2d\x5d\x81\x18\x3b\x0e\x83\x47\x13\x10\x3b\x2e\x3c\x09\xc7\x9d\xa1\x20\xd8\x60\xa7\x78\x73\xa1\xa7\xc9\x05\x8a\xaa\x8f\xb3\xee\x6f\xc4\x3b\xf7\x74\x4b\xb7\xae\x64\x88\x8d\x7e\x86\xe8\xd4\x28\x48\x11\x3e\xba\xc9\x4e\x84\x54\x4f\xc4\xa8\x5e\xcb\x3e\x4a\x06\x44\x1f\xa7\x7a\x2d\x5f\x2b\xc1\x52\xa0\xb4\x60\x25\xc7\xf3\xd7\x7c\x43\x5b\x4e\xe7\x7c\x16\xaf\xb9\x85\xf5\x70\x46\x8e\xc9\xd7\x5f\x93\xe3\xff\x35\xbc\xf2\xd6\xb8\xd1\x5a\x79\xdb\x30\x25\xdc\x6a\x7f\x2e\x34\x69\x5f\x6b\x89\xd7\x78\xc5\xeb\x52\x04\x83\x9e\x12\xf3\x49\x6b\x01\x2e\x00\x1e\x21\x5c\xe8\x27\xf5\x5a\xe2\xa3\x7a\x2d\x23\x86\x79\x63\x0c\x2b\xe0\x9a\x95\xd3\xfe\x76\xd2\xfa\x99\xe6\x9b\x55\x6f\x7f\xe0\xe1\x06\xb1\x87\x7f\x56\x43\x1b\x43\x17\x6e\x0b\xa6\x21\x2e\x29\xff\xaf\xdd\x11\x60\x43\xf8\xb4\x1d\xa1\xb7\xdc\xa1\xe5\x1a\xae\xb9\x5d\x72\xbb\x5d\x3c\x73\x8b\xd0\x3b\x84\x51\xfb\x86\x68\xd1\x1a\xbf\xa5\x4d\x5a\x1b\x1b\xf3\x19\xa0\x2c\xd9\xf6\x94\xa4\x75\xd0\x92\x6d\x2d\x71\x9e\xa8\xaa\xdc\xe8\x3f\xcb\x36\x3d\xba\xb1\xd5\x3f\x0d\xec\x85\x32\xec\xd3\x80\x9d\xcd\xff\x89\xa0\xc1\xf6\x07\xd8\xa5\x72\x00\x42\x79\xc0\x47\x28\x0e\x1a\xe8\x8f\xb6\x95\x96\x09\xcf\x7b\x28\x08\x76\x78\x8a\xd5\xa4\xe1\x20\xda\x25\x38\x60\xd8\x37\x10\x8d\xba\x2c\x3b\x26\xbf\x15\xb5\x30\xba\x4b\x6d\x06\x3c\x07\xc5\x83\xc2\x53\x92\x12\x91\xa5\xa2\x16\xdb\x55\xbd\xee\x62\x95\xe5\x43\x51\x5a\xcb\xb1\x71\x38\x29\x94\x3f\xdf\x1b\xf2\x65\x10\xff\xa5\x98\xb6\x8c\xc4\x2f\xf1\x4e\x52\x64\xe7\x72\xc8\x80\x0f\xa4\x11\xff\xf9\xab\x58\xfa\x82\x58\xc4\xb3\x3a\x25\xee\xf3\x5e\x21\xf5\x5c\xc2\xdf\x2b\xa1\xaa\x55\x52\x4a\x71\x29\x9d\x88\x21\x7d\x1d\xeb\x3d\x8e\xc1\xae\xd2\x6e\x9f\xf1\x1e\x33\x8c\x00\x4c\x7f\xae\x61\xc0\x2c\xed\xb8\x4d\xdf\x43\x2b\xe5\xf4\x58\x5f\x30\x9c\x24\x31\x9b\xea\x52\x3f\x8b\x9c\xfa\xf1\x2e\x2f\xc9\xf4\x49\x7a\x42\xe6\xa5\x62\xec\x1d\x6f\xb5\x5b\x25\x77\x3a\x54\x8f\xe3\x31\x38\xa9\xbe\x9d\xaa\x99\x4f\xa1\xa8\xc9\x4b\x04\xea\xfd\xb1\xb6\x8d\xcd\x46\x39\x1e\x7d\xd0\x6c\x62\xbe\xaf\xea\xb2\x34\xdf\x3f\x3f\x09\xdf\x7f\x7e\x32\x1e\x5b\x93\x99\x18\x3f\xc7\x92\x2f\x93\xe4\xa5\x8f\x46\x6e\xf6\xa9\x2c\xb7\x8d\x3d\x37\x5d\x4e\x0d\x28\x05\x61\x43\x5b\x12\xd9\xda\x44\x2b\x87\x15\x6d\x2e\x71\x2d\xae\x42\xf8\xde\xb8\x3a\x70\x60\x5e\x67\x79\x88\x8a\x37\x6c\x6c\xd0\xcb\x2b\x4b\x43\x63\x67\x78\xf4\xc3\x08\x00\x21\xe4\x3f\x35\xf7\x9c\x4e\x54\xab\xc9\x7f\x8e\x8d\xd1\xe1\x48\x67\x6d\x1a\xfd\x60\xac\x0c\x0b\x42\x8c\x75\x36\x06\xab\xc2\x7d\xf5\xc9\x66\x46\xce\x09\x17\x40\x2d\x17\x7a\x70\xd4\xe2\x62\xa0\x4f\xbd\x96\x83\x9d\xea\xb5\xb4\xf3\x53\x4c\xe0\xcd\xed\x7a\x2b\x59\x47\x5e\xaa\x3f\x41\x93\xef\xa9\xa4\x5e\x33\xe8\xa5\xfe\x61\x1c\x61\x3c\x92\x74\x41\x82\x07\x46\x0f\x91\xeb\xba\xae\xcc\x62\xaa\x6e\xf1\x22\xaa\xa1\xae\x5e\x9a\x31\xec\xfa\x09\x68\x9c\xc3\xff\x59\x4e\xb2\x4e\x43\xce\xc9\x3d\xd1\x33\xd1\xd0\x2e\xc5\x14\xb0\xbe\x9a\x02\x56\x8f\x11\x00\x49\x17\x61\xff\x1d\x00\xd4\x2c\xe2\xfe\x5a\x5a\xb2\x5c\x03\xf0\xfa\x4f\x26\xbd\xd6\xbc\xfb\x41\x4f\x3c\xcb\x61\xea\x3b\x46\xb3\x24\x32\x2b\x68\x94\xa2\x28\x14\xd6\x7a\xbc\x82\x04\xa4\x44\x8a\xc0\x52\xa9\x7d\x4b\xb0\x8f\x99\x02\x97\xe3\x9a\x28\xf8\xd7\x6a\xab\x39\x30\x04\x55\x9a\xd8\xed\x32\xa0\xc3\x25\x5d\xe8\x9d\x40\xd2\x85\x7a\x60\x06\x38\xb5\x43\x15\x4a\x8b\x8e\x3c\xc4\x15\x18\x40\xfb\x94\x5c\xc3\x4b\x6f\x45\xcf\xcb\xf2\x27\xde\x29\x2e\x56\xdf\xfa\x02\xa8\xdb\x64\x4a\x8b\xe8\xcf\x6e\x16\xde\x18\x1a\xce\x25\x17\x52\xb5\xcd\xaf\xc6\x11\x61\xc0\x48\xf5\xf8\xe2\xbc\x2c\x21\x10\xa7\x08\x51\x31\x91\x79\x40\x34\x3d\x0c\x6a\x67\x84\x36\x0d\x13\x73\xbf\x49\x41\x44\x1e\x8f\xaf\x8c\x03\x3d\x33\x89\x46\xab\x9e\x99\x96\xcf\xde\xdc\x74\x2b\x98\x9b\xfe\xec\xc7\x08\x8d\xcc\x39\x58\xe9\xd9\x19\x0b\xb9\x07\x38\x98\x9f\x07\x26\x1f\x8f\x7c\x04\xed\xfc\xbc\x87\x05\x91\x79\x8c\x81\x9e\x9f\x8e\x63\xbb\xad\xb7\x93\xed\xf9\xf5\x6d\x10\xe8\xd4\xdc\x7e\x3f\x1e\x29\x6a\xcc\xb4\xf0\xdf\xab\xbf\xe6\xdd\x63\x6a\xab\x9a\xe9\x3d\xaa\x93\xed\xa4\x20\x08\x18\xa2\xb7\x0b\x26\x4d\xc7\x8f\x5c\xde\x28\xbd\x67\x50\xe0\xbf\x81\xce\xd0\xb8\xce\xa6\x9d\x6c\x1d\x9a\xdd\xff\x69\xd5\xe4\xe6\x5e\x88\x17\x05\xcb\x0b\xee\x1a\x7b\x54\x47\x74\x3f\x62\x0f\x6b\x03\x59\x60\xb3\xba\xd9\xa2\x5d\x9a\xcd\x15\x85\xba\x76\xe6\x4d\x1a\x22\x33\x7a\x88\xfb\xb1\x67\xb5\xf6\x06\x70\xd6\xab\x35\x41\x5f\x7d\x45\x38\xf9\x3a\x36\x53\xbf\x22\xfc\xf0\x10\x8c\xc5\xa6\xad\x9b\x84\x2d\xaa\x2d\x9e\xb6\x6e\x26\xf9\xf4\x02\xc8\x93\x29\x3b\x66\xde\x49\xa0\xa3\x7a\x03\x78\x42\x43\xf5\x4d\x59\x08\x8f\x76\x46\x4a\x91\xfe\x4a\xab\x35\xcb\x24\x60\x5e\x90\x4d\x30\xa3\xb2\x22\x65\x45\x17\x39\x81\x46\xb8\x7d\x81\x21\x3e\x35\xbb\x22\x46\xb2\x4d\xf8\xe9\xec\x0c\x03\x4f\x10\x46\xf5\x1e\x22\xd5\xe2\xa7\x3f\xcb\x16\xa3\xdb\xb8\x10\x30\xc6\xbd\xb2\x05\x23\x7b\x6b\xe3\x4c\x2b\x40\xe9\x01\x90\xca\x0c\xa8\xfc\xd1\xd7\x37\x83\x50\x7a\x81\x61\xc1\x3e\x2a\x1d\xa7\xdf\x4f\x0a\xb2\x29\xcc\x5a\xb5\x72\xaa\x3c\xa3\x5a\x19\x73\x7b\x06\xd7\x0f\xde\x88\x39\x6f\x1d\x61\xdf\xd2\x25\x03\xef\xc8\xf2\x5d\xa1\x84\xb0\x20\x33\xda\x28\xc6\xf5\x28\xaa\x83\x1b\x9a\x2c\x2f\xce\xd0\xab\xc2\x55\xa7\x82\xcf\xac\x99\x39\xb5\x40\x49\x5d\x12\x51\x8b\xcf\xc0\xc9\x02\xe9\x9c\xc0\xb2\x2a\x58\x15\x13\xe4\x6b\xf2\x6a\x67\x7f\x65\x41\x2f\xa8\xe4\x1b\x46\x20\x7c\x67\xfa\x2a\xe4\x9e\xd1\x77\x46\x9b\x70\xdc\x6f\x00\xc2\xee\xde\xb6\x1d\x76\xb5\xeb\xe6\xb1\xe2\xb6\x29\x12\x61\x7c\x03\x62\x52\xf8\x12\xe5\xc8\x9a\x32\x68\x21\x77\x16\x26\x75\x48\x4f\xec\xa7\x3f\x54\x6c\x95\xe5\xb9\x1e\xe9\x37\xd6\xd6\x93\x9c\x3c\xaa\xf5\x7e\xe5\x84\x5f\xe7\x96\xa2\x44\xdc\xdf\x5d\x3a\xe7\x85\x9f\x9d\xba\x27\x36\xbd\x07\x39\x45\xb5\x62\x36\x53\xe5\x58\x5e\x67\x74\x1e\x0d\x11\xb9\x12\x0b\xc1\x2b\x5f\x2c\x04\xaf\x7c\xfe\xf6\xbd\xaf\xfe\x84\x8d\x4a\x98\xd5\x02\x55\x6e\xdd\x4e\x3c\x7f\x04\x08\xdc\x9f\x85\xcf\x8b\x29\x14\x50\xa6\x02\x31\x73\xcb\xf5\x29\x08\xa5\xd6\xca\xb4\xfc\xd3\x86\x56\x93\x90\xf6\xa0\x53\xce\xcb\x0c\x3d\x0d\x2e\x64\x41\x58\xc5\x56\x5a\xd9\x46\xe6\x78\x84\x4f\xc8\x45\x36\xf6\xed\xb8\x48\x41\xca\x0b\x02\xb0\x3d\x52\xbd\xbe\xa1\xe2\xbc\xcc\xe6\xbc\x85\x8f\xdf\xf3\xb6\x20\xf2\x13\x46\x34\x41\x66\x8f\x6d\xf3\x82\x40\x84\xda\x06\xb7\xed\x77\x1d\xb2\xf6\xd0\xf8\x71\x2d\x66\x6a\xc1\x44\x41\xd0\xd6\xd7\x6a\x5a\x47\x41\xb5\x55\xe7\xb1\xa1\x7d\x73\x70\x40\x32\xb5\xef\x73\x01\xca\x16\x52\x5b\x5c\x5c\xea\x47\x9f\x1d\x5f\xc5\x2a\x27\x4f\x49\x2e\x8e\x7f\x4a\x2a\xda\x49\x42\xdb\x85\x62\x64\x3b\x04\xee\x21\xeb\x4e\x92\x6b\x46\x40\x19\x19\xa1\xbe\xed\xde\x04\xd1\x6d\x6f\x4f\xd1\x08\x98\xdd\x4f\x6d\x39\x71\x68\x5b\xf5\xc6\xa0\x87\x26\xd9\x06\xd5\xcc\x6d\x77\x1e\x06\xa9\x23\xb0\xf5\x5a\xa6\xe1\x9a\x08\x35\x00\x48\x41\x7e\xca\x4a\x1a\xf7\x08\x56\xf2\x8d\x50\xff\x9f\xaf\xa5\x5b\x0b\x6f\xd5\xde\xd2\xe6\xbc\xcc\x96\x6c\x9b\x64\x54\x9d\xb5\x59\xb2\xad\x97\xb6\xb1\xa9\x83\x42\xf5\x2e\x5c\x6c\xad\xa7\x4a\x1b\xb5\x1e\x5c\x6c\x68\xc5\xe7\x0a\x08\x6c\x00\x64\x42\x0e\x01\xa2\xb1\x02\x42\xed\xba\x73\x62\x3a\x04\xe9\x38\x74\xc9\xb6\x79\x28\x1f\xde\xdc\x3c\x33\x53\xef\x91\x7d\x93\x75\xe7\x70\x3a\xe6\xe8\x0b\x84\x07\x1e\xe6\x7d\x5e\x66\x9f\x22\x6b\x36\xe8\xd8\x87\x7d\x74\x84\xdc\x8a\x96\xc8\x79\x99\x69\xfb\xec\xf2\xea\xc2\xc5\xd5\xec\x68\x47\x47\x64\x74\xdb\xf5\x42\x8a\x31\xbf\x21\x8c\x3c\x87\xf6\x65\xc7\x34\x6f\x36\x97\x68\xa9\xea\x10\xe4\xfd\xe3\xfd\x23\xb6\x40\xbe\x2c\x1d\x5f\x96\x26\xd8\xa8\x5e\x63\xc8\x10\x4b\x19\x8c\x0a\x86\xe7\x31\x0b\x98\x39\x9c\x62\x7f\x58\x7a\x5d\xaf\x32\x7d\x23\x6b\x9a\xf1\x9c\x1c\x92\x09\xb9\xa1\x1d\x11\xb5\xb1\x0f\x00\x14\x52\x02\x9d\x3a\xb0\x27\xa7\xca\x35\xb2\xc3\xc3\x63\x88\xc3\xdb\xb1\x8f\x8e\xc8\x0f\xab\x6b\x36\x9f\xb3\x39\x0e\xa7\x9f\x5b\x64\x7b\x06\x1d\xbe\x0f\x3a\xbe\x7c\x49\xa8\x98\x93\x97\xde\xae\x43\x68\xcb\x08\xaf\x2a\xb6\xa0\x95\xe9\x02\xb2\x02\x58\x01\x60\xdc\x97\xcd\x4b\x5e\x92\xa5\x7a\xa9\x1a\xe9\x31\xbf\x22\x4b\x33\xec\xc3\x03\x7e\xb6\xb9\x14\x87\xc8\x30\xf9\xf4\xf0\xc4\x46\x68\x35\x41\xad\x40\x69\x44\x9c\x4c\x69\x90\x8f\xe6\x03\x12\x0c\x71\xb2\xf6\x37\xbe\x7b\x24\xac\xea\x3c\x34\x74\xd3\x08\xa4\x69\x1c\x2e\x0f\x2f\xc9\x87\x82\xcc\xd7\x68\xf3\x77\x4c\x5e\xaa\xde\x57\x5f\xc1\xa3\xbd\x5c\x31\x5f\x37\x15\x9f\x51\xc9\x3c\xfe\x00\xbf\xd7\x0c\x02\x7f\x1c\x58\x1b\x5c\x06\x4e\xc5\xb7\xb7\x5d\x19\x56\x53\xc0\xde\x8c\xcc\x3f\xc9\xa7\xef\xd8\x47\x83\xfb\x6d\x57\xa2\xcf\x06\x6e\x48\xe1\x8f\x64\x5f\x41\x08\x3a\xfd\xca\x86\x9c\x0b\x28\xe8\x89\x5f\xcb\x6d\xe3\x84\x19\x69\x97\xf7\xda\xd0\xc5\xa4\x50\x84\xa5\x0b\xfb\xca\x8f\x9c\xdf\x76\x25\x3c\xc6\x89\x3f\x49\x91\xd8\x58\xf4\x04\x83\xc8\x06\x20\x8e\x6d\x74\xd5\xff\x63\x6d\xed\x39\x96\xce\x49\x1a\x30\x69\x9d\x1f\xe8\x9b\x9a\x81\xa9\x83\x4e\xcb\x07\x45\x5f\x28\x1e\xb2\x61\x48\xdf\x97\xf1\x36\x11\xcf\x75\x30\x9b\x88\x4b\x9d\xd8\x00\x65\xe4\x08\x45\xfe\x68\x23\x5b\xb3\xa4\xce\xd9\x19\x47\x75\x04\xfb\x61\xf9\x73\xf2\xe1\xcc\x59\x49\xd7\xd5\x4e\x84\xf6\x79\x66\xc3\xa4\xf3\xcc\xf8\x84\xc7\x16\xfb\xba\x6f\x84\xcc\x4a\xf0\xd7\x0a\x72\xcd\x65\x07\x36\xf9\x17\x7f\x76\x96\x9d\x5d\x42\x45\xfc\xc8\xd1\x6d\x24\x54\x31\x84\x2b\x94\xef\x5a\x89\x37\x42\x7e\xa9\xa6\xfd\x32\x53\x9a\xef\xcb\x3c\x6b\x64\x9b\x93\x33\x02\xd5\x58\x6a\xfc\xdc\x35\x3c\xfe\xc2\xb5\x3c\xfe\xc2\x6f\x7a\xfc\x45\xdc\xb6\x50\xff\x7d\x7e\xe2\x3a\x7c\x7e\xe2\x77\xf8\xfc\x24\xee\xf0\xc5\x9f\x5d\xdb\x2f\xfe\xec\xb7\xfd\xe2\xcf\x41\xdb\xf7\xdc\xa1\xbc\x0e\x70\x5e\xf7\x90\x7e\xcf\x3d\xac\xd7\x21\xda\xeb\x3e\xde\xef\xc1\x6e\x7f\x0f\xf8\xe1\xdf\x06\xb3\x92\xba\xb7\x37\x87\x75\x7f\x12\xef\xb9\x37\x8b\x75\x38\x8d\x75\x30\x8f\x38\x14\x00\xb2\xd7\xc8\x56\x6d\xbc\x9e\xaf\x6e\x1d\x79\xbb\x6c\x79\xe8\xbe\x2b\x5b\xcc\xf3\xde\x4b\x81\x95\x98\xb4\x5d\x28\xab\x01\x60\xe7\xc4\xd4\x2b\xd8\x27\xbb\x1c\x7b\x05\x31\x61\x63\x9f\x92\x19\xad\x2a\x65\x58\x9b\x61\x21\xc4\x05\x1e\x3e\x7c\x73\x0e\xfe\x78\x24\x4d\x1e\xd4\xf1\x65\xa9\x79\x35\x73\x01\xfc\x5e\xc6\x0a\x0a\xe5\xca\x8d\x56\xe9\x76\x7a\x30\x23\x79\xc3\xbb\x20\xea\x43\xdb\xc5\x7a\xc5\x04\xcc\xca\x0f\xea\xf9\xbb\xb7\x9a\x06\x90\xc2\x59\x47\x30\xf1\x82\x28\x74\xa6\xef\xd6\xab\x37\x02\xf3\xac\x51\x9a\x15\x3a\x41\x86\x8f\xb6\x0b\x30\x76\xd4\x16\xa7\xfa\xbc\x11\xca\x07\x74\xf3\xc2\x01\x74\x35\x9a\x55\xa5\xba\x97\x87\xe5\x25\xbf\x02\x15\x8a\x89\x45\xbd\x20\x18\x27\x51\xa0\x05\x2c\x59\xee\xaa\xa5\x0c\x82\xe7\x6b\xe9\x57\x4c\xbd\x3a\xc5\x6c\xb2\x73\xba\xf1\xf9\xb1\xff\xdc\x87\x7e\xf9\xea\x6a\x5a\xa3\xef\x0a\x31\x37\xa7\xe6\xfc\x62\x9b\x68\x07\x05\x7d\xaa\xb5\x6d\x80\x88\x4b\x49\x17\xa4\xf5\xb3\xd2\xde\x74\x74\x62\x54\x97\xc8\x5c\x30\xa9\xe3\x80\x05\x69\x2d\x26\x7e\xc5\x8f\x8f\xb2\xce\x6e\xe6\xe3\x58\x3c\x7a\x81\xb2\x32\x8a\xb7\xd1\x45\xa6\x98\xc5\x13\x0f\xc5\x90\xf3\x15\x5b\xad\xea\x0d\xcb\x5c\x5a\xd3\x06\x45\x43\x80\x03\x99\xcd\x79\x27\x73\xbb\xdf\x42\x75\x66\xbf\x4d\xd7\xce\x6c\x9b\x05\x93\x7e\x28\xa3\xaa\xe9\xfc\x62\x46\x2b\xda\x66\x4d\x34\x60\x41\x84\x49\xc9\xe7\xe6\xc3\xce\x6a\xde\x26\x1c\xc4\x4e\x3f\xd8\x3b\x94\x23\xef\xed\xc9\x05\xe9\xf8\x6f\x0c\x63\x79\xd9\xec\x26\x35\xe7\x99\x15\x4c\x13\x04\x48\xa5\x92\xf3\x7c\xbc\x77\x5f\xc4\xc0\xc8\xeb\x1b\x2a\x34\xeb\xe8\x6d\x4f\x8d\x30\xd5\x01\x0c\x85\x8e\xbf\xf5\xf9\xb8\xaf\x68\xe3\xad\x93\x8d\x41\x66\xab\x14\xda\x4f\x42\x26\xb4\x04\x13\xc3\x2e\xd9\xf6\xc7\xba\xf5\x46\x55\x9e\x6a\x3c\x5a\xe6\xab\x1d\x9b\xa2\x1b\x8f\x96\x46\x53\xc5\x99\x6c\xb6\xc5\x88\xf3\x72\xa3\x69\x02\x0b\xa6\x94\x6b\xaf\x66\x7a\xb9\x21\x67\xaa\x9d\xbf\xb2\xb0\x3b\x2c\xfd\xa0\xfc\xf4\x6f\x6c\xeb\x62\x7f\x88\xf4\xa4\x20\xcb\x8d\x1f\x4f\xd7\x14\x59\x6e\x0a\xb2\xf4\xe8\xda\xd0\xd9\x8c\x75\x9d\x37\xc7\x55\x7a\x9a\x7d\xeb\xed\x43\x81\xce\x8c\xa1\x12\xf4\xcb\xc7\x23\x26\x64\xbb\x4d\xcf\x7d\x85\xd6\xda\x12\x09\x80\x0d\x93\xb5\xe2\xc9\xb0\xe1\xb3\x4d\x2e\x18\x40\x97\xdc\x79\x86\xd6\xcf\x60\x64\x49\x13\x33\xcd\xd3\x1c\xd7\xd0\xae\xe3\x0b\xd1\xa3\x4c\x41\x36\xb4\x4a\xf1\x1c\x90\x36\x45\x90\xdb\xee\x57\x5a\xa5\x09\xb2\xa1\x55\x1e\xad\x2e\xd3\xd9\x09\xed\x39\x02\xa1\x12\x79\x08\x48\x6b\xb2\x8f\x16\x32\xc6\x39\x64\x68\x5b\x2a\xfd\xef\x12\x3e\xd8\x5c\x91\x01\xfe\x30\x99\x43\x38\x49\x81\x80\x3c\xea\xaf\x14\xc9\xed\x2f\xe0\x0e\xcf\x09\xdb\xe9\xca\x0e\xe4\xb7\xe0\xd9\x66\xa2\x87\x4a\x16\x74\xac\x30\x4b\xb6\xd4\xab\x14\x50\x7e\xce\x2a\x26\x7d\xad\x1c\xcb\x78\x9a\x45\x77\xf0\x64\x72\xfc\xef\x71\x98\xa5\xab\x17\x59\xd1\xe6\x8d\xe2\x6e\x97\xe7\x97\x84\x10\x82\x01\xef\x15\x54\x57\x5a\x61\x1f\x8f\x96\x6c\xdb\x05\x0f\x38\x56\x4b\x4a\x7f\x2e\x5c\xb2\x16\x0e\xcc\x0c\xcf\x26\xc7\x72\x03\x4f\x6f\x65\xf0\xa0\xa7\x69\x0f\x34\x7e\x6a\xc3\x4b\xcd\x28\x91\x72\x50\x38\x26\xb7\xa5\x15\xe4\x06\x1e\x43\x96\x57\xc8\x2e\xd9\x36\xe3\x12\x51\x4a\x89\xbd\x6a\x83\x3b\x82\xc6\xa6\x87\x26\x87\x08\x26\xac\x83\x6a\x3c\x55\x38\x98\x74\x9f\xfa\xce\x9f\xb0\x5b\x0c\x89\x34\x00\xc0\xd2\xc9\xa5\x8b\x69\xe8\xf2\xc2\x9e\x8c\x43\x6b\xa3\x1f\x87\xe4\x5c\x35\x12\xec\x4e\x7a\xb3\x7e\xc6\x34\x71\x46\x87\x87\x3e\xc4\x8a\x89\xc4\xb6\xc4\x45\x74\x1e\xe7\xe9\x2b\x65\xb3\xa9\x2e\x8f\xbb\x91\xdf\xf3\x16\x54\x08\xd1\x46\x6b\xc2\x89\xdf\xd0\x56\x19\x33\x28\xe1\x1b\xcf\xd2\xe3\xa5\x7d\xee\xc2\xc8\x53\xe7\x4e\x0b\x5e\x4d\x72\x5f\x15\xef\x88\x03\xb8\x0e\x05\xd9\x4c\x21\xd7\x8a\x76\xbe\x1a\x5d\xe9\x4a\x5f\x44\x4c\xdc\xd8\xb8\x00\x2e\x08\x66\x5d\x7f\x13\x34\xee\x8c\xf9\xeb\x0f\xa6\x54\x0f\x62\xae\x37\x4f\x8a\xc6\x68\x6e\x3a\xa0\xee\xf9\x13\x16\xed\x4d\x0a\x12\x34\xd6\x4f\x7b\xad\x2b\x20\x6f\xdc\x5a\x3f\xed\xb5\x9e\xa9\x5d\x93\xcb\x6d\xdc\xde\x3e\x87\x1e\x1b\x20\xfa\x7e\x8e\x06\xc8\xf1\xde\xa4\x4c\x2a\xe3\x36\xea\xc2\x57\xed\x8a\xe1\xb6\x90\xde\x0f\xc2\x36\xea\x25\xac\xa9\xf9\x8e\xa6\x37\xe2\x85\x88\xc3\x83\xeb\x96\xd1\xa5\xb5\xb8\x0d\xda\x21\xc9\xc1\x22\xf7\xb6\x92\x8d\xda\x40\x10\x46\xe1\x0d\x09\xcd\x0c\xbc\xc7\xf1\x10\xb4\x80\x6a\xb0\xed\x45\x94\x34\x8b\x14\xc5\x82\xfa\xd0\xe2\xd8\xcf\x78\x27\x96\x41\x40\xa8\x20\xdf\xd5\x75\x55\x40\x66\xac\xd0\x59\x0b\x1b\x79\x35\x09\x0c\x50\x30\xfe\xd0\xbd\x0d\x7c\xaa\x2c\xf4\x20\x40\x84\x9e\xf1\x01\x48\xcb\x0f\x6d\x5b\xb7\xf7\x36\xbe\xf9\xba\x16\x1b\xd6\x2a\xb6\x5c\x3e\xa6\xdd\x7c\xeb\x3b\xf6\x2b\x08\x68\xe5\xfb\x34\x28\x69\xd3\xb6\xce\x72\xf2\xa0\xbf\x1d\x3c\x2d\x32\xf0\xba\x6e\xb6\xae\xfa\x43\x47\x01\xb4\x76\x9a\x83\x64\xce\x3b\x39\x5d\x42\x37\x50\x15\xf3\xa5\xb2\x4e\xb1\x2a\xe2\xe0\x40\x7f\x8d\x53\xfc\x03\x13\x6e\x94\x98\xcc\xcd\x74\x11\x98\x2d\xb1\xb8\xd7\x75\x1e\xab\x75\x27\xbf\x63\xdf\x82\xc1\x45\xaf\x2b\xe5\xb6\xa8\xd6\xee\x95\xab\x29\x1b\x8f\x47\x1d\xe0\xd8\xb5\x33\x8b\x23\xe8\x39\x58\x2b\x35\x20\x56\xdc\x81\x8e\x0b\x11\xef\x22\xc4\xbd\x2e\x67\xea\x25\x4a\x13\x17\x0b\x98\x65\x27\xa7\x49\x81\x83\xf8\x12\x0a\xe4\x0b\x0f\xc2\xfd\x78\xf4\x14\x52\x74\x4b\x57\xa5\x3b\x52\x73\x48\x4c\x30\x01\x59\x59\x0e\xdd\xdb\x75\x27\xdf\x52\x39\xbb\xc9\x7a\x04\x0e\x90\xc5\x72\x99\x40\x2c\x95\x3e\x9e\x77\x52\x9b\x8b\xaa\x79\xb0\x19\x24\x16\xe5\x57\x5f\xd8\x4c\x46\x2b\x1c\x27\x47\xa9\xc3\xc6\x7a\x10\xbd\xad\xe8\x05\x0a\x77\x9c\x68\x10\xbb\x33\x45\x83\x44\xc8\xfb\x3a\x43\x0f\xa2\x80\x85\xf4\x19\xda\x55\xb5\x36\xe0\x62\x81\x54\xfa\xd5\xa9\x04\x7d\xe2\xcb\x17\xc3\x74\x77\x5d\xb1\x91\xee\x6d\xb7\x7d\xa8\xda\xfd\x85\xcd\x18\xdf\xb0\x36\xab\x1b\x5b\xbd\x68\x37\x68\xae\x3d\xd6\x0f\x05\x71\xc6\x60\x19\x1b\x41\xb9\xd9\xb8\xa1\x5e\xca\x54\x93\xf2\x52\xeb\x72\xc7\x87\x7e\x9a\x68\x34\x92\x12\xad\x95\xe0\x9c\x48\xcf\x66\xc1\x3d\x5e\x9f\x1f\xe5\x50\x28\xf3\xf0\x40\x38\xf9\x46\xd7\xd7\xc9\xa9\xae\x3e\xce\x7d\x7e\x76\x51\x3e\x53\xaf\x86\x15\x21\x2e\x85\xab\xeb\x98\xb9\x32\xf2\x26\x26\x8c\x05\x79\xb0\x03\x07\xf3\x92\x5f\x69\xb1\x91\x72\x6a\xea\x0d\x57\xf0\x29\x9f\x06\x75\xa3\xc9\xb1\x27\xe4\x90\xd4\x0d\x64\x05\xeb\x92\xac\x85\xad\x0a\x45\xf0\x76\x58\x49\xce\x88\x04\x36\xd5\x03\xe8\xd3\x86\x40\x4f\x78\x15\x8f\x8d\x25\xb6\x63\x97\xee\x1a\x8d\xf0\xcc\x1b\x92\xdc\x0c\xf4\xd6\x14\x6e\xe3\x2c\xd6\x5c\xc8\x8c\xe7\x8a\x76\xf0\x11\xac\xbe\x2e\xff\xc3\x28\xb7\xf2\x08\x86\x88\xfc\x73\x69\x86\x63\x38\xb2\xad\x42\xba\xed\x3c\x94\x1c\x98\x90\xf9\xbe\xda\x3e\x25\x70\xb3\x4d\x8b\x14\x0e\x54\x84\xab\x75\x44\x50\x28\xdb\xaa\x6d\x6c\xa6\x2a\x9d\xa0\x5e\x20\xb8\x52\x90\xb3\x78\xc3\x54\x6f\x5d\xcd\xa0\x9f\x50\x41\x69\xb7\xa2\xbb\x51\xe2\x69\xa5\xc9\x19\xd4\xaa\xbd\x2e\x4e\x89\xc2\xc6\x20\x8d\x70\x08\x1a\xaa\x52\xf6\x6c\x82\xf0\x6c\x6a\x07\x98\x80\xdf\x65\xb6\x43\x18\xe4\xe0\xc0\xdf\xc1\x7f\x39\xc7\x73\xdc\x89\x52\x96\x08\xd4\x29\x99\x51\x21\x6a\x69\x0a\xc2\x60\x26\xa4\xbe\x96\x14\x42\x29\x65\x5b\xaf\xfc\x45\xc7\x54\x6a\xdd\x7a\xab\xff\xe8\x4d\x06\x06\x47\x26\x77\x08\x6c\x74\xe4\x1a\x9f\xa3\x0b\x30\xf1\xe7\xb2\x71\x3a\x39\xbd\x7a\x88\x9a\x47\xc1\x58\x29\xf5\x17\xd6\x71\x45\x70\x24\xc5\xd3\xd4\x3b\xc0\xb9\xce\xa9\xe3\x2c\x5c\x75\xfa\xe1\xe4\x8d\xe7\x8f\x2b\x2b\xc8\x83\x07\x9a\xfe\x8f\x8d\xff\xc6\xdb\xc4\x3b\xac\xe9\x77\x15\xc6\xa6\x9e\xfe\xdf\x7f\x7c\xf3\x7f\xdf\xfe\xf0\xef\x93\x20\xf2\xe9\x93\xbe\xbf\xaf\x84\xd9\x9a\xfe\x4a\x9e\xa5\x59\x69\x58\x23\xad\x3b\x28\xce\x54\x23\xff\x4c\x5b\xc9\x69\xa5\x8c\x63\x93\xbc\xf9\x50\x90\x0f\xb0\x6b\xd9\x13\x97\xde\x9e\x07\xf5\xa7\x4a\x17\x6a\x3f\xf0\x9b\x6f\x1c\x22\x17\x37\xbc\x84\x7a\xec\x3f\x58\xf2\xff\xe0\x84\xd0\x60\x80\xbd\x14\x66\xa9\x69\xd3\x54\xca\xe8\x52\x48\x78\x80\x73\x48\x4d\x84\x16\xfd\x06\xb2\xfd\x59\x3e\x6c\xd6\x87\x99\x8a\xd0\xaa\x4f\xe5\x2d\xfc\xd2\x25\x04\xd1\x65\xae\x1e\xdc\xe4\x71\xe3\x2c\xee\xcf\xb2\xd5\x2e\x8d\xef\xee\xa0\x9b\x54\xf4\x12\xe4\x78\x2b\x49\x3f\xe7\x8d\x97\xc0\x8c\x92\xc8\xbc\xae\x57\x0d\x6d\xd1\x78\xdf\x8b\x8e\x1e\x1e\x3d\x5f\x7d\xac\x34\x1c\x23\x99\xb8\x37\x41\xd1\xa9\x3f\x58\xcf\x4b\x8c\x0b\xd2\xe5\xf4\xdd\x7a\x05\xa5\x0f\x7e\x35\x3a\xda\x21\x53\x7c\xce\x73\xac\x68\x09\x26\x61\x32\x55\x3e\x5a\xb8\x5b\x06\x55\xa4\x40\xac\x04\x41\x90\xeb\x33\x6e\xd3\x14\xf8\x20\x37\x69\xd5\xdf\x69\xc9\x41\xf0\xc9\xe2\x20\xa7\x66\x38\x94\x0a\xff\x00\x76\xca\x7e\x49\x5a\x7f\x81\xe9\x17\x6b\x8b\xb7\x9e\x9d\x02\xb5\x88\x75\x89\xe9\x3d\xbd\x8b\x34\xde\x11\x6c\xb0\x5b\x1a\x53\x9f\xe5\xec\x2d\xb4\x60\xf2\xf1\x68\x05\x25\x5b\xe4\x8c\x40\x23\x6b\x7f\x95\xe0\x37\x38\xae\x1f\xc3\x9d\x1a\x08\xc3\xd8\x25\x8d\xb1\x4b\x4a\xb9\x27\x61\xbc\xd2\xa6\x6e\x70\x47\x01\xe6\x5d\x5f\x15\xe4\xf8\x10\xaa\xdf\xe4\x94\x0b\xdc\x5b\xb8\x70\x87\x48\xb8\xc0\xb3\x23\x8a\x95\x3e\x80\x88\x7b\xf5\x6e\xd8\x05\x88\x14\xf7\xa1\x2d\xc6\xbe\xa2\x8b\x08\xec\xa0\x7a\x48\x38\x9a\x96\x3b\xf8\x2d\xc6\xfc\x2d\xfc\xda\x66\x75\x15\x1c\x3b\x42\xbd\x96\xd0\x56\x2f\x31\xf4\x09\x6b\x6b\x0b\xd5\xfb\x4d\xf7\xab\xae\xe6\x04\x63\x67\xa5\xcb\xf1\xc8\x4a\x8e\xed\x19\x8c\x3d\xc6\x5c\xef\xaa\xa0\xe8\xa2\xa0\xbd\x16\x1e\xee\x0f\x7f\xa0\x56\xd6\x9b\x86\x4b\x98\xbf\xba\x72\xec\x1f\x59\x7a\x3b\xb5\xf4\xe5\xf1\xe9\x95\xd6\xd4\x2b\xa8\x0c\x26\x67\x5a\x57\xaf\xa4\xbd\x6b\xa9\xaf\xa5\x45\x98\x4f\x56\x3b\xe1\x0a\x89\x40\xce\x08\x77\xe5\x52\x4e\x13\xd8\xed\xd9\x6c\x73\xd1\xbd\x4c\x09\x8f\xce\x9e\x3b\x89\x5f\x78\x31\xbe\xc1\xfd\xc9\x44\xa2\x7a\x16\x1d\x06\x84\x9c\x41\x37\x98\x8b\x02\x00\x51\x36\x0a\xcb\xb1\x2b\x9d\x9d\x0c\x52\xb9\x60\x49\xbd\x83\x40\xb1\xb2\x5f\xcd\xf3\xa0\x4a\x1e\xfb\x79\xbb\x37\x6a\x55\xbd\x2f\x04\xd3\x84\x17\x5e\x9d\x4c\xe1\x8a\x7e\xa2\xc8\x9f\x6f\x28\x5a\x6c\x6e\xf8\xe2\x06\x22\xd0\x2e\x7c\x5b\x7f\xc4\x48\xac\xbe\xc9\xa5\x5e\x35\x15\xbb\x53\x80\xf5\xc7\xe3\x93\x2f\x9f\x0a\xbd\x65\x58\xd0\xef\x9e\xf0\x15\x1c\x3b\xb7\xe0\xdd\x3d\x02\x86\x64\x67\x67\x03\x44\x89\x43\xec\x03\x18\xb8\x56\xd8\xc6\xc6\x69\xf5\xf9\xfa\x5e\xf6\x2f\x89\xb9\x17\x1f\x37\x5d\xe2\x10\xf9\x26\x19\x1f\x8f\x5a\xdb\x10\xf9\x26\x19\x1f\x8f\x5a\x7b\x21\xf2\xcd\x40\x7c\xdc\x4c\xda\x24\x1e\xed\xd6\xba\x83\xc5\xfd\x10\x68\x14\xb7\x49\x4b\x43\x5f\x1a\x31\xab\xfb\xf7\x3a\x9b\xd5\x42\xb2\x3b\x69\xcd\x69\x65\xf4\x1b\x8f\x40\xd2\x76\xc1\xfa\x3e\xc0\x6e\x43\x7b\xa7\xcb\xa4\x47\x73\xee\x92\x16\x01\x63\x11\xcd\x21\x99\x53\x6d\xbd\x18\x28\x44\x68\x71\x4d\x15\x5f\x1d\x1d\x91\xf3\x0d\x6b\x3f\xb6\x5c\xe2\x79\x29\xd2\xd5\x44\xde\x50\x49\xe4\x0d\xdb\x92\x15\x95\xb3\x9b\x29\xb6\xbb\x50\x9b\xeb\x8a\xad\xea\x76\x4b\x2a\xba\x85\x8d\xa1\xab\x89\xa8\xc9\x0d\x6d\x57\x64\x5e\x0b\xa6\x5a\xe2\x76\xab\x27\x92\xa9\xff\xbf\x9d\xcf\xdb\x07\xab\x33\x5c\x60\x19\x0c\x52\xec\xf1\xa0\x37\xe8\x79\x67\x8f\x8f\xc5\x87\x6c\x34\xe2\x58\xaf\x06\xaa\x12\xa6\xc8\x95\xd0\x81\x0e\x8e\xa7\xa6\xcc\x21\xa4\xb8\x77\x6e\x67\x64\x1e\xf9\xd5\x8a\x73\x38\xf8\x09\x5c\x72\x74\x44\xfe\x02\xd7\x16\xfe\xf5\xe2\x94\x5c\x2c\x79\xa3\xe8\x40\x36\x49\xb3\x0a\xfc\xeb\x37\xdd\x3b\x5e\x65\x39\x81\xe0\x21\x95\x80\x0a\xc2\x71\xff\xd0\x63\x6e\x3a\xd9\x32\xba\x9a\x5a\x67\x91\x5c\xb3\xaa\xfe\x48\xe6\x35\xeb\x88\x72\xb7\xc1\x38\x2a\xa0\x1e\x9c\x4b\x22\x18\x9b\x77\x31\x24\x59\x93\x76\x2d\x0a\xb2\xe0\x1b\x26\x08\x97\x1d\x99\xad\x3b\x59\xaf\x1c\x19\xe0\x8e\x44\xb5\x0e\x77\xb0\x0c\x51\x10\xc2\x5c\xfa\x80\xe4\x51\xd4\x7e\xb7\x5e\x69\x23\x2f\x77\x4e\x9d\x2e\x88\xb4\xe7\xa0\x32\xa4\x5a\x4e\xce\xc8\xdd\x78\xe4\x47\xb4\x46\xd6\xf3\x05\xea\xdf\x19\x2e\xcf\x43\xa9\xf3\x96\x10\xdf\x17\xfd\x7a\x43\x8b\x66\xae\x2f\x9b\x38\x3a\x22\x3f\x52\x5e\xb1\xf9\x74\xac\x0d\x47\x23\x5d\x87\x64\x72\x6a\xc2\x12\xa5\x2b\x4a\x47\xcd\x6f\xec\x05\x88\x4f\x71\x24\x2d\xb5\x02\xa0\x48\x68\x3b\xc0\x69\x50\x5b\xc2\xae\x4f\x28\xcf\x68\x55\xfd\x6f\x56\x35\xac\x25\xfd\xed\x49\xbd\xc4\x5b\xbd\x34\x49\xf3\x29\x1a\x21\xd3\xe9\x34\x38\x39\xe6\xd9\x1d\x3d\x6d\xa1\x80\xf8\x3e\x37\x17\xae\x6e\x52\x7f\x30\xe1\xda\x0c\xc2\x68\x78\xd7\x07\x1e\x90\x2b\x05\x21\x91\x0e\x31\xa6\x8c\x9f\x12\xcd\xf7\xe9\x93\x0f\x05\x91\xe0\x72\x7f\xa2\xc7\x6d\xdc\x68\xdf\xe3\x1e\x74\xb9\xf7\xfa\xdc\xe0\xfd\x38\xb6\xb2\x91\x43\x9c\x70\x2f\x0a\x97\x8a\xc6\xf8\x9e\xbd\xab\xfc\xb1\x61\x24\x05\xc6\xe9\x81\x64\x04\x4c\x19\x29\xae\xe6\x54\x35\x55\x0b\xa7\x04\xca\xc4\x29\xb8\x2b\x9f\xac\x1b\x38\x0f\xa2\xfa\x60\x2c\x7f\x3c\x12\xe8\x54\xe8\x12\x4f\x1d\x80\x70\x89\x21\xf4\x0d\x7d\x43\x3a\x1d\x5e\xb5\x20\xcd\x69\xd6\xe0\x58\x99\x41\x07\xc4\x0b\x8f\x97\xc2\x49\xb6\xaf\x89\xd8\x07\x0e\x8a\x67\x65\x5d\x93\x92\x7d\x24\x5c\x34\x6b\xe9\x2c\xd8\x14\xc8\x6f\x9e\x01\x72\x45\xc5\x76\x08\xa6\xb7\xb0\xe0\xa3\xf6\x49\x20\x3e\xfb\xec\x99\x33\x7a\xf2\x64\x62\x92\x1f\x1c\x3c\x6d\x7e\x4f\x9c\x9a\x75\xb7\xee\x7a\x87\xf5\x78\x49\xee\x82\x8d\x03\x23\x61\xfb\x42\xea\xeb\x8e\x8b\x05\xf9\x8d\xb5\xb5\x36\x0d\xcc\xa0\xd1\x98\x7e\x34\x42\xb8\x10\x84\x1a\x55\xab\x59\xa8\x95\x11\x97\xfc\x4a\xc7\x8b\x0a\x45\x7b\x91\xf1\xfc\x2b\xf2\xe2\x4e\x4e\x9d\x55\xf0\xf7\x1a\x34\xfc\xfe\x70\x3f\xe2\xa6\x1e\xdc\xc9\x50\xd1\xd2\xce\xa9\x55\x05\xcb\x3f\x6e\x37\xb2\xc7\x78\x5f\x18\x79\x38\x38\x48\xf1\xc1\xd1\x11\x69\x5a\xd6\xd0\x56\x1f\x9a\xd4\xd7\xd2\xae\x28\x17\x6a\x5c\xd0\xf8\x9d\xc9\x64\x98\x55\xfc\x8c\x08\xbf\xae\xc3\x3b\x60\xae\x26\x2b\x72\x28\xb1\x5b\x29\x34\xcc\x29\x2a\xfd\xc2\x16\xc3\xf5\xc8\xb9\xf2\x22\x3a\x77\x9a\x8a\xe2\x10\xf2\x26\x48\x5f\xf5\xec\x4e\x53\x35\x41\x4c\x28\x3c\xd5\x56\x78\xbf\xa4\x1d\x62\xeb\xeb\x8e\xed\xa5\x63\x70\x78\x0a\xb7\x33\xa1\x57\xc3\x15\x33\x63\x0d\x89\xf5\x9c\x95\xa5\x7c\x67\xd8\xbf\x6e\xf9\x02\x8f\x9b\x72\x61\x02\x0b\x61\x4d\xba\x38\x3c\x36\xe5\x0d\x19\x17\x97\xa7\xe2\xaa\x20\xd8\x0b\xd4\xb9\xb8\x14\x70\x08\x4a\x8d\x81\x1a\x50\x60\xe0\x43\x13\x1f\x16\x55\x3d\x7a\xe1\x29\xbe\x7d\x0a\xf6\x63\x5b\x8b\x85\xe5\x6a\x3c\x5f\xac\xe3\x3d\x42\x87\x38\xa4\xad\xfe\x1e\x8f\xa1\xd8\x1d\x9d\xd8\xdd\x55\xe3\xd2\x2b\xae\xd7\xf5\xe2\x41\x8c\x45\x8b\xa5\x05\x17\xd4\x89\xaf\xc5\xc7\x96\x36\x7f\xed\x4c\x6c\x02\x05\x05\x20\x4c\xad\x75\x9f\x98\xce\xc4\x0a\x95\x17\x8d\x15\xbc\xca\x5d\xb2\xc1\x38\x15\xb6\xf2\xdd\x59\x18\x89\x73\xe1\xa5\xe2\x58\x1b\x5e\x40\x4c\x73\x67\xda\x0b\x7d\x62\xd7\x55\xe6\xfb\x65\xad\xae\x2e\x5f\x3f\xd5\x0b\x7d\xef\x55\x5a\x4d\x15\x5d\x5f\xe5\x05\x89\x26\x6c\x1e\x6b\x44\xe1\xf4\xd5\x63\x1c\xb0\xed\x9f\x6a\x50\x08\x25\x4e\x33\xa8\xb6\xf7\xba\xd8\x3e\x3e\xa9\x80\x63\xf1\x34\x0a\xdc\xa1\xe0\x2e\xc6\x0c\x8e\x31\xe8\xe2\x7d\x19\xc4\x8c\xad\x71\xf5\x9a\x36\x99\x2d\x3c\x59\xa2\x2f\x62\x2a\x3a\x6c\x9d\xd8\xfd\x40\x2c\x18\x2d\xc8\x9f\x98\xb0\x11\x60\x8c\x6c\x5b\x3f\xdc\xb6\xb3\xf6\x47\xec\x85\x7a\xf9\xff\xbd\xd9\xbb\xd7\xb4\xd1\x55\x3b\xda\xf6\xbc\xd5\xb4\xf8\x59\xb6\xd1\x5d\xa1\xb1\x21\xea\xb5\x54\x9e\x2f\x52\x21\x24\xa7\x3d\xa1\x13\x96\xcb\x25\x42\x46\xaa\x29\x94\xec\xb9\xd1\x83\xa8\x90\xc6\xc0\xbe\xb5\xe1\x80\xc0\x5f\xde\x78\xd7\x87\xc7\xe2\xf4\x47\xe1\x62\xfd\xfe\x5a\x97\x0d\x0f\x21\xe0\x18\x42\xd7\xa9\x59\xb3\xda\x2f\x16\x34\xac\xe1\x97\x0a\x06\x97\x8e\xea\xb8\x56\x6c\xe4\x6e\x4c\x8d\xe3\x60\xf0\xea\xde\x3b\x68\x62\x6f\x89\xc0\xac\x38\x06\x9f\xfd\xc5\x4d\x47\x74\xf2\xc1\x42\x49\x17\xfd\xd0\x57\x42\x78\x0e\x75\x3e\xee\x55\xf8\x39\x2f\x75\x18\xab\xd4\x44\x4d\xce\x40\x9f\x4b\xdf\x51\xf7\x11\x38\xfd\x3a\xdb\xdc\x3f\x52\xf6\xed\x7c\xde\x86\xfe\xbe\x94\x53\xef\xd4\x72\xcf\xe7\xd7\xaf\x7b\x81\xd3\x90\xb7\x4c\x23\x28\x7b\xef\x05\x54\x9f\x56\x43\x87\xf2\xa8\x58\xc5\x95\xd1\xf5\x59\x49\xe7\x75\xfa\xf7\xd4\x18\x3e\x82\x4a\x30\x17\x56\xdd\x3b\x20\x00\x9c\x14\xb6\xbf\xce\xe0\x1b\xc2\xbb\xd3\xb6\xc3\xb4\x1f\xa8\x19\x91\x72\x6a\x0e\xe1\x27\x33\x2f\x30\xf2\x60\xe2\xc5\x8f\xe9\xf7\xa2\x87\xe6\x96\xa6\xbd\xe1\x7a\x18\x42\x57\xeb\x94\xe6\xd8\xb1\x3d\x41\x0a\x4f\xc0\xc7\x1b\x27\x82\x46\x17\x92\xcf\x96\xdb\x5f\xce\x5d\xe0\xe8\xc1\xb0\x50\x9e\xa8\x43\x44\xeb\x12\x41\x42\xf6\xa7\x57\xc5\xa2\x5c\x40\x78\x4d\x45\x6d\x8c\x14\x8f\x15\xe1\x44\xfe\x2f\xe7\x51\x74\xc3\xbd\x37\xf8\xb8\xbb\x30\x21\xbe\x04\xe6\x85\x3f\x3d\x1c\x1d\x6e\xc7\xfb\x0a\xde\xbf\x80\x4b\x03\x0e\x0e\x08\x77\xbe\x37\x2f\x15\x5d\xb1\xf3\x82\xc9\xbf\xaa\xcf\x99\xa4\x8b\xfc\x2b\xfd\xfc\x85\xbe\x69\x40\x9f\x7c\xd3\x35\xb6\xe0\x14\x23\x0f\xbe\xca\x6d\x50\x78\x3a\xa0\x31\x47\xa3\x51\x1d\x8a\x74\xac\x39\x47\xb1\x32\x00\xe5\x92\xae\xa3\xf0\x4a\x88\x41\xf9\x63\xef\x44\xf5\xc2\xce\x9b\x85\xa2\xfc\x90\xbb\xa8\x8c\x4d\x0a\x52\x03\x7e\x40\x80\xe0\xfc\x72\x9e\x93\x47\x73\x85\xea\xd0\x80\x77\xc1\xa6\x72\x4f\x6a\x30\x84\x01\x56\xe2\xfc\x02\xbb\xf3\xc7\xbd\x0b\x07\xf3\x46\xeb\xa9\x13\x17\x27\x4f\x24\x5a\x3c\xc2\xe3\x52\x59\xff\xc2\xbb\xde\x55\x33\x4f\xb7\x2b\x5b\x82\xf1\x8a\x2a\xce\xb3\x28\x9f\x29\x38\x36\x6b\x4b\x50\xa3\x6b\xb2\x7a\x79\x9d\x4f\x5a\xdd\x67\x2d\x6d\xbc\xdb\x17\xa4\xf3\x6e\x56\x33\x14\x7d\xe2\xe2\x75\xde\x15\x6d\x7d\x43\xa2\x20\x77\x16\x62\x7f\x81\x52\x17\x31\x41\xa7\xdd\x18\xaa\xde\x2e\xb0\xef\xcb\xa4\x3d\x7d\xe7\xea\x6a\x94\x48\xca\x40\x4a\x8f\x8e\x48\xb7\xe4\x0d\xa9\x18\x9d\xab\x46\x5d\x43\x95\xc3\x84\x77\x0c\xbe\xb2\xd6\xf1\xd7\x58\x0f\x49\x17\x10\x86\x90\x74\x01\x96\xf1\x19\xf9\x37\xf2\x6f\x3a\x9a\x7a\x78\x68\xac\x04\xba\x20\x67\xd8\xe4\xf4\xca\x44\xb3\x17\xf6\x0a\x92\xa0\x22\x5e\x23\x30\xa3\x82\xc8\x9a\xcc\xea\x0a\x23\xc0\x47\x47\x84\x22\x26\xa4\x6e\x09\x25\xff\x58\xd7\x92\x11\xde\xa9\xa7\x5b\x21\xe9\x1d\xd6\xe8\x00\x9a\x7b\xb1\x7c\x81\x58\x86\x0f\x4e\xe3\x07\x93\xde\x3c\x78\x49\xf8\xe1\xb1\x2d\x05\x55\x40\x1f\x1e\x22\x18\xe6\xc1\xe1\x71\x08\xc5\xaf\xf9\x37\x79\x7f\x5c\x05\x05\xe8\xf2\x94\x5f\xe5\x21\xa5\x0e\x8f\x4f\xaf\x7c\x6a\xc0\x8c\xe7\x66\xe5\x64\x4d\x4a\x2e\xe6\x18\x46\xd0\xb3\x3e\xde\x3f\x6b\x3b\xa7\xd2\x5f\xb1\xff\xf8\x0f\xfd\x58\xcf\x55\xff\x06\x43\x30\xef\x60\xd6\xbd\x19\xfd\x03\x03\xd8\xf1\x9c\x0e\x8f\x87\x66\xe5\x5f\x43\x73\xdb\x69\x2e\xd8\xa0\x17\xf6\x41\xc3\x81\xab\x6e\xde\x0b\x98\x78\x86\x23\xe4\x9e\xcd\x67\xa6\x1e\x08\xca\x64\x92\x30\x75\xf4\xde\x1e\x99\x3a\xfb\x6c\x67\xeb\x4f\x19\x0b\xc6\x5e\x2b\xf6\xf4\xa2\x61\x08\x3c\x4b\x39\xad\x98\x18\x08\x48\x01\xd0\x01\xdb\xc5\x37\xb1\xb5\x65\x98\x4c\x4a\xf5\x4d\x8a\x44\x95\x94\x6f\x60\x8c\x47\x23\xba\x5b\x69\xff\x61\x5a\xfb\xf7\x6d\xca\xbf\x53\x6f\x53\xe7\x75\xdb\x8d\xf0\x89\x7a\x9b\xee\x8c\xa8\x84\x9a\x3b\xb5\xb7\x3e\x0e\x3a\x3c\x3b\xd1\x44\xdd\xdd\x3b\xe8\x95\xf2\xdb\xc2\xf2\xa4\x2e\x4a\x39\xa3\xeb\x9e\xe6\x39\x8c\x2f\xee\xe2\x39\x63\xb3\x9b\xab\xb6\x76\x70\xfc\x00\x7f\x1a\x6e\x8c\x5c\xa7\xfd\x8c\xc9\xc9\xa1\x9b\x8d\x49\xb7\x9b\x40\x04\xb2\x6d\x17\x66\xee\xff\x87\x5b\xff\x35\xb8\xd5\x1e\x05\xeb\xf0\x0e\x9d\x97\xe0\xf4\x29\x7b\x23\x50\x2b\xfd\xb2\xba\x4e\xb6\x43\x9c\x8a\xbb\xdd\x0e\x56\xf5\xb5\x61\xc0\x56\x70\x08\x29\xb8\xb8\x75\x3c\x1a\xcd\xf4\xd6\x82\xe7\x06\x82\xc5\xb6\x17\x77\xf6\x96\xfc\x60\xf6\x49\x0e\x38\x50\x69\x97\x07\x6e\x83\x33\xdf\x53\x49\xb3\x9c\x5c\x9e\x5c\x79\xf7\x58\x20\x7c\xfc\xad\x42\x60\xb1\x49\xd0\xde\x64\x83\xbb\x75\x63\xae\xfe\xde\xda\x74\xbf\x7f\x85\x86\x37\x9e\x0e\x9c\x44\xb5\xa7\x83\x1b\x20\x94\xc4\x0e\x47\x0b\x77\x1d\x8c\x1d\x87\xbf\x0d\x35\xd0\x37\x4a\x47\xdf\x50\xf1\xce\xeb\x6c\x7e\x61\xe9\x49\x9d\xe5\x4d\x5b\x7f\x7c\xc7\x2b\xbd\x66\xb0\x20\x16\x52\x58\x3f\xdb\x03\x14\x0b\x98\xae\x2a\xe8\x07\xd0\x9e\x84\x89\x8b\x9b\x3d\x93\x5d\xd4\xea\xec\x62\x17\x88\xe4\x9a\x60\xf0\x93\x8c\x17\xff\x78\x66\x3f\xd8\x6b\x4f\x4c\x47\x9b\xcd\x50\x58\x38\xdc\x59\xf6\xad\xb0\xee\x74\xbd\x2e\x4b\x66\x2b\xba\x92\x20\xc2\xd5\x19\x3a\xf5\xed\x1f\x78\x70\x98\x3f\x87\xc0\x3f\x31\xb1\x8b\xbc\x46\xda\x83\xcb\x64\xf6\x91\x19\x23\xea\x50\x36\x0e\xd2\x82\x8a\x55\x83\xda\x19\xb1\x7c\x15\x6a\xdd\x44\x11\x40\x24\x06\x4f\x85\x74\x1c\xaf\xe7\x27\xa0\x10\x6c\xaf\x1e\x42\xcf\x21\xb7\x3b\xbf\x3d\x48\x72\xc8\xef\x99\x2f\xf7\xe3\xd1\x26\x79\xcc\xf5\xae\x7f\x00\x74\x74\x47\xce\xc8\x5d\x22\x97\x85\xe5\xb9\xa0\x8e\x30\x73\xb5\xa7\xd4\x73\xa8\xcc\x32\xfa\x75\xbd\x50\xcd\x21\x63\xce\xf0\x5c\xe9\x90\x09\x9d\x7a\x73\x07\x6f\x06\x7e\x11\x6c\x5f\xb9\xe9\xd0\xe9\x99\xa8\x2c\xea\xce\xfe\xa8\x61\xea\x57\x96\xbc\xa3\xdf\xcf\x47\xdc\x14\xa4\x45\xd7\x60\x3d\x0d\xf1\xbb\xe0\xee\x2a\xc7\x76\xe0\xbc\x41\x07\x58\xd2\xc6\xbb\xd6\x3f\x60\x94\xef\xb6\x92\x75\xd9\x1d\xb9\xbc\xb2\x17\x50\xa4\xd9\xc5\x3c\xc5\xc3\xb2\xb9\x57\x46\x1c\x9e\x53\x7e\xa1\xcf\x29\x0f\x67\x78\xcd\xa8\xa6\x74\x05\xae\x20\xf1\x2e\x40\xf6\xef\x5f\xe8\x51\xcc\x1f\x58\x1f\x66\xc2\x10\x8b\x2d\x5e\xd6\xe8\x04\x2f\xcd\x41\xe6\xf9\x45\x74\xb5\x83\x57\x65\x84\x49\xf2\x5e\xed\xaa\xeb\xd6\xbb\xe0\xc1\xeb\xe0\xd7\xaf\xf6\x7a\xb8\x4b\x1e\xbc\x1e\x7e\x0d\x6b\xaf\x87\x7f\xd1\x83\xd7\x27\xac\x63\x45\x32\x9d\x11\xd7\x5b\xdf\xf3\xfc\x14\xbe\xe9\x70\x15\x93\x3c\xf1\x9a\x36\x99\x40\xaf\xfe\xe9\xec\xb0\x33\x5a\x19\xd5\x76\xf3\x92\x08\xf2\xf5\x90\x6f\xf5\xf0\x40\x04\xf9\xc6\xbe\x8d\xd3\xa6\xc9\x54\x05\xd2\xc2\x34\x0d\x4c\x5a\xc2\x85\x9e\x94\x29\x20\x60\x1f\x77\xb1\x41\x8f\x05\x4c\xfb\xde\xfa\xf7\xd7\x3e\x6a\xea\x16\xbe\xbf\xe8\x51\x53\x6f\xc5\x45\xf2\xda\xa0\xd4\x22\x1a\x18\x03\xeb\xa8\x2c\x9b\xff\x8a\x75\x7c\xf5\x3b\x96\x0c\x29\x92\x5a\xb0\x9f\xec\x8f\x2b\xfc\x37\x2c\x98\xd8\xb9\x42\xfd\x79\xfe\x31\x4b\x06\x25\x49\xbc\x20\xb7\x51\x48\xcd\x54\x79\xea\xbb\xe7\x74\x74\x40\xff\x1a\x42\x17\x5d\x0e\xe5\xd5\x30\x70\x31\x8f\x2c\x2c\xf5\xa4\x17\x88\x0b\xb7\x72\x88\x2e\xb8\x32\xdf\xb4\x0a\xc7\x9f\xa3\xe8\x4c\x05\xe2\x5a\xd0\xf9\xbc\x65\x5d\x07\xe5\xb3\x2e\x7e\xf0\xf8\xcc\x30\xdf\x0c\x7e\xa1\xca\x0b\xee\xe9\xa9\x9e\xb9\x9b\xcd\x31\x1e\x02\xfa\x2f\x71\xc1\x8b\x67\xce\xf6\xa2\x3d\x08\xc8\x94\x8c\x76\x71\x5d\x2a\x8e\x3d\xc4\xc2\x9f\xec\x8d\xdf\x92\xaf\x09\xc7\x0f\xdf\xec\xf4\xca\x23\xd2\xa2\x87\x9e\x08\x29\x5d\xd7\x6b\x31\x77\xe5\x8b\xbe\xb3\x7d\x5e\x66\xe0\x84\x9f\xde\x5e\xe5\xcf\xf4\xaa\xcd\x5d\x13\x8a\x43\x1e\xbd\x83\xd5\xc9\x69\x0c\xfc\x50\x49\x82\x37\x06\x30\x7f\xc6\x4f\x97\x74\xeb\xeb\x4e\xe3\xd6\x15\x44\x09\x47\x5c\xcb\x30\x20\x48\x9f\x83\x24\x15\x64\xf9\x3f\xc2\xf4\x2f\x28\x4c\xcf\xe6\xcd\xcf\x9f\xc2\x9c\x4b\xf2\x35\xb9\xc5\x0f\x4f\xe1\xd2\xcf\xff\x99\x6c\x5a\x90\xe5\x7e\x4e\x7d\x5d\xd5\x9d\x3e\xf2\x6b\x77\x62\xe5\xfc\x7a\x3b\xb3\xef\x9f\xf5\xaf\x89\x51\xfd\x43\x37\xde\xd4\x89\x75\x4c\x4d\x77\xf0\x94\x02\xbe\xfe\xc4\x73\x0a\xb3\x1b\x2a\x5a\x36\xdb\xf4\xef\x6e\x2d\x88\xb8\x86\x48\x58\xfa\xb6\xca\x0c\x87\x65\xf3\x82\xb4\x78\x96\xc0\xfc\xb6\x9e\x12\xa4\x7a\x85\xb7\x9f\x5c\x5e\xf9\x87\x32\xef\xef\x13\x3f\x75\x76\x93\x3f\x62\xb9\xb0\xb8\x46\xcf\x12\xfa\xda\x13\xab\xf0\xb5\x08\xce\x76\xde\xeb\xc2\x19\xc4\xe0\x17\x06\x23\xf9\x44\xc2\x4e\xb9\x81\x7a\x70\x40\x6c\x53\x1d\x9a\x7d\x65\xec\x99\xb3\x33\x72\xec\x27\xcf\xc1\x35\x2c\xdc\x31\xf5\x91\x22\x4e\x30\x84\x03\x72\x9c\xb6\x15\xbc\xfb\x38\xd1\x52\xd0\x20\xec\xd0\x79\x70\xf0\x3b\x7e\x7f\xdc\xff\xc1\xb5\x1b\x2a\x3a\xa0\x45\x7f\x8d\xfa\x4b\x63\xd7\xcd\xc5\x31\x9f\xb7\x1c\x03\x3e\x74\x68\x32\xfe\xcb\xad\xd9\xe0\x79\xfa\x16\xe1\x64\xfa\x6f\x47\x2e\xaf\xda\xb5\x90\x7c\xc5\x2e\xe0\x01\xdc\x5b\x5c\x77\x4c\xe0\x2f\x2a\xc1\x8f\xe9\xff\x2d\xc1\xca\xba\x10\xb6\xff\xf3\x27\x06\xb0\x57\x89\xdc\x79\xa5\xb1\x66\x58\x2f\x9a\x82\x03\x7f\xcf\xdb\xac\x9b\xc2\x21\x39\x1b\x51\xd1\x6f\xbc\xe0\x01\x8c\x8f\x35\xb5\x21\x3d\xc3\x2e\xbf\xb0\xd9\x06\xdb\xdf\x24\x0a\xa7\xfd\xd0\xb1\x2e\x48\xea\xdd\x31\x32\x9d\xdd\x98\x1b\x84\xa3\x57\xaf\x4c\x75\xfb\xec\x26\x79\x81\x1d\x74\xb5\x59\xf1\x21\x84\x67\x37\x11\xca\x17\x4c\xcc\x9f\x8a\x72\xea\x1e\xc8\x7f\xe2\x44\x06\xef\xea\xeb\xa6\x89\xeb\x76\xf7\x4e\x1c\xc4\xd4\xdd\xfa\xb0\x5f\x06\x66\x29\x75\xf3\xca\x46\x85\x79\xe9\xb1\x90\x61\xb0\xcb\xd9\x15\x32\x13\xfc\xa0\x96\xe1\x09\x2d\x27\x3b\x75\x58\xea\xf7\x96\x3d\xa0\x4f\x52\x68\xf6\x77\x27\x87\xd5\x99\x27\xa0\x33\xa3\x61\x8d\x90\x7e\xcf\x58\xf3\xc3\x3f\xd6\xb4\xca\xe8\x71\x41\xe8\x49\xf8\xc3\x6c\x46\x8f\xf1\xe3\xb4\x4b\x4b\xd5\x2c\xf8\xc9\xc0\xcb\x13\x7d\x38\xeb\x58\x51\x86\x9f\xf8\x9a\x03\x6f\x29\x79\xf4\xde\x0b\x5e\x41\xe6\xed\xc4\xff\x72\x3c\x70\x2c\x9d\x9f\xa4\x5e\xec\xd2\x4c\x73\xc6\x1a\x34\x8f\xd4\x64\xff\xda\x65\xc6\xda\xa7\xc7\x79\x61\x4d\x7f\x7a\xa2\x8f\x15\x58\xfa\xf4\xfa\x6d\x8e\x0b\xb2\x39\x31\xd7\x4c\x6d\x78\xc7\x25\x9b\x2b\xfd\x7e\x72\x15\xef\xd4\x96\x7a\x25\x79\xb1\x39\x86\x73\x38\x15\x9f\x63\x78\xe6\xc5\xe6\xc4\x7b\xe0\x61\x1e\xb6\x3c\x38\x08\x5b\xda\x2b\x02\x8e\xf5\xb1\x18\x45\x8d\xcd\x89\xf9\x92\xa4\x40\xd0\x7c\xb8\xe6\x3b\x4a\xcd\x7a\xad\x0a\xd5\xdf\x1a\x47\x0a\xc4\xce\xb6\x27\x7e\x3c\xd5\x3b\x2e\xbd\x39\x8e\xaf\x92\xd1\xa9\x20\xf7\x7b\x63\x45\x74\x15\xcc\x07\x7d\xc3\xb4\xd3\xea\x86\xe0\xa6\x56\x68\x73\x8c\x01\xda\x33\x6c\x78\xf9\xea\x0a\x0e\x0c\x9f\x84\x4f\x8f\xaf\x48\x70\x23\x0c\xb2\x9f\x3b\xb5\x6e\xa0\xda\x8d\x54\x3f\x28\x48\x6f\x59\xef\x71\xc4\x42\x8f\xf1\xf8\xc4\x39\x06\x39\x8f\x63\xff\x7a\x08\xf7\xcb\x0a\xf8\xca\xe4\x43\x70\x61\x83\xec\x48\xf2\x42\x1b\xdd\xcd\x4f\xfc\x79\x4b\xb0\x67\xde\xb4\x25\x42\x39\x1e\xc7\xe6\x34\x06\x06\xa4\x70\x6c\x4c\xeb\xf9\x79\x19\x33\xf0\x63\xe2\x34\x97\x88\xee\xe7\x49\x48\x8e\x4d\xcf\x03\xf5\xbc\x2f\x48\xed\x3d\xd7\xf6\x84\x93\xe8\xe7\x29\x42\xf2\x3d\x3c\xf4\xc8\x67\xb2\x49\xae\x11\xb2\x8a\xfe\x16\x8e\x92\x42\xdf\xdc\xd0\xb9\x39\x71\x1f\x35\xea\xe1\x69\x80\xdf\x05\xc3\xbf\x33\xd7\x2e\x8f\xbb\x06\xe9\x13\x49\x6f\x2e\x4b\x82\x91\xbd\x2f\x9f\x4a\x7a\x9d\x1b\xdd\xcb\xb3\x09\xce\x79\x02\xc3\x86\xfc\x6a\x58\x15\x2e\x6d\x07\x72\xbc\xa5\xcd\xdf\xd8\xd6\x5e\xe7\xa8\xac\x41\xf5\x32\x7f\x32\xe7\x9a\xcb\xe6\x51\xab\x00\x60\x53\xe8\x07\x7b\x1d\x8e\x81\x2c\xba\xd4\x96\x50\x05\x1b\xdd\xe6\x24\x7e\x03\xfa\x9d\x56\x3d\x0d\x4f\xab\x93\xe8\x51\x7f\x61\x68\x75\x0c\x46\xca\xc9\xef\x58\x8a\xb8\x1c\x61\x90\xbf\xf1\x86\x96\x38\x11\xec\xba\x0d\x2c\x49\xe0\xc5\xa7\xab\xcb\x95\x0c\xbe\xe9\x60\x56\x4f\x49\x05\xaa\x4d\x54\xe7\x02\x9f\xd2\xfa\xc4\x65\x0e\x9d\x8b\xf6\xff\x03\x00\x00\xff\xff\xfc\x89\x3a\xb8\x56\x93\x00\x00"), }, "/src/reflect/reflect_test.go": &vfsgen۰CompressedFileInfo{ name: "reflect_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 4275, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x57\x5d\x6f\xdb\xb8\x12\x7d\xb6\x7e\xc5\x5c\xe1\xde\x56\xba\x2b\xc8\x96\xdd\xa6\x80\x8b\x3c\xa4\xf9\x28\xb2\x68\xed\x45\x1d\xec\x3e\x18\xd9\x05\x23\x8f\x2c\x36\x14\xa5\x25\x29\xa7\x5e\x43\xff\x7d\x41\xda\x96\x69\xcb\x6a\xdc\x8f\x00\xb1\xc9\x99\x33\x87\xe4\x9c\xd1\x88\xee\x76\xe1\x97\x87\x92\xb2\x19\x7c\x96\x8e\x53\x90\xf8\x91\xcc\x11\x04\x26\x0c\x63\xf5\x97\x42\xa9\x1c\x87\x66\x45\x2e\x14\x78\x4e\xc7\xcd\x88\x4a\x5d\xa7\xe3\x6e\x00\x7a\xa8\x31\x94\xcf\x5d\xc7\x77\x9c\xa4\xe4\x31\xdc\xa1\x54\x17\x8c\xce\x79\x86\x5c\x79\x0a\xfe\xbf\x41\x84\x77\x3e\xac\x9c\x8e\x0a\x27\x8f\xb4\xf0\x7c\xa7\xb2\xf0\x13\x46\x63\x1c\x2f\x50\x24\x2c\x7f\x3a\x31\xe6\xa6\xe4\xf1\x07\xb2\xcc\xcb\x53\x17\xb9\x10\x82\x2c\xc7\xc9\x15\x15\x18\xab\xdb\x84\xc4\x78\x62\xe0\xdd\xb2\x40\x46\xf9\xa3\x9c\xe4\x42\xe1\xec\xc4\xa8\xf7\x97\xef\xa8\x92\x27\x82\x2f\x53\xc2\x2f\x18\xcb\xe3\x13\xf1\x23\x92\xe1\xbb\xa5\x42\x79\x21\xd0\x24\xfb\xe4\x6d\x8d\x93\x44\xa2\xfa\x90\xc7\x8f\xa7\x6a\x83\x5a\xea\x31\xbf\xe5\x0b\xc2\xe8\x91\x65\x36\xc5\x10\xae\x81\xde\xf4\x7e\xdf\x70\x49\x24\xae\x9c\x4e\x47\xff\x77\xae\xa8\x18\x02\xec\x03\x3e\x61\xbc\x08\xb4\x53\x27\x61\x58\x3b\x7f\x27\xac\xc4\x55\xa5\x3d\x55\x00\xad\xd1\x13\xe4\xb3\xaf\x47\x77\x34\xe4\xc0\x33\x4e\xbc\xc8\x6f\x50\xef\x33\x5f\x61\x42\x4a\xa6\xd6\x28\xa7\x53\x1d\xa4\x45\x89\x32\x56\xe3\xe4\x86\x22\x9b\x69\x39\x5a\xd3\xe9\x6e\xa1\xee\x71\x86\xef\x0e\xbc\xfe\xa2\x1f\xcc\x4f\x25\xc3\xf6\x32\x7b\x8e\xe3\xfd\xe5\x77\x87\x5e\xb0\xf9\xf7\x2f\x8b\x1c\x05\x8d\x7f\x84\xe2\x94\xe7\xf8\x39\x8e\x3f\xa8\x4a\x6f\xb9\x42\xf1\x2d\x2c\x0b\x22\x60\x86\x58\x5c\xff\x5d\x12\xa6\xd9\x24\x9c\xc3\xf4\xfe\xca\x36\xad\x9c\x4e\xb7\x0b\x66\x4a\x15\x45\xe9\x74\x56\x9c\xb2\x00\xcc\x87\x12\x25\xea\x8a\x5a\x45\x01\x44\xd6\x94\x72\x35\xe8\xeb\xba\x84\xdd\xa8\x76\xf6\xc2\xd7\x01\x98\x8f\xda\x94\xb0\x9c\x68\x5c\x2f\x7c\xed\x07\xb0\x3f\xab\x41\x6e\x8a\x8c\xe5\x6e\x00\xf5\xa0\x76\x65\xe4\x11\xbd\xe9\x3d\xe5\x2a\x80\xa8\xe7\x07\xd0\x30\xd4\xd0\x17\xd3\x81\x36\xeb\x1d\xf7\x03\x18\x54\x01\x34\x2d\x35\xf8\x1d\x91\x34\xd6\x8e\x5e\xf8\xba\x0a\xe0\x60\x5a\xc3\x50\x88\x5c\x78\x9c\x32\x3f\x00\x7b\x6c\xed\xaf\x98\x52\xae\xee\xa5\x12\x94\xcf\x57\xd1\x10\xdc\x9c\xa3\x1b\x40\x7f\x08\xae\x7a\xca\xdd\x4a\x6f\x79\x0f\xb3\xf5\x04\xb0\x45\xdb\x2b\x26\x3c\x0a\x20\xe1\xfd\xda\x64\x54\xba\xe5\x68\xeb\xb4\x3e\x50\x42\x98\x3c\xae\x4a\xdf\xb7\xbd\x1b\x59\xce\x6c\x5b\x9b\x2e\x67\x7b\x91\xb6\x30\x4b\xd7\xf6\x7c\x5d\x97\x68\x8f\xe5\x39\x61\x5e\x55\x36\xba\x5d\x99\xb3\x16\x5c\x8d\xea\xaf\x27\xf6\x2e\x5b\xd4\x19\x7c\x9b\x3a\x27\x30\x9a\xb8\x2f\x3f\x8f\xf1\x47\x79\x8e\xa2\xdb\xd7\xda\xf1\x98\xc7\x3f\xb2\x2d\xd1\xa6\x27\x58\xd5\xb3\x2e\xd2\xc1\xbe\x6d\xd0\xb0\x4d\xef\x4d\x45\xac\x56\x51\x55\x05\x50\xcf\xfa\xd5\xc1\xce\x55\x1a\x8e\xc8\xc8\x33\x65\xb4\x1b\xdb\x15\x14\xdd\x9b\x1a\x3d\x7b\x65\xa1\x4d\x21\xb5\x38\x4e\x88\x95\xc8\x92\x95\xfd\xe8\x4d\x8f\xe3\x5a\xcc\xf6\x29\x4f\xe3\xd7\xd9\xdf\x20\x8f\x44\x0c\x21\xda\x28\x74\x88\x89\x86\xd0\x6f\x48\xfd\x1c\xd1\xc1\xea\xa6\x8b\x8c\x28\x83\x85\x04\xcc\x0a\xb5\x1c\x02\xcf\x15\xa8\x14\x41\x92\x0c\x43\x73\x0c\x2d\x8e\x39\x30\xe5\x6a\xd3\xe8\xec\x53\xda\xee\x83\xc4\xed\x02\xec\x71\xa3\x4b\x6e\x02\xad\x69\x63\x99\x76\x68\x23\x97\xfb\x14\x4d\x8b\x7d\xf4\x8f\x54\x66\x44\xc5\x29\xce\x40\x2d\x8b\x6d\x13\x8d\xc2\x5e\x6b\x1b\x3d\x7b\xe5\x45\xcd\x36\x5a\x77\xc4\xc3\xc4\xec\x9a\x5b\xa3\xdb\x35\x3a\xe1\xfa\x5d\xbe\xaa\xac\xfe\x77\xdc\xe3\x4a\xf7\x6b\xbd\x71\x94\xab\x03\xcb\x7e\x1e\xcb\x9f\xf1\x66\xda\x52\x9a\x34\xfe\x96\x4b\x49\x1f\x18\x02\xcb\xf3\x42\xea\xaa\x79\xa1\x47\x51\x00\xdb\xef\xad\x42\xdd\xee\xbe\xab\x7e\xa1\x41\xb7\x0b\x77\xe3\xab\xf1\x10\x6e\xe8\x97\x9a\x61\xb9\xc5\x2d\x8f\x70\xec\x9c\x6d\x2c\x95\xe3\xd8\x06\x50\x29\x95\x21\x4c\x10\x21\x55\xaa\x90\xc3\x6e\x77\x4e\x55\x5a\x3e\x84\x71\x9e\x75\xe7\x79\x91\xa2\xf8\x2c\x77\x03\x2a\x65\x89\xb2\xfb\xe6\x6c\x10\xee\x2e\x60\xb7\xda\xd8\xef\xf7\xde\x0c\x9a\xb7\xae\x0c\x86\xe7\x8d\xdb\xfa\x28\xe7\xeb\xeb\x2e\xce\x6e\xa8\x90\xca\xeb\xf9\x7e\xf8\x11\x55\x9a\xcf\xbc\x9e\xef\x38\x1d\x9a\xc0\x3c\x57\x3a\x34\x0b\xf5\x0f\x36\xcf\x0f\x47\x65\x36\x2e\x95\xe7\xbf\x35\x9e\xff\x9c\x43\xcf\xdc\xf5\x55\x78\xad\x6f\x1b\x89\xe7\xae\x01\x43\xe3\xfe\xdf\x22\x80\x27\xc2\x15\xf4\xdc\x40\x1b\x7c\xa7\x53\xad\x75\x39\x3c\xf9\x5d\x8a\x10\x13\xc6\xe0\x01\x59\xfe\x04\x09\xa1\x4c\xc2\x13\x55\xe9\x50\xc3\x4d\x48\x47\xdf\x11\xff\x6b\x40\xe7\xa0\x0f\xad\x68\xce\xbd\x84\x07\x20\xe2\x85\x08\x80\x88\xb9\xf4\x61\x05\x02\x55\x29\x38\x24\x3c\x24\x45\xc1\x96\x9e\xe5\x7d\x0b\xd5\xdb\x35\x17\x7c\xeb\xdf\x9f\xeb\x38\x9d\x05\x73\xd2\x21\x5c\x12\xae\x3b\x92\x40\x32\x83\x42\xe4\x05\x0a\xb5\x84\x97\x66\xcd\x97\x90\x27\x50\xf2\x19\x26\x94\xe3\x6c\x7d\xe2\x49\x9a\x97\x6c\xc6\x5f\x2a\x28\x08\xa7\x71\xa8\x8d\x59\x78\x49\x18\x33\x4f\xff\xfe\x2f\x57\xc2\xd8\x27\x73\x0c\x79\xad\x7b\x5f\xfb\x2d\x5a\x5b\xa1\x94\x28\x41\x94\x5c\xd1\x0c\xc3\x09\xaa\x1b\xca\x09\xa3\xff\xa0\x08\xe0\x29\xa5\x71\x0a\x54\x9a\xe6\x29\xcb\x62\xad\x36\x3c\x2c\xe1\xbd\xa9\xa5\x5f\x27\xe6\xfe\xfd\x6f\x00\x00\x00\xff\xff\x4c\x70\xda\xa9\xb3\x10\x00\x00"), }, "/src/reflect/swapper.go": &vfsgen۰CompressedFileInfo{ name: "swapper.go", - modTime: time.Date(2018, 4, 6, 3, 35, 29, 555802829, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 834, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x52\x4d\x8f\xd3\x30\x10\x3d\x7b\x7e\xc5\x23\x42\x28\xd6\x56\x69\xf7\x5a\xa9\xdc\x00\xad\x58\xd8\x43\x25\xee\x6e\x3a\x6e\x6c\x5a\xdb\xb2\x9d\x16\x68\xf3\xdf\x91\x93\xb2\x95\x40\x5a\x2d\x87\x48\x93\x79\x6f\x3e\xde\x1b\xcf\xe7\xb8\xdb\xf4\x66\xbf\x85\x4d\x44\x41\xb5\xdf\xd5\x8e\x11\x59\xef\xb9\xcd\x44\xe6\x10\x7c\xcc\xa8\x76\x26\x77\xfd\xa6\x69\xfd\x61\xbe\xf3\xa1\xe3\x68\xd3\x2d\xb0\xa9\x22\xd2\xbd\x6b\xb1\x3e\xa9\x10\x38\xd6\x69\x6f\x5a\x86\x71\x99\xa3\x56\x2d\x9f\x07\x89\x82\xd7\x66\x06\x5b\xd2\x12\x67\x12\x47\x2c\x57\xf8\xa6\xf6\x3d\x3f\xe9\xa9\x42\x92\x30\x1a\xc7\xe6\xb3\x71\xdb\x5a\xe2\xcd\x0a\xeb\xb1\xd1\x99\x84\x08\xca\x99\xb6\x7e\x37\xf2\x3f\xc4\xe8\xe3\xf9\x0b\xe7\xce\x6f\x97\xa8\xae\x53\xab\x19\x4a\xe1\xf2\xb9\xc1\x20\x49\x0c\x24\xe6\x73\x7c\x54\x29\x23\xa8\xdc\x41\xfb\x88\x71\x56\x82\xd7\x48\xe6\x17\x63\x01\xe5\xb6\xb8\x6f\xf0\xd5\xe7\xce\xb8\x1d\xb2\x47\x3a\xa9\xd0\x90\x38\x3e\xb2\x2b\x5b\xf6\xc6\xe5\xfa\xd8\x3c\xb2\xab\xa5\x24\x91\x4e\x26\xb7\x1d\x46\xf4\x4c\xa2\x55\x89\xb1\x58\x92\x10\x91\x73\x1f\xdd\x3f\x5a\x31\x2d\x5f\x5d\x6d\x5d\xe2\x8f\x3f\x5b\xfe\x01\xdf\xe7\xb2\x4a\x54\x6e\xc7\x95\xc4\x70\xed\x77\xff\x42\x3f\x12\xa2\x18\x65\x8a\x43\x0b\x5c\x2e\xb0\x53\x34\x02\xe2\xf5\xc3\x0a\x7d\xa0\xf1\x1b\x48\xa8\xa2\xd4\xa6\xe6\xa1\x9c\xcd\xa9\xfd\xd3\xc6\x72\x9b\xaf\x97\x69\x3e\x71\xae\xab\xb7\x2a\x46\xf5\xb3\x14\x7a\xad\x5f\x41\xf7\x5a\x27\xce\x95\x2c\xa4\x5a\xd2\x0b\x7a\x8c\x9e\x4c\x36\x12\xef\x57\x93\xb3\x97\xcb\x94\xb2\xb7\xd4\x28\xf0\xbf\xf4\x15\x79\x06\x77\x2b\x78\xad\x49\x08\x7b\x0b\xf3\x21\x14\x05\xaa\x79\x28\x95\xb5\x29\x6c\xd5\xac\x39\x5f\xff\x67\xcf\x90\x95\x7f\x61\x76\x86\x7c\x08\xe3\xeb\x1a\xe8\x77\x00\x00\x00\xff\xff\xf3\x76\x65\x45\x42\x03\x00\x00"), }, "/src/regexp": &vfsgen۰DirInfo{ name: "regexp", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), }, "/src/regexp/regexp_test.go": &vfsgen۰FileInfo{ name: "regexp_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x72\x65\x67\x65\x78\x70\x0a\x0a\x69\x6d\x70\x6f\x72\x74\x20\x28\x0a\x09\x22\x74\x65\x73\x74\x69\x6e\x67\x22\x0a\x29\x0a\x0a\x66\x75\x6e\x63\x20\x54\x65\x73\x74\x4f\x6e\x65\x50\x61\x73\x73\x43\x75\x74\x6f\x66\x66\x28\x74\x20\x2a\x74\x65\x73\x74\x69\x6e\x67\x2e\x54\x29\x20\x7b\x0a\x09\x74\x2e\x53\x6b\x69\x70\x28\x29\x20\x2f\x2f\x20\x22\x4d\x61\x78\x69\x6d\x75\x6d\x20\x63\x61\x6c\x6c\x20\x73\x74\x61\x63\x6b\x20\x73\x69\x7a\x65\x20\x65\x78\x63\x65\x65\x64\x65\x64\x22\x20\x6f\x6e\x20\x56\x38\x0a\x7d\x0a"), }, "/src/runtime": &vfsgen۰DirInfo{ name: "runtime", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/runtime/debug": &vfsgen۰DirInfo{ name: "debug", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/runtime/debug/debug.go": &vfsgen۰CompressedFileInfo{ name: "debug.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 298, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\xce\xb1\x4e\x03\x31\x0c\xc6\xf1\xb9\x7e\x8a\x6f\x2c\x02\x9a\x34\xa5\x3c\x00\x0c\x9d\x8a\x10\xf0\x02\x49\xce\x1c\xa6\x77\x6e\x75\x71\x24\x2a\xd4\x77\x47\xbd\x0e\x87\xd8\xf0\xe2\xe1\x2f\xff\x64\xe7\x70\x9d\xaa\x74\x0d\x3e\x0b\xd1\x21\xe6\x5d\x6c\x19\x0d\xa7\xda\x12\xbd\x57\xcd\x28\x6c\x9b\xc7\x67\x1e\x32\xab\xcd\x45\x6d\x15\xae\x30\x2e\x7c\xd3\xcc\x39\x3c\xed\x0d\xd2\x1f\x3a\xee\x59\x8d\x9b\x05\x5e\xd8\xea\xa0\x10\x15\x93\xd8\x9d\xef\x4d\xb4\x5d\xd0\x6c\xb8\x84\xa5\xf7\x74\x9a\xf0\x6d\xfc\x7a\xb5\x98\x77\xf3\x74\x34\x2e\x67\x7a\xf4\xff\xad\x3b\x87\xb7\x0f\xfe\x1b\x20\x05\x4b\x6c\x1e\xb0\x57\xdc\xdf\xdd\x26\x31\x94\x63\x31\xee\xcb\x0d\xc2\xda\x63\x3b\x96\x55\xf8\x5d\xa6\x57\xc3\xda\x5f\x86\x4e\xf4\x13\x00\x00\xff\xff\xad\x79\xbd\xd2\x2a\x01\x00\x00"), }, "/src/runtime/pprof": &vfsgen۰DirInfo{ name: "pprof", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/runtime/pprof/pprof.go": &vfsgen۰CompressedFileInfo{ name: "pprof.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 660, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x92\x4f\x6b\xc2\x40\x10\xc5\xcf\x99\x4f\x31\xe4\xb4\x69\x45\xfb\x15\x8a\x97\x1e\xda\x22\xb5\xa5\x07\xf1\xb0\x26\x13\xd9\x9a\xfd\xc3\x64\x56\x2b\xe2\x77\x2f\x6b\xa4\x2c\x18\x0a\x3d\xee\xcc\xfb\x0d\xef\x3d\x76\x36\xc3\xfb\x4d\x34\x5d\x83\x5f\x3d\x40\xd0\xf5\x4e\x6f\x09\x43\x60\xdf\x02\x18\x1b\x3c\x0b\x2a\x28\x4a\xe3\x4b\x28\xca\xfe\xe8\xea\x12\x2a\x00\x39\x06\xc2\x05\xfb\xd6\x74\x84\xbd\x70\xac\x05\x4f\x50\x38\x6d\x09\xd3\xdb\xb8\x2d\x14\x36\x22\x22\x26\x66\xfa\x12\x85\xbe\xa1\xb0\x69\x80\x56\x87\x95\x71\x42\xdc\xea\x9a\x4e\xe7\xf5\x6a\x1d\x8d\x93\x20\x0c\x45\xed\xa3\x13\x6c\xa3\xab\x55\x85\xc6\x09\x14\x07\x36\x42\xc3\xc4\xf8\xe9\x67\x7a\xf1\x24\xad\x2a\x24\x66\xcf\x70\x06\x48\x5b\x54\x01\xef\xae\x8e\x2a\xbc\xe8\xde\xbd\x3a\x60\x06\x35\xb4\x89\xdb\x0c\x4d\x8e\x99\x24\xb2\x43\x67\xba\xf1\x43\xf3\x64\x68\xf0\x92\xc9\x1f\xc6\xc5\xaf\xda\x92\xaa\xae\xf9\x33\x79\x59\x8e\xeb\x1f\x9b\x46\xed\x75\x17\x09\xb3\x3a\x26\xd8\xef\x4c\x18\x6c\x9e\xc6\xb9\x37\xb2\x7e\x4f\xb7\x68\x0e\x2c\x45\xb3\xcc\x17\x1f\x57\x28\x6f\xe2\xef\xf8\x4b\xf1\x21\xe3\xf2\x9b\x17\xfc\x89\x74\xf8\xf7\xd1\x67\xef\x77\x31\xa8\xcb\xff\x18\xea\xa9\x7e\xf3\xdc\x20\x3f\x01\x00\x00\xff\xff\x14\x4a\xfc\x56\x94\x02\x00\x00"), }, "/src/runtime/runtime.go": &vfsgen۰CompressedFileInfo{ name: "runtime.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 5725, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x58\xef\x72\xdb\xb8\x11\xff\x4c\x3e\xc5\x96\xd3\xde\x91\x8e\x22\xd9\xe9\x25\x9d\x66\xea\x0f\x89\xee\xac\xcb\x34\xb6\x3c\x96\xd3\xde\x4c\x9a\xb9\x81\xc0\xa5\x04\x0b\x04\x58\x00\xb4\xac\xf3\xf8\x01\xfa\x20\x7d\xb1\x3e\x49\x67\x01\xfe\x93\x2d\x5f\xda\x4e\xf9\x45\xe2\xe2\xb7\x8b\xc5\xfe\xc3\x2e\x27\x13\x78\xb1\xac\x85\xcc\xe1\xc6\xc6\x71\xc5\xf8\x86\xad\x10\x4c\xad\x9c\x28\x31\x8e\x45\x59\x69\xe3\x20\x8d\xa3\xa4\xa1\x4d\x84\x72\x68\x14\x93\x13\xbb\xb3\x49\x1c\x47\xc9\x4a\xb8\x75\xbd\x1c\x73\x5d\x4e\x56\xba\x5a\xa3\xb9\xb1\xfd\x9f\x1b\x9b\xc4\x59\x1c\x73\xad\xac\x83\xd9\x7c\xbe\x80\x53\xb0\x3b\x3b\xa6\xbf\x1d\xf5\xdd\xd5\xf4\x47\x38\x85\x84\xc0\x81\x36\xd5\x65\x25\x24\x1a\xa2\xb6\xb2\x92\x38\x9e\x4c\xa0\x60\x1b\x84\x42\x1b\x40\x63\xb4\x19\xaf\x74\xec\x76\x15\x02\x16\x8c\x23\x58\x67\x6a\xee\xe0\x3e\x8e\x7e\xf6\xd4\x23\xff\x13\x3f\x04\x4c\xa0\x75\x98\x87\x38\x2e\x6a\xc5\x21\x75\x0d\x2e\xa3\x35\xa1\x56\x69\xfb\x87\x04\x19\x74\xb5\x51\x90\x24\x1d\x5e\x28\xe1\xd2\x8c\xd6\x6e\xec\xe5\x66\x05\x6f\x4f\xe1\xc6\x8e\x67\x52\x2f\x99\x1c\xcf\xd0\xa5\xc9\x6f\x1b\x3b\xda\x24\x0b\x84\xaf\x99\x28\x23\x59\xad\x88\x85\x17\x71\x63\xe7\xcb\x1b\xe4\xee\xd2\x99\x64\x04\x7e\xa7\x20\x2b\x90\x5b\xc9\x95\x33\x49\x76\x90\xfd\x07\xb2\xcf\x13\x6e\x4f\xfd\x1a\xb3\x5b\x1b\xbd\xbd\x0a\xfe\x0e\x0c\x24\x63\xfc\xa1\xf1\x7c\xd0\x20\xf5\x28\x62\x9f\x4c\x80\xdd\x6a\x91\x43\x8e\x2c\x07\xae\x73\x04\x94\xa2\x14\x8a\x39\xa1\x55\x1c\xdd\x32\x03\x18\xfc\x15\x47\x08\xa7\xf0\xcd\xf5\xae\xc2\x77\xd6\xa2\x21\x80\xdf\xe1\xfe\x21\x8e\x7e\x86\x53\xc0\xce\xcc\xb3\xf9\xd5\x7c\x7e\xbd\xe7\x8b\xca\x68\x8e\xd6\x1e\xb0\x78\xb3\x42\x86\x14\x05\xb4\xb8\x53\x8f\xfb\xa4\x72\x2c\x84\xc2\x9c\x44\x74\xfe\x9c\x24\x71\xf4\x10\x47\x2b\x6d\xb4\x76\x24\xb1\x61\x0a\xf2\x50\xdd\xb6\x46\x0a\x7a\x34\x92\x1b\xf8\x6f\x9e\x17\x1c\x10\xe3\x45\x13\x49\x7e\x93\xc9\xc4\xc7\xfc\xf7\x58\xb0\x5a\xba\x59\x90\x21\x2c\x28\xbd\x85\x95\x56\x38\x02\xce\xd4\xb7\x0e\x6a\x8b\x20\x1c\x30\x0b\x05\x93\x72\xc9\xf8\x06\x98\xda\x95\xda\xe0\xd8\x0b\xb9\x9e\x7f\x3f\x7f\x0b\x0b\x44\x10\x05\x30\x58\xa2\x73\x68\xc0\x6a\x59\x93\x1d\xbd\x44\xc4\x1c\xf3\x71\x1f\xb6\x93\xda\x9a\x89\xd4\x9c\xc9\xc9\x4a\xf7\x31\xfc\xde\x20\xdb\x54\x5a\xa8\x2e\x92\xc7\xdf\xe3\xb2\x5e\xad\xd0\xa4\x59\x87\x9a\x32\x29\xd1\xa4\x76\x23\x2a\x10\xca\x65\x90\x56\x1c\x6a\xa1\x5c\xe5\xcc\x08\x0a\x21\xb1\x71\xce\x08\xa4\x50\x48\x98\x11\xe8\x0d\x2c\xb5\x96\x5e\xac\x50\x85\x3e\xe0\xad\x36\x08\x2f\x70\x9b\x36\x56\xb6\x8e\xf1\x4d\x92\x8d\x69\xcb\x34\xb1\x95\x14\x2e\x19\x41\xf2\x37\x95\x64\xe3\x0f\x2a\xc7\xbb\xa0\xc5\x0b\x78\x15\x1c\xe1\x25\xff\x8a\x7f\x8f\x47\x90\x24\x23\xfa\x29\x98\xb4\xe8\xdd\x50\x31\xe3\x7c\xf0\x10\x73\xbb\x53\xbd\x0c\x47\x48\x46\x43\xb2\xa0\x2d\xe7\x05\xa9\x90\x7a\x0d\x5c\x9a\xbd\x38\x79\x0e\x92\xb5\x90\x27\xfa\xbf\xa5\xb8\xe9\x55\xf2\x1a\x34\xe7\x39\xce\xba\x20\xd9\x5f\x38\x69\x84\x8d\xc0\x99\x1a\x1f\x39\xc3\x76\xde\x18\x41\xc5\xe1\xf3\x97\xc6\x1d\x19\x91\x06\xf5\xea\x98\xf8\x26\x93\x96\xeb\xcc\xb0\x12\x6d\x88\x39\x07\xa2\xac\x24\x96\xa8\x1c\xe6\xbe\x94\x86\x0a\x7c\x7a\x63\xc7\x71\x17\x65\x1f\x5a\x0c\xc5\x5a\xa5\xad\x15\x4b\x89\xe3\x3d\x55\x82\xd0\x94\x87\xb7\xa1\x2e\x47\xcd\x7e\xf7\xd0\xa8\xf3\x4d\x20\xdc\x3f\xc0\x43\x1c\x8a\x71\x83\x08\xd5\xf8\xbe\xab\xc5\x5c\xb4\xcc\x19\x5c\xe0\x1d\x85\x67\x5a\xd0\x7b\x60\x18\x01\x65\x43\x1b\x60\xad\xf4\x3d\x99\x83\x4b\xe0\x72\x0a\xe1\x69\x14\x8b\xa3\x33\xda\x84\x9e\x23\xfa\x17\xde\x7d\xee\x84\x20\x88\xa3\x33\x0a\x6a\x7a\x5a\xc2\x47\x0a\x6c\x7a\x84\x72\x71\xf4\x83\x72\x66\x37\x94\xd8\x55\xab\xa9\x4f\xa4\xee\x55\xe3\x5d\x7f\x4b\xec\x5f\x0e\xbc\x36\x54\x02\x6a\x27\x14\x26\x59\x28\xb9\x84\x4e\x82\xc3\xf7\xea\x71\x08\xa7\x50\x90\x93\x11\x28\x21\xb3\x41\x81\x3c\x7f\xf7\xd3\xe5\xd5\x7c\xba\x48\x55\x48\xcf\xfd\x10\x38\x19\x68\x63\xf9\x1a\xf3\xa0\x0e\xa7\x0c\x28\xd9\x06\x53\xbe\x66\xaa\x73\xc0\xa1\x6d\x2d\xba\x6b\x51\xa2\xae\xdd\xc1\x0b\x80\x64\x93\x4c\xe0\x52\x5b\x4c\x79\x06\x0f\xd9\x08\x8e\xb3\x38\xfa\xd3\x4b\xde\x6d\x7e\x51\x97\xd3\xcb\x4f\xe9\xf3\xda\x5d\xd4\x65\x67\x8f\x27\xb0\xc7\xc6\x73\xda\x31\xd9\xc1\x6d\x9b\x78\x71\x1b\x02\xe7\x58\x2e\x1c\x73\x76\x10\x05\x93\x09\xcc\x50\xa1\x61\x12\xac\x63\x4e\x58\x27\xb8\x1d\xc7\xd1\x3b\x29\x35\xef\xe3\xe3\xcd\x77\x30\x99\xc0\x72\xe7\xd0\x02\xa3\x25\x46\xe9\xc1\x54\x0e\xd6\x09\x29\x41\x28\xaa\xcf\x71\x74\x4d\x1a\x04\xde\xe7\xd9\x52\xbc\x45\x45\x99\x53\x18\xc4\x3c\x8b\xa3\xc5\xce\x02\x1c\xde\x4c\x2f\x1d\xf3\xe5\xab\x30\xba\xa4\x8b\xc2\x61\x09\xa9\xad\x4b\xd0\x05\xfc\x74\x77\x47\xac\x4b\x94\x7a\x9b\xc5\xd1\x47\xad\x37\x75\x65\xf7\xc5\xa8\xba\x5c\xa2\x21\xb4\xaf\xe8\x68\x40\x06\x58\x1c\x9d\x7b\x95\x9e\xc5\x97\x61\x39\x8e\xce\x0c\xa2\x7d\xac\x5e\x8f\xa3\x53\xd8\xd8\x9b\xf2\x9c\x09\xd5\x1e\x94\x12\x67\x8d\xac\xda\xb7\xeb\x8f\xc8\xaa\xce\xb6\xff\x8d\x65\x89\xb1\xb3\xd3\x7f\x62\xa5\xc0\xf2\x21\x6f\x52\xf6\x31\x8b\x50\x20\x68\xcd\x56\x4c\xd9\x06\xab\xe8\x8e\x3d\x8c\x55\x5a\xbd\xec\xf0\x01\x7e\x85\x12\x99\xc5\xfc\x09\xdc\xb4\x0b\x4e\x83\x5b\x23\xcc\x17\x81\x21\x64\x86\x1d\xca\xf7\x11\x3b\xb0\x65\x6f\x01\x1d\xc0\xc1\xae\x1f\xf5\xf6\xa5\xc4\x5b\x94\x50\x88\x3b\xcc\x5f\x5a\xf1\x4b\x5b\xca\x6a\x83\x2d\x97\x36\xfb\xb6\x9e\x4c\xa2\x70\x24\x61\x1b\xcd\x6a\xd2\x4a\xe9\x6d\x58\x24\x73\x76\x4b\x87\x4c\x38\x8e\xa3\x05\x5d\xbd\x8d\x61\x1e\x9f\xd3\x4b\x5b\xee\xc0\x5f\xcf\xbd\x12\x0d\x53\xe3\xac\xc0\x14\x47\xe7\x8b\x8a\xa9\x27\x82\x4a\x32\x67\x7f\x12\xdb\xe0\x1e\xf3\x4e\x19\x5f\x63\x60\x1e\xf0\x72\xa2\xee\x33\x7b\x60\xe0\x6e\x99\xdf\xd7\x7c\xf3\x23\xb3\x6b\xa2\xf6\xcc\x95\xd1\x85\x90\xd4\x3a\x2e\x6b\xbe\x41\x07\x6b\x66\xd7\xe0\xd8\x52\x62\x1c\xcd\xa6\x7d\x46\xf6\x2c\xb3\x29\x94\xe8\x58\xce\x1c\x8b\xa3\xb9\x5b\xa3\xd9\x53\x93\x20\x9a\xa8\x6d\x96\xf6\x79\xd0\x78\x71\xc6\xcc\x92\x06\x28\xae\xa5\x44\xfe\xc4\x5d\x74\xa3\xcd\xa6\x4f\x0b\x81\xc2\x3b\xd7\xf2\x50\x52\x6d\x29\x2d\xd6\xac\xaa\x50\xc1\x76\x8d\x0a\xfa\x9c\xfa\xd7\x3f\xfe\x09\x6e\x2d\x2c\xb0\x52\xd7\x74\x25\x7d\x64\xf6\xa0\x4c\x54\x39\x50\x03\x4f\x31\x27\x99\xdd\x93\x9f\x2a\xa6\xb4\x45\xae\x55\x6e\xc1\x0a\xc5\x11\x4e\xfe\xf8\x07\xaa\xdc\x97\xac\xb6\xe8\x4b\xdc\x85\xed\x0d\xec\xa9\x17\xad\xbd\x3e\xbf\x7a\xfd\xe6\x4b\xbf\x11\x17\x86\xd7\x92\x19\x58\xd6\x45\x11\x62\xdc\x20\xa7\xce\x61\x36\x85\x8a\x38\x21\xaf\x4d\xb0\x12\xdd\xdf\xd6\xb5\xeb\xcc\xc1\xe7\x94\xca\xff\xf4\xc5\xab\xd7\xaf\xb3\xdf\x91\xdc\x66\xb3\x1f\x54\xfe\xbf\x6e\xd6\x1e\xdc\xc6\x91\x97\x0d\x43\xdb\xfc\xfe\x15\xf9\x7e\x7a\xf9\xe9\xcc\xb0\x60\x8b\x42\x6a\xd6\x08\x2f\x5a\x9a\x2e\x60\x7a\xf9\x29\x98\xaf\x4d\x81\xd9\x94\xae\x7f\x8a\x9e\x56\x24\x75\x21\x71\xe4\xfb\xe6\x6e\x17\x4f\xf3\xa1\x70\x89\x26\x24\xf1\xa0\x58\x3e\xca\x5d\x78\x73\x42\xd9\x79\x51\x97\x0b\xf1\x0b\x4e\x25\xb3\x36\x94\x22\x2a\x29\x53\x3f\x49\x8d\xe3\xe8\xfd\x8e\x56\xe1\xf3\x9b\x93\x2f\xfd\xa5\x16\x79\xda\xe0\x50\x5d\xa9\x6f\x7d\xd6\xd5\xf4\x96\xf0\xd0\xdd\xb8\x57\xc8\xf2\xf6\xa2\x4c\x4b\x38\x6a\xff\x0f\x3b\x98\x05\xba\x33\xa1\x98\x14\xbf\xa0\x49\xef\x46\x40\x2d\xb7\x43\x43\x63\xf6\xfd\x43\x03\x0c\x4d\x17\xa1\x7b\xc5\x74\xc5\xfe\x5e\x63\xd7\x56\x90\x59\x6b\x85\x77\x95\x36\xbe\xdb\x14\x28\x7d\xd1\xcc\x85\x25\x7d\xb7\xc0\xb5\xba\x45\x63\x7d\x0a\x75\x5d\xe0\xcf\xa1\x3f\xcb\xc0\xf7\x5b\x69\xd6\xb6\x5b\xf0\xab\x4f\xd7\x0f\x1e\xc3\xc3\x63\x41\xd4\xd7\x51\x2b\x37\x98\x60\xa8\xb3\x3c\x34\xc2\x0c\x1a\x4b\x3f\x42\x3c\x15\x76\xc1\x4a\xec\x07\xd3\xaf\x3c\x03\x61\xd0\x1e\x90\xc4\x9c\x69\x73\x39\xdd\x53\xc7\x4b\x1f\xf4\x3e\x4a\x48\x32\x09\x8d\xcf\xe7\x58\x5e\xfa\x72\x86\x57\xcc\x79\x2d\xe1\x14\x5e\x9f\xbc\x82\x23\x38\x39\x7e\xf5\x5d\xef\xb3\xf7\x52\xf3\xcd\x00\x9a\x9a\x06\xff\xc8\xb7\xe7\xb5\xc3\xbb\x06\xd7\xa6\xc2\x00\xdb\x34\x61\xfd\x34\xa0\x6e\xd1\x3a\xb1\x22\x00\x55\x9f\x31\x7c\x28\x40\xb8\x6f\x6d\x37\x1a\x90\x53\xbb\xb9\x62\x44\x6e\xb5\x22\x47\x03\xb9\x26\x1b\x59\x3d\x0a\x95\x73\x2b\x2c\x82\xc1\x52\xdf\x06\x41\xc0\x75\x49\x1c\xe3\xfd\xc9\x25\xa8\x49\x77\x4c\xba\xac\x0b\xf8\xfc\x85\xae\xa3\x11\xa5\x52\xd3\xfb\x37\x0a\x1e\xfa\x16\xf0\xfc\x74\xe9\x27\xc7\x5f\xfd\x2c\x70\xec\x07\xc5\xe6\x85\xeb\x6a\x47\xdb\x8f\xc0\xee\x4d\x8b\x49\x4f\x18\x0c\x81\xcd\xa8\xea\x07\xc5\x7e\xb4\xeb\xdb\xf5\x8f\x9a\x6f\xe6\x8b\xeb\xb5\x41\xe6\x3b\xf1\x96\xfe\x49\xc9\x67\x56\xfe\x12\xf2\xe2\xd0\xe7\x28\xbb\xb3\xe3\xeb\x35\x36\x88\xa1\xc5\x8c\xbb\x36\x8c\x53\x78\xfa\x0f\x2e\x7d\xf8\x29\x21\xdb\x48\x5e\x38\x5d\xb5\xa8\x36\x4a\x1f\xfa\xd2\xd0\x2e\x05\xab\xfb\x31\xf2\xaf\x18\x3e\xbc\x31\xe0\x2b\x0d\xa8\x6e\x85\xd1\xca\x4f\x87\x4e\x03\x67\x8e\xaf\xc3\x76\x76\x0c\xd7\x6b\x34\x48\x53\xe5\x16\x61\xcd\x6e\xf7\x03\xa3\xb9\xba\x54\x0e\x4c\x6e\xd9\xce\x76\x19\xdb\xcf\x0a\x2b\xed\x4d\xeb\x5d\xfc\xe6\xbb\xc7\x23\xad\x87\xf9\x8f\x7d\xf3\x22\xc5\x0a\x8e\xf6\xaa\xd2\x51\xf8\x0c\x78\x4f\xb3\xbe\x12\x3c\x4d\x1a\xe4\x5b\x3f\xf6\xda\xba\x0a\x65\x28\xe9\xbd\xf2\x67\xc4\xea\x9d\x14\xb7\x98\xee\x97\xb7\x76\xdd\x4f\x5e\xa9\x6d\x3c\x90\xf5\xa2\xfd\x71\x1b\x2f\xdb\xe0\x66\xca\x96\x35\x5a\x04\x66\xfa\x6b\xc3\xa3\xb7\x86\x55\x63\xb8\xf8\x3f\x8c\xde\x2b\x74\x61\xde\xae\xf8\x81\xb2\xf8\xb4\x02\x16\x42\xe5\x7e\x4e\x1b\x16\x1a\x22\x7c\x50\x85\xee\xf1\x2d\xc5\x0f\xe8\x81\xb1\x56\x5c\x51\x9d\x2b\xba\xc5\x41\xc5\x7b\x54\xd4\xfc\x45\xd0\x49\xed\x66\xfa\x7f\x07\x00\x00\xff\xff\x8e\x83\xca\x2c\x5d\x16\x00\x00"), }, "/src/strings": &vfsgen۰DirInfo{ name: "strings", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/strings/strings.go": &vfsgen۰CompressedFileInfo{ name: "strings.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 1759, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x94\xd1\x6f\xe3\x44\x10\xc6\x9f\xbd\x7f\xc5\x60\x1e\xce\xa6\xa9\x9d\xb4\x4d\x49\x83\x82\x74\x0d\x52\x29\x42\xea\xe9\x0a\xe2\xe1\x74\x0f\xeb\xf5\x38\x9e\x64\xbd\x6b\xed\xac\xdb\x0b\xa8\xff\x3b\x5a\x3b\x6e\x73\xe5\x10\x02\xfa\xe4\xc6\xb3\xbf\xf9\xe6\xf3\x37\x9b\xe7\x70\x52\x74\xa4\x4b\xd8\xb2\x10\xad\x54\x3b\xb9\x41\x60\xef\xc8\x6c\x58\x08\x6a\x5a\xeb\x3c\x24\x22\x8a\x3b\x43\xca\x96\x98\x77\xbe\x5a\xc4\x42\x44\xf1\x86\x7c\xdd\x15\x99\xb2\x4d\xbe\xb1\x6d\x8d\x6e\xcb\x2f\x0f\x5b\x8e\x45\x2a\x44\xd5\x19\x05\xb7\xa6\xc4\x4f\xd7\x7b\x8f\x09\x1f\xc8\x13\x50\x50\xec\x3d\xa6\x40\xc6\xc3\x1f\x22\x72\xe8\x3b\x67\x60\xcb\xd9\xad\xf1\xe8\x8c\xd4\x77\xc5\x16\x95\x4f\x38\xcd\xd6\x52\xeb\x24\xa6\x00\xb9\xab\xe2\x49\x28\xba\xd1\xb6\x90\x3a\xbb\x41\x9f\xc4\xf7\x3d\x31\x1e\xeb\x2a\x67\x9b\x75\x2d\xdd\xda\x96\x18\x4f\x40\xa5\x69\x40\x26\xa9\x78\x3a\x56\x93\xf0\x04\x18\xdb\x83\x9c\xff\x2a\xe3\x75\x11\xb6\x7f\xe9\xf6\xb3\x64\xff\xff\x3a\xea\x91\xf0\x2f\xba\xae\x6d\x67\xfc\xdf\x74\x34\xb0\x5c\xc1\x54\x44\x79\x0e\xdc\xa2\x22\xa9\x41\x49\x46\x16\x11\x3f\x92\x57\x75\xa8\x09\x3f\x80\x46\xd3\xc3\x61\xb5\x82\xe9\x52\x44\xa3\xd6\x10\x80\xec\x7d\x67\xb0\xef\x72\x6b\x86\x0f\x90\x70\x0a\x27\x30\x7b\x7d\xf6\xfb\xe1\x31\x3d\x3a\x3f\xfd\x02\xff\xa5\x88\xaa\x5e\xf4\x6a\x05\x1c\x94\x3c\x9f\x9a\x89\x28\x7a\xfa\x0c\xf2\x24\x44\x54\x59\xd7\x57\xb5\x96\xc3\x58\xc7\x4e\xa7\x03\x2c\xbc\x59\xad\xe0\x74\x36\xd0\x0a\x87\x72\x77\x40\x99\x93\x13\x11\x45\x0c\x2b\xe0\x0f\xad\xe5\x93\x51\xd0\xf2\x63\x80\x8f\x9d\xcc\xb3\xab\x49\x01\xdf\x5c\x87\x5d\x41\x97\xc2\x61\xea\xf4\x60\x6f\xa0\xe7\x39\xfc\xda\xb2\x77\x28\x1b\x38\xd4\x65\x43\x19\x38\xd4\x84\x0c\xd6\xc0\xb8\x62\x9d\x61\x59\x61\x06\xbf\x21\x28\x69\xde\x78\x28\x2d\xf8\x5a\xfa\xac\xe7\xfc\x72\xf7\xc3\xdd\x12\x6e\xfd\x1b\x0e\x03\x30\x15\x1a\xfb\xb7\xe0\x6b\x04\x34\x9e\xdc\xf3\x92\x66\x87\x56\xf0\xf6\xdd\x6d\x40\x41\x81\x40\x4d\xab\xb1\x41\xe3\xb1\xec\x71\xc3\x5f\x63\x1d\x02\x56\x15\x29\x42\xe3\xf5\x1e\x82\x7b\x37\x77\x6f\xdf\xaf\x7f\x5c\x6d\x79\x48\x43\x45\x4a\x6a\xbd\x87\x44\x3e\x58\x2a\xa1\xe3\xa0\xfe\xc3\xc7\xb0\xac\x13\x20\xc3\x1e\xe5\x31\xb2\x63\x04\x79\xf0\x02\x4a\x72\xa8\xbc\xde\x7f\x07\xd6\x01\xdb\x06\xe1\x27\xf9\x20\xef\x95\xa3\xd6\x8f\x36\x15\x47\x62\xa9\x02\x6b\x10\xf0\x13\xb1\xe7\x34\x3b\xc2\x5e\x77\x61\x52\x62\x20\x1e\x54\x3f\x5a\xb7\x9b\x40\x89\x15\x3a\x28\x6d\x00\x91\x87\xce\x78\xd2\xc1\x11\x87\x6f\x18\x24\x18\xc4\x12\xb8\xb6\x8f\x06\x1e\x48\x42\xeb\x6c\x45\x3a\xdc\x36\x47\x64\x69\xca\xe1\x04\x48\x87\x50\xa0\x51\x75\x23\xdd\x8e\x41\x3e\x48\xd2\x32\xf8\x9c\x30\x22\xd4\xde\xb7\xbc\xcc\xf3\xcf\x2e\x39\x2d\xcd\x26\xdf\xd8\x9c\x98\x3b\xe4\x7c\xb6\xb8\xba\x9a\x7e\xdd\xff\xa3\x6c\x13\xec\x3e\x3d\x9f\x9f\x4d\x2f\x17\xf3\xf3\xf3\x30\xce\x21\x40\xc3\xe4\x49\x91\x15\x5d\x95\x7e\x39\x4c\xca\xb6\xfb\x75\x8d\x6a\x97\xa4\x21\x48\x54\x41\x91\xc9\xb2\x74\x21\xb9\x86\x74\x1f\xdd\xe3\x74\x3d\xd7\x87\x0f\xc0\x60\x2c\xb2\x92\x2d\x4e\xe0\xb1\x26\x55\x43\x8b\xae\xb2\xae\xe1\x31\x64\xef\x2c\x85\x3b\x03\x1a\x69\xa8\xed\xb4\xf4\x64\x4d\x36\x20\x5f\xc7\x6f\x02\x6c\x81\x77\xd4\x02\xf9\x0c\xee\xff\xc9\x89\x30\x37\xf9\xfc\x62\x71\x31\x5f\x5c\xaa\xc5\x4c\x4e\x67\x57\x97\x78\x71\x26\xd5\xfc\xac\xba\x9c\xcf\x0a\x35\xbf\x9c\xce\xbe\x55\xf2\x62\x7e\x71\xb6\x98\x86\xa6\xe3\x64\x50\x88\xe8\x09\x50\x33\xc2\xcb\xbc\x5f\xad\xa0\x18\x16\x5a\x1a\x52\x49\x7c\xc8\xf8\x12\x48\x6b\xdc\x48\xdd\x07\xce\x56\x60\xac\x39\xfd\x1d\x9d\x1d\xf7\x2c\x38\x42\x58\x42\xb1\x87\x07\xa9\x3b\x8c\xd3\xb0\xc2\x4f\xe2\xcf\x00\x00\x00\xff\xff\x3c\x43\xb4\x54\xdf\x06\x00\x00"), }, "/src/strings/strings_test.go": &vfsgen۰CompressedFileInfo{ name: "strings_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 175, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x34\xcd\xc1\xaa\xc2\x40\x0c\x85\xe1\xf5\xcd\x53\x84\x59\xb5\x57\x69\x9f\x41\x37\x82\x20\x48\xdb\xbd\x8c\x6d\xac\xb1\x6d\x66\x98\x64\x56\xe2\xbb\x4b\x51\x97\x07\xfe\x8f\x53\xd7\xb8\xb9\x66\x9e\x07\x7c\x28\x40\xf4\xfd\xe4\x47\x42\xb5\xc4\x32\xea\xc5\x48\x0d\x80\x97\x18\x92\xa1\x5b\x17\xcb\xe8\x00\x6e\x59\x7a\xec\x48\x6d\xbf\x52\x4a\xbb\x79\x0e\xbd\x16\x86\xff\xdf\xa6\xea\x4a\x7c\xc2\x9f\x55\xed\xc4\xb1\x70\x29\x8b\xf1\x42\x55\x43\x7e\x38\xd1\xd2\x9a\x37\xdd\xe2\xaf\xfd\xe8\x33\xa5\x26\x0b\x4a\x30\xd4\x1c\xd7\x47\x1a\x90\x05\x0f\x21\xde\x29\x1d\x5b\x57\xc2\x0b\xde\x01\x00\x00\xff\xff\xdd\x64\x86\x91\xaf\x00\x00\x00"), }, "/src/sync": &vfsgen۰DirInfo{ name: "sync", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/sync/atomic": &vfsgen۰DirInfo{ name: "atomic", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), }, "/src/sync/atomic/atomic.go": &vfsgen۰CompressedFileInfo{ name: "atomic.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), uncompressedSize: 3060, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x56\xcf\x6f\x9b\x3e\x14\x3f\xe3\xbf\xe2\x7d\x39\x54\xd0\x7e\x45\xa4\xad\xea\xa1\x52\x0e\xd5\x0e\x53\xa5\x49\x9b\x54\x75\x77\x07\x4c\xea\xcc\xb1\x91\xb1\x69\xa2\x28\xff\xfb\x64\x03\xc1\x80\x61\x5d\xb2\xf6\x84\x8b\xfc\xf9\xc1\x7b\x9f\xf7\x9a\xc5\x02\x6e\x56\x9a\xb2\x0c\x36\x25\x42\x05\x4e\x7f\xe1\x35\x01\xac\xc4\x96\xa6\x08\xd1\x6d\x21\xa4\x82\x08\x05\xa1\xe6\x25\xce\x49\x88\x50\x10\xae\xa9\x7a\xd1\xab\x24\x15\xdb\xc5\x5a\x14\x2f\x44\x6e\xca\xee\xb0\x29\x43\x14\x23\x94\x6b\x9e\xc2\xd3\x2b\x2e\x1e\xb9\xfa\xfc\x29\xc2\x59\x26\xe1\x9a\x9a\xf3\xff\xc0\xc9\x2b\xd8\x63\x5c\x3f\xe0\x80\x02\xc1\x32\xb8\x5f\xc2\xb5\xb9\x88\x02\xfb\x80\xa5\xb9\x89\x02\x49\x94\x96\x1c\x04\xcb\xd0\xb1\x4f\x7c\x77\xdb\x11\xdf\xdd\x9e\x88\xef\x6e\xe3\xfa\x71\x1e\xf1\x33\x75\x2c\x6b\xc7\xb3\x6e\x4c\xeb\x0b\x5c\x3f\x53\xc7\xb6\x76\x7c\xeb\xc6\xb8\xbe\xd0\x79\xa1\xa4\xc3\x5e\x28\xd9\xd1\x17\x4a\xc6\xed\xe1\x3c\x81\x1f\x82\x72\x45\x4e\x02\x36\x12\x49\xf3\xb2\xd1\xe9\xbd\x8b\x07\x7f\xff\xbd\xea\x17\xb1\x2d\xb0\x24\x0f\x3c\x9b\x08\x93\x60\x59\x2f\x51\x2b\x21\x98\x91\xa1\x39\x34\xdc\x4b\x73\xc7\xbc\xea\x8b\xb5\x6a\x4a\x6a\x82\x82\xe3\x49\x3d\xc7\xac\x24\xd3\xfa\xc3\xcc\xb9\xfa\xa6\x7f\xef\xaa\xef\x8d\xe6\xc9\x81\xfe\x88\x12\x78\x03\xdc\xb3\xf0\x21\x55\xf0\xc4\xbc\x67\xc2\x66\xfd\x5d\x5d\xcc\xcf\x42\x67\x66\x30\x10\xff\xd8\xd3\x43\x96\x79\x86\x22\x23\x4c\xe1\xd1\x8e\x35\x76\xda\xc9\x83\x9b\xfa\x92\x7f\x02\xcd\xd9\x51\xf0\xc6\xae\xd6\x18\xef\xc4\xb3\x55\x3c\xc3\x75\xfa\x8e\xde\x4a\xbf\xe8\x3b\x46\xd9\xed\xbe\xa3\xbf\x7e\x2f\x52\xf1\xc4\xb3\xd3\x19\xee\xe1\xf3\x94\xbe\x09\x3c\x6e\xbd\xd3\xed\x06\x52\xef\xd9\x01\xa8\x5f\x67\xa7\xb4\x93\x20\x4f\x04\xdc\xa6\xcf\xe2\x06\x25\x77\x8b\x3c\x8b\x1b\x15\xb1\x57\xb5\x49\xe8\xdc\x60\xfa\xfe\x21\x79\x89\x9e\x94\x90\xc4\x33\x59\x15\x66\xed\x5c\x1d\xba\x1e\x55\x98\x8d\x90\xc3\x2c\x37\x48\xf3\xfd\x73\x48\xef\xac\x19\xac\x7e\x83\xac\x37\xe0\x2d\xf8\x2d\xca\x9e\xdc\xb6\x70\x5b\xff\x39\xfc\xfc\x42\xb4\x34\x83\x5e\x4c\xb0\x45\x15\x5c\xff\xc4\x4c\x93\xd8\xf6\x33\x8a\x21\xda\x81\x85\xe4\x38\x25\x87\x63\xec\x74\xad\x4a\x2a\x1f\xce\x1a\xf2\xa0\x68\x0e\x3b\xb3\x71\x39\xb5\x4b\x38\x28\x30\xa7\x69\x14\x96\x7b\x9e\x2e\xea\x1f\xbd\xf7\x50\x1a\x2c\x88\xdc\x5e\xaa\x0c\x9f\xa1\x11\x60\xa9\xc3\xd8\xee\x62\x9a\x1b\x65\xf8\xaf\x66\xba\xba\x82\x4d\x99\x3c\x1a\x2d\x8e\xd9\xf7\xd5\x86\xa4\x2a\xda\xc5\xc9\x57\xa2\xa2\x30\x15\xbc\x54\x52\xa7\x4a\xc8\x30\x36\x88\xf1\xd5\x2a\xa9\xbc\x97\xff\xe8\x90\x72\x03\xa0\xa5\x22\x5c\xb1\x3d\xa8\x7d\x41\xb2\x29\xcb\xc6\xef\x12\x76\xe8\x88\x7e\x07\x00\x00\xff\xff\x2a\xf7\xf1\xfd\xf4\x0b\x00\x00"), }, "/src/sync/atomic/atomic_test.go": &vfsgen۰FileInfo{ name: "atomic_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x61\x74\x6f\x6d\x69\x63\x5f\x74\x65\x73\x74\x0a\x0a\x69\x6d\x70\x6f\x72\x74\x20\x22\x74\x65\x73\x74\x69\x6e\x67\x22\x0a\x0a\x66\x75\x6e\x63\x20\x54\x65\x73\x74\x48\x61\x6d\x6d\x65\x72\x53\x74\x6f\x72\x65\x4c\x6f\x61\x64\x28\x74\x20\x2a\x74\x65\x73\x74\x69\x6e\x67\x2e\x54\x29\x20\x7b\x0a\x09\x74\x2e\x53\x6b\x69\x70\x28\x22\x75\x73\x65\x20\x6f\x66\x20\x75\x6e\x73\x61\x66\x65\x22\x29\x0a\x7d\x0a"), }, "/src/sync/cond.go": &vfsgen۰CompressedFileInfo{ name: "cond.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), uncompressedSize: 511, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x8f\x31\x73\xab\x30\x10\x84\x6b\xdd\xaf\xd8\x12\x1e\x83\x71\xfd\x6c\x9a\xe7\x96\xee\x4d\x26\xb5\x2c\x84\x7d\x41\x3e\x31\x20\x92\x61\x32\xfc\xf7\x8c\x90\x93\x14\xb6\x9a\x93\x76\x75\xfb\xcd\x56\x15\x8a\xf3\xcc\xae\xc5\xdb\x44\x34\x68\xd3\xeb\x8b\xc5\xb4\x88\x21\x0a\xcb\x60\x71\xf2\xd2\x62\x0a\xe3\x6c\x02\x3e\x49\x55\x15\x3a\xb6\xae\x9d\x30\x4f\xb6\xc5\x79\xc1\xbb\x16\x76\x4e\x83\x6f\x83\xb3\x37\x2b\x41\x07\xf6\x42\x4a\xfc\xc9\x0f\x0b\x90\x26\xa9\x06\xe9\x34\xde\xf4\x76\x8c\x7e\xe0\x6e\xf3\xe3\x6c\x78\x0a\xa4\xcc\xd5\x46\x13\xc6\x0f\xcb\x29\xdd\xe9\x19\x53\xec\xc7\x23\x0f\x60\xd9\x32\x60\xae\x5a\x70\xf6\xde\xd1\x4a\xd4\xcd\x62\x90\x19\xfc\x89\x4d\x72\xbc\x6a\x0e\x59\x1e\xab\x98\x9d\x14\x05\x29\xee\x60\x76\xe6\x8a\xba\x86\xb0\x8b\x86\x4a\x6f\xdc\x74\x6f\xb3\x9f\xac\x9c\xd4\x1a\x97\x9a\xdd\x8b\x38\x6f\xfa\x2c\x27\x75\x2c\xe3\xd7\xa4\x36\x49\x7b\x24\xfe\xe7\x8b\x68\x97\x98\x1b\x4c\x22\x6b\xbf\x91\x46\x1b\xe6\x51\xee\xc9\x52\x96\x94\xd8\xc7\x12\x61\x9c\xed\x93\xb0\x7f\xa3\xd7\xad\xd1\xd3\xbd\x83\xe0\x6f\x1d\x13\xb7\x75\xd4\xd8\x93\xea\xfc\x08\x8e\xf2\xfe\x00\xc6\x11\x72\x00\x17\xc5\x6f\xaf\xef\x6c\xb5\xd2\x4a\x5f\x01\x00\x00\xff\xff\x2c\xcb\x53\xaf\xff\x01\x00\x00"), }, "/src/sync/export_test.go": &vfsgen۰CompressedFileInfo{ name: "export_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 168, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\xca\x4d\x0a\xc2\x30\x10\x05\xe0\x7d\x4e\xf1\x96\x8a\x3f\xf1\x02\xde\x41\x0a\xae\x25\x4d\x5f\x35\xda\x4c\x42\x32\x29\x94\xd2\xbb\xbb\x15\xdc\x7f\xd6\xe2\xd0\xb7\x30\x0d\x78\x57\x63\xb2\xf3\x1f\xf7\x24\xea\x22\xde\x18\x6b\xd1\x71\x64\xa1\x78\x0e\xe8\x17\x28\xab\xd6\x23\x84\x1c\xa0\x09\x2f\x37\x13\x92\x4e\x29\x23\xc4\x3c\x31\x52\xd4\x69\x48\x52\xcf\x66\x76\x05\x5d\x13\x0d\x91\x8f\x5c\x92\xbf\x05\xc1\x15\x63\x13\xbf\xdb\x23\x88\x62\x45\xa1\xb6\x22\xb8\x60\xfb\xd3\x77\xc9\xbf\x7e\xdd\xcc\x37\x00\x00\xff\xff\x78\xcd\x49\xae\xa8\x00\x00\x00"), }, "/src/sync/pool.go": &vfsgen۰CompressedFileInfo{ name: "pool.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), uncompressedSize: 505, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x90\xcf\x4e\xf3\x30\x10\xc4\xcf\xde\xa7\x98\xaf\xa7\xe4\x03\x5a\xb8\x56\xca\x89\x03\x37\x54\x89\x63\x55\x21\xe3\x6e\x2a\x83\xeb\x58\xce\x5a\xa4\x54\x79\x77\xe4\x24\xfd\x83\x20\x97\x68\x77\x46\xbf\x99\xf5\x62\x81\x9b\xb7\x64\xdd\x16\xef\x2d\x51\xd0\xe6\x43\xef\x18\xed\xc1\x1b\x22\xbb\x0f\x4d\x14\xcc\x92\x6f\x75\xcd\x33\x22\x39\x04\xc6\xaa\x69\x1c\x5a\x89\xc9\x08\x8e\xa4\x5c\x63\xb4\x43\xfe\x46\xdb\x7c\xd5\x58\x2f\x1c\x27\xe5\xc5\x7e\x31\x92\xf5\x12\x24\x12\xa9\x56\x9a\xc8\x58\x6f\x06\x4b\xad\x0d\x1f\x7b\x52\xcf\xfc\x09\xa0\x4e\xde\x14\x25\xae\x95\x9e\x28\x6f\x51\x04\xfc\xcf\xb1\x25\x9e\x58\x7e\x7a\x72\x05\x5b\xc3\xb1\x2f\xc2\x7c\xa0\x97\xa8\x2a\xdc\xe7\x7d\x16\xc2\x3c\xd3\xff\x55\xf0\xd6\x0d\x3b\x15\x59\x52\xf4\xa3\x50\x94\xa4\x54\x4f\xe7\xa5\xb7\x8e\xf2\xdc\x61\x59\x61\xe2\xad\xaf\xd9\x77\x0f\x1b\x52\xd3\x80\x8b\x65\xf9\xcb\x33\x01\xbb\x3f\x6e\x58\x25\x29\xba\xeb\x1b\xca\xe9\x88\x2e\x37\x3f\xf5\x1c\x01\x43\x9b\x4b\x9e\x0e\x81\xfd\xf6\x94\x74\x8b\xae\x3c\xf3\x63\xf2\x62\xf7\xfc\x1a\x79\x67\x5b\xe1\x98\xb3\x1e\x1d\x6b\x9f\x42\x61\xc6\xff\xf4\xc4\x39\xae\xa7\xef\x00\x00\x00\xff\xff\xd6\xf1\x0f\x08\xf9\x01\x00\x00"), }, "/src/sync/sync.go": &vfsgen۰CompressedFileInfo{ name: "sync.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 2015, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x55\xdb\x6e\xe3\x36\x10\x7d\x36\xbf\x62\x60\x14\xa8\x94\xd8\x52\xd2\x2d\xb6\x40\xb0\x7e\x28\xb2\xc5\x22\x40\xbb\x0b\x34\x29\xfa\x10\x18\x0d\x25\x8d\x4c\xc6\x14\xa9\x72\x28\xab\x6e\x90\x7f\x5f\x0c\xa5\xf8\x92\x9b\x5f\x4c\x90\x33\x67\xce\x9c\xb9\x28\xcf\xe1\xb4\xe8\xb4\xa9\xe0\x9e\x84\x68\x65\xb9\x96\x2b\x04\xda\xda\x52\x08\xdd\xb4\xce\x07\x98\xae\x74\x50\x5d\x91\x95\xae\xc9\x57\xae\x55\xe8\xef\x69\x7f\xb8\xa7\xa9\x10\x1b\xe9\x81\xb0\xf9\x5b\xea\x80\x9e\x60\x01\x8d\x5c\x63\xd2\xc8\xf6\xf6\xa4\xd3\x36\x7c\xf8\x69\x79\xbb\x2c\x95\xb4\x50\x38\x67\x52\x21\xf2\x9c\xcd\x7f\xed\xdd\x1a\x2d\x04\x2f\xcb\x35\x41\x50\x08\xb6\x6b\x0a\xf4\xe0\x6a\xe8\x47\x28\x39\xd8\x14\x5b\xf0\x9d\x0d\xba\xc1\x7f\xae\xb1\xf1\x68\x50\x12\x42\x72\x57\x2a\xf8\x34\x87\xe0\x3b\xbc\x4b\x19\x35\x28\x19\x40\xc9\x0d\x82\x75\x01\xb6\x18\x40\x96\xff\x76\xda\x63\x15\xf1\x09\x1b\xd9\x2a\xe7\xd9\xf5\xd3\xbc\x54\x77\xa0\xed\x21\xf0\x68\xfc\x47\x17\xf0\xbf\x34\x13\x79\xce\x98\x37\x4a\x13\xb4\x1e\x37\x68\x03\x81\x04\x8b\x3d\x94\xd2\x18\x08\xee\x2d\x5f\x7e\xea\xbd\xb3\x2b\xb3\x7d\x22\x70\x1c\x9f\x71\xb5\x85\x02\x43\x8f\x68\x21\x29\xb0\x94\x1d\xe1\x6b\x49\x2a\x49\x20\x8d\x47\x59\x6d\x41\xdb\xd2\x63\x83\x36\xbc\xc8\xa7\x57\xda\x44\xd4\x48\x4c\x21\xb4\x68\x2b\x6d\x57\x91\x29\xbd\x47\xf5\x48\x2d\x8f\x25\xea\x0d\x56\x50\x7b\xd7\x44\x1c\x2e\x9b\x45\x13\xa1\x2d\x47\xed\x08\x2a\x7c\x83\xc6\x4e\xb3\x6b\x44\x50\x21\xb4\x74\x91\xe7\xef\xb6\x8f\x26\xea\x90\xf2\x5f\x3e\x7c\xcc\x9e\xba\x68\x6c\x8b\x57\x9a\x68\xf8\x4b\x85\xa8\x3b\x5b\xbe\x92\x50\x42\x30\x9a\xa6\xf0\x20\x26\x6f\x64\x9c\xd0\x0c\x6a\x69\x08\x53\xf1\x28\x06\xb2\xc7\x8a\x68\x02\xa3\xd7\x78\x70\x3f\x83\xa2\x0b\x50\x3b\x0f\xad\x77\xb5\x36\x51\x58\x67\x03\xda\x0a\x2b\x88\x5e\x48\x9c\xfb\x70\x3e\xb0\xd2\x14\xb5\xa5\xae\xe5\x59\xc2\x6a\x06\xe4\xe0\xbe\xa3\x00\x5c\xee\x28\x9e\x6c\x10\x74\xd3\x9a\xa8\xa8\x0c\xda\x59\x90\xf4\x4a\x76\x11\xff\xe6\xdb\xe7\x6f\x17\x70\x65\x37\x48\x41\xaf\x64\x60\x0c\x4d\x19\x5c\xd5\xa0\xc3\x8f\x04\xad\x23\xd2\x85\x41\xae\xf8\x0e\x74\xc6\x64\x49\x57\xe8\xa1\x72\xcc\x8a\xdc\x0c\x5c\x50\xe8\x7b\xcd\x4d\x87\x8d\xdb\x0c\x40\x50\xba\x86\x3d\xb2\xb7\x24\x1e\x15\x7c\xd2\x79\x06\x46\xd7\x6e\x18\x6b\x96\x5c\xd7\x90\x9c\x10\xcc\xf7\x75\xbc\xa5\x65\x0a\x8b\x05\x9c\xf1\xf3\xa4\x54\x70\x31\x16\xf6\x60\x1f\x4c\xd8\x2f\x02\xb1\xcd\x64\xbf\x49\x6e\x69\x09\x0b\x90\x2d\x37\x73\x72\xb0\x42\x1e\x4a\xf5\x38\x83\x23\xbb\x2c\xcb\x18\xe8\x11\xd0\x10\xbe\x8b\x73\x74\x3d\x83\x52\x45\x3f\x31\x99\xf0\x46\x10\xd1\x6d\x47\x1d\xe6\x0b\x38\x1f\xf8\x1d\x5d\xef\x12\x9a\x54\x68\x30\x60\xb2\x7b\x9d\x01\x8d\x78\x8f\x62\x72\x42\xf3\x39\x37\xd9\x73\x31\xc7\xd9\x3e\xd4\x51\x49\x5b\xb9\xba\xde\x4b\xb9\x2b\xf6\x5f\x71\x09\x0c\xaf\xba\x06\x8b\x58\x61\x95\x3f\x15\x3a\xe3\x28\xa7\xa7\x42\x4c\x7a\x96\xf6\x28\xb9\x58\x0f\x83\x36\xe9\x0f\x4a\xe0\x31\x74\xde\x32\x3d\x31\x96\xa3\xbf\x3d\x5b\xb2\x3b\x9f\xce\x2f\x96\xe2\x85\x70\xfd\xab\x40\xfb\xcc\x47\xe3\x21\x75\xc6\x3d\xd2\xea\x94\x25\x8c\xb1\xc6\x55\xfd\x42\x11\xeb\x82\xae\xb7\xbf\x6b\x0a\x97\x0a\xcb\x75\x42\xfa\x7f\x04\x16\xa6\x0d\x3e\x85\x87\xe7\xe6\xa5\xb4\xd7\xad\xb6\x89\x06\x6d\x43\x1a\x15\x8b\xe3\x1e\x13\x1b\x46\x7b\x9c\xec\x4b\xd7\x6e\xf9\x6b\xc2\x6e\xd9\xe8\xfe\x55\x5a\xf7\xac\xbd\xad\x64\x06\x0d\x26\x29\x23\x7e\xfc\x99\xd1\x78\x62\x02\x34\xda\x18\x4d\x58\x3a\x5b\xc1\x02\xce\xcf\xe2\x6f\x17\xea\x9e\xb2\x2f\xc6\x15\xd2\x64\x5f\x30\x24\xd3\xcf\x32\xe0\x34\xcd\xbe\x62\x9f\xa4\xd9\xa5\x34\x26\x99\xae\x30\xdc\xe8\x86\x6f\xaf\x18\x38\x49\xe1\xe4\x10\x73\xa4\x79\xf5\x34\xa8\x58\x1d\x7c\x90\x46\x92\x41\x79\xd7\x27\x04\x14\xbc\xb6\xab\xd8\x1a\xfb\xb8\x43\x94\x1f\xa2\xcd\x9f\x83\xdb\x6f\xde\x3b\x3f\x8d\xb5\x78\x14\xdf\x03\x00\x00\xff\xff\xaa\x5d\x20\xc4\xdf\x07\x00\x00"), }, "/src/sync/sync_test.go": &vfsgen۰CompressedFileInfo{ name: "sync_test.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 4, 20, 11, 18, 8, 301989298, time.UTC), uncompressedSize: 240, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd2\xd7\x57\xd0\x4e\x2a\xcd\xcc\x49\x51\xc8\x2a\xe6\xe2\x2a\x48\x4c\xce\x4e\x4c\x4f\x55\x28\xae\xcc\x4b\x8e\x2f\x49\x2d\x2e\xe1\xe2\xca\xcc\x2d\xc8\x2f\x2a\x51\xd0\xe0\xe2\x54\x02\x09\x64\xe6\xa5\x2b\x71\x69\x72\x71\xa5\x95\xe6\x25\x2b\x84\xa4\x16\x97\x04\xe4\xe7\xe7\x68\x94\x28\x68\x41\x25\xf5\x42\x34\x15\xaa\xb9\x38\x4b\xf4\x82\xb3\x33\x0b\x34\x34\xb9\x6a\xd1\x94\xba\x3b\x93\xa0\x38\x28\x35\x27\x35\xb1\x38\x95\x48\x1d\xce\xf9\x79\x29\xce\xf9\x05\x95\x78\x95\x03\x02\x00\x00\xff\xff\x93\xcf\x90\x60\xf0\x00\x00\x00"), }, "/src/sync/waitgroup.go": &vfsgen۰CompressedFileInfo{ name: "waitgroup.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 460, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\xd0\xbb\x4e\xc3\x30\x14\x06\xe0\xd9\xe7\x29\x7e\x3a\x54\x0e\x15\xf4\xc2\x86\x1a\x24\x26\x1e\x81\x01\x31\xb8\x8e\x9b\x98\xa6\x4e\x14\x1f\x53\x45\x55\xde\x1d\xd9\x04\x08\xb7\x4c\xd1\xef\xa3\xef\x5c\x96\x4b\x2c\x76\xc1\xd6\x05\x5e\x3c\x51\xab\xf4\x41\x95\x06\xbe\x77\x9a\x88\xfb\xd6\xe0\x51\x59\x7e\xe8\x9a\xd0\xc2\x73\x17\x34\xe3\x4c\x42\x37\xc1\xb1\xe9\x60\x1d\x93\xd0\x15\xd2\xa7\x2b\xe5\xc6\x9a\xf3\x40\x24\x3c\x2b\x36\x6b\x3c\xad\x37\xcf\xbb\x9e\x0d\x09\x6f\x8e\x0a\x40\xb0\x8e\x6f\x36\x34\x10\xed\x83\xd3\x90\xa7\x12\x97\x9f\x4d\x32\xdc\x17\x85\x2c\x4c\xcd\x2a\xea\x59\xec\x76\x2a\xaf\x3f\x1a\x2e\x72\xa4\x37\x12\x76\x8f\x49\xbe\xc5\x2a\x56\x8a\x56\x39\xab\xe5\x2c\x8e\x7f\x0b\x67\x4a\xc5\xf6\x75\xba\xc2\x58\x3f\xcb\x48\x0c\x3f\x8d\x3b\xac\x30\x9f\xa7\xa4\x42\x9e\xc3\xd9\x3a\x99\x63\x80\xa3\x3a\x18\xf9\x6d\xc9\xbf\x94\x3c\x9f\x32\x17\x5f\x8c\xae\x1b\x6f\x64\x8a\xb3\x89\xea\x6c\x1d\x95\xff\xae\x11\x7f\x65\xba\xc2\xef\x61\xa3\xba\xbd\x4a\xd0\x3b\xf1\x16\x00\x00\xff\xff\x7a\x12\x74\x53\xcc\x01\x00\x00"), }, "/src/syscall": &vfsgen۰DirInfo{ name: "syscall", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/syscall/syscall.go": &vfsgen۰CompressedFileInfo{ name: "syscall.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 1346, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x94\x41\x6f\xf3\x36\x0c\x86\xcf\xd6\xaf\x60\x8d\x01\xb1\xf1\xb9\x76\x7b\x0d\x90\x4b\x8b\xa1\xe8\x69\x05\xda\x61\x87\xae\x07\xd9\xa6\x1d\xa6\x0a\x65\x48\x74\x96\x6e\xc8\x7f\x1f\x64\x39\x6d\x92\x02\x1b\xf0\xdd\x0c\x8b\xa4\xf8\xf2\x79\xc5\xaa\x82\x1f\xf5\x48\xa6\x85\x8d\x57\x6a\xd0\xcd\xbb\xee\x11\xfc\x87\x6f\xb4\x31\x4a\xd1\x76\xb0\x4e\x20\x53\x49\x3a\xb2\xd7\x1d\xa6\x4a\x25\x69\x4f\xb2\x1e\xeb\xb2\xb1\xdb\xaa\xb7\xc3\x1a\xdd\xc6\x7f\x7d\x6c\x7c\xaa\x72\xa5\x76\xda\xc1\x5f\xda\x31\x71\xff\xe4\x88\x05\x5b\x58\x41\xa7\x8d\xc7\xe9\xc8\x10\xe3\xdd\xd8\x75\xe8\xe0\xf5\xad\xfe\x10\x54\xaa\x1b\xb9\x01\x62\x92\x2c\x87\x7f\x54\xb2\xf1\xe5\x83\xb1\xb5\x36\xe5\x33\x4a\x96\xfe\xd2\x99\xd1\xaf\xef\x2d\x7b\x6b\x30\x2d\x60\xe3\xcb\x47\x16\x74\xac\xcd\x6f\xf5\x06\x1b\xc9\x42\x7e\x4c\x4d\xa8\x03\x83\x9c\x7d\x5d\x92\xc3\xd5\x0a\x6e\xa6\xb3\x93\xc2\x0f\xa1\x70\x33\x97\xcc\xcb\x7b\x6d\x4c\x96\x1a\xdb\xa7\x05\x78\x71\xc4\xfd\x69\x85\x3c\xe4\x9e\xb4\xbd\x02\x26\xa3\x92\xe4\xa0\x92\x43\x9e\xab\xc3\x2c\x60\x08\x62\xff\x88\xc2\x63\x37\xd4\xc1\xd5\xc5\x24\x42\x1f\xff\xd3\x06\x3a\x67\x5d\x5a\x40\x3a\xa7\x2e\x03\x14\xc1\x2d\x04\x30\x1e\xd8\x0a\xe8\x9d\x26\xa3\x6b\x83\x05\x78\x44\x58\x8b\x0c\x7e\x59\x55\xff\x49\xa7\x36\xb6\xae\xb6\xda\x0b\xba\xaa\xb5\x4d\x35\x93\xf6\xe5\xb6\x4d\x73\x15\xc4\x7c\x83\x26\x6e\xc4\x73\x79\x2f\x76\xe6\x90\xd5\x33\xbd\x49\x68\x6f\x9f\xce\x4e\x61\xb9\x82\x0b\x95\x97\x21\xe1\x4e\xea\xe0\x5b\xe6\xd5\x94\xf9\x3b\xb7\xd8\x11\xcf\x03\xbb\x0c\x2a\x1f\x79\x67\xdf\x31\xfb\xee\x84\x7a\x82\xe5\x50\x46\xc7\x41\x93\x3a\xe7\xa6\x87\x01\xb9\x3d\x61\x5b\x40\x5d\x96\x65\xae\x92\xce\xba\xe8\x9f\xd0\x3a\x71\x8b\xfb\xbb\x0f\xc1\xb3\xc8\xc5\x9f\xbc\xc8\xa3\xc5\x08\x56\x2b\xb8\xbe\x8d\xae\xaa\x1d\xea\xf7\x68\x87\x9f\x74\xd8\xeb\x92\xde\xf2\x1c\xaa\x0a\x5a\xcb\x0b\x81\xd1\x63\x1c\xb7\xe1\x02\x3c\x71\x83\x40\x02\xad\xc5\x48\x1f\xf7\x51\x33\xfd\x8d\xb0\x1d\x8d\x50\xe0\x00\xcd\x5a\x3b\xdd\x08\x3a\xaf\x2e\xdc\x7a\x72\x11\xfd\xb8\x5d\xbe\x85\xc1\x1c\xa9\x8e\x1e\xb3\x01\xe2\x0b\x2f\x9f\x6c\x20\xef\x26\xa4\x55\x05\x6c\xaf\xed\xf0\x19\xf9\xeb\x9e\x24\x6b\x6c\x8b\x40\x2c\x53\xc8\x73\x74\x50\x86\x7b\x92\x17\xa7\x87\x02\x46\x62\x19\xc4\x4d\x61\x79\x01\x37\x05\xdc\x4c\xef\xa3\xaa\xbe\x66\x0a\xe4\xa1\xb1\x03\x61\x0b\x9d\xb3\x5b\x08\xcd\x7b\x38\xee\x1f\xb1\xa0\x77\x96\x5a\x88\xfb\x87\xb8\x0f\xd2\xb3\x38\x04\x59\x23\x38\xd4\xe6\xb8\xa5\x3e\xb3\xc2\x68\x78\x21\x79\x79\x5c\x25\x47\x7e\x7e\x76\x69\x01\x0d\x44\xb7\x12\x4b\xe8\x3d\xf0\xa6\x02\xea\x80\xdb\x69\x0e\x9b\xef\xb8\x3f\xea\x00\xb7\x89\x6c\xa3\x93\x80\xe6\xd7\xae\x8e\x3f\xae\x6f\xd5\x41\xfd\x1b\x00\x00\xff\xff\xa9\xfc\xcd\x86\x42\x05\x00\x00"), }, "/src/syscall/syscall_linux.go": &vfsgen۰FileInfo{ name: "syscall_linux.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x73\x79\x73\x63\x61\x6c\x6c\x0a\x0a\x63\x6f\x6e\x73\x74\x20\x65\x78\x69\x74\x54\x72\x61\x70\x20\x3d\x20\x53\x59\x53\x5f\x45\x58\x49\x54\x5f\x47\x52\x4f\x55\x50\x0a"), }, "/src/syscall/syscall_nonlinux.go": &vfsgen۰FileInfo{ name: "syscall_nonlinux.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x2c\x21\x6c\x69\x6e\x75\x78\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x73\x79\x73\x63\x61\x6c\x6c\x0a\x0a\x63\x6f\x6e\x73\x74\x20\x65\x78\x69\x74\x54\x72\x61\x70\x20\x3d\x20\x53\x59\x53\x5f\x45\x58\x49\x54\x0a"), }, "/src/syscall/syscall_unix.go": &vfsgen۰CompressedFileInfo{ name: "syscall_unix.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 2931, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x56\x4d\x6f\x1b\x37\x10\x3d\x2f\x7f\xc5\x78\x51\x04\x64\xc4\xae\x3e\xda\x1a\x45\x5d\x1d\x5c\x43\x35\x04\xb8\x71\x10\xc9\x4d\x8b\x20\x30\x28\xed\xac\x4c\x69\x45\xaa\x24\x57\x8e\x90\xe8\xbf\x17\xe4\x72\x2d\x59\xd2\x25\x35\xd0\x4b\x6e\x8b\x9d\x37\x33\x8f\x8f\x8f\x43\xb6\xdb\xd0\x9a\x54\xb2\xcc\x61\x6e\xf9\xd9\xa3\x54\xb9\x7e\xb4\x84\xac\xc4\x74\x21\x66\x08\x76\x63\xa7\xa2\x2c\x09\x91\xcb\x95\x36\x0e\x28\x49\x52\x53\x29\x27\x97\x98\x92\x24\xad\x94\x15\x05\xa6\x84\x24\xe9\x4c\xba\x87\x6a\x92\x4d\xf5\xb2\x3d\xd3\xab\x07\x34\x73\xbb\xfb\x98\xdb\x94\x30\x42\x8a\x4a\x4d\x21\xa6\xdf\xa3\x5a\x5b\xca\xe0\xc3\x47\xeb\x8c\x54\x33\xf8\x4c\x92\x95\xd1\x53\xb4\x16\x7e\xe9\xc3\xdc\x66\xd7\xa5\x9e\x88\x32\xbb\x46\x47\xd3\x18\x49\x19\x49\x64\x01\x0d\xae\x1f\x70\x77\x2a\xc7\x42\x2a\xcc\x7d\x89\xc4\xa0\xab\x8c\x02\x25\x4b\x92\x6c\x49\x32\xb7\x03\xb5\xf6\x05\x63\x4e\x5d\x0e\xd5\xda\x97\x42\xb5\x5e\xe0\xe6\x54\xbf\xdb\xc9\x1c\xa7\x2e\x65\xd9\x95\x28\x4b\x9a\x7a\x54\xca\x21\x14\xab\xf3\x42\xd2\x52\x2c\x90\x36\x0b\xe0\x10\xcb\x65\x37\xa8\x66\xee\x81\x32\x46\x92\x42\x1b\x90\x1e\xda\xb9\x00\x09\xbf\x1e\x41\x2e\x40\xb6\x5a\x81\xf7\x02\x37\x1e\xd7\x00\x86\x2a\xc7\x4f\x54\xb2\x6c\x14\x8a\x53\x46\x92\xd0\xf6\x83\xfc\x08\x7d\xf0\xe0\x16\xa4\xfd\x14\x5a\x35\xa9\xc0\x7a\x81\x9b\x7d\xfc\x96\x34\x62\xf8\x44\xb2\x8d\xfa\x5b\x74\xa8\xd6\xf7\x53\xba\xe0\xb0\x86\x9a\x3b\xfb\x2f\xea\x9f\x9d\x50\xff\x58\xe5\x6c\xe4\x99\x71\x58\x07\x46\x5b\x42\xd6\xc2\x34\xb6\xfa\x43\xe7\x55\x89\xf0\x7a\x6e\xb3\x5a\xf0\x10\x14\xa5\x41\x91\x6f\xc6\x46\x62\x3e\xd6\x37\x5a\xe4\xd0\x87\x42\x94\x16\x43\x78\x29\x55\x65\x6f\x15\x42\x1f\xbe\xef\x36\x6b\xaa\xeb\x51\x25\x96\xf8\xb4\xa4\x5d\x59\x4f\x2d\xc7\x02\x0d\x78\x34\x65\xd1\x28\x53\xbd\x46\x13\x94\x6d\xb7\x61\xe7\x1b\x90\x05\xc4\x20\xe6\x24\xd9\xd2\x7a\xd9\xcf\x39\xf7\xfb\x01\xea\x0b\xc9\xe2\x14\x65\x1f\x79\x66\x46\xbf\x1f\xc9\xc9\xb5\x39\x53\x61\x20\xf4\x4f\x25\x0d\x9e\xd0\x3f\x46\xbc\xfe\x49\x20\x57\x03\x4f\xd9\x3f\x59\x09\x25\xa7\x34\x0d\x58\xdf\xf1\x80\x76\x93\x9c\x0d\xd5\x5a\x2f\x90\xa6\x31\x9e\x3e\x33\xcc\xb3\xa4\xc0\xc1\x2b\xcb\x9e\x3c\x34\x8a\x7a\x3b\x23\x56\x1c\x44\x97\x83\xe8\x71\x10\x3f\x40\x25\x95\x5b\x39\xc3\x80\x9a\x2e\x07\xd3\x6b\x7e\x70\x40\x63\x60\x60\x8c\xd2\x41\x7d\x59\x40\xe1\x17\xda\x6c\x5c\x3a\x6a\x68\x5c\x40\xe1\x9d\xd5\x88\x6b\x3c\xaa\x68\xd8\x1e\xf6\x63\xbb\x03\x1f\x1b\x51\x13\x8f\x4e\x87\x65\x43\xe5\x28\x63\xfc\x28\xd4\xdd\x85\x02\xa3\xa7\x40\xaf\x09\x04\x2d\x64\x01\xbe\x9f\x97\x79\xf4\xf7\xe8\xfe\xfd\xbb\xe1\x78\x00\xaf\x5e\x01\x15\x5d\xff\xaf\x0b\x5f\xbe\x40\xfd\xd9\xab\x1d\x25\x8c\x11\x9b\xb8\x7d\x43\xe5\xd0\x28\x51\xd6\x06\xa4\xa2\xe7\xa9\xda\x52\x4e\x71\x6f\x70\x4c\x36\x0e\x39\x84\xb4\xfd\xa1\x91\x1c\xe7\x87\xcc\xfa\x2c\xa5\xdf\x85\x84\x34\x26\xb2\x70\xea\xa4\x72\x63\x7d\xa5\x95\xd5\x25\x46\xf0\xb1\x34\x07\x8d\x38\x74\x38\x74\x0e\x97\x8a\x9f\xa4\x1b\xfb\xef\xa0\x7e\x3d\xab\xb3\x6b\xed\x7f\xc7\xa1\x12\xba\xbd\x17\x46\xc5\x39\x73\xd0\xa5\x39\x9f\x75\xfd\xc1\xe5\xd5\xd5\x60\x74\x68\x9c\xf3\xa3\x9d\xe4\x20\x7e\xe4\x20\x7e\xe2\x20\xce\x5f\xec\xa2\xf3\xaf\xb4\xd1\x7e\xf3\xff\xc5\x52\x67\x7d\xe8\x75\x7a\xf0\x19\xda\x6d\x58\xa0\x51\x99\xb6\x06\x4b\x14\x16\x41\x2b\xb8\x1d\xc1\x5f\x1c\x1e\xc4\x6a\x85\xca\x82\x54\x20\x95\x74\xa0\x0b\x48\xb5\x4d\x21\x5e\xcd\xcd\xb6\xef\x6d\xc4\xf6\xeb\xf6\xe2\x9d\x78\xfc\x26\xce\xf1\x4b\xfc\xba\xd3\xe8\x5b\xb5\xec\x4b\xd4\xfb\x6d\xe3\xf0\xad\x33\xbf\x1b\xbd\x8c\xcf\x12\xfb\x74\x3b\xd3\xd7\xf5\xf4\x43\x63\xb4\x09\xd2\xec\x8f\xcf\xfd\xdb\xef\x4e\x2a\xf7\xf3\x65\x98\x79\x2c\x7b\x83\x8f\xb4\x44\x45\x2d\x83\x16\x74\x9b\x17\x16\x87\x89\x4f\x34\x42\xcd\x10\xea\xb9\xea\x11\xf1\x76\x9e\xf8\xb9\xd6\x39\xbc\x91\x39\x0c\x86\x6f\xfe\xbc\xbc\x69\x6e\xe6\x30\x1c\x47\xe8\xe2\xcb\x8b\xc3\xa4\x16\xe0\x20\x50\x37\xe7\xd0\xd9\x69\x51\x2f\x85\xd1\xfa\x35\x9c\xbd\xd5\xd2\x0f\xef\x38\x6e\xef\xc2\x4f\xca\xbc\xce\xfe\x1d\xb0\x25\xff\x06\x00\x00\xff\xff\xe5\xb9\x3d\x4c\x73\x0b\x00\x00"), }, "/src/syscall/syscall_windows.go": &vfsgen۰CompressedFileInfo{ name: "syscall_windows.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), uncompressedSize: 2363, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x95\x5f\x6f\xdb\x36\x10\xc0\x9f\xa3\x4f\x71\xf0\xc3\x40\x7a\x5c\x1c\xb9\x4b\x96\x14\xf0\x43\x10\xbb\xe9\x00\x77\x29\x12\x17\x05\x56\x14\xc5\x49\x3c\xcb\x6c\x29\x52\x20\x29\xa3\x4e\x9a\xef\x3e\x50\x7f\x6c\x67\x49\x81\x0d\x1d\x82\xbd\x48\xe4\xdd\xf1\xee\x77\x7f\x44\x8d\x46\xf0\x73\x56\x2b\x2d\xe1\xb3\x4f\x92\x0a\xf3\x2f\x58\x10\xf8\x8d\xcf\x51\xeb\x24\x51\x65\x65\x5d\x80\x81\xab\x4d\x50\x25\x0d\x92\x64\x8d\x0e\x4a\x65\x6a\x7f\x65\x08\x26\xf0\x4b\x9a\x24\xcb\xda\xe4\x70\xd3\x1e\x61\xc1\x61\x25\xc0\xa0\x2b\xbc\x00\x4c\x05\xe0\x58\x00\xbe\x80\x5a\x99\x50\x05\xc7\x81\xb9\x54\x80\x1b\xf7\x02\x01\xe4\x1c\xcc\x9c\x33\x96\xc3\x5d\x72\x50\x39\x65\xc2\x7b\x74\x46\x99\x82\xf1\xe4\xc0\x51\xa8\x9d\xe9\xad\x59\x1f\x9a\x0b\x38\x12\x30\x3b\xbf\xb8\x98\xdd\x24\xf7\x0f\x19\x4e\xbe\x07\x21\x00\x7f\x15\x80\xc7\x02\xf0\xe4\x39\x81\xce\xfe\x09\x90\x00\xfc\x4d\x00\x9e\x0a\xc0\xb3\xe7\x84\x4b\xc7\xff\x96\x2e\xda\x1c\xc5\x47\xb4\x4c\xc7\xcf\x0a\x7b\xfc\x83\xb0\xf1\x11\x6d\xd3\x68\x9c\x1e\x3f\x0b\xbb\xb6\x28\xb5\xca\x1c\xba\x0d\x5b\x2a\x4d\x06\x4b\x82\x61\x3c\x9a\x9e\x70\x60\x2b\x34\x52\xd3\x8f\x07\xfe\x5b\xd4\x82\x42\xe5\x6c\x8e\x52\x3a\xf2\xfe\x51\x94\xa8\xdb\x81\x9c\x72\x60\x51\xf2\x9f\x53\x30\x09\xc3\x39\xde\x6e\xa6\xf3\x39\x87\xb9\x45\xc9\x78\x74\x6d\x5d\xf4\xda\x79\xf9\x69\x3a\x9f\xcf\xa2\xec\xee\x8d\x2f\x5e\xc2\xc0\x6f\x7c\xa0\x12\x62\xbf\x3d\x18\x1b\x00\xd7\xa8\x34\x66\x9a\x04\x78\x22\x58\x85\x50\xf9\x97\xa3\x51\xa1\xc2\xaa\xce\x0e\x73\x5b\x8e\x0a\x5b\xad\xc8\x7d\xf6\xbb\x45\xa6\x6d\x36\x2a\xd1\x07\x72\x23\x69\xf3\x51\x77\xa5\xf9\xc3\x52\x0e\xee\x77\x78\x55\x8b\xf7\xd6\xd9\x9c\xc3\x2b\x65\xfe\x67\x7c\x05\x85\x9b\x20\x5f\x37\xbd\x63\x2b\x50\x26\x70\x60\x4b\x09\xad\xa4\x69\x8d\x5a\xc2\x0a\x26\x13\xb8\x59\x4c\x3f\x5d\xbd\x5b\xbc\x7d\xb7\xf8\xf4\xfa\xfc\x8f\xe9\x7c\x16\x95\x7d\x0a\x69\x72\x70\xff\xd0\x74\x76\x7d\x7d\x75\xfd\x84\xe5\xb8\xb1\xec\x36\x47\x5b\x90\x4b\x0a\x17\xd6\x78\xab\xe9\x8d\x95\xc4\xf2\x76\xdd\x71\x08\x28\xad\xec\x26\xe9\xc5\x98\x03\x8b\xc3\xd3\x54\x91\xef\x95\x71\x5a\x97\xe5\xa6\xad\xe3\x2e\xc1\xf7\x4e\x05\x7a\xa5\x62\x76\xed\x80\xf6\x1e\xb3\x7a\x09\x1f\x3e\x66\x9b\x40\x02\xa4\x35\x5b\xef\x02\xec\x9a\x9c\xc6\xaa\x22\x09\xc3\xab\xed\xfa\x51\xd4\x98\x6c\xeb\x72\x32\x81\x14\xbe\x7d\xdb\xdb\x8e\x9b\x8c\x9b\xa1\x5e\xd8\x2e\x2f\x96\xd5\x4b\x9e\x1c\x1c\x0c\x9b\x68\x13\x68\xc3\x31\x4d\xa6\xd1\xf0\x5d\x89\x8c\xd2\x4d\x91\xbe\xf3\x51\x44\x75\x9f\xde\xec\xab\x0a\x71\xb6\xe2\x17\x48\x5f\x55\xc8\x63\x9d\xfa\x32\xc5\xd2\xb4\xff\xd5\xc3\x4b\x1b\xb5\x8c\x3f\xac\x77\x59\xa2\x91\x73\x65\x88\x71\x60\x79\x29\x77\x97\xc6\xb6\xaa\xdb\x03\x7b\xd6\x0b\x7b\xee\x8a\xf5\xfe\x01\x01\xe8\x8a\x1c\x86\x7d\x7f\xd0\x15\x6b\x18\x7e\x38\x4d\xcf\xc6\x1f\xbb\x57\x6f\xf8\x64\xeb\x8c\xd2\xe2\xe9\xfe\x5d\x52\x20\xb3\x66\x5f\x68\x03\x3e\x38\x65\x0a\x0e\x6c\x8d\xba\xa6\x6e\x2b\x60\x69\x6b\x23\x21\xb3\x56\xef\x7b\x1c\x0c\x04\x2c\x51\x7b\xda\xf7\xb4\x50\x25\xfd\x69\x0d\xfd\x6e\x96\xd6\x95\x18\x94\x35\x2c\xdc\x2a\x18\x46\xc5\xad\x35\xa4\x76\x8a\x78\x63\xe7\xd0\xcf\xc4\x93\xd4\x47\x8f\x99\xc3\xa6\xa2\x3d\x61\x84\xac\xf3\x70\xb7\xbd\x0e\xf6\x95\x1c\x9a\x17\xe3\x5d\x2a\x0f\xe8\x93\xfb\xe4\xaf\x00\x00\x00\xff\xff\x4f\x7e\x0c\x93\x3b\x09\x00\x00"), }, "/src/testing": &vfsgen۰DirInfo{ name: "testing", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/testing/example.go": &vfsgen۰CompressedFileInfo{ name: "example.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 1424, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x54\x5d\x6b\xf3\x36\x14\xbe\x96\x7e\xc5\xa9\x20\x45\x5a\x5d\x85\xdd\x06\x7c\x51\xb6\x06\x0a\xa5\x2b\xcd\x7a\x57\x18\xaa\x73\xec\x6a\xb5\x25\x23\xc9\x49\xc7\x9a\xff\x3e\x74\xec\x7c\x8e\xf7\xe6\xbd\x09\x91\x2c\x3d\xe7\xf9\x38\x47\xf3\x39\xdc\xbc\x0f\xb6\x5d\xc3\xdf\x91\xf3\xde\x54\x9f\xa6\x41\x48\x18\x93\x75\x0d\xe7\xb6\xeb\x7d\x48\x20\x39\x13\x75\x97\x04\x67\xc2\xc7\xfc\x1b\x53\xb0\xae\xa1\xbf\xc9\x76\x28\xb8\xe2\xbc\x1e\x5c\x05\x61\x70\xf7\x5f\xa6\xeb\x5b\x94\xd8\xc0\x83\x4b\x18\x9c\x69\xa7\x2d\x05\xd2\x7f\xc2\xbb\xf7\xad\x82\x7f\x39\xb3\x35\xfc\x52\x7d\x98\x94\xfe\xc9\x2b\x56\x77\x49\x3f\x07\xeb\x52\x2d\x45\x59\x96\xf0\xf2\xfa\x04\x00\xb3\xf8\xe6\x44\x01\xd8\xe8\x27\xd3\xa1\xe2\x6c\xc7\x39\x9b\xcf\xe1\x37\xd3\xa7\x21\x20\xc4\xb4\xf6\x43\xd2\x9c\x8d\x7f\x60\x51\x82\x8f\x7a\x45\x0b\xce\xb6\x05\x60\x08\x79\x33\x61\xd7\x2f\x6d\x8b\x52\x68\x01\x37\x7b\x3c\xb8\x01\xa1\x27\x08\xa1\x88\x52\x3e\x7f\x55\x82\xb3\xed\x81\xd5\xb2\xcf\xb4\x5a\x27\x47\x64\x0c\x81\x60\x15\x67\xcc\x47\x7d\xff\x65\x93\xfc\x95\x98\xb1\x43\x69\x28\x61\xcb\x33\x29\x13\x88\x53\x76\x49\x3f\xf9\xad\x54\x9c\xf9\x4f\x28\x21\x85\x01\x27\x25\x2d\x1a\x07\x43\x0f\xd6\x81\x81\x35\xd6\x18\x02\xae\xa1\x32\x6d\x0b\xd1\xc3\x16\xa1\x32\x0e\x02\x56\x7e\x83\x01\x6c\x0d\xe9\x03\x01\x47\x47\xa1\x37\xce\x56\x51\x73\x46\xf7\x20\x67\x20\xc9\x5c\xb6\x8e\x89\x84\xd7\x5d\xfa\x7d\x08\x26\x59\xef\xe4\x91\x85\x5e\x0d\xef\x92\xd8\x29\xc5\x39\x1b\x79\xf8\x88\x50\xdb\x16\x0b\x08\x18\x93\x3f\xb8\x5b\x40\x83\x09\xfc\x90\x7a\x72\x9a\x6d\x35\x9d\x95\x93\x01\x07\xc5\x71\x72\x9d\xd1\x9d\x80\x66\x9d\x1d\xbf\x1f\x03\xd8\x2f\xe5\x96\x9c\x97\x2a\xdf\xfe\x0b\x28\xae\x17\xec\xfc\xe6\xfc\x8b\xad\xcf\x00\x4e\x12\x39\x89\xa4\x3e\x4d\x44\x4c\x5d\xbb\xa0\x8b\xd6\x35\x13\x1f\x92\xb4\x80\xd9\x86\x1a\xe9\x04\x34\x97\x39\x0b\x90\x7a\x8b\x6d\x4c\x80\xda\xd8\x16\xc6\x26\xe7\x8c\xe1\x5e\x01\x45\x40\xb2\x1b\x4f\xb1\x4e\x73\xa0\xff\x0c\xb6\x5b\xf5\xa6\x42\xe9\x87\x94\xbf\x6f\x8d\xfb\xc1\x01\x6c\xf4\x1f\xe4\xe4\xa4\x12\x1b\xfd\xea\x7c\x58\x63\x0e\x9d\xf4\xd9\x1a\xa2\x0f\xe9\xd1\x3a\x8c\xb2\xf1\x49\x65\xf5\xc7\x9d\x0c\xad\xe0\xfa\x9a\x3a\xb5\x3c\xf1\x85\x11\x6b\x4a\x5c\xaf\x26\x7f\x44\xe3\xd3\xe2\xcd\xe5\x29\x22\x4a\x72\xd8\xd7\x52\xd3\xb6\x28\x80\xe2\x3a\xe3\x95\x7b\x99\xed\x00\xdb\x88\x07\x4e\x59\xf2\x55\x09\x04\xf3\x73\xd5\x8f\x15\x1b\x9f\x0a\x42\x3a\x16\x1b\xdd\x20\x90\xab\x12\x84\x80\xef\xef\xcb\x59\x3c\x7b\x22\x6e\x6f\x6f\x61\x79\xf7\xf0\xb8\x80\x59\x04\x39\x8b\x2a\x83\x1f\x5f\x8a\x02\xf2\x00\x14\x04\x38\x06\x9d\xa7\xae\x36\x6d\xc4\xa3\xb4\x8b\x17\xe8\x7f\xf8\xcf\x77\xab\xd5\x09\xfe\x25\xba\x3a\xf2\xbe\x64\x4a\x73\x29\xa7\x47\x62\xc7\xd9\x4e\xaa\x71\xda\x5f\x06\xb7\x1f\x5e\xcd\x19\x36\x7a\x99\xfb\x29\x60\x1a\x82\xe3\x3b\xfe\x5f\x00\x00\x00\xff\xff\x6d\xa8\x39\x72\x90\x05\x00\x00"), }, "/src/testing/ioutil.go": &vfsgen۰CompressedFileInfo{ name: "ioutil.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 1163, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x53\x61\x6f\x23\x35\x10\xfd\x6c\xff\x8a\x21\x12\xc8\xbe\x8d\x36\xbb\x69\x2f\x52\x7b\x04\xe9\xc8\x05\x74\x52\x29\x28\x6d\x05\x12\x42\x95\xb3\x3b\x2e\x43\x37\xf6\xca\xf6\x96\x44\xd0\xff\x8e\x6c\x6f\xb7\x94\x4f\x7c\x48\x76\x3c\x9e\x7d\xf3\xe6\xcd\xdb\xc5\x02\x8a\xfd\x40\x5d\x0b\x7f\x78\xce\x7b\xd5\x3c\xaa\x07\x84\x80\x3e\x90\x79\xe0\x9c\x0e\xbd\x75\x01\x04\x67\xb3\xfd\x29\xa0\x9f\x71\x36\x23\x1b\xff\x6d\x8a\x7d\x70\x8d\x35\x4f\x29\x3c\x99\x26\x3e\x03\x1d\x70\xc6\x25\xe7\x4f\xca\x81\x53\xa6\x85\x81\x4c\x38\x5b\x4e\xe7\xc3\x00\xb1\xb6\xfc\x61\x08\x78\xe4\x5c\x0f\xa6\x01\x87\x1e\xb1\x15\x72\xac\x85\xbf\x38\x73\x18\x06\x67\xc6\x84\x88\xa8\xe5\xb5\xfd\x53\xc8\xf2\xce\xd0\xf1\x5a\x19\x2b\x24\x14\x40\x26\xac\xce\x85\xf5\xe5\xf7\x18\x7a\x6a\x85\x94\x92\x3f\x8f\xa0\x06\x8f\xe1\x66\xd0\x9a\x8e\x42\x82\x0f\x8e\xcc\x43\x02\x4e\x1c\xca\x2b\xdb\x3c\x0a\xc9\x99\x83\xcb\x75\xe2\xc5\x19\x69\x70\xb0\x5e\x43\x15\xcb\x98\x83\xf5\xc4\x8b\xb3\x67\x9e\x13\xef\xea\xd5\xea\xfc\xfd\xf2\x3d\x14\x50\x57\xf5\xd9\x45\x75\xbe\x5c\x9e\xc1\x62\x01\x8d\x35\x3e\x28\x13\x3c\x68\x67\x0f\x70\x3d\x1c\xd0\x51\xa3\x3a\xd8\x61\x43\x3d\xfa\xdc\x38\x42\x4c\x14\xee\x4c\xf7\x42\x22\x0f\x3b\xca\x59\x7e\x0e\x56\x09\x32\x41\xd4\x78\x01\x05\xb8\x2f\x6b\xbc\x90\xf2\xd7\xfa\xf2\xb7\x38\xdc\x62\x01\x1f\x21\x4e\x18\xc8\x1a\xd5\x41\x63\xfb\x13\x58\x0d\x64\x87\x40\x5d\x79\x8b\x87\xfe\x3b\xea\x70\x0e\xc1\x82\x7a\xb2\xd4\x02\x1e\x83\x53\x90\x97\xe9\xcb\xac\x4e\x18\xcb\x44\xef\x50\xd3\x71\x14\x48\x82\xd0\xf0\xce\xfa\x32\x23\xa0\x73\xf1\x67\x9d\x8c\x92\xb4\x94\xc4\xb2\x3e\xf5\xf8\x44\x4e\x48\xce\x99\x69\xac\xd1\x1d\x35\x21\xde\x55\x9c\x69\xeb\x80\x52\xfc\x01\x08\xbe\x86\xba\xaa\xaa\x18\x16\x45\x92\xd5\xa8\x03\xc6\xdb\x08\x56\x8c\x5d\xe3\x02\x7f\x52\xe1\xf7\x1b\xec\x95\x53\x21\xb6\x2b\x60\xe4\x55\xbc\xd9\x23\x67\x4c\x67\x5a\x89\xc7\x8f\x3d\x9a\x34\x44\x44\x9d\xa7\xcc\xfd\xee\xd3\xcf\xbb\xbf\x53\xb4\xd9\x6d\x3f\xde\x6e\x73\xbc\xfd\x65\x73\x35\x87\x6a\x55\x55\x11\x83\x74\xac\xfd\xec\xb7\x47\xf2\x41\xa0\xcb\xf3\xa5\xfc\x34\x4e\x51\x7c\x78\x3d\xc0\x37\x50\x67\x5b\xb0\xff\x1a\x68\xcc\xbc\x71\xcb\x6b\xd5\xeb\x8e\x59\xf4\x10\x63\x8d\x35\x81\xcc\x80\x3c\x9f\xf7\x0e\xd5\x63\xb6\x57\xf2\xc0\xe4\x5e\x87\xaa\x4d\xa3\x69\xea\x30\x89\x36\x6d\x28\x07\xf3\x7f\x6d\x66\xd4\xe4\x72\x12\x65\x7a\x4b\x26\x5b\xc7\xcb\x2f\xd6\x60\xa8\xcb\xd6\xce\x76\x9b\xcd\xd2\x6b\xa9\x7b\x8b\x1a\x1d\xe8\x72\xd3\x59\x8f\x91\x6e\xfc\x5c\xf7\x83\x86\xf4\xdd\x97\xdf\x0e\x5a\xa3\xe3\xec\xfe\x45\x7c\xb2\xe5\xc6\xf6\x27\xf1\xd5\x7e\xd0\x73\xd0\xff\xb7\xcd\x98\xda\x0f\xba\xbc\xc9\xab\x97\xf3\x58\xcf\x9f\xf9\x3f\x01\x00\x00\xff\xff\x2f\x92\x73\x9b\x8b\x04\x00\x00"), }, "/src/testing/testing.go": &vfsgen۰CompressedFileInfo{ name: "testing.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 586, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x91\xcd\x6e\xd4\x50\x0c\x85\xd7\xbd\x4f\x71\xd4\x0d\x2d\x8c\x92\x3d\x42\x6c\x40\xe2\x67\x41\x17\x6d\x1f\xc0\x93\x38\x13\x33\xb9\xbe\xc1\xf6\x65\x04\xa8\xef\x8e\xee\x00\x22\x1a\xb1\x64\xef\xf3\xf9\x3b\x76\xdf\xe3\xc5\xbe\xca\x32\xe2\xb3\xa7\xb4\xd2\x70\xa4\x03\x23\xd8\x43\xf4\x90\x52\xdf\xe3\x61\x66\xd4\xd5\xc3\x98\x32\x06\x5a\x16\xb6\x4f\x94\x19\xa4\x23\x26\xa3\xcc\xf7\x47\x59\x61\xbc\x7c\x43\x51\x58\xd5\x90\xcc\xdd\x9b\xf3\xa0\xef\x1a\xa1\x4d\xae\xa4\x32\x40\x26\xc4\xcc\xc6\x20\x63\x7c\x67\x2b\xbf\x81\x8e\xa9\x54\x1d\x3b\xbc\x2f\x27\xfe\xca\xb6\xbb\xe4\x34\x8c\x38\xb4\x04\x24\xaf\x0b\x67\xd6\xe0\x11\x53\x31\xbc\x2b\xeb\xcc\xf6\xf1\x1e\x14\x88\x59\x1c\x2d\xb7\x83\x17\x9c\x18\x03\xe9\xb3\x40\x75\x6e\x80\x98\x69\x13\xa7\x90\xa2\x1d\x1e\x9d\x9b\x93\x33\x3c\xea\xde\x21\xea\xc1\x34\x76\x69\xaa\x3a\x6c\xfa\xde\x78\xab\x29\x1a\xb7\xf0\x30\xd1\x03\x7e\xa4\xab\xbe\xc7\xe3\x3f\x4e\x63\xfc\xa5\x8a\xb1\x83\xd0\x28\x6d\x11\x2d\x97\x95\xba\x73\xfc\xe1\xee\xed\xdd\x4b\x7c\xf8\x23\xd5\x2e\xb4\x16\x77\xd9\x2f\xdc\xa5\x2b\xe3\xa8\xa6\xb8\x7e\x55\xf5\xa8\xe5\xa4\xaf\xaf\xd3\xd3\x2f\xb1\x9b\xe7\x43\xc9\xb9\xe8\xed\xdf\x1f\x6c\x0c\x45\xe3\x52\x6f\xfb\xaa\xff\x6b\xd7\xd6\xa6\xa7\xf4\x33\x00\x00\xff\xff\xa2\x55\xb0\x30\x4a\x02\x00\x00"), }, "/src/text": &vfsgen۰DirInfo{ name: "text", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), }, "/src/text/template": &vfsgen۰DirInfo{ name: "template", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/text/template/template.go": &vfsgen۰FileInfo{ name: "template.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x74\x65\x6d\x70\x6c\x61\x74\x65\x0a\x0a\x63\x6f\x6e\x73\x74\x20\x6d\x61\x78\x45\x78\x65\x63\x44\x65\x70\x74\x68\x20\x3d\x20\x33\x30\x30\x30\x0a"), }, "/src/time": &vfsgen۰DirInfo{ name: "time", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), }, "/src/time/time.go": &vfsgen۰CompressedFileInfo{ name: "time.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 222527579, time.UTC), + modTime: time.Date(2018, 7, 2, 16, 18, 2, 112920712, time.UTC), uncompressedSize: 2155, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x55\xdf\x6f\xdb\x36\x10\x7e\x26\xff\x8a\x9b\xb0\x21\x64\xa3\x48\xf9\x51\x64\x58\x10\x0f\xd8\x92\x35\x08\xd0\xd4\xc0\x92\xbe\xac\x28\x06\x9a\x3a\xd9\x74\x64\x52\x20\xa9\x38\x8e\xeb\xff\x7d\x20\x29\x2b\x76\xbb\x15\x98\x9e\xc4\xe3\xf1\xee\xfb\x3e\x1e\xef\xca\x12\x0e\x27\x9d\x6a\x2a\x98\x3b\x4a\x5b\x21\x1f\xc5\x14\xc1\xab\x05\x52\xaa\x16\xad\xb1\x1e\x18\x25\x99\xed\x74\xb0\x65\x94\x92\x6c\xaa\xfc\xac\x9b\x14\xd2\x2c\xca\xa9\x69\x67\x68\xe7\xee\xf5\x67\xee\x32\xca\x29\x2d\x4b\xb8\x13\x8f\x08\xae\xb3\x29\x5a\xf1\x51\xab\x67\xa8\x3b\x2d\x41\xe8\x2a\x99\x1e\xd4\x02\xc1\x79\xdb\x49\x0f\xca\x83\x45\xdf\x59\xed\x40\x58\x04\xd1\x2c\xc5\xca\x81\xd2\xb2\xe9\x2a\xac\x60\xa9\xfc\x0c\xfc\x4c\x39\xd8\x42\x64\x15\xba\x56\x79\x84\xeb\xab\x3f\x78\x1e\x12\x4e\x50\x8a\xce\x21\xf8\x19\xae\x0e\x2c\x82\x46\x0c\x47\x6b\x63\x41\x69\x8f\x56\x8b\x46\xbd\x08\xaf\x8c\x2e\xf1\x79\x6f\x0d\xa6\x7e\x45\x54\x5e\x0b\x8f\x05\xdc\x23\x82\x72\xae\x43\x98\x79\xdf\xba\x8b\xb2\xfc\x2e\xef\xe8\xea\xca\xd3\x9f\x7f\x29\x68\x64\xa9\xb4\xf2\x8c\xc3\x9a\x92\xb2\x04\xf1\x64\x54\x05\x15\x8a\x0a\xa4\xa9\x10\xb0\x51\x0b\xa5\x63\x6e\x4a\x9e\x84\x85\xbf\x21\x8a\x31\x82\x20\x13\x3b\xce\xe1\x98\xd3\x0d\xa5\x7e\xd5\x22\xf4\xda\x07\x07\xbb\x95\x6b\x4d\x89\x82\xf4\x29\xed\xcf\x4e\x29\x59\xce\x50\xf7\xcb\xf3\xb7\x94\xb4\x68\x95\xa9\x86\x65\xdd\x3b\x07\x68\x2c\xaa\x51\x0b\x89\xeb\x4d\x0e\x9d\xd2\xbe\xf5\x96\x53\x22\xec\x74\x1b\x70\xbb\x4d\x49\xc8\x6c\x3a\x0f\x6f\xe6\xae\x18\x4f\xe6\x28\x3d\x25\x42\x7a\xf5\x84\x00\x13\x63\x9a\x80\x72\xe0\xfb\xde\x48\xd1\x24\xd2\x15\x5c\x8c\x60\xee\x8a\x9b\xc6\x4c\x44\x53\xdc\xa0\x67\x59\x10\x36\xe3\xc5\x07\x5c\x32\x4e\x89\x0b\x1e\x55\x71\xef\xad\xd2\xd3\x60\x50\xc1\xa0\x74\x85\xcf\xbf\xaf\x3c\x32\x97\xc3\x01\x3b\xe0\x94\xcc\xbf\xb5\xf3\x60\x57\x35\x28\x18\x8d\xe0\xe8\x04\xbe\x7c\x81\x79\xff\xbb\xa6\x84\x34\x01\xc7\x7b\x23\x0b\x2d\xa2\xa8\xd9\xc7\x87\xab\x8c\x12\x92\x2a\x8c\x92\x0d\xfd\xc6\xc5\x7d\x52\x87\x27\x70\x01\xf3\xcf\x3b\x7b\x2f\x46\x87\xbd\x4f\x9f\xc3\xcf\x7a\xbd\x77\x26\x87\xaa\xb8\x12\x4d\xc3\xb2\x29\xfa\x70\x37\xc1\x67\x5c\xd7\x0e\x7d\xc6\x8b\x5b\x1d\x2e\xff\x0d\x1c\x9d\x1f\xe7\x50\x8b\xc6\xe1\x66\x33\x48\xd5\x5f\xe8\x07\xa1\x0d\xe3\xe9\x86\x02\xec\x84\xee\x7b\xa2\xed\x27\x4c\x69\xce\xdf\xc6\x44\x31\x0a\xbb\x53\x4d\xa3\x1c\x4a\xa3\x2b\x3e\xa4\xd3\x66\xc9\x38\x30\x87\x32\x79\xe5\xa0\xfb\xff\xb3\xd3\x1c\x16\x46\x9b\x64\x8f\xf7\xa6\x83\xd8\x7b\x00\x07\x60\x1a\xca\x3e\xcd\x7d\xca\x90\xa7\x18\x4c\xc3\x4f\xfb\x1b\x3c\x07\x3d\xa4\xbf\x6f\x10\x5b\x56\xc1\x75\x67\x63\xc1\xc7\x34\x32\xa4\x59\x88\x47\x64\x72\x26\x74\x5f\xd5\xeb\x4d\xb8\xed\x81\x7e\x22\xfb\xa3\x4b\x6c\x4d\xe7\xb3\x3c\x88\x73\xdb\xbf\xe5\x54\x8d\x2c\x56\x34\x87\x35\xc8\xc6\x38\x64\x92\xc3\x26\x01\x63\x55\xb9\x2b\x07\xa7\xe4\xf2\x48\x0e\xa8\x9c\x17\x36\xc6\xb5\xcc\xc3\x9b\xdd\x27\x16\xf1\xf9\xa2\x2f\xf2\x11\x78\xdb\x21\x25\x95\xaa\xeb\x80\x99\xf9\x22\xbe\xb4\xa3\x7d\x91\xf8\xa0\xcd\xde\x15\x84\x1a\x8d\x27\x7f\x85\x93\xcb\xcb\xb3\x93\x50\x9f\x50\x96\xb0\x10\x7e\x56\xdc\x89\xe7\xdb\xf4\x76\x77\x0b\x73\x7b\xe2\x12\x8e\x63\x2d\xc7\xc5\x08\x8e\xe3\xa6\x2f\xb6\xef\x71\xf7\x71\xfd\x3f\xa1\x28\xd9\x65\x17\x6b\x93\x92\x90\xd6\x17\x7d\xd3\xf8\x61\xd4\xe7\x26\x3d\xd9\xc3\xd1\xb0\x19\xac\xbb\xda\x71\x4a\x02\x30\x32\x35\xe0\x8b\x9a\xf9\x42\xd8\x69\xec\x5e\x24\x5c\x43\x00\x7f\x78\xc2\x77\x54\x37\xed\x7f\x88\x1e\x9a\x49\x48\xfa\x35\x2d\xd9\xa0\xb0\xaf\xbc\x06\x05\x38\x25\x4b\xe1\x7e\x4b\x3c\x2e\x02\xc0\xc4\x89\xfe\x0b\xbb\xbe\x80\x07\xff\x01\x4f\x6d\xac\xc4\xbf\x54\xfb\x4e\x35\xf8\xce\xd8\x07\x74\x3e\x34\xa3\x17\xd5\x8e\x75\xb3\x8a\x98\x82\x62\x1b\x4a\x43\x93\x0e\x2f\xfc\xde\x74\x56\xa2\x8b\x5d\xc1\xc5\xd6\x15\x5e\x6e\x62\x52\xdc\x8c\xff\x1c\x8f\x1f\x18\x87\x43\xc8\xca\x46\x4d\xca\x60\x2d\xc3\x31\xa5\x6b\x53\xbc\xa8\x36\xcb\x43\xb0\xb2\x7c\xed\x67\xa0\x1c\x48\xd3\xaa\x30\xa9\xac\x59\x40\x0a\xfa\x3a\xe7\xbc\xe9\xa7\x47\x9a\xc6\x4a\x4f\xc3\xac\x64\x4e\x69\x19\x47\x1d\x58\x14\x4d\x9c\x5e\xc3\x91\xca\xa0\xd3\x07\x9e\x0f\x93\x68\x68\x9d\x7d\xf4\x1c\x24\x4c\x56\x1e\x63\xf3\xd9\x6f\x3d\x5f\x15\x8d\xdb\xf6\x9c\x18\x64\x5c\xa7\xca\xda\xed\x4f\xa9\x7f\x67\x5b\xbf\xc0\xe1\x6a\x26\xec\x95\xa9\x30\xcb\x41\xf2\xbe\x17\xd2\x0d\xfd\x27\x00\x00\xff\xff\xbc\xb4\x65\x1c\x6b\x08\x00\x00"), }, "/src/unicode": &vfsgen۰DirInfo{ name: "unicode", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 226527494, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), }, "/src/unicode/unicode.go": &vfsgen۰CompressedFileInfo{ name: "unicode.go", - modTime: time.Date(2018, 4, 3, 19, 31, 7, 226527494, time.UTC), + modTime: time.Date(2016, 9, 24, 10, 23, 48, 431713592, time.UTC), uncompressedSize: 600, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x51\xc1\x8e\xd3\x30\x10\x3d\x7b\xbe\xe2\x9d\xa2\x44\xd9\x25\x5b\x8e\xab\x96\x4b\x91\x40\x08\x2e\xe5\x58\x15\x64\x9c\x49\x63\x70\xec\x68\xe2\x48\xa0\x6d\xff\x1d\xd9\xe9\x46\xdd\xdb\xf8\xcd\x9b\x37\x7e\x6f\x9a\x06\xf5\xaf\xd9\xba\x16\xbf\x27\xa2\x51\x9b\x3f\xfa\xcc\x98\xbd\x35\xa1\x65\xa2\x6e\xf6\x06\x31\x94\x3f\x8d\x9e\x18\xd6\xc7\x07\x08\x64\xf6\xfc\x80\x84\x1c\xb4\x3f\x33\x8e\xa7\xfd\x6b\x5d\xe5\x26\x5e\x48\xd9\x0e\xcb\xd0\x16\x4f\xb8\x5c\xf0\x4d\xff\xdd\xe7\xe7\xee\x86\xbf\x90\x52\xc2\x71\x16\x8f\x03\x8f\x4e\x1b\x1e\xd8\xc7\x7d\xaf\x85\xd4\x95\x94\x0b\x78\xde\xe1\x89\x54\x6f\x53\xe1\xd8\x97\xeb\xc6\x8a\x54\x17\x04\x2e\x60\x8b\xde\x66\xa5\x21\x93\x02\x6a\x94\xbd\x7d\x74\xa1\x6a\xde\x93\x52\x46\x12\x5c\xac\x83\xc7\xe1\x84\xa6\xc1\xc8\xd2\x05\x19\xb4\x37\x0c\x23\x36\x5a\xa3\x1d\x92\xe2\xa7\x30\xf6\x2c\x5f\xbe\x3f\xe3\xcc\x11\xba\x6d\x85\xa7\x09\x3d\x4b\xf2\x3e\x45\xd6\x2d\x42\x07\x13\xc6\x7f\xd6\x9f\x11\x7b\xc6\xea\x9c\x54\xb2\x9c\xdc\x97\x46\xde\x7d\x0d\x55\x72\x2a\x28\x0a\x48\xae\x6e\x8d\xcf\xb6\xca\xff\x55\x2d\xbb\xa8\xd3\xef\x5e\x3b\x1f\x13\x70\xcc\xd9\x9c\xaa\xc4\xb0\x1d\x16\xd2\x87\x14\xde\xe1\x96\xab\x5a\x53\xbb\xdf\x55\xa3\x2c\xe5\xf1\x0e\xa9\x8a\x1f\x1b\x5c\x16\x4e\xd6\x2c\x36\x55\x56\xbd\xd2\x9d\x02\xea\x65\x05\x2d\x78\x32\x80\xed\x1b\xe1\xbc\xb1\xb7\xd8\x61\x48\x24\xb0\xbb\x9d\x2e\x1d\x68\x87\x01\x35\x36\xcb\xf4\x95\x56\x59\xba\xd2\xff\x00\x00\x00\xff\xff\xba\x6a\xe6\xd2\x58\x02\x00\x00"), diff --git a/compiler/prelude/jsmapping.js b/compiler/prelude/jsmapping.js index 0a16a8250..1ef7e540d 100644 --- a/compiler/prelude/jsmapping.js +++ b/compiler/prelude/jsmapping.js @@ -20,7 +20,7 @@ var $needsExternalization = function(t) { } }; -var $externalize = function(v, t) { +var $externalize = function(v, t, makeWrapper) { if (t === $jsObjectPtr) { return v; } @@ -44,12 +44,12 @@ var $externalize = function(v, t) { case $kindArray: if ($needsExternalization(t.elem)) { return $mapArray(v, function(e) { - return $externalize(e, t.elem); + return $externalize(e, t.elem, makeWrapper); }); } return v; case $kindFunc: - return $externalizeFunction(v, t, false); + return $externalizeFunction(v, t, false, makeWrapper); case $kindInterface: if (v === $ifaceNil) { return null; @@ -57,24 +57,24 @@ var $externalize = function(v, t) { if (v.constructor === $jsObjectPtr) { return v.$val.object; } - return $externalize(v.$val, v.constructor); + return $externalize(v.$val, v.constructor, makeWrapper); case $kindMap: var m = {}; var keys = $keys(v); for (var i = 0; i < keys.length; i++) { var entry = v[keys[i]]; - m[$externalize(entry.k, t.key)] = $externalize(entry.v, t.elem); + m[$externalize(entry.k, t.key, makeWrapper)] = $externalize(entry.v, t.elem, makeWrapper); } return m; case $kindPtr: if (v === t.nil) { return null; } - return $externalize(v.$get(), t.elem); + return $externalize(v.$get(), t.elem, makeWrapper); case $kindSlice: if ($needsExternalization(t.elem)) { return $mapArray($sliceToArray(v), function(e) { - return $externalize(e, t.elem); + return $externalize(e, t.elem, makeWrapper); }); } return $sliceToArray(v); @@ -128,20 +128,24 @@ var $externalize = function(v, t) { return o; } + if (makeWrapper !== undefined) { + return makeWrapper(v); + } + o = {}; for (var i = 0; i < t.fields.length; i++) { var f = t.fields[i]; if (!f.exported) { continue; } - o[f.name] = $externalize(v[f.prop], f.typ); + o[f.name] = $externalize(v[f.prop], f.typ, makeWrapper); } return o; } $throwRuntimeError("cannot externalize " + t.string); }; -var $externalizeFunction = function(v, t, passThis) { +var $externalizeFunction = function(v, t, passThis, makeWrapper) { if (v === $throwNilPointerError) { return null; } @@ -154,22 +158,22 @@ var $externalizeFunction = function(v, t, passThis) { var vt = t.params[i].elem, varargs = []; for (var j = i; j < arguments.length; j++) { - varargs.push($internalize(arguments[j], vt)); + varargs.push($internalize(arguments[j], vt, makeWrapper)); } args.push(new t.params[i](varargs)); break; } - args.push($internalize(arguments[i], t.params[i])); + args.push($internalize(arguments[i], t.params[i], makeWrapper)); } var result = v.apply(passThis ? this : undefined, args); switch (t.results.length) { case 0: return; case 1: - return $externalize(result, t.results[0]); + return $externalize($copyIfRequired(result, t.results[0]), t.results[0], makeWrapper); default: for (var i = 0; i < t.results.length; i++) { - result[i] = $externalize(result[i], t.results[i]); + result[i] = $externalize($copyIfRequired(result[i], t.results[i]), t.results[i], makeWrapper); } return result; } @@ -178,7 +182,7 @@ var $externalizeFunction = function(v, t, passThis) { return v.$externalizeWrapper; }; -var $internalize = function(v, t, recv) { +var $internalize = function(v, t, recv, makeWrapper) { if (t === $jsObjectPtr) { return v; } @@ -226,7 +230,7 @@ var $internalize = function(v, t, recv) { $throwRuntimeError("got array with wrong size from JavaScript native"); } return $mapArray(v, function(e) { - return $internalize(e, t.elem); + return $internalize(e, t.elem, makeWrapper); }); case $kindFunc: return function() { @@ -236,21 +240,21 @@ var $internalize = function(v, t, recv) { var vt = t.params[i].elem, varargs = arguments[i]; for (var j = 0; j < varargs.$length; j++) { - args.push($externalize(varargs.$array[varargs.$offset + j], vt)); + args.push($externalize(varargs.$array[varargs.$offset + j], vt, makeWrapper)); } break; } - args.push($externalize(arguments[i], t.params[i])); + args.push($externalize(arguments[i], t.params[i], makeWrapper)); } var result = v.apply(recv, args); switch (t.results.length) { case 0: return; case 1: - return $internalize(result, t.results[0]); + return $internalize(result, t.results[0], makeWrapper); default: for (var i = 0; i < t.results.length; i++) { - result[i] = $internalize(result[i], t.results[i]); + result[i] = $internalize(result[i], t.results[i], makeWrapper); } return result; } @@ -283,7 +287,7 @@ var $internalize = function(v, t, recv) { case Float64Array: return new ($sliceType($Float64))(v); case Array: - return $internalize(v, $sliceType($emptyInterface)); + return $internalize(v, $sliceType($emptyInterface), makeWrapper); case Boolean: return new $Bool(!!v); case Date: @@ -291,37 +295,37 @@ var $internalize = function(v, t, recv) { /* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */ return new $jsObjectPtr(v); } - return new timePkg.Time($internalize(v, timePkg.Time)); + return new timePkg.Time($internalize(v, timePkg.Time, makeWrapper)); case Function: var funcType = $funcType([$sliceType($emptyInterface)], [$jsObjectPtr], true); - return new funcType($internalize(v, funcType)); + return new funcType($internalize(v, funcType, makeWrapper)); case Number: return new $Float64(parseFloat(v)); case String: - return new $String($internalize(v, $String)); + return new $String($internalize(v, $String, makeWrapper)); default: if ($global.Node && v instanceof $global.Node) { return new $jsObjectPtr(v); } var mapType = $mapType($String, $emptyInterface); - return new mapType($internalize(v, mapType)); + return new mapType($internalize(v, mapType, makeWrapper)); } case $kindMap: var m = {}; var keys = $keys(v); for (var i = 0; i < keys.length; i++) { - var k = $internalize(keys[i], t.key); - m[t.key.keyFor(k)] = { k: k, v: $internalize(v[keys[i]], t.elem) }; + var k = $internalize(keys[i], t.key, makeWrapper); + m[t.key.keyFor(k)] = { k: k, v: $internalize(v[keys[i]], t.elem, makeWrapper) }; } return m; case $kindPtr: if (t.elem.kind === $kindStruct) { - return $internalize(v, t.elem); + return $internalize(v, t.elem, makeWrapper); } case $kindSlice: return new t( $mapArray(v, function(e) { - return $internalize(e, t.elem); + return $internalize(e, t.elem, makeWrapper); }) ); case $kindString: @@ -386,3 +390,17 @@ var $isASCII = function(s) { } return true; }; + +var $copyIfRequired = function(v, typ) { + // interface values + if (v.constructor.copy) { + return new v.constructor($clone(v.$val, v.constructor)); + } + // array and struct values + if (typ.copy) { + var clone = typ.zero(); + typ.copy(clone, v); + return clone; + } + return v; +}; diff --git a/compiler/prelude/jspmapping.js b/compiler/prelude/jspmapping.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/compiler/prelude/prelude.go b/compiler/prelude/prelude.go index f28837e7d..20ec3725a 100644 --- a/compiler/prelude/prelude.go +++ b/compiler/prelude/prelude.go @@ -3,4 +3,4 @@ package prelude // Prelude is the GopherJS JavaScript interop layer. -const Prelude = "Error.stackTraceLimit = Infinity;\n\nvar $global, $module;\nif (typeof window !== \"undefined\") {\n /* web page */\n $global = window;\n} else if (typeof self !== \"undefined\") {\n /* web worker */\n $global = self;\n} else if (typeof global !== \"undefined\") {\n /* Node.js */\n $global = global;\n $global.require = require;\n} else {\n /* others (e.g. Nashorn) */\n $global = this;\n}\n\nif ($global === undefined || $global.Array === undefined) {\n throw new Error(\"no global object found\");\n}\nif (typeof module !== \"undefined\") {\n $module = module;\n}\n\nvar $packages = {},\n $idCounter = 0;\nvar $keys = function(m) {\n return m ? Object.keys(m) : [];\n};\nvar $flushConsole = function() {};\nvar $throwRuntimeError; /* set by package \"runtime\" */\nvar $throwNilPointerError = function() {\n $throwRuntimeError(\"invalid memory address or nil pointer dereference\");\n};\nvar $call = function(fn, rcvr, args) {\n return fn.apply(rcvr, args);\n};\nvar $makeFunc = function(fn) {\n return function() {\n return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface);\n };\n};\nvar $unused = function(v) {};\n\nvar $mapArray = function(array, f) {\n var newArray = new array.constructor(array.length);\n for (var i = 0; i < array.length; i++) {\n newArray[i] = f(array[i]);\n }\n return newArray;\n};\n\nvar $methodVal = function(recv, name) {\n var vals = recv.$methodVals || {};\n recv.$methodVals = vals; /* noop for primitives */\n var f = vals[name];\n if (f !== undefined) {\n return f;\n }\n var method = recv[name];\n f = function() {\n $stackDepthOffset--;\n try {\n return method.apply(recv, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n vals[name] = f;\n return f;\n};\n\nvar $methodExpr = function(typ, name) {\n var method = typ.prototype[name];\n if (method.$expr === undefined) {\n method.$expr = function() {\n $stackDepthOffset--;\n try {\n if (typ.wrapped) {\n arguments[0] = new typ(arguments[0]);\n }\n return Function.call.apply(method, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return method.$expr;\n};\n\nvar $ifaceMethodExprs = {};\nvar $ifaceMethodExpr = function(name) {\n var expr = $ifaceMethodExprs[\"$\" + name];\n if (expr === undefined) {\n expr = $ifaceMethodExprs[\"$\" + name] = function() {\n $stackDepthOffset--;\n try {\n return Function.call.apply(arguments[0][name], arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return expr;\n};\n\nvar $subslice = function(slice, low, high, max) {\n if (high === undefined) {\n high = slice.$length;\n }\n if (max === undefined) {\n max = slice.$capacity;\n }\n if (low < 0 || high < low || max < high || high > slice.$capacity || max > slice.$capacity) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n var s = new slice.constructor(slice.$array);\n s.$offset = slice.$offset + low;\n s.$length = high - low;\n s.$capacity = max - low;\n return s;\n};\n\nvar $substring = function(str, low, high) {\n if (low < 0 || high < low || high > str.length) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n return str.substring(low, high);\n};\n\nvar $sliceToArray = function(slice) {\n if (slice.$array.constructor !== Array) {\n return slice.$array.subarray(slice.$offset, slice.$offset + slice.$length);\n }\n return slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n};\n\nvar $decodeRune = function(str, pos) {\n var c0 = str.charCodeAt(pos);\n\n if (c0 < 0x80) {\n return [c0, 1];\n }\n\n if (c0 !== c0 || c0 < 0xc0) {\n return [0xfffd, 1];\n }\n\n var c1 = str.charCodeAt(pos + 1);\n if (c1 !== c1 || c1 < 0x80 || 0xc0 <= c1) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xe0) {\n var r = ((c0 & 0x1f) << 6) | (c1 & 0x3f);\n if (r <= 0x7f) {\n return [0xfffd, 1];\n }\n return [r, 2];\n }\n\n var c2 = str.charCodeAt(pos + 2);\n if (c2 !== c2 || c2 < 0x80 || 0xc0 <= c2) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xf0) {\n var r = ((c0 & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f);\n if (r <= 0x7ff) {\n return [0xfffd, 1];\n }\n if (0xd800 <= r && r <= 0xdfff) {\n return [0xfffd, 1];\n }\n return [r, 3];\n }\n\n var c3 = str.charCodeAt(pos + 3);\n if (c3 !== c3 || c3 < 0x80 || 0xc0 <= c3) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xf8) {\n var r = ((c0 & 0x07) << 18) | ((c1 & 0x3f) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f);\n if (r <= 0xffff || 0x10ffff < r) {\n return [0xfffd, 1];\n }\n return [r, 4];\n }\n\n return [0xfffd, 1];\n};\n\nvar $encodeRune = function(r) {\n if (r < 0 || r > 0x10ffff || (0xd800 <= r && r <= 0xdfff)) {\n r = 0xfffd;\n }\n if (r <= 0x7f) {\n return String.fromCharCode(r);\n }\n if (r <= 0x7ff) {\n return String.fromCharCode(0xc0 | (r >> 6), 0x80 | (r & 0x3f));\n }\n if (r <= 0xffff) {\n return String.fromCharCode(0xe0 | (r >> 12), 0x80 | ((r >> 6) & 0x3f), 0x80 | (r & 0x3f));\n }\n return String.fromCharCode(0xf0 | (r >> 18), 0x80 | ((r >> 12) & 0x3f), 0x80 | ((r >> 6) & 0x3f), 0x80 | (r & 0x3f));\n};\n\nvar $stringToBytes = function(str) {\n var array = new Uint8Array(str.length);\n for (var i = 0; i < str.length; i++) {\n array[i] = str.charCodeAt(i);\n }\n return array;\n};\n\nvar $bytesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i += 10000) {\n str += String.fromCharCode.apply(undefined, slice.$array.subarray(slice.$offset + i, slice.$offset + Math.min(slice.$length, i + 10000)));\n }\n return str;\n};\n\nvar $stringToRunes = function(str) {\n var array = new Int32Array(str.length);\n var rune,\n j = 0;\n for (var i = 0; i < str.length; i += rune[1], j++) {\n rune = $decodeRune(str, i);\n array[j] = rune[0];\n }\n return array.subarray(0, j);\n};\n\nvar $runesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i++) {\n str += $encodeRune(slice.$array[slice.$offset + i]);\n }\n return str;\n};\n\nvar $copyString = function(dst, src) {\n var n = Math.min(src.length, dst.$length);\n for (var i = 0; i < n; i++) {\n dst.$array[dst.$offset + i] = src.charCodeAt(i);\n }\n return n;\n};\n\nvar $copySlice = function(dst, src) {\n var n = Math.min(src.$length, dst.$length);\n $copyArray(dst.$array, src.$array, dst.$offset, src.$offset, n, dst.constructor.elem);\n return n;\n};\n\nvar $copyArray = function(dst, src, dstOffset, srcOffset, n, elem) {\n if (n === 0 || (dst === src && dstOffset === srcOffset)) {\n return;\n }\n\n if (src.subarray) {\n dst.set(src.subarray(srcOffset, srcOffset + n), dstOffset);\n return;\n }\n\n switch (elem.kind) {\n case $kindArray:\n case $kindStruct:\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n};\n\nvar $clone = function(src, type) {\n var clone = type.zero();\n type.copy(clone, src);\n return clone;\n};\n\nvar $pointerOfStructConversion = function(obj, type) {\n if (obj.$proxies === undefined) {\n obj.$proxies = {};\n obj.$proxies[obj.constructor.string] = obj;\n }\n var proxy = obj.$proxies[type.string];\n if (proxy === undefined) {\n var properties = {};\n for (var i = 0; i < type.elem.fields.length; i++) {\n (function(fieldProp) {\n properties[fieldProp] = {\n get: function() {\n return obj[fieldProp];\n },\n set: function(value) {\n obj[fieldProp] = value;\n },\n };\n })(type.elem.fields[i].prop);\n }\n proxy = Object.create(type.prototype, properties);\n proxy.$val = proxy;\n obj.$proxies[type.string] = proxy;\n proxy.$proxies = obj.$proxies;\n }\n return proxy;\n};\n\nvar $append = function(slice) {\n return $internalAppend(slice, arguments, 1, arguments.length - 1);\n};\n\nvar $appendSlice = function(slice, toAppend) {\n if (toAppend.constructor === String) {\n var bytes = $stringToBytes(toAppend);\n return $internalAppend(slice, bytes, 0, bytes.length);\n }\n return $internalAppend(slice, toAppend.$array, toAppend.$offset, toAppend.$length);\n};\n\nvar $internalAppend = function(slice, array, offset, length) {\n if (length === 0) {\n return slice;\n }\n\n var newArray = slice.$array;\n var newOffset = slice.$offset;\n var newLength = slice.$length + length;\n var newCapacity = slice.$capacity;\n\n if (newLength > newCapacity) {\n newOffset = 0;\n newCapacity = Math.max(newLength, slice.$capacity < 1024 ? slice.$capacity * 2 : Math.floor(slice.$capacity * 5 / 4));\n\n if (slice.$array.constructor === Array) {\n newArray = slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n newArray.length = newCapacity;\n var zero = slice.constructor.elem.zero;\n for (var i = slice.$length; i < newCapacity; i++) {\n newArray[i] = zero();\n }\n } else {\n newArray = new slice.$array.constructor(newCapacity);\n newArray.set(slice.$array.subarray(slice.$offset, slice.$offset + slice.$length));\n }\n }\n\n $copyArray(newArray, array, newOffset + slice.$length, offset, length, slice.constructor.elem);\n\n var newSlice = new slice.constructor(newArray);\n newSlice.$offset = newOffset;\n newSlice.$length = newLength;\n newSlice.$capacity = newCapacity;\n return newSlice;\n};\n\nvar $equal = function(a, b, type) {\n if (type === $jsObjectPtr) {\n return a === b;\n }\n switch (type.kind) {\n case $kindComplex64:\n case $kindComplex128:\n return a.$real === b.$real && a.$imag === b.$imag;\n case $kindInt64:\n case $kindUint64:\n return a.$high === b.$high && a.$low === b.$low;\n case $kindArray:\n if (a.length !== b.length) {\n return false;\n }\n for (var i = 0; i < a.length; i++) {\n if (!$equal(a[i], b[i], type.elem)) {\n return false;\n }\n }\n return true;\n case $kindStruct:\n for (var i = 0; i < type.fields.length; i++) {\n var f = type.fields[i];\n if (!$equal(a[f.prop], b[f.prop], f.typ)) {\n return false;\n }\n }\n return true;\n case $kindInterface:\n return $interfaceIsEqual(a, b);\n default:\n return a === b;\n }\n};\n\nvar $interfaceIsEqual = function(a, b) {\n if (a === $ifaceNil || b === $ifaceNil) {\n return a === b;\n }\n if (a.constructor !== b.constructor) {\n return false;\n }\n if (a.constructor === $jsObjectPtr) {\n return a.object === b.object;\n }\n if (!a.constructor.comparable) {\n $throwRuntimeError(\"comparing uncomparable type \" + a.constructor.string);\n }\n return $equal(a.$val, b.$val, a.constructor);\n};\nvar $min = Math.min;\nvar $mod = function(x, y) {\n return x % y;\n};\nvar $parseInt = parseInt;\nvar $parseFloat = function(f) {\n if (f !== undefined && f !== null && f.constructor === Number) {\n return f;\n }\n return parseFloat(f);\n};\n\nvar $froundBuf = new Float32Array(1);\nvar $fround =\n Math.fround ||\n function(f) {\n $froundBuf[0] = f;\n return $froundBuf[0];\n };\n\nvar $imul =\n Math.imul ||\n function(a, b) {\n var ah = (a >>> 16) & 0xffff;\n var al = a & 0xffff;\n var bh = (b >>> 16) & 0xffff;\n var bl = b & 0xffff;\n return (al * bl + (((ah * bl + al * bh) << 16) >>> 0)) >> 0;\n };\n\nvar $floatKey = function(f) {\n if (f !== f) {\n $idCounter++;\n return \"NaN$\" + $idCounter;\n }\n return String(f);\n};\n\nvar $flatten64 = function(x) {\n return x.$high * 4294967296 + x.$low;\n};\n\nvar $shiftLeft64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor((x.$high << y) | (x.$low >>> (32 - y)), (x.$low << y) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$low << (y - 32), 0);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightInt64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >> y, ((x.$low >>> y) | (x.$high << (32 - y))) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$high >> 31, (x.$high >> (y - 32)) >>> 0);\n }\n if (x.$high < 0) {\n return new x.constructor(-1, 4294967295);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightUint64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >>> y, ((x.$low >>> y) | (x.$high << (32 - y))) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(0, x.$high >>> (y - 32));\n }\n return new x.constructor(0, 0);\n};\n\nvar $mul64 = function(x, y) {\n var high = 0,\n low = 0;\n if ((y.$low & 1) !== 0) {\n high = x.$high;\n low = x.$low;\n }\n for (var i = 1; i < 32; i++) {\n if ((y.$low & (1 << i)) !== 0) {\n high += (x.$high << i) | (x.$low >>> (32 - i));\n low += (x.$low << i) >>> 0;\n }\n }\n for (var i = 0; i < 32; i++) {\n if ((y.$high & (1 << i)) !== 0) {\n high += x.$low << i;\n }\n }\n return new x.constructor(high, low);\n};\n\nvar $div64 = function(x, y, returnRemainder) {\n if (y.$high === 0 && y.$low === 0) {\n $throwRuntimeError(\"integer divide by zero\");\n }\n\n var s = 1;\n var rs = 1;\n\n var xHigh = x.$high;\n var xLow = x.$low;\n if (xHigh < 0) {\n s = -1;\n rs = -1;\n xHigh = -xHigh;\n if (xLow !== 0) {\n xHigh--;\n xLow = 4294967296 - xLow;\n }\n }\n\n var yHigh = y.$high;\n var yLow = y.$low;\n if (y.$high < 0) {\n s *= -1;\n yHigh = -yHigh;\n if (yLow !== 0) {\n yHigh--;\n yLow = 4294967296 - yLow;\n }\n }\n\n var high = 0,\n low = 0,\n n = 0;\n while (yHigh < 2147483648 && (xHigh > yHigh || (xHigh === yHigh && xLow > yLow))) {\n yHigh = ((yHigh << 1) | (yLow >>> 31)) >>> 0;\n yLow = (yLow << 1) >>> 0;\n n++;\n }\n for (var i = 0; i <= n; i++) {\n high = (high << 1) | (low >>> 31);\n low = (low << 1) >>> 0;\n if (xHigh > yHigh || (xHigh === yHigh && xLow >= yLow)) {\n xHigh = xHigh - yHigh;\n xLow = xLow - yLow;\n if (xLow < 0) {\n xHigh--;\n xLow += 4294967296;\n }\n low++;\n if (low === 4294967296) {\n high++;\n low = 0;\n }\n }\n yLow = ((yLow >>> 1) | (yHigh << (32 - 1))) >>> 0;\n yHigh = yHigh >>> 1;\n }\n\n if (returnRemainder) {\n return new x.constructor(xHigh * rs, xLow * rs);\n }\n return new x.constructor(high * s, low * s);\n};\n\nvar $divComplex = function(n, d) {\n var ninf = n.$real === Infinity || n.$real === -Infinity || n.$imag === Infinity || n.$imag === -Infinity;\n var dinf = d.$real === Infinity || d.$real === -Infinity || d.$imag === Infinity || d.$imag === -Infinity;\n var nnan = !ninf && (n.$real !== n.$real || n.$imag !== n.$imag);\n var dnan = !dinf && (d.$real !== d.$real || d.$imag !== d.$imag);\n if (nnan || dnan) {\n return new n.constructor(NaN, NaN);\n }\n if (ninf && !dinf) {\n return new n.constructor(Infinity, Infinity);\n }\n if (!ninf && dinf) {\n return new n.constructor(0, 0);\n }\n if (d.$real === 0 && d.$imag === 0) {\n if (n.$real === 0 && n.$imag === 0) {\n return new n.constructor(NaN, NaN);\n }\n return new n.constructor(Infinity, Infinity);\n }\n var a = Math.abs(d.$real);\n var b = Math.abs(d.$imag);\n if (a <= b) {\n var ratio = d.$real / d.$imag;\n var denom = d.$real * ratio + d.$imag;\n return new n.constructor((n.$real * ratio + n.$imag) / denom, (n.$imag * ratio - n.$real) / denom);\n }\n var ratio = d.$imag / d.$real;\n var denom = d.$imag * ratio + d.$real;\n return new n.constructor((n.$imag * ratio + n.$real) / denom, (n.$imag - n.$real * ratio) / denom);\n};\nvar $kindBool = 1;\nvar $kindInt = 2;\nvar $kindInt8 = 3;\nvar $kindInt16 = 4;\nvar $kindInt32 = 5;\nvar $kindInt64 = 6;\nvar $kindUint = 7;\nvar $kindUint8 = 8;\nvar $kindUint16 = 9;\nvar $kindUint32 = 10;\nvar $kindUint64 = 11;\nvar $kindUintptr = 12;\nvar $kindFloat32 = 13;\nvar $kindFloat64 = 14;\nvar $kindComplex64 = 15;\nvar $kindComplex128 = 16;\nvar $kindArray = 17;\nvar $kindChan = 18;\nvar $kindFunc = 19;\nvar $kindInterface = 20;\nvar $kindMap = 21;\nvar $kindPtr = 22;\nvar $kindSlice = 23;\nvar $kindString = 24;\nvar $kindStruct = 25;\nvar $kindUnsafePointer = 26;\n\nvar $methodSynthesizers = [];\nvar $addMethodSynthesizer = function(f) {\n if ($methodSynthesizers === null) {\n f();\n return;\n }\n $methodSynthesizers.push(f);\n};\nvar $synthesizeMethods = function() {\n $methodSynthesizers.forEach(function(f) {\n f();\n });\n $methodSynthesizers = null;\n};\n\nvar $ifaceKeyFor = function(x) {\n if (x === $ifaceNil) {\n return \"nil\";\n }\n var c = x.constructor;\n return c.string + \"$\" + c.keyFor(x.$val);\n};\n\nvar $identity = function(x) {\n return x;\n};\n\nvar $typeIDCounter = 0;\n\nvar $idKey = function(x) {\n if (x.$id === undefined) {\n $idCounter++;\n x.$id = $idCounter;\n }\n return String(x.$id);\n};\n\nvar $newType = function(size, kind, string, named, pkg, exported, constructor) {\n var typ;\n switch (kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = $identity;\n break;\n\n case $kindString:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = function(x) {\n return \"$\" + x;\n };\n break;\n\n case $kindFloat32:\n case $kindFloat64:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = function(x) {\n return $floatKey(x);\n };\n break;\n\n case $kindInt64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$high + \"$\" + x.$low;\n };\n break;\n\n case $kindUint64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >>> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$high + \"$\" + x.$low;\n };\n break;\n\n case $kindComplex64:\n typ = function(real, imag) {\n this.$real = $fround(real);\n this.$imag = $fround(imag);\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$real + \"$\" + x.$imag;\n };\n break;\n\n case $kindComplex128:\n typ = function(real, imag) {\n this.$real = real;\n this.$imag = imag;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$real + \"$\" + x.$imag;\n };\n break;\n\n case $kindArray:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, \"\", false, function(array) {\n this.$get = function() {\n return array;\n };\n this.$set = function(v) {\n typ.copy(this, v);\n };\n this.$val = array;\n });\n typ.init = function(elem, len) {\n typ.elem = elem;\n typ.len = len;\n typ.comparable = elem.comparable;\n typ.keyFor = function(x) {\n return Array.prototype.join.call(\n $mapArray(x, function(e) {\n return String(elem.keyFor(e))\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\$/g, \"\\\\$\");\n }),\n \"$\"\n );\n };\n typ.copy = function(dst, src) {\n $copyArray(dst, src, 0, 0, src.length, elem);\n };\n typ.ptr.init(typ);\n Object.defineProperty(typ.ptr.nil, \"nilCheck\", { get: $throwNilPointerError });\n };\n break;\n\n case $kindChan:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = $idKey;\n typ.init = function(elem, sendOnly, recvOnly) {\n typ.elem = elem;\n typ.sendOnly = sendOnly;\n typ.recvOnly = recvOnly;\n };\n break;\n\n case $kindFunc:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.init = function(params, results, variadic) {\n typ.params = params;\n typ.results = results;\n typ.variadic = variadic;\n typ.comparable = false;\n };\n break;\n\n case $kindInterface:\n typ = { implementedBy: {}, missingMethodFor: {} };\n typ.keyFor = $ifaceKeyFor;\n typ.init = function(methods) {\n typ.methods = methods;\n methods.forEach(function(m) {\n $ifaceNil[m.prop] = $throwNilPointerError;\n });\n };\n break;\n\n case $kindMap:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.init = function(key, elem) {\n typ.key = key;\n typ.elem = elem;\n typ.comparable = false;\n };\n break;\n\n case $kindPtr:\n typ =\n constructor ||\n function(getter, setter, target) {\n this.$get = getter;\n this.$set = setter;\n this.$target = target;\n this.$val = this;\n };\n typ.keyFor = $idKey;\n typ.init = function(elem) {\n typ.elem = elem;\n typ.wrapped = elem.kind === $kindArray;\n typ.nil = new typ($throwNilPointerError, $throwNilPointerError);\n };\n break;\n\n case $kindSlice:\n typ = function(array) {\n if (array.constructor !== typ.nativeArray) {\n array = new typ.nativeArray(array);\n }\n this.$array = array;\n this.$offset = 0;\n this.$length = array.length;\n this.$capacity = array.length;\n this.$val = this;\n };\n typ.init = function(elem) {\n typ.elem = elem;\n typ.comparable = false;\n typ.nativeArray = $nativeArray(elem.kind);\n typ.nil = new typ([]);\n };\n break;\n\n case $kindStruct:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, pkg, exported, constructor);\n typ.ptr.elem = typ;\n typ.ptr.prototype.$get = function() {\n return this;\n };\n typ.ptr.prototype.$set = function(v) {\n typ.copy(this, v);\n };\n typ.init = function(pkgPath, fields) {\n typ.pkgPath = pkgPath;\n typ.fields = fields;\n fields.forEach(function(f) {\n if (!f.typ.comparable) {\n typ.comparable = false;\n }\n });\n typ.keyFor = function(x) {\n var val = x.$val;\n return $mapArray(fields, function(f) {\n return String(f.typ.keyFor(val[f.prop]))\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\$/g, \"\\\\$\");\n }).join(\"$\");\n };\n typ.copy = function(dst, src) {\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n switch (f.typ.kind) {\n case $kindArray:\n case $kindStruct:\n f.typ.copy(dst[f.prop], src[f.prop]);\n continue;\n default:\n dst[f.prop] = src[f.prop];\n continue;\n }\n }\n };\n /* nil value */\n var properties = {};\n fields.forEach(function(f) {\n properties[f.prop] = { get: $throwNilPointerError, set: $throwNilPointerError };\n });\n typ.ptr.nil = Object.create(constructor.prototype, properties);\n typ.ptr.nil.$val = typ.ptr.nil;\n /* methods for embedded fields */\n $addMethodSynthesizer(function() {\n var synthesizeMethod = function(target, m, f) {\n if (target.prototype[m.prop] !== undefined) {\n return;\n }\n target.prototype[m.prop] = function() {\n var v = this.$val[f.prop];\n if (f.typ === $jsObjectPtr) {\n v = new $jsObjectPtr(v);\n }\n if (v.$val === undefined) {\n v = new f.typ(v);\n }\n return v[m.prop].apply(v, arguments);\n };\n };\n fields.forEach(function(f) {\n if (f.anonymous) {\n $methodSet(f.typ).forEach(function(m) {\n synthesizeMethod(typ, m, f);\n synthesizeMethod(typ.ptr, m, f);\n });\n $methodSet($ptrType(f.typ)).forEach(function(m) {\n synthesizeMethod(typ.ptr, m, f);\n });\n }\n });\n });\n };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n switch (kind) {\n case $kindBool:\n case $kindMap:\n typ.zero = function() {\n return false;\n };\n break;\n\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n case $kindFloat32:\n case $kindFloat64:\n typ.zero = function() {\n return 0;\n };\n break;\n\n case $kindString:\n typ.zero = function() {\n return \"\";\n };\n break;\n\n case $kindInt64:\n case $kindUint64:\n case $kindComplex64:\n case $kindComplex128:\n var zero = new typ(0, 0);\n typ.zero = function() {\n return zero;\n };\n break;\n\n case $kindPtr:\n case $kindSlice:\n typ.zero = function() {\n return typ.nil;\n };\n break;\n\n case $kindChan:\n typ.zero = function() {\n return $chanNil;\n };\n break;\n\n case $kindFunc:\n typ.zero = function() {\n return $throwNilPointerError;\n };\n break;\n\n case $kindInterface:\n typ.zero = function() {\n return $ifaceNil;\n };\n break;\n\n case $kindArray:\n typ.zero = function() {\n var arrayClass = $nativeArray(typ.elem.kind);\n if (arrayClass !== Array) {\n return new arrayClass(typ.len);\n }\n var array = new Array(typ.len);\n for (var i = 0; i < typ.len; i++) {\n array[i] = typ.elem.zero();\n }\n return array;\n };\n break;\n\n case $kindStruct:\n typ.zero = function() {\n return new typ.ptr();\n };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n typ.id = $typeIDCounter;\n $typeIDCounter++;\n typ.size = size;\n typ.kind = kind;\n typ.string = string;\n typ.named = named;\n typ.pkg = pkg;\n typ.exported = exported;\n typ.methods = [];\n typ.methodSetCache = null;\n typ.comparable = true;\n return typ;\n};\n\nvar $methodSet = function(typ) {\n if (typ.methodSetCache !== null) {\n return typ.methodSetCache;\n }\n var base = {};\n\n var isPtr = typ.kind === $kindPtr;\n if (isPtr && typ.elem.kind === $kindInterface) {\n typ.methodSetCache = [];\n return [];\n }\n\n var current = [{ typ: isPtr ? typ.elem : typ, indirect: isPtr }];\n\n var seen = {};\n\n while (current.length > 0) {\n var next = [];\n var mset = [];\n\n current.forEach(function(e) {\n if (seen[e.typ.string]) {\n return;\n }\n seen[e.typ.string] = true;\n\n if (e.typ.named) {\n mset = mset.concat(e.typ.methods);\n if (e.indirect) {\n mset = mset.concat($ptrType(e.typ).methods);\n }\n }\n\n switch (e.typ.kind) {\n case $kindStruct:\n e.typ.fields.forEach(function(f) {\n if (f.anonymous) {\n var fTyp = f.typ;\n var fIsPtr = fTyp.kind === $kindPtr;\n next.push({ typ: fIsPtr ? fTyp.elem : fTyp, indirect: e.indirect || fIsPtr });\n }\n });\n break;\n\n case $kindInterface:\n mset = mset.concat(e.typ.methods);\n break;\n }\n });\n\n mset.forEach(function(m) {\n if (base[m.name] === undefined) {\n base[m.name] = m;\n }\n });\n\n current = next;\n }\n\n typ.methodSetCache = [];\n Object.keys(base)\n .sort()\n .forEach(function(name) {\n typ.methodSetCache.push(base[name]);\n });\n return typ.methodSetCache;\n};\n\nvar $Bool = $newType(1, $kindBool, \"bool\", true, \"\", false, null);\nvar $Int = $newType(4, $kindInt, \"int\", true, \"\", false, null);\nvar $Int8 = $newType(1, $kindInt8, \"int8\", true, \"\", false, null);\nvar $Int16 = $newType(2, $kindInt16, \"int16\", true, \"\", false, null);\nvar $Int32 = $newType(4, $kindInt32, \"int32\", true, \"\", false, null);\nvar $Int64 = $newType(8, $kindInt64, \"int64\", true, \"\", false, null);\nvar $Uint = $newType(4, $kindUint, \"uint\", true, \"\", false, null);\nvar $Uint8 = $newType(1, $kindUint8, \"uint8\", true, \"\", false, null);\nvar $Uint16 = $newType(2, $kindUint16, \"uint16\", true, \"\", false, null);\nvar $Uint32 = $newType(4, $kindUint32, \"uint32\", true, \"\", false, null);\nvar $Uint64 = $newType(8, $kindUint64, \"uint64\", true, \"\", false, null);\nvar $Uintptr = $newType(4, $kindUintptr, \"uintptr\", true, \"\", false, null);\nvar $Float32 = $newType(4, $kindFloat32, \"float32\", true, \"\", false, null);\nvar $Float64 = $newType(8, $kindFloat64, \"float64\", true, \"\", false, null);\nvar $Complex64 = $newType(8, $kindComplex64, \"complex64\", true, \"\", false, null);\nvar $Complex128 = $newType(16, $kindComplex128, \"complex128\", true, \"\", false, null);\nvar $String = $newType(8, $kindString, \"string\", true, \"\", false, null);\nvar $UnsafePointer = $newType(4, $kindUnsafePointer, \"unsafe.Pointer\", true, \"\", false, null);\n\nvar $nativeArray = function(elemKind) {\n switch (elemKind) {\n case $kindInt:\n return Int32Array;\n case $kindInt8:\n return Int8Array;\n case $kindInt16:\n return Int16Array;\n case $kindInt32:\n return Int32Array;\n case $kindUint:\n return Uint32Array;\n case $kindUint8:\n return Uint8Array;\n case $kindUint16:\n return Uint16Array;\n case $kindUint32:\n return Uint32Array;\n case $kindUintptr:\n return Uint32Array;\n case $kindFloat32:\n return Float32Array;\n case $kindFloat64:\n return Float64Array;\n default:\n return Array;\n }\n};\nvar $toNativeArray = function(elemKind, array) {\n var nativeArray = $nativeArray(elemKind);\n if (nativeArray === Array) {\n return array;\n }\n return new nativeArray(array);\n};\nvar $arrayTypes = {};\nvar $arrayType = function(elem, len) {\n var typeKey = elem.id + \"$\" + len;\n var typ = $arrayTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(12, $kindArray, \"[\" + len + \"]\" + elem.string, false, \"\", false, null);\n $arrayTypes[typeKey] = typ;\n typ.init(elem, len);\n }\n return typ;\n};\n\nvar $chanType = function(elem, sendOnly, recvOnly) {\n var string = (recvOnly ? \"<-\" : \"\") + \"chan\" + (sendOnly ? \"<- \" : \" \") + elem.string;\n var field = sendOnly ? \"SendChan\" : recvOnly ? \"RecvChan\" : \"Chan\";\n var typ = elem[field];\n if (typ === undefined) {\n typ = $newType(4, $kindChan, string, false, \"\", false, null);\n elem[field] = typ;\n typ.init(elem, sendOnly, recvOnly);\n }\n return typ;\n};\nvar $Chan = function(elem, capacity) {\n if (capacity < 0 || capacity > 2147483647) {\n $throwRuntimeError(\"makechan: size out of range\");\n }\n this.$elem = elem;\n this.$capacity = capacity;\n this.$buffer = [];\n this.$sendQueue = [];\n this.$recvQueue = [];\n this.$closed = false;\n};\nvar $chanNil = new $Chan(null, 0);\n$chanNil.$sendQueue = $chanNil.$recvQueue = {\n length: 0,\n push: function() {},\n shift: function() {\n return undefined;\n },\n indexOf: function() {\n return -1;\n },\n};\n\nvar $funcTypes = {};\nvar $funcType = function(params, results, variadic) {\n var typeKey =\n $mapArray(params, function(p) {\n return p.id;\n }).join(\",\") +\n \"$\" +\n $mapArray(results, function(r) {\n return r.id;\n }).join(\",\") +\n \"$\" +\n variadic;\n var typ = $funcTypes[typeKey];\n if (typ === undefined) {\n var paramTypes = $mapArray(params, function(p) {\n return p.string;\n });\n if (variadic) {\n paramTypes[paramTypes.length - 1] = \"...\" + paramTypes[paramTypes.length - 1].substr(2);\n }\n var string = \"func(\" + paramTypes.join(\", \") + \")\";\n if (results.length === 1) {\n string += \" \" + results[0].string;\n } else if (results.length > 1) {\n string +=\n \" (\" +\n $mapArray(results, function(r) {\n return r.string;\n }).join(\", \") +\n \")\";\n }\n typ = $newType(4, $kindFunc, string, false, \"\", false, null);\n $funcTypes[typeKey] = typ;\n typ.init(params, results, variadic);\n }\n return typ;\n};\n\nvar $interfaceTypes = {};\nvar $interfaceType = function(methods) {\n var typeKey = $mapArray(methods, function(m) {\n return m.pkg + \",\" + m.name + \",\" + m.typ.id;\n }).join(\"$\");\n var typ = $interfaceTypes[typeKey];\n if (typ === undefined) {\n var string = \"interface {}\";\n if (methods.length !== 0) {\n string =\n \"interface { \" +\n $mapArray(methods, function(m) {\n return (m.pkg !== \"\" ? m.pkg + \".\" : \"\") + m.name + m.typ.string.substr(4);\n }).join(\"; \") +\n \" }\";\n }\n typ = $newType(8, $kindInterface, string, false, \"\", false, null);\n $interfaceTypes[typeKey] = typ;\n typ.init(methods);\n }\n return typ;\n};\nvar $emptyInterface = $interfaceType([]);\nvar $ifaceNil = {};\nvar $error = $newType(8, $kindInterface, \"error\", true, \"\", false, null);\n$error.init([{ prop: \"Error\", name: \"Error\", pkg: \"\", typ: $funcType([], [$String], false) }]);\n\nvar $mapTypes = {};\nvar $mapType = function(key, elem) {\n var typeKey = key.id + \"$\" + elem.id;\n var typ = $mapTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(4, $kindMap, \"map[\" + key.string + \"]\" + elem.string, false, \"\", false, null);\n $mapTypes[typeKey] = typ;\n typ.init(key, elem);\n }\n return typ;\n};\nvar $makeMap = function(keyForFunc, entries) {\n var m = {};\n for (var i = 0; i < entries.length; i++) {\n var e = entries[i];\n m[keyForFunc(e.k)] = e;\n }\n return m;\n};\n\nvar $ptrType = function(elem) {\n var typ = elem.ptr;\n if (typ === undefined) {\n typ = $newType(4, $kindPtr, \"*\" + elem.string, false, \"\", elem.exported, null);\n elem.ptr = typ;\n typ.init(elem);\n }\n return typ;\n};\n\nvar $newDataPointer = function(data, constructor) {\n if (constructor.elem.kind === $kindStruct) {\n return data;\n }\n return new constructor(\n function() {\n return data;\n },\n function(v) {\n data = v;\n }\n );\n};\n\nvar $indexPtr = function(array, index, constructor) {\n array.$ptr = array.$ptr || {};\n return (\n array.$ptr[index] ||\n (array.$ptr[index] = new constructor(\n function() {\n return array[index];\n },\n function(v) {\n array[index] = v;\n }\n ))\n );\n};\n\nvar $sliceType = function(elem) {\n var typ = elem.slice;\n if (typ === undefined) {\n typ = $newType(12, $kindSlice, \"[]\" + elem.string, false, \"\", false, null);\n elem.slice = typ;\n typ.init(elem);\n }\n return typ;\n};\nvar $makeSlice = function(typ, length, capacity) {\n capacity = capacity || length;\n if (length < 0 || length > 2147483647) {\n $throwRuntimeError(\"makeslice: len out of range\");\n }\n if (capacity < 0 || capacity < length || capacity > 2147483647) {\n $throwRuntimeError(\"makeslice: cap out of range\");\n }\n var array = new typ.nativeArray(capacity);\n if (typ.nativeArray === Array) {\n for (var i = 0; i < capacity; i++) {\n array[i] = typ.elem.zero();\n }\n }\n var slice = new typ(array);\n slice.$length = length;\n return slice;\n};\n\nvar $structTypes = {};\nvar $structType = function(pkgPath, fields) {\n var typeKey = $mapArray(fields, function(f) {\n return f.name + \",\" + f.typ.id + \",\" + f.tag;\n }).join(\"$\");\n var typ = $structTypes[typeKey];\n if (typ === undefined) {\n var string =\n \"struct { \" +\n $mapArray(fields, function(f) {\n return f.name + \" \" + f.typ.string + (f.tag !== \"\" ? ' \"' + f.tag.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"') + '\"' : \"\");\n }).join(\"; \") +\n \" }\";\n if (fields.length === 0) {\n string = \"struct {}\";\n }\n typ = $newType(0, $kindStruct, string, false, \"\", false, function() {\n this.$val = this;\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n var arg = arguments[i];\n this[f.prop] = arg !== undefined ? arg : f.typ.zero();\n }\n });\n $structTypes[typeKey] = typ;\n typ.init(pkgPath, fields);\n }\n return typ;\n};\n\nvar $assertType = function(value, type, returnTuple) {\n var isInterface = type.kind === $kindInterface,\n ok,\n missingMethod = \"\";\n if (value === $ifaceNil) {\n ok = false;\n } else if (!isInterface) {\n ok = value.constructor === type;\n } else {\n var valueTypeString = value.constructor.string;\n ok = type.implementedBy[valueTypeString];\n if (ok === undefined) {\n ok = true;\n var valueMethodSet = $methodSet(value.constructor);\n var interfaceMethods = type.methods;\n for (var i = 0; i < interfaceMethods.length; i++) {\n var tm = interfaceMethods[i];\n var found = false;\n for (var j = 0; j < valueMethodSet.length; j++) {\n var vm = valueMethodSet[j];\n if (vm.name === tm.name && vm.pkg === tm.pkg && vm.typ === tm.typ) {\n found = true;\n break;\n }\n }\n if (!found) {\n ok = false;\n type.missingMethodFor[valueTypeString] = tm.name;\n break;\n }\n }\n type.implementedBy[valueTypeString] = ok;\n }\n if (!ok) {\n missingMethod = type.missingMethodFor[valueTypeString];\n }\n }\n\n if (!ok) {\n if (returnTuple) {\n return [type.zero(), false];\n }\n $panic(new $packages[\"runtime\"].TypeAssertionError.ptr(\"\", value === $ifaceNil ? \"\" : value.constructor.string, type.string, missingMethod));\n }\n\n if (!isInterface) {\n value = value.$val;\n }\n if (type === $jsObjectPtr) {\n value = value.object;\n }\n return returnTuple ? [value, true] : value;\n};\nvar $stackDepthOffset = 0;\nvar $getStackDepth = function() {\n var err = new Error();\n if (err.stack === undefined) {\n return undefined;\n }\n return $stackDepthOffset + err.stack.split(\"\\n\").length;\n};\n\nvar $panicStackDepth = null,\n $panicValue;\nvar $callDeferred = function(deferred, jsErr, fromPanic) {\n if (!fromPanic && deferred !== null && deferred.index >= $curGoroutine.deferStack.length) {\n throw jsErr;\n }\n if (jsErr !== null) {\n var newErr = null;\n try {\n $curGoroutine.deferStack.push(deferred);\n $panic(new $jsErrorPtr(jsErr));\n } catch (err) {\n newErr = err;\n }\n $curGoroutine.deferStack.pop();\n $callDeferred(deferred, newErr);\n return;\n }\n if ($curGoroutine.asleep) {\n return;\n }\n\n $stackDepthOffset--;\n var outerPanicStackDepth = $panicStackDepth;\n var outerPanicValue = $panicValue;\n\n var localPanicValue = $curGoroutine.panicStack.pop();\n if (localPanicValue !== undefined) {\n $panicStackDepth = $getStackDepth();\n $panicValue = localPanicValue;\n }\n\n try {\n while (true) {\n if (deferred === null) {\n deferred = $curGoroutine.deferStack[$curGoroutine.deferStack.length - 1];\n if (deferred === undefined) {\n /* The panic reached the top of the stack. Clear it and throw it as a JavaScript error. */\n $panicStackDepth = null;\n if (localPanicValue.Object instanceof Error) {\n throw localPanicValue.Object;\n }\n var msg;\n if (localPanicValue.constructor === $String) {\n msg = localPanicValue.$val;\n } else if (localPanicValue.Error !== undefined) {\n msg = localPanicValue.Error();\n } else if (localPanicValue.String !== undefined) {\n msg = localPanicValue.String();\n } else {\n msg = localPanicValue;\n }\n throw new Error(msg);\n }\n }\n var call = deferred.pop();\n if (call === undefined) {\n $curGoroutine.deferStack.pop();\n if (localPanicValue !== undefined) {\n deferred = null;\n continue;\n }\n return;\n }\n var r = call[0].apply(call[2], call[1]);\n if (r && r.$blk !== undefined) {\n deferred.push([r.$blk, [], r]);\n if (fromPanic) {\n throw null;\n }\n return;\n }\n\n if (localPanicValue !== undefined && $panicStackDepth === null) {\n throw null; /* error was recovered */\n }\n }\n } finally {\n if (localPanicValue !== undefined) {\n if ($panicStackDepth !== null) {\n $curGoroutine.panicStack.push(localPanicValue);\n }\n $panicStackDepth = outerPanicStackDepth;\n $panicValue = outerPanicValue;\n }\n $stackDepthOffset++;\n }\n};\n\nvar $panic = function(value) {\n $curGoroutine.panicStack.push(value);\n $callDeferred(null, null, true);\n};\nvar $recover = function() {\n if ($panicStackDepth === null || ($panicStackDepth !== undefined && $panicStackDepth !== $getStackDepth() - 2)) {\n return $ifaceNil;\n }\n $panicStackDepth = null;\n return $panicValue;\n};\nvar $throw = function(err) {\n throw err;\n};\n\nvar $noGoroutine = {\n asleep: false,\n exit: false,\n deferStack: [],\n panicStack: [],\n};\nvar $curGoroutine = $noGoroutine,\n $totalGoroutines = 0,\n $awakeGoroutines = 0,\n $checkForDeadlock = true;\nvar $mainFinished = false;\nvar $go = function(fun, args) {\n $totalGoroutines++;\n $awakeGoroutines++;\n var $goroutine = function() {\n try {\n $curGoroutine = $goroutine;\n var r = fun.apply(undefined, args);\n if (r && r.$blk !== undefined) {\n fun = function() {\n return r.$blk();\n };\n args = [];\n return;\n }\n $goroutine.exit = true;\n } catch (err) {\n if (!$goroutine.exit) {\n throw err;\n }\n } finally {\n $curGoroutine = $noGoroutine;\n if ($goroutine.exit) {\n /* also set by runtime.Goexit() */\n $totalGoroutines--;\n $goroutine.asleep = true;\n }\n if ($goroutine.asleep) {\n $awakeGoroutines--;\n if (!$mainFinished && $awakeGoroutines === 0 && $checkForDeadlock) {\n console.error(\"fatal error: all goroutines are asleep - deadlock!\");\n if ($global.process !== undefined) {\n $global.process.exit(2);\n }\n }\n }\n }\n };\n $goroutine.asleep = false;\n $goroutine.exit = false;\n $goroutine.deferStack = [];\n $goroutine.panicStack = [];\n $schedule($goroutine);\n};\n\nvar $scheduled = [];\nvar $runScheduled = function() {\n try {\n var r;\n while ((r = $scheduled.shift()) !== undefined) {\n r();\n }\n } finally {\n if ($scheduled.length > 0) {\n setTimeout($runScheduled, 0);\n }\n }\n};\n\nvar $schedule = function(goroutine) {\n if (goroutine.asleep) {\n goroutine.asleep = false;\n $awakeGoroutines++;\n }\n $scheduled.push(goroutine);\n if ($curGoroutine === $noGoroutine) {\n $runScheduled();\n }\n};\n\nvar $setTimeout = function(f, t) {\n $awakeGoroutines++;\n return setTimeout(function() {\n $awakeGoroutines--;\n f();\n }, t);\n};\n\nvar $block = function() {\n if ($curGoroutine === $noGoroutine) {\n $throwRuntimeError(\"cannot block in JavaScript callback, fix by wrapping code in goroutine\");\n }\n $curGoroutine.asleep = true;\n};\n\nvar $send = function(chan, value) {\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv !== undefined) {\n queuedRecv([value, true]);\n return;\n }\n if (chan.$buffer.length < chan.$capacity) {\n chan.$buffer.push(value);\n return;\n }\n\n var thisGoroutine = $curGoroutine;\n var closedDuringSend;\n chan.$sendQueue.push(function(closed) {\n closedDuringSend = closed;\n $schedule(thisGoroutine);\n return value;\n });\n $block();\n return {\n $blk: function() {\n if (closedDuringSend) {\n $throwRuntimeError(\"send on closed channel\");\n }\n },\n };\n};\nvar $recv = function(chan) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend !== undefined) {\n chan.$buffer.push(queuedSend(false));\n }\n var bufferedValue = chan.$buffer.shift();\n if (bufferedValue !== undefined) {\n return [bufferedValue, true];\n }\n if (chan.$closed) {\n return [chan.$elem.zero(), false];\n }\n\n var thisGoroutine = $curGoroutine;\n var f = {\n $blk: function() {\n return this.value;\n },\n };\n var queueEntry = function(v) {\n f.value = v;\n $schedule(thisGoroutine);\n };\n chan.$recvQueue.push(queueEntry);\n $block();\n return f;\n};\nvar $close = function(chan) {\n if (chan.$closed) {\n $throwRuntimeError(\"close of closed channel\");\n }\n chan.$closed = true;\n while (true) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend === undefined) {\n break;\n }\n queuedSend(true); /* will panic */\n }\n while (true) {\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv === undefined) {\n break;\n }\n queuedRecv([chan.$elem.zero(), false]);\n }\n};\nvar $select = function(comms) {\n var ready = [];\n var selection = -1;\n for (var i = 0; i < comms.length; i++) {\n var comm = comms[i];\n var chan = comm[0];\n switch (comm.length) {\n case 0 /* default */:\n selection = i;\n break;\n case 1 /* recv */:\n if (chan.$sendQueue.length !== 0 || chan.$buffer.length !== 0 || chan.$closed) {\n ready.push(i);\n }\n break;\n case 2 /* send */:\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n if (chan.$recvQueue.length !== 0 || chan.$buffer.length < chan.$capacity) {\n ready.push(i);\n }\n break;\n }\n }\n\n if (ready.length !== 0) {\n selection = ready[Math.floor(Math.random() * ready.length)];\n }\n if (selection !== -1) {\n var comm = comms[selection];\n switch (comm.length) {\n case 0 /* default */:\n return [selection];\n case 1 /* recv */:\n return [selection, $recv(comm[0])];\n case 2 /* send */:\n $send(comm[0], comm[1]);\n return [selection];\n }\n }\n\n var entries = [];\n var thisGoroutine = $curGoroutine;\n var f = {\n $blk: function() {\n return this.selection;\n },\n };\n var removeFromQueues = function() {\n for (var i = 0; i < entries.length; i++) {\n var entry = entries[i];\n var queue = entry[0];\n var index = queue.indexOf(entry[1]);\n if (index !== -1) {\n queue.splice(index, 1);\n }\n }\n };\n for (var i = 0; i < comms.length; i++) {\n (function(i) {\n var comm = comms[i];\n switch (comm.length) {\n case 1 /* recv */:\n var queueEntry = function(value) {\n f.selection = [i, value];\n removeFromQueues();\n $schedule(thisGoroutine);\n };\n entries.push([comm[0].$recvQueue, queueEntry]);\n comm[0].$recvQueue.push(queueEntry);\n break;\n case 2 /* send */:\n var queueEntry = function() {\n if (comm[0].$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n f.selection = [i];\n removeFromQueues();\n $schedule(thisGoroutine);\n return comm[1];\n };\n entries.push([comm[0].$sendQueue, queueEntry]);\n comm[0].$sendQueue.push(queueEntry);\n break;\n }\n })(i);\n }\n $block();\n return f;\n};\nvar $jsObjectPtr, $jsErrorPtr;\n\nvar $needsExternalization = function(t) {\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return false;\n default:\n return t !== $jsObjectPtr;\n }\n};\n\nvar $externalize = function(v, t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return v;\n case $kindInt64:\n case $kindUint64:\n return $flatten64(v);\n case $kindArray:\n if ($needsExternalization(t.elem)) {\n return $mapArray(v, function(e) {\n return $externalize(e, t.elem);\n });\n }\n return v;\n case $kindFunc:\n return $externalizeFunction(v, t, false);\n case $kindInterface:\n if (v === $ifaceNil) {\n return null;\n }\n if (v.constructor === $jsObjectPtr) {\n return v.$val.object;\n }\n return $externalize(v.$val, v.constructor);\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var entry = v[keys[i]];\n m[$externalize(entry.k, t.key)] = $externalize(entry.v, t.elem);\n }\n return m;\n case $kindPtr:\n if (v === t.nil) {\n return null;\n }\n return $externalize(v.$get(), t.elem);\n case $kindSlice:\n if ($needsExternalization(t.elem)) {\n return $mapArray($sliceToArray(v), function(e) {\n return $externalize(e, t.elem);\n });\n }\n return $sliceToArray(v);\n case $kindString:\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\",\n r;\n for (var i = 0; i < v.length; i += r[1]) {\n r = $decodeRune(v, i);\n var c = r[0];\n if (c > 0xffff) {\n var h = Math.floor((c - 0x10000) / 0x400) + 0xd800;\n var l = (c - 0x10000) % 0x400 + 0xdc00;\n s += String.fromCharCode(h, l);\n continue;\n }\n s += String.fromCharCode(c);\n }\n return s;\n case $kindStruct:\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && v.constructor === timePkg.Time.ptr) {\n var milli = $div64(v.UnixNano(), new $Int64(0, 1000000));\n return new Date($flatten64(milli));\n }\n\n var noJsObject = {};\n var searchJsObject = function(v, t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindPtr:\n if (v === t.nil) {\n return noJsObject;\n }\n return searchJsObject(v.$get(), t.elem);\n case $kindStruct:\n var f = t.fields[0];\n return searchJsObject(v[f.prop], f.typ);\n case $kindInterface:\n return searchJsObject(v.$val, v.constructor);\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(v, t);\n if (o !== noJsObject) {\n return o;\n }\n\n o = {};\n for (var i = 0; i < t.fields.length; i++) {\n var f = t.fields[i];\n if (!f.exported) {\n continue;\n }\n o[f.name] = $externalize(v[f.prop], f.typ);\n }\n return o;\n }\n $throwRuntimeError(\"cannot externalize \" + t.string);\n};\n\nvar $externalizeFunction = function(v, t, passThis) {\n if (v === $throwNilPointerError) {\n return null;\n }\n if (v.$externalizeWrapper === undefined) {\n $checkForDeadlock = false;\n v.$externalizeWrapper = function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem,\n varargs = [];\n for (var j = i; j < arguments.length; j++) {\n varargs.push($internalize(arguments[j], vt));\n }\n args.push(new t.params[i](varargs));\n break;\n }\n args.push($internalize(arguments[i], t.params[i]));\n }\n var result = v.apply(passThis ? this : undefined, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $externalize(result, t.results[0]);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $externalize(result[i], t.results[i]);\n }\n return result;\n }\n };\n }\n return v.$externalizeWrapper;\n};\n\nvar $internalize = function(v, t, recv) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n if (v && v.__internal_object__ !== undefined) {\n return $assertType(v.__internal_object__, t, false);\n }\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && t === timePkg.Time) {\n if (!(v !== null && v !== undefined && v.constructor === Date)) {\n $throwRuntimeError(\"cannot internalize time.Time from \" + typeof v + \", must be Date\");\n }\n return timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000));\n }\n switch (t.kind) {\n case $kindBool:\n return !!v;\n case $kindInt:\n return parseInt(v);\n case $kindInt8:\n return (parseInt(v) << 24) >> 24;\n case $kindInt16:\n return (parseInt(v) << 16) >> 16;\n case $kindInt32:\n return parseInt(v) >> 0;\n case $kindUint:\n return parseInt(v);\n case $kindUint8:\n return (parseInt(v) << 24) >>> 24;\n case $kindUint16:\n return (parseInt(v) << 16) >>> 16;\n case $kindUint32:\n case $kindUintptr:\n return parseInt(v) >>> 0;\n case $kindInt64:\n case $kindUint64:\n return new t(0, v);\n case $kindFloat32:\n case $kindFloat64:\n return parseFloat(v);\n case $kindArray:\n if (v.length !== t.len) {\n $throwRuntimeError(\"got array with wrong size from JavaScript native\");\n }\n return $mapArray(v, function(e) {\n return $internalize(e, t.elem);\n });\n case $kindFunc:\n return function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem,\n varargs = arguments[i];\n for (var j = 0; j < varargs.$length; j++) {\n args.push($externalize(varargs.$array[varargs.$offset + j], vt));\n }\n break;\n }\n args.push($externalize(arguments[i], t.params[i]));\n }\n var result = v.apply(recv, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $internalize(result, t.results[0]);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $internalize(result[i], t.results[i]);\n }\n return result;\n }\n };\n case $kindInterface:\n if (t.methods.length !== 0) {\n $throwRuntimeError(\"cannot internalize \" + t.string);\n }\n if (v === null) {\n return $ifaceNil;\n }\n if (v === undefined) {\n return new $jsObjectPtr(undefined);\n }\n switch (v.constructor) {\n case Int8Array:\n return new ($sliceType($Int8))(v);\n case Int16Array:\n return new ($sliceType($Int16))(v);\n case Int32Array:\n return new ($sliceType($Int))(v);\n case Uint8Array:\n return new ($sliceType($Uint8))(v);\n case Uint16Array:\n return new ($sliceType($Uint16))(v);\n case Uint32Array:\n return new ($sliceType($Uint))(v);\n case Float32Array:\n return new ($sliceType($Float32))(v);\n case Float64Array:\n return new ($sliceType($Float64))(v);\n case Array:\n return $internalize(v, $sliceType($emptyInterface));\n case Boolean:\n return new $Bool(!!v);\n case Date:\n if (timePkg === undefined) {\n /* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */\n return new $jsObjectPtr(v);\n }\n return new timePkg.Time($internalize(v, timePkg.Time));\n case Function:\n var funcType = $funcType([$sliceType($emptyInterface)], [$jsObjectPtr], true);\n return new funcType($internalize(v, funcType));\n case Number:\n return new $Float64(parseFloat(v));\n case String:\n return new $String($internalize(v, $String));\n default:\n if ($global.Node && v instanceof $global.Node) {\n return new $jsObjectPtr(v);\n }\n var mapType = $mapType($String, $emptyInterface);\n return new mapType($internalize(v, mapType));\n }\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var k = $internalize(keys[i], t.key);\n m[t.key.keyFor(k)] = { k: k, v: $internalize(v[keys[i]], t.elem) };\n }\n return m;\n case $kindPtr:\n if (t.elem.kind === $kindStruct) {\n return $internalize(v, t.elem);\n }\n case $kindSlice:\n return new t(\n $mapArray(v, function(e) {\n return $internalize(e, t.elem);\n })\n );\n case $kindString:\n v = String(v);\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\";\n var i = 0;\n while (i < v.length) {\n var h = v.charCodeAt(i);\n if (0xd800 <= h && h <= 0xdbff) {\n var l = v.charCodeAt(i + 1);\n var c = (h - 0xd800) * 0x400 + l - 0xdc00 + 0x10000;\n s += $encodeRune(c);\n i += 2;\n continue;\n }\n s += $encodeRune(h);\n i++;\n }\n return s;\n case $kindStruct:\n var noJsObject = {};\n var searchJsObject = function(t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n switch (t.kind) {\n case $kindPtr:\n return searchJsObject(t.elem);\n case $kindStruct:\n var f = t.fields[0];\n var o = searchJsObject(f.typ);\n if (o !== noJsObject) {\n var n = new t.ptr();\n n[f.prop] = o;\n return n;\n }\n return noJsObject;\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(t);\n if (o !== noJsObject) {\n return o;\n }\n }\n $throwRuntimeError(\"cannot internalize \" + t.string);\n};\n\n/* $isASCII reports whether string s contains only ASCII characters. */\nvar $isASCII = function(s) {\n for (var i = 0; i < s.length; i++) {\n if (s.charCodeAt(i) >= 128) {\n return false;\n }\n }\n return true;\n};\n" +const Prelude = "Error.stackTraceLimit = Infinity;\n\nvar $global, $module;\nif (typeof window !== \"undefined\") {\n /* web page */\n $global = window;\n} else if (typeof self !== \"undefined\") {\n /* web worker */\n $global = self;\n} else if (typeof global !== \"undefined\") {\n /* Node.js */\n $global = global;\n $global.require = require;\n} else {\n /* others (e.g. Nashorn) */\n $global = this;\n}\n\nif ($global === undefined || $global.Array === undefined) {\n throw new Error(\"no global object found\");\n}\nif (typeof module !== \"undefined\") {\n $module = module;\n}\n\nvar $packages = {},\n $idCounter = 0;\nvar $keys = function(m) {\n return m ? Object.keys(m) : [];\n};\nvar $flushConsole = function() {};\nvar $throwRuntimeError; /* set by package \"runtime\" */\nvar $throwNilPointerError = function() {\n $throwRuntimeError(\"invalid memory address or nil pointer dereference\");\n};\nvar $call = function(fn, rcvr, args) {\n return fn.apply(rcvr, args);\n};\nvar $makeFunc = function(fn) {\n return function() {\n return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface);\n };\n};\nvar $unused = function(v) {};\n\nvar $mapArray = function(array, f) {\n var newArray = new array.constructor(array.length);\n for (var i = 0; i < array.length; i++) {\n newArray[i] = f(array[i]);\n }\n return newArray;\n};\n\nvar $methodVal = function(recv, name) {\n var vals = recv.$methodVals || {};\n recv.$methodVals = vals; /* noop for primitives */\n var f = vals[name];\n if (f !== undefined) {\n return f;\n }\n var method = recv[name];\n f = function() {\n $stackDepthOffset--;\n try {\n return method.apply(recv, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n vals[name] = f;\n return f;\n};\n\nvar $methodExpr = function(typ, name) {\n var method = typ.prototype[name];\n if (method.$expr === undefined) {\n method.$expr = function() {\n $stackDepthOffset--;\n try {\n if (typ.wrapped) {\n arguments[0] = new typ(arguments[0]);\n }\n return Function.call.apply(method, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return method.$expr;\n};\n\nvar $ifaceMethodExprs = {};\nvar $ifaceMethodExpr = function(name) {\n var expr = $ifaceMethodExprs[\"$\" + name];\n if (expr === undefined) {\n expr = $ifaceMethodExprs[\"$\" + name] = function() {\n $stackDepthOffset--;\n try {\n return Function.call.apply(arguments[0][name], arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return expr;\n};\n\nvar $subslice = function(slice, low, high, max) {\n if (high === undefined) {\n high = slice.$length;\n }\n if (max === undefined) {\n max = slice.$capacity;\n }\n if (low < 0 || high < low || max < high || high > slice.$capacity || max > slice.$capacity) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n var s = new slice.constructor(slice.$array);\n s.$offset = slice.$offset + low;\n s.$length = high - low;\n s.$capacity = max - low;\n return s;\n};\n\nvar $substring = function(str, low, high) {\n if (low < 0 || high < low || high > str.length) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n return str.substring(low, high);\n};\n\nvar $sliceToArray = function(slice) {\n if (slice.$array.constructor !== Array) {\n return slice.$array.subarray(slice.$offset, slice.$offset + slice.$length);\n }\n return slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n};\n\nvar $decodeRune = function(str, pos) {\n var c0 = str.charCodeAt(pos);\n\n if (c0 < 0x80) {\n return [c0, 1];\n }\n\n if (c0 !== c0 || c0 < 0xc0) {\n return [0xfffd, 1];\n }\n\n var c1 = str.charCodeAt(pos + 1);\n if (c1 !== c1 || c1 < 0x80 || 0xc0 <= c1) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xe0) {\n var r = ((c0 & 0x1f) << 6) | (c1 & 0x3f);\n if (r <= 0x7f) {\n return [0xfffd, 1];\n }\n return [r, 2];\n }\n\n var c2 = str.charCodeAt(pos + 2);\n if (c2 !== c2 || c2 < 0x80 || 0xc0 <= c2) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xf0) {\n var r = ((c0 & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f);\n if (r <= 0x7ff) {\n return [0xfffd, 1];\n }\n if (0xd800 <= r && r <= 0xdfff) {\n return [0xfffd, 1];\n }\n return [r, 3];\n }\n\n var c3 = str.charCodeAt(pos + 3);\n if (c3 !== c3 || c3 < 0x80 || 0xc0 <= c3) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xf8) {\n var r = ((c0 & 0x07) << 18) | ((c1 & 0x3f) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f);\n if (r <= 0xffff || 0x10ffff < r) {\n return [0xfffd, 1];\n }\n return [r, 4];\n }\n\n return [0xfffd, 1];\n};\n\nvar $encodeRune = function(r) {\n if (r < 0 || r > 0x10ffff || (0xd800 <= r && r <= 0xdfff)) {\n r = 0xfffd;\n }\n if (r <= 0x7f) {\n return String.fromCharCode(r);\n }\n if (r <= 0x7ff) {\n return String.fromCharCode(0xc0 | (r >> 6), 0x80 | (r & 0x3f));\n }\n if (r <= 0xffff) {\n return String.fromCharCode(0xe0 | (r >> 12), 0x80 | ((r >> 6) & 0x3f), 0x80 | (r & 0x3f));\n }\n return String.fromCharCode(0xf0 | (r >> 18), 0x80 | ((r >> 12) & 0x3f), 0x80 | ((r >> 6) & 0x3f), 0x80 | (r & 0x3f));\n};\n\nvar $stringToBytes = function(str) {\n var array = new Uint8Array(str.length);\n for (var i = 0; i < str.length; i++) {\n array[i] = str.charCodeAt(i);\n }\n return array;\n};\n\nvar $bytesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i += 10000) {\n str += String.fromCharCode.apply(undefined, slice.$array.subarray(slice.$offset + i, slice.$offset + Math.min(slice.$length, i + 10000)));\n }\n return str;\n};\n\nvar $stringToRunes = function(str) {\n var array = new Int32Array(str.length);\n var rune,\n j = 0;\n for (var i = 0; i < str.length; i += rune[1], j++) {\n rune = $decodeRune(str, i);\n array[j] = rune[0];\n }\n return array.subarray(0, j);\n};\n\nvar $runesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i++) {\n str += $encodeRune(slice.$array[slice.$offset + i]);\n }\n return str;\n};\n\nvar $copyString = function(dst, src) {\n var n = Math.min(src.length, dst.$length);\n for (var i = 0; i < n; i++) {\n dst.$array[dst.$offset + i] = src.charCodeAt(i);\n }\n return n;\n};\n\nvar $copySlice = function(dst, src) {\n var n = Math.min(src.$length, dst.$length);\n $copyArray(dst.$array, src.$array, dst.$offset, src.$offset, n, dst.constructor.elem);\n return n;\n};\n\nvar $copyArray = function(dst, src, dstOffset, srcOffset, n, elem) {\n if (n === 0 || (dst === src && dstOffset === srcOffset)) {\n return;\n }\n\n if (src.subarray) {\n dst.set(src.subarray(srcOffset, srcOffset + n), dstOffset);\n return;\n }\n\n switch (elem.kind) {\n case $kindArray:\n case $kindStruct:\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n};\n\nvar $clone = function(src, type) {\n var clone = type.zero();\n type.copy(clone, src);\n return clone;\n};\n\nvar $pointerOfStructConversion = function(obj, type) {\n if (obj.$proxies === undefined) {\n obj.$proxies = {};\n obj.$proxies[obj.constructor.string] = obj;\n }\n var proxy = obj.$proxies[type.string];\n if (proxy === undefined) {\n var properties = {};\n for (var i = 0; i < type.elem.fields.length; i++) {\n (function(fieldProp) {\n properties[fieldProp] = {\n get: function() {\n return obj[fieldProp];\n },\n set: function(value) {\n obj[fieldProp] = value;\n },\n };\n })(type.elem.fields[i].prop);\n }\n proxy = Object.create(type.prototype, properties);\n proxy.$val = proxy;\n obj.$proxies[type.string] = proxy;\n proxy.$proxies = obj.$proxies;\n }\n return proxy;\n};\n\nvar $append = function(slice) {\n return $internalAppend(slice, arguments, 1, arguments.length - 1);\n};\n\nvar $appendSlice = function(slice, toAppend) {\n if (toAppend.constructor === String) {\n var bytes = $stringToBytes(toAppend);\n return $internalAppend(slice, bytes, 0, bytes.length);\n }\n return $internalAppend(slice, toAppend.$array, toAppend.$offset, toAppend.$length);\n};\n\nvar $internalAppend = function(slice, array, offset, length) {\n if (length === 0) {\n return slice;\n }\n\n var newArray = slice.$array;\n var newOffset = slice.$offset;\n var newLength = slice.$length + length;\n var newCapacity = slice.$capacity;\n\n if (newLength > newCapacity) {\n newOffset = 0;\n newCapacity = Math.max(newLength, slice.$capacity < 1024 ? slice.$capacity * 2 : Math.floor(slice.$capacity * 5 / 4));\n\n if (slice.$array.constructor === Array) {\n newArray = slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n newArray.length = newCapacity;\n var zero = slice.constructor.elem.zero;\n for (var i = slice.$length; i < newCapacity; i++) {\n newArray[i] = zero();\n }\n } else {\n newArray = new slice.$array.constructor(newCapacity);\n newArray.set(slice.$array.subarray(slice.$offset, slice.$offset + slice.$length));\n }\n }\n\n $copyArray(newArray, array, newOffset + slice.$length, offset, length, slice.constructor.elem);\n\n var newSlice = new slice.constructor(newArray);\n newSlice.$offset = newOffset;\n newSlice.$length = newLength;\n newSlice.$capacity = newCapacity;\n return newSlice;\n};\n\nvar $equal = function(a, b, type) {\n if (type === $jsObjectPtr) {\n return a === b;\n }\n switch (type.kind) {\n case $kindComplex64:\n case $kindComplex128:\n return a.$real === b.$real && a.$imag === b.$imag;\n case $kindInt64:\n case $kindUint64:\n return a.$high === b.$high && a.$low === b.$low;\n case $kindArray:\n if (a.length !== b.length) {\n return false;\n }\n for (var i = 0; i < a.length; i++) {\n if (!$equal(a[i], b[i], type.elem)) {\n return false;\n }\n }\n return true;\n case $kindStruct:\n for (var i = 0; i < type.fields.length; i++) {\n var f = type.fields[i];\n if (!$equal(a[f.prop], b[f.prop], f.typ)) {\n return false;\n }\n }\n return true;\n case $kindInterface:\n return $interfaceIsEqual(a, b);\n default:\n return a === b;\n }\n};\n\nvar $interfaceIsEqual = function(a, b) {\n if (a === $ifaceNil || b === $ifaceNil) {\n return a === b;\n }\n if (a.constructor !== b.constructor) {\n return false;\n }\n if (a.constructor === $jsObjectPtr) {\n return a.object === b.object;\n }\n if (!a.constructor.comparable) {\n $throwRuntimeError(\"comparing uncomparable type \" + a.constructor.string);\n }\n return $equal(a.$val, b.$val, a.constructor);\n};\nvar $min = Math.min;\nvar $mod = function(x, y) {\n return x % y;\n};\nvar $parseInt = parseInt;\nvar $parseFloat = function(f) {\n if (f !== undefined && f !== null && f.constructor === Number) {\n return f;\n }\n return parseFloat(f);\n};\n\nvar $froundBuf = new Float32Array(1);\nvar $fround =\n Math.fround ||\n function(f) {\n $froundBuf[0] = f;\n return $froundBuf[0];\n };\n\nvar $imul =\n Math.imul ||\n function(a, b) {\n var ah = (a >>> 16) & 0xffff;\n var al = a & 0xffff;\n var bh = (b >>> 16) & 0xffff;\n var bl = b & 0xffff;\n return (al * bl + (((ah * bl + al * bh) << 16) >>> 0)) >> 0;\n };\n\nvar $floatKey = function(f) {\n if (f !== f) {\n $idCounter++;\n return \"NaN$\" + $idCounter;\n }\n return String(f);\n};\n\nvar $flatten64 = function(x) {\n return x.$high * 4294967296 + x.$low;\n};\n\nvar $shiftLeft64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor((x.$high << y) | (x.$low >>> (32 - y)), (x.$low << y) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$low << (y - 32), 0);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightInt64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >> y, ((x.$low >>> y) | (x.$high << (32 - y))) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$high >> 31, (x.$high >> (y - 32)) >>> 0);\n }\n if (x.$high < 0) {\n return new x.constructor(-1, 4294967295);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightUint64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >>> y, ((x.$low >>> y) | (x.$high << (32 - y))) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(0, x.$high >>> (y - 32));\n }\n return new x.constructor(0, 0);\n};\n\nvar $mul64 = function(x, y) {\n var high = 0,\n low = 0;\n if ((y.$low & 1) !== 0) {\n high = x.$high;\n low = x.$low;\n }\n for (var i = 1; i < 32; i++) {\n if ((y.$low & (1 << i)) !== 0) {\n high += (x.$high << i) | (x.$low >>> (32 - i));\n low += (x.$low << i) >>> 0;\n }\n }\n for (var i = 0; i < 32; i++) {\n if ((y.$high & (1 << i)) !== 0) {\n high += x.$low << i;\n }\n }\n return new x.constructor(high, low);\n};\n\nvar $div64 = function(x, y, returnRemainder) {\n if (y.$high === 0 && y.$low === 0) {\n $throwRuntimeError(\"integer divide by zero\");\n }\n\n var s = 1;\n var rs = 1;\n\n var xHigh = x.$high;\n var xLow = x.$low;\n if (xHigh < 0) {\n s = -1;\n rs = -1;\n xHigh = -xHigh;\n if (xLow !== 0) {\n xHigh--;\n xLow = 4294967296 - xLow;\n }\n }\n\n var yHigh = y.$high;\n var yLow = y.$low;\n if (y.$high < 0) {\n s *= -1;\n yHigh = -yHigh;\n if (yLow !== 0) {\n yHigh--;\n yLow = 4294967296 - yLow;\n }\n }\n\n var high = 0,\n low = 0,\n n = 0;\n while (yHigh < 2147483648 && (xHigh > yHigh || (xHigh === yHigh && xLow > yLow))) {\n yHigh = ((yHigh << 1) | (yLow >>> 31)) >>> 0;\n yLow = (yLow << 1) >>> 0;\n n++;\n }\n for (var i = 0; i <= n; i++) {\n high = (high << 1) | (low >>> 31);\n low = (low << 1) >>> 0;\n if (xHigh > yHigh || (xHigh === yHigh && xLow >= yLow)) {\n xHigh = xHigh - yHigh;\n xLow = xLow - yLow;\n if (xLow < 0) {\n xHigh--;\n xLow += 4294967296;\n }\n low++;\n if (low === 4294967296) {\n high++;\n low = 0;\n }\n }\n yLow = ((yLow >>> 1) | (yHigh << (32 - 1))) >>> 0;\n yHigh = yHigh >>> 1;\n }\n\n if (returnRemainder) {\n return new x.constructor(xHigh * rs, xLow * rs);\n }\n return new x.constructor(high * s, low * s);\n};\n\nvar $divComplex = function(n, d) {\n var ninf = n.$real === Infinity || n.$real === -Infinity || n.$imag === Infinity || n.$imag === -Infinity;\n var dinf = d.$real === Infinity || d.$real === -Infinity || d.$imag === Infinity || d.$imag === -Infinity;\n var nnan = !ninf && (n.$real !== n.$real || n.$imag !== n.$imag);\n var dnan = !dinf && (d.$real !== d.$real || d.$imag !== d.$imag);\n if (nnan || dnan) {\n return new n.constructor(NaN, NaN);\n }\n if (ninf && !dinf) {\n return new n.constructor(Infinity, Infinity);\n }\n if (!ninf && dinf) {\n return new n.constructor(0, 0);\n }\n if (d.$real === 0 && d.$imag === 0) {\n if (n.$real === 0 && n.$imag === 0) {\n return new n.constructor(NaN, NaN);\n }\n return new n.constructor(Infinity, Infinity);\n }\n var a = Math.abs(d.$real);\n var b = Math.abs(d.$imag);\n if (a <= b) {\n var ratio = d.$real / d.$imag;\n var denom = d.$real * ratio + d.$imag;\n return new n.constructor((n.$real * ratio + n.$imag) / denom, (n.$imag * ratio - n.$real) / denom);\n }\n var ratio = d.$imag / d.$real;\n var denom = d.$imag * ratio + d.$real;\n return new n.constructor((n.$imag * ratio + n.$real) / denom, (n.$imag - n.$real * ratio) / denom);\n};\nvar $kindBool = 1;\nvar $kindInt = 2;\nvar $kindInt8 = 3;\nvar $kindInt16 = 4;\nvar $kindInt32 = 5;\nvar $kindInt64 = 6;\nvar $kindUint = 7;\nvar $kindUint8 = 8;\nvar $kindUint16 = 9;\nvar $kindUint32 = 10;\nvar $kindUint64 = 11;\nvar $kindUintptr = 12;\nvar $kindFloat32 = 13;\nvar $kindFloat64 = 14;\nvar $kindComplex64 = 15;\nvar $kindComplex128 = 16;\nvar $kindArray = 17;\nvar $kindChan = 18;\nvar $kindFunc = 19;\nvar $kindInterface = 20;\nvar $kindMap = 21;\nvar $kindPtr = 22;\nvar $kindSlice = 23;\nvar $kindString = 24;\nvar $kindStruct = 25;\nvar $kindUnsafePointer = 26;\n\nvar $methodSynthesizers = [];\nvar $addMethodSynthesizer = function(f) {\n if ($methodSynthesizers === null) {\n f();\n return;\n }\n $methodSynthesizers.push(f);\n};\nvar $synthesizeMethods = function() {\n $methodSynthesizers.forEach(function(f) {\n f();\n });\n $methodSynthesizers = null;\n};\n\nvar $ifaceKeyFor = function(x) {\n if (x === $ifaceNil) {\n return \"nil\";\n }\n var c = x.constructor;\n return c.string + \"$\" + c.keyFor(x.$val);\n};\n\nvar $identity = function(x) {\n return x;\n};\n\nvar $typeIDCounter = 0;\n\nvar $idKey = function(x) {\n if (x.$id === undefined) {\n $idCounter++;\n x.$id = $idCounter;\n }\n return String(x.$id);\n};\n\nvar $newType = function(size, kind, string, named, pkg, exported, constructor) {\n var typ;\n switch (kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = $identity;\n break;\n\n case $kindString:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = function(x) {\n return \"$\" + x;\n };\n break;\n\n case $kindFloat32:\n case $kindFloat64:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = function(x) {\n return $floatKey(x);\n };\n break;\n\n case $kindInt64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$high + \"$\" + x.$low;\n };\n break;\n\n case $kindUint64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >>> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$high + \"$\" + x.$low;\n };\n break;\n\n case $kindComplex64:\n typ = function(real, imag) {\n this.$real = $fround(real);\n this.$imag = $fround(imag);\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$real + \"$\" + x.$imag;\n };\n break;\n\n case $kindComplex128:\n typ = function(real, imag) {\n this.$real = real;\n this.$imag = imag;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$real + \"$\" + x.$imag;\n };\n break;\n\n case $kindArray:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, \"\", false, function(array) {\n this.$get = function() {\n return array;\n };\n this.$set = function(v) {\n typ.copy(this, v);\n };\n this.$val = array;\n });\n typ.init = function(elem, len) {\n typ.elem = elem;\n typ.len = len;\n typ.comparable = elem.comparable;\n typ.keyFor = function(x) {\n return Array.prototype.join.call(\n $mapArray(x, function(e) {\n return String(elem.keyFor(e))\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\$/g, \"\\\\$\");\n }),\n \"$\"\n );\n };\n typ.copy = function(dst, src) {\n $copyArray(dst, src, 0, 0, src.length, elem);\n };\n typ.ptr.init(typ);\n Object.defineProperty(typ.ptr.nil, \"nilCheck\", { get: $throwNilPointerError });\n };\n break;\n\n case $kindChan:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = $idKey;\n typ.init = function(elem, sendOnly, recvOnly) {\n typ.elem = elem;\n typ.sendOnly = sendOnly;\n typ.recvOnly = recvOnly;\n };\n break;\n\n case $kindFunc:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.init = function(params, results, variadic) {\n typ.params = params;\n typ.results = results;\n typ.variadic = variadic;\n typ.comparable = false;\n };\n break;\n\n case $kindInterface:\n typ = { implementedBy: {}, missingMethodFor: {} };\n typ.keyFor = $ifaceKeyFor;\n typ.init = function(methods) {\n typ.methods = methods;\n methods.forEach(function(m) {\n $ifaceNil[m.prop] = $throwNilPointerError;\n });\n };\n break;\n\n case $kindMap:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.init = function(key, elem) {\n typ.key = key;\n typ.elem = elem;\n typ.comparable = false;\n };\n break;\n\n case $kindPtr:\n typ =\n constructor ||\n function(getter, setter, target) {\n this.$get = getter;\n this.$set = setter;\n this.$target = target;\n this.$val = this;\n };\n typ.keyFor = $idKey;\n typ.init = function(elem) {\n typ.elem = elem;\n typ.wrapped = elem.kind === $kindArray;\n typ.nil = new typ($throwNilPointerError, $throwNilPointerError);\n };\n break;\n\n case $kindSlice:\n typ = function(array) {\n if (array.constructor !== typ.nativeArray) {\n array = new typ.nativeArray(array);\n }\n this.$array = array;\n this.$offset = 0;\n this.$length = array.length;\n this.$capacity = array.length;\n this.$val = this;\n };\n typ.init = function(elem) {\n typ.elem = elem;\n typ.comparable = false;\n typ.nativeArray = $nativeArray(elem.kind);\n typ.nil = new typ([]);\n };\n break;\n\n case $kindStruct:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, pkg, exported, constructor);\n typ.ptr.elem = typ;\n typ.ptr.prototype.$get = function() {\n return this;\n };\n typ.ptr.prototype.$set = function(v) {\n typ.copy(this, v);\n };\n typ.init = function(pkgPath, fields) {\n typ.pkgPath = pkgPath;\n typ.fields = fields;\n fields.forEach(function(f) {\n if (!f.typ.comparable) {\n typ.comparable = false;\n }\n });\n typ.keyFor = function(x) {\n var val = x.$val;\n return $mapArray(fields, function(f) {\n return String(f.typ.keyFor(val[f.prop]))\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\$/g, \"\\\\$\");\n }).join(\"$\");\n };\n typ.copy = function(dst, src) {\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n switch (f.typ.kind) {\n case $kindArray:\n case $kindStruct:\n f.typ.copy(dst[f.prop], src[f.prop]);\n continue;\n default:\n dst[f.prop] = src[f.prop];\n continue;\n }\n }\n };\n /* nil value */\n var properties = {};\n fields.forEach(function(f) {\n properties[f.prop] = { get: $throwNilPointerError, set: $throwNilPointerError };\n });\n typ.ptr.nil = Object.create(constructor.prototype, properties);\n typ.ptr.nil.$val = typ.ptr.nil;\n /* methods for embedded fields */\n $addMethodSynthesizer(function() {\n var synthesizeMethod = function(target, m, f) {\n if (target.prototype[m.prop] !== undefined) {\n return;\n }\n target.prototype[m.prop] = function() {\n var v = this.$val[f.prop];\n if (f.typ === $jsObjectPtr) {\n v = new $jsObjectPtr(v);\n }\n if (v.$val === undefined) {\n v = new f.typ(v);\n }\n return v[m.prop].apply(v, arguments);\n };\n };\n fields.forEach(function(f) {\n if (f.anonymous) {\n $methodSet(f.typ).forEach(function(m) {\n synthesizeMethod(typ, m, f);\n synthesizeMethod(typ.ptr, m, f);\n });\n $methodSet($ptrType(f.typ)).forEach(function(m) {\n synthesizeMethod(typ.ptr, m, f);\n });\n }\n });\n });\n };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n switch (kind) {\n case $kindBool:\n case $kindMap:\n typ.zero = function() {\n return false;\n };\n break;\n\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n case $kindFloat32:\n case $kindFloat64:\n typ.zero = function() {\n return 0;\n };\n break;\n\n case $kindString:\n typ.zero = function() {\n return \"\";\n };\n break;\n\n case $kindInt64:\n case $kindUint64:\n case $kindComplex64:\n case $kindComplex128:\n var zero = new typ(0, 0);\n typ.zero = function() {\n return zero;\n };\n break;\n\n case $kindPtr:\n case $kindSlice:\n typ.zero = function() {\n return typ.nil;\n };\n break;\n\n case $kindChan:\n typ.zero = function() {\n return $chanNil;\n };\n break;\n\n case $kindFunc:\n typ.zero = function() {\n return $throwNilPointerError;\n };\n break;\n\n case $kindInterface:\n typ.zero = function() {\n return $ifaceNil;\n };\n break;\n\n case $kindArray:\n typ.zero = function() {\n var arrayClass = $nativeArray(typ.elem.kind);\n if (arrayClass !== Array) {\n return new arrayClass(typ.len);\n }\n var array = new Array(typ.len);\n for (var i = 0; i < typ.len; i++) {\n array[i] = typ.elem.zero();\n }\n return array;\n };\n break;\n\n case $kindStruct:\n typ.zero = function() {\n return new typ.ptr();\n };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n typ.id = $typeIDCounter;\n $typeIDCounter++;\n typ.size = size;\n typ.kind = kind;\n typ.string = string;\n typ.named = named;\n typ.pkg = pkg;\n typ.exported = exported;\n typ.methods = [];\n typ.methodSetCache = null;\n typ.comparable = true;\n return typ;\n};\n\nvar $methodSet = function(typ) {\n if (typ.methodSetCache !== null) {\n return typ.methodSetCache;\n }\n var base = {};\n\n var isPtr = typ.kind === $kindPtr;\n if (isPtr && typ.elem.kind === $kindInterface) {\n typ.methodSetCache = [];\n return [];\n }\n\n var current = [{ typ: isPtr ? typ.elem : typ, indirect: isPtr }];\n\n var seen = {};\n\n while (current.length > 0) {\n var next = [];\n var mset = [];\n\n current.forEach(function(e) {\n if (seen[e.typ.string]) {\n return;\n }\n seen[e.typ.string] = true;\n\n if (e.typ.named) {\n mset = mset.concat(e.typ.methods);\n if (e.indirect) {\n mset = mset.concat($ptrType(e.typ).methods);\n }\n }\n\n switch (e.typ.kind) {\n case $kindStruct:\n e.typ.fields.forEach(function(f) {\n if (f.anonymous) {\n var fTyp = f.typ;\n var fIsPtr = fTyp.kind === $kindPtr;\n next.push({ typ: fIsPtr ? fTyp.elem : fTyp, indirect: e.indirect || fIsPtr });\n }\n });\n break;\n\n case $kindInterface:\n mset = mset.concat(e.typ.methods);\n break;\n }\n });\n\n mset.forEach(function(m) {\n if (base[m.name] === undefined) {\n base[m.name] = m;\n }\n });\n\n current = next;\n }\n\n typ.methodSetCache = [];\n Object.keys(base)\n .sort()\n .forEach(function(name) {\n typ.methodSetCache.push(base[name]);\n });\n return typ.methodSetCache;\n};\n\nvar $Bool = $newType(1, $kindBool, \"bool\", true, \"\", false, null);\nvar $Int = $newType(4, $kindInt, \"int\", true, \"\", false, null);\nvar $Int8 = $newType(1, $kindInt8, \"int8\", true, \"\", false, null);\nvar $Int16 = $newType(2, $kindInt16, \"int16\", true, \"\", false, null);\nvar $Int32 = $newType(4, $kindInt32, \"int32\", true, \"\", false, null);\nvar $Int64 = $newType(8, $kindInt64, \"int64\", true, \"\", false, null);\nvar $Uint = $newType(4, $kindUint, \"uint\", true, \"\", false, null);\nvar $Uint8 = $newType(1, $kindUint8, \"uint8\", true, \"\", false, null);\nvar $Uint16 = $newType(2, $kindUint16, \"uint16\", true, \"\", false, null);\nvar $Uint32 = $newType(4, $kindUint32, \"uint32\", true, \"\", false, null);\nvar $Uint64 = $newType(8, $kindUint64, \"uint64\", true, \"\", false, null);\nvar $Uintptr = $newType(4, $kindUintptr, \"uintptr\", true, \"\", false, null);\nvar $Float32 = $newType(4, $kindFloat32, \"float32\", true, \"\", false, null);\nvar $Float64 = $newType(8, $kindFloat64, \"float64\", true, \"\", false, null);\nvar $Complex64 = $newType(8, $kindComplex64, \"complex64\", true, \"\", false, null);\nvar $Complex128 = $newType(16, $kindComplex128, \"complex128\", true, \"\", false, null);\nvar $String = $newType(8, $kindString, \"string\", true, \"\", false, null);\nvar $UnsafePointer = $newType(4, $kindUnsafePointer, \"unsafe.Pointer\", true, \"\", false, null);\n\nvar $nativeArray = function(elemKind) {\n switch (elemKind) {\n case $kindInt:\n return Int32Array;\n case $kindInt8:\n return Int8Array;\n case $kindInt16:\n return Int16Array;\n case $kindInt32:\n return Int32Array;\n case $kindUint:\n return Uint32Array;\n case $kindUint8:\n return Uint8Array;\n case $kindUint16:\n return Uint16Array;\n case $kindUint32:\n return Uint32Array;\n case $kindUintptr:\n return Uint32Array;\n case $kindFloat32:\n return Float32Array;\n case $kindFloat64:\n return Float64Array;\n default:\n return Array;\n }\n};\nvar $toNativeArray = function(elemKind, array) {\n var nativeArray = $nativeArray(elemKind);\n if (nativeArray === Array) {\n return array;\n }\n return new nativeArray(array);\n};\nvar $arrayTypes = {};\nvar $arrayType = function(elem, len) {\n var typeKey = elem.id + \"$\" + len;\n var typ = $arrayTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(12, $kindArray, \"[\" + len + \"]\" + elem.string, false, \"\", false, null);\n $arrayTypes[typeKey] = typ;\n typ.init(elem, len);\n }\n return typ;\n};\n\nvar $chanType = function(elem, sendOnly, recvOnly) {\n var string = (recvOnly ? \"<-\" : \"\") + \"chan\" + (sendOnly ? \"<- \" : \" \") + elem.string;\n var field = sendOnly ? \"SendChan\" : recvOnly ? \"RecvChan\" : \"Chan\";\n var typ = elem[field];\n if (typ === undefined) {\n typ = $newType(4, $kindChan, string, false, \"\", false, null);\n elem[field] = typ;\n typ.init(elem, sendOnly, recvOnly);\n }\n return typ;\n};\nvar $Chan = function(elem, capacity) {\n if (capacity < 0 || capacity > 2147483647) {\n $throwRuntimeError(\"makechan: size out of range\");\n }\n this.$elem = elem;\n this.$capacity = capacity;\n this.$buffer = [];\n this.$sendQueue = [];\n this.$recvQueue = [];\n this.$closed = false;\n};\nvar $chanNil = new $Chan(null, 0);\n$chanNil.$sendQueue = $chanNil.$recvQueue = {\n length: 0,\n push: function() {},\n shift: function() {\n return undefined;\n },\n indexOf: function() {\n return -1;\n },\n};\n\nvar $funcTypes = {};\nvar $funcType = function(params, results, variadic) {\n var typeKey =\n $mapArray(params, function(p) {\n return p.id;\n }).join(\",\") +\n \"$\" +\n $mapArray(results, function(r) {\n return r.id;\n }).join(\",\") +\n \"$\" +\n variadic;\n var typ = $funcTypes[typeKey];\n if (typ === undefined) {\n var paramTypes = $mapArray(params, function(p) {\n return p.string;\n });\n if (variadic) {\n paramTypes[paramTypes.length - 1] = \"...\" + paramTypes[paramTypes.length - 1].substr(2);\n }\n var string = \"func(\" + paramTypes.join(\", \") + \")\";\n if (results.length === 1) {\n string += \" \" + results[0].string;\n } else if (results.length > 1) {\n string +=\n \" (\" +\n $mapArray(results, function(r) {\n return r.string;\n }).join(\", \") +\n \")\";\n }\n typ = $newType(4, $kindFunc, string, false, \"\", false, null);\n $funcTypes[typeKey] = typ;\n typ.init(params, results, variadic);\n }\n return typ;\n};\n\nvar $interfaceTypes = {};\nvar $interfaceType = function(methods) {\n var typeKey = $mapArray(methods, function(m) {\n return m.pkg + \",\" + m.name + \",\" + m.typ.id;\n }).join(\"$\");\n var typ = $interfaceTypes[typeKey];\n if (typ === undefined) {\n var string = \"interface {}\";\n if (methods.length !== 0) {\n string =\n \"interface { \" +\n $mapArray(methods, function(m) {\n return (m.pkg !== \"\" ? m.pkg + \".\" : \"\") + m.name + m.typ.string.substr(4);\n }).join(\"; \") +\n \" }\";\n }\n typ = $newType(8, $kindInterface, string, false, \"\", false, null);\n $interfaceTypes[typeKey] = typ;\n typ.init(methods);\n }\n return typ;\n};\nvar $emptyInterface = $interfaceType([]);\nvar $ifaceNil = {};\nvar $error = $newType(8, $kindInterface, \"error\", true, \"\", false, null);\n$error.init([{ prop: \"Error\", name: \"Error\", pkg: \"\", typ: $funcType([], [$String], false) }]);\n\nvar $mapTypes = {};\nvar $mapType = function(key, elem) {\n var typeKey = key.id + \"$\" + elem.id;\n var typ = $mapTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(4, $kindMap, \"map[\" + key.string + \"]\" + elem.string, false, \"\", false, null);\n $mapTypes[typeKey] = typ;\n typ.init(key, elem);\n }\n return typ;\n};\nvar $makeMap = function(keyForFunc, entries) {\n var m = {};\n for (var i = 0; i < entries.length; i++) {\n var e = entries[i];\n m[keyForFunc(e.k)] = e;\n }\n return m;\n};\n\nvar $ptrType = function(elem) {\n var typ = elem.ptr;\n if (typ === undefined) {\n typ = $newType(4, $kindPtr, \"*\" + elem.string, false, \"\", elem.exported, null);\n elem.ptr = typ;\n typ.init(elem);\n }\n return typ;\n};\n\nvar $newDataPointer = function(data, constructor) {\n if (constructor.elem.kind === $kindStruct) {\n return data;\n }\n return new constructor(\n function() {\n return data;\n },\n function(v) {\n data = v;\n }\n );\n};\n\nvar $indexPtr = function(array, index, constructor) {\n array.$ptr = array.$ptr || {};\n return (\n array.$ptr[index] ||\n (array.$ptr[index] = new constructor(\n function() {\n return array[index];\n },\n function(v) {\n array[index] = v;\n }\n ))\n );\n};\n\nvar $sliceType = function(elem) {\n var typ = elem.slice;\n if (typ === undefined) {\n typ = $newType(12, $kindSlice, \"[]\" + elem.string, false, \"\", false, null);\n elem.slice = typ;\n typ.init(elem);\n }\n return typ;\n};\nvar $makeSlice = function(typ, length, capacity) {\n capacity = capacity || length;\n if (length < 0 || length > 2147483647) {\n $throwRuntimeError(\"makeslice: len out of range\");\n }\n if (capacity < 0 || capacity < length || capacity > 2147483647) {\n $throwRuntimeError(\"makeslice: cap out of range\");\n }\n var array = new typ.nativeArray(capacity);\n if (typ.nativeArray === Array) {\n for (var i = 0; i < capacity; i++) {\n array[i] = typ.elem.zero();\n }\n }\n var slice = new typ(array);\n slice.$length = length;\n return slice;\n};\n\nvar $structTypes = {};\nvar $structType = function(pkgPath, fields) {\n var typeKey = $mapArray(fields, function(f) {\n return f.name + \",\" + f.typ.id + \",\" + f.tag;\n }).join(\"$\");\n var typ = $structTypes[typeKey];\n if (typ === undefined) {\n var string =\n \"struct { \" +\n $mapArray(fields, function(f) {\n return f.name + \" \" + f.typ.string + (f.tag !== \"\" ? ' \"' + f.tag.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"') + '\"' : \"\");\n }).join(\"; \") +\n \" }\";\n if (fields.length === 0) {\n string = \"struct {}\";\n }\n typ = $newType(0, $kindStruct, string, false, \"\", false, function() {\n this.$val = this;\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n var arg = arguments[i];\n this[f.prop] = arg !== undefined ? arg : f.typ.zero();\n }\n });\n $structTypes[typeKey] = typ;\n typ.init(pkgPath, fields);\n }\n return typ;\n};\n\nvar $assertType = function(value, type, returnTuple) {\n var isInterface = type.kind === $kindInterface,\n ok,\n missingMethod = \"\";\n if (value === $ifaceNil) {\n ok = false;\n } else if (!isInterface) {\n ok = value.constructor === type;\n } else {\n var valueTypeString = value.constructor.string;\n ok = type.implementedBy[valueTypeString];\n if (ok === undefined) {\n ok = true;\n var valueMethodSet = $methodSet(value.constructor);\n var interfaceMethods = type.methods;\n for (var i = 0; i < interfaceMethods.length; i++) {\n var tm = interfaceMethods[i];\n var found = false;\n for (var j = 0; j < valueMethodSet.length; j++) {\n var vm = valueMethodSet[j];\n if (vm.name === tm.name && vm.pkg === tm.pkg && vm.typ === tm.typ) {\n found = true;\n break;\n }\n }\n if (!found) {\n ok = false;\n type.missingMethodFor[valueTypeString] = tm.name;\n break;\n }\n }\n type.implementedBy[valueTypeString] = ok;\n }\n if (!ok) {\n missingMethod = type.missingMethodFor[valueTypeString];\n }\n }\n\n if (!ok) {\n if (returnTuple) {\n return [type.zero(), false];\n }\n $panic(new $packages[\"runtime\"].TypeAssertionError.ptr(\"\", value === $ifaceNil ? \"\" : value.constructor.string, type.string, missingMethod));\n }\n\n if (!isInterface) {\n value = value.$val;\n }\n if (type === $jsObjectPtr) {\n value = value.object;\n }\n return returnTuple ? [value, true] : value;\n};\nvar $stackDepthOffset = 0;\nvar $getStackDepth = function() {\n var err = new Error();\n if (err.stack === undefined) {\n return undefined;\n }\n return $stackDepthOffset + err.stack.split(\"\\n\").length;\n};\n\nvar $panicStackDepth = null,\n $panicValue;\nvar $callDeferred = function(deferred, jsErr, fromPanic) {\n if (!fromPanic && deferred !== null && deferred.index >= $curGoroutine.deferStack.length) {\n throw jsErr;\n }\n if (jsErr !== null) {\n var newErr = null;\n try {\n $curGoroutine.deferStack.push(deferred);\n $panic(new $jsErrorPtr(jsErr));\n } catch (err) {\n newErr = err;\n }\n $curGoroutine.deferStack.pop();\n $callDeferred(deferred, newErr);\n return;\n }\n if ($curGoroutine.asleep) {\n return;\n }\n\n $stackDepthOffset--;\n var outerPanicStackDepth = $panicStackDepth;\n var outerPanicValue = $panicValue;\n\n var localPanicValue = $curGoroutine.panicStack.pop();\n if (localPanicValue !== undefined) {\n $panicStackDepth = $getStackDepth();\n $panicValue = localPanicValue;\n }\n\n try {\n while (true) {\n if (deferred === null) {\n deferred = $curGoroutine.deferStack[$curGoroutine.deferStack.length - 1];\n if (deferred === undefined) {\n /* The panic reached the top of the stack. Clear it and throw it as a JavaScript error. */\n $panicStackDepth = null;\n if (localPanicValue.Object instanceof Error) {\n throw localPanicValue.Object;\n }\n var msg;\n if (localPanicValue.constructor === $String) {\n msg = localPanicValue.$val;\n } else if (localPanicValue.Error !== undefined) {\n msg = localPanicValue.Error();\n } else if (localPanicValue.String !== undefined) {\n msg = localPanicValue.String();\n } else {\n msg = localPanicValue;\n }\n throw new Error(msg);\n }\n }\n var call = deferred.pop();\n if (call === undefined) {\n $curGoroutine.deferStack.pop();\n if (localPanicValue !== undefined) {\n deferred = null;\n continue;\n }\n return;\n }\n var r = call[0].apply(call[2], call[1]);\n if (r && r.$blk !== undefined) {\n deferred.push([r.$blk, [], r]);\n if (fromPanic) {\n throw null;\n }\n return;\n }\n\n if (localPanicValue !== undefined && $panicStackDepth === null) {\n throw null; /* error was recovered */\n }\n }\n } finally {\n if (localPanicValue !== undefined) {\n if ($panicStackDepth !== null) {\n $curGoroutine.panicStack.push(localPanicValue);\n }\n $panicStackDepth = outerPanicStackDepth;\n $panicValue = outerPanicValue;\n }\n $stackDepthOffset++;\n }\n};\n\nvar $panic = function(value) {\n $curGoroutine.panicStack.push(value);\n $callDeferred(null, null, true);\n};\nvar $recover = function() {\n if ($panicStackDepth === null || ($panicStackDepth !== undefined && $panicStackDepth !== $getStackDepth() - 2)) {\n return $ifaceNil;\n }\n $panicStackDepth = null;\n return $panicValue;\n};\nvar $throw = function(err) {\n throw err;\n};\n\nvar $noGoroutine = {\n asleep: false,\n exit: false,\n deferStack: [],\n panicStack: [],\n};\nvar $curGoroutine = $noGoroutine,\n $totalGoroutines = 0,\n $awakeGoroutines = 0,\n $checkForDeadlock = true;\nvar $mainFinished = false;\nvar $go = function(fun, args) {\n $totalGoroutines++;\n $awakeGoroutines++;\n var $goroutine = function() {\n try {\n $curGoroutine = $goroutine;\n var r = fun.apply(undefined, args);\n if (r && r.$blk !== undefined) {\n fun = function() {\n return r.$blk();\n };\n args = [];\n return;\n }\n $goroutine.exit = true;\n } catch (err) {\n if (!$goroutine.exit) {\n throw err;\n }\n } finally {\n $curGoroutine = $noGoroutine;\n if ($goroutine.exit) {\n /* also set by runtime.Goexit() */\n $totalGoroutines--;\n $goroutine.asleep = true;\n }\n if ($goroutine.asleep) {\n $awakeGoroutines--;\n if (!$mainFinished && $awakeGoroutines === 0 && $checkForDeadlock) {\n console.error(\"fatal error: all goroutines are asleep - deadlock!\");\n if ($global.process !== undefined) {\n $global.process.exit(2);\n }\n }\n }\n }\n };\n $goroutine.asleep = false;\n $goroutine.exit = false;\n $goroutine.deferStack = [];\n $goroutine.panicStack = [];\n $schedule($goroutine);\n};\n\nvar $scheduled = [];\nvar $runScheduled = function() {\n try {\n var r;\n while ((r = $scheduled.shift()) !== undefined) {\n r();\n }\n } finally {\n if ($scheduled.length > 0) {\n setTimeout($runScheduled, 0);\n }\n }\n};\n\nvar $schedule = function(goroutine) {\n if (goroutine.asleep) {\n goroutine.asleep = false;\n $awakeGoroutines++;\n }\n $scheduled.push(goroutine);\n if ($curGoroutine === $noGoroutine) {\n $runScheduled();\n }\n};\n\nvar $setTimeout = function(f, t) {\n $awakeGoroutines++;\n return setTimeout(function() {\n $awakeGoroutines--;\n f();\n }, t);\n};\n\nvar $block = function() {\n if ($curGoroutine === $noGoroutine) {\n $throwRuntimeError(\"cannot block in JavaScript callback, fix by wrapping code in goroutine\");\n }\n $curGoroutine.asleep = true;\n};\n\nvar $send = function(chan, value) {\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv !== undefined) {\n queuedRecv([value, true]);\n return;\n }\n if (chan.$buffer.length < chan.$capacity) {\n chan.$buffer.push(value);\n return;\n }\n\n var thisGoroutine = $curGoroutine;\n var closedDuringSend;\n chan.$sendQueue.push(function(closed) {\n closedDuringSend = closed;\n $schedule(thisGoroutine);\n return value;\n });\n $block();\n return {\n $blk: function() {\n if (closedDuringSend) {\n $throwRuntimeError(\"send on closed channel\");\n }\n },\n };\n};\nvar $recv = function(chan) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend !== undefined) {\n chan.$buffer.push(queuedSend(false));\n }\n var bufferedValue = chan.$buffer.shift();\n if (bufferedValue !== undefined) {\n return [bufferedValue, true];\n }\n if (chan.$closed) {\n return [chan.$elem.zero(), false];\n }\n\n var thisGoroutine = $curGoroutine;\n var f = {\n $blk: function() {\n return this.value;\n },\n };\n var queueEntry = function(v) {\n f.value = v;\n $schedule(thisGoroutine);\n };\n chan.$recvQueue.push(queueEntry);\n $block();\n return f;\n};\nvar $close = function(chan) {\n if (chan.$closed) {\n $throwRuntimeError(\"close of closed channel\");\n }\n chan.$closed = true;\n while (true) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend === undefined) {\n break;\n }\n queuedSend(true); /* will panic */\n }\n while (true) {\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv === undefined) {\n break;\n }\n queuedRecv([chan.$elem.zero(), false]);\n }\n};\nvar $select = function(comms) {\n var ready = [];\n var selection = -1;\n for (var i = 0; i < comms.length; i++) {\n var comm = comms[i];\n var chan = comm[0];\n switch (comm.length) {\n case 0 /* default */:\n selection = i;\n break;\n case 1 /* recv */:\n if (chan.$sendQueue.length !== 0 || chan.$buffer.length !== 0 || chan.$closed) {\n ready.push(i);\n }\n break;\n case 2 /* send */:\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n if (chan.$recvQueue.length !== 0 || chan.$buffer.length < chan.$capacity) {\n ready.push(i);\n }\n break;\n }\n }\n\n if (ready.length !== 0) {\n selection = ready[Math.floor(Math.random() * ready.length)];\n }\n if (selection !== -1) {\n var comm = comms[selection];\n switch (comm.length) {\n case 0 /* default */:\n return [selection];\n case 1 /* recv */:\n return [selection, $recv(comm[0])];\n case 2 /* send */:\n $send(comm[0], comm[1]);\n return [selection];\n }\n }\n\n var entries = [];\n var thisGoroutine = $curGoroutine;\n var f = {\n $blk: function() {\n return this.selection;\n },\n };\n var removeFromQueues = function() {\n for (var i = 0; i < entries.length; i++) {\n var entry = entries[i];\n var queue = entry[0];\n var index = queue.indexOf(entry[1]);\n if (index !== -1) {\n queue.splice(index, 1);\n }\n }\n };\n for (var i = 0; i < comms.length; i++) {\n (function(i) {\n var comm = comms[i];\n switch (comm.length) {\n case 1 /* recv */:\n var queueEntry = function(value) {\n f.selection = [i, value];\n removeFromQueues();\n $schedule(thisGoroutine);\n };\n entries.push([comm[0].$recvQueue, queueEntry]);\n comm[0].$recvQueue.push(queueEntry);\n break;\n case 2 /* send */:\n var queueEntry = function() {\n if (comm[0].$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n f.selection = [i];\n removeFromQueues();\n $schedule(thisGoroutine);\n return comm[1];\n };\n entries.push([comm[0].$sendQueue, queueEntry]);\n comm[0].$sendQueue.push(queueEntry);\n break;\n }\n })(i);\n }\n $block();\n return f;\n};\nvar $jsObjectPtr, $jsErrorPtr;\n\nvar $needsExternalization = function(t) {\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return false;\n default:\n return t !== $jsObjectPtr;\n }\n};\n\nvar $externalize = function(v, t, makeWrapper) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return v;\n case $kindInt64:\n case $kindUint64:\n return $flatten64(v);\n case $kindArray:\n if ($needsExternalization(t.elem)) {\n return $mapArray(v, function(e) {\n return $externalize(e, t.elem, makeWrapper);\n });\n }\n return v;\n case $kindFunc:\n return $externalizeFunction(v, t, false, makeWrapper);\n case $kindInterface:\n if (v === $ifaceNil) {\n return null;\n }\n if (v.constructor === $jsObjectPtr) {\n return v.$val.object;\n }\n return $externalize(v.$val, v.constructor, makeWrapper);\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var entry = v[keys[i]];\n m[$externalize(entry.k, t.key, makeWrapper)] = $externalize(entry.v, t.elem, makeWrapper);\n }\n return m;\n case $kindPtr:\n if (v === t.nil) {\n return null;\n }\n return $externalize(v.$get(), t.elem, makeWrapper);\n case $kindSlice:\n if ($needsExternalization(t.elem)) {\n return $mapArray($sliceToArray(v), function(e) {\n return $externalize(e, t.elem, makeWrapper);\n });\n }\n return $sliceToArray(v);\n case $kindString:\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\",\n r;\n for (var i = 0; i < v.length; i += r[1]) {\n r = $decodeRune(v, i);\n var c = r[0];\n if (c > 0xffff) {\n var h = Math.floor((c - 0x10000) / 0x400) + 0xd800;\n var l = (c - 0x10000) % 0x400 + 0xdc00;\n s += String.fromCharCode(h, l);\n continue;\n }\n s += String.fromCharCode(c);\n }\n return s;\n case $kindStruct:\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && v.constructor === timePkg.Time.ptr) {\n var milli = $div64(v.UnixNano(), new $Int64(0, 1000000));\n return new Date($flatten64(milli));\n }\n\n var noJsObject = {};\n var searchJsObject = function(v, t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindPtr:\n if (v === t.nil) {\n return noJsObject;\n }\n return searchJsObject(v.$get(), t.elem);\n case $kindStruct:\n var f = t.fields[0];\n return searchJsObject(v[f.prop], f.typ);\n case $kindInterface:\n return searchJsObject(v.$val, v.constructor);\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(v, t);\n if (o !== noJsObject) {\n return o;\n }\n\n if (makeWrapper !== undefined) {\n return makeWrapper(v);\n }\n\n o = {};\n for (var i = 0; i < t.fields.length; i++) {\n var f = t.fields[i];\n if (!f.exported) {\n continue;\n }\n o[f.name] = $externalize(v[f.prop], f.typ, makeWrapper);\n }\n return o;\n }\n $throwRuntimeError(\"cannot externalize \" + t.string);\n};\n\nvar $externalizeFunction = function(v, t, passThis, makeWrapper) {\n if (v === $throwNilPointerError) {\n return null;\n }\n if (v.$externalizeWrapper === undefined) {\n $checkForDeadlock = false;\n v.$externalizeWrapper = function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem,\n varargs = [];\n for (var j = i; j < arguments.length; j++) {\n varargs.push($internalize(arguments[j], vt, makeWrapper));\n }\n args.push(new t.params[i](varargs));\n break;\n }\n args.push($internalize(arguments[i], t.params[i], makeWrapper));\n }\n var result = v.apply(passThis ? this : undefined, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $externalize($copyIfRequired(result, t.results[0]), t.results[0], makeWrapper);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $externalize($copyIfRequired(result[i], t.results[i]), t.results[i], makeWrapper);\n }\n return result;\n }\n };\n }\n return v.$externalizeWrapper;\n};\n\nvar $internalize = function(v, t, recv, makeWrapper) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n if (v && v.__internal_object__ !== undefined) {\n return $assertType(v.__internal_object__, t, false);\n }\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && t === timePkg.Time) {\n if (!(v !== null && v !== undefined && v.constructor === Date)) {\n $throwRuntimeError(\"cannot internalize time.Time from \" + typeof v + \", must be Date\");\n }\n return timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000));\n }\n switch (t.kind) {\n case $kindBool:\n return !!v;\n case $kindInt:\n return parseInt(v);\n case $kindInt8:\n return (parseInt(v) << 24) >> 24;\n case $kindInt16:\n return (parseInt(v) << 16) >> 16;\n case $kindInt32:\n return parseInt(v) >> 0;\n case $kindUint:\n return parseInt(v);\n case $kindUint8:\n return (parseInt(v) << 24) >>> 24;\n case $kindUint16:\n return (parseInt(v) << 16) >>> 16;\n case $kindUint32:\n case $kindUintptr:\n return parseInt(v) >>> 0;\n case $kindInt64:\n case $kindUint64:\n return new t(0, v);\n case $kindFloat32:\n case $kindFloat64:\n return parseFloat(v);\n case $kindArray:\n if (v.length !== t.len) {\n $throwRuntimeError(\"got array with wrong size from JavaScript native\");\n }\n return $mapArray(v, function(e) {\n return $internalize(e, t.elem, makeWrapper);\n });\n case $kindFunc:\n return function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem,\n varargs = arguments[i];\n for (var j = 0; j < varargs.$length; j++) {\n args.push($externalize(varargs.$array[varargs.$offset + j], vt, makeWrapper));\n }\n break;\n }\n args.push($externalize(arguments[i], t.params[i], makeWrapper));\n }\n var result = v.apply(recv, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $internalize(result, t.results[0], makeWrapper);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $internalize(result[i], t.results[i], makeWrapper);\n }\n return result;\n }\n };\n case $kindInterface:\n if (t.methods.length !== 0) {\n $throwRuntimeError(\"cannot internalize \" + t.string);\n }\n if (v === null) {\n return $ifaceNil;\n }\n if (v === undefined) {\n return new $jsObjectPtr(undefined);\n }\n switch (v.constructor) {\n case Int8Array:\n return new ($sliceType($Int8))(v);\n case Int16Array:\n return new ($sliceType($Int16))(v);\n case Int32Array:\n return new ($sliceType($Int))(v);\n case Uint8Array:\n return new ($sliceType($Uint8))(v);\n case Uint16Array:\n return new ($sliceType($Uint16))(v);\n case Uint32Array:\n return new ($sliceType($Uint))(v);\n case Float32Array:\n return new ($sliceType($Float32))(v);\n case Float64Array:\n return new ($sliceType($Float64))(v);\n case Array:\n return $internalize(v, $sliceType($emptyInterface), makeWrapper);\n case Boolean:\n return new $Bool(!!v);\n case Date:\n if (timePkg === undefined) {\n /* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */\n return new $jsObjectPtr(v);\n }\n return new timePkg.Time($internalize(v, timePkg.Time, makeWrapper));\n case Function:\n var funcType = $funcType([$sliceType($emptyInterface)], [$jsObjectPtr], true);\n return new funcType($internalize(v, funcType, makeWrapper));\n case Number:\n return new $Float64(parseFloat(v));\n case String:\n return new $String($internalize(v, $String, makeWrapper));\n default:\n if ($global.Node && v instanceof $global.Node) {\n return new $jsObjectPtr(v);\n }\n var mapType = $mapType($String, $emptyInterface);\n return new mapType($internalize(v, mapType, makeWrapper));\n }\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var k = $internalize(keys[i], t.key, makeWrapper);\n m[t.key.keyFor(k)] = { k: k, v: $internalize(v[keys[i]], t.elem, makeWrapper) };\n }\n return m;\n case $kindPtr:\n if (t.elem.kind === $kindStruct) {\n return $internalize(v, t.elem, makeWrapper);\n }\n case $kindSlice:\n return new t(\n $mapArray(v, function(e) {\n return $internalize(e, t.elem, makeWrapper);\n })\n );\n case $kindString:\n v = String(v);\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\";\n var i = 0;\n while (i < v.length) {\n var h = v.charCodeAt(i);\n if (0xd800 <= h && h <= 0xdbff) {\n var l = v.charCodeAt(i + 1);\n var c = (h - 0xd800) * 0x400 + l - 0xdc00 + 0x10000;\n s += $encodeRune(c);\n i += 2;\n continue;\n }\n s += $encodeRune(h);\n i++;\n }\n return s;\n case $kindStruct:\n var noJsObject = {};\n var searchJsObject = function(t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n switch (t.kind) {\n case $kindPtr:\n return searchJsObject(t.elem);\n case $kindStruct:\n var f = t.fields[0];\n var o = searchJsObject(f.typ);\n if (o !== noJsObject) {\n var n = new t.ptr();\n n[f.prop] = o;\n return n;\n }\n return noJsObject;\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(t);\n if (o !== noJsObject) {\n return o;\n }\n }\n $throwRuntimeError(\"cannot internalize \" + t.string);\n};\n\n/* $isASCII reports whether string s contains only ASCII characters. */\nvar $isASCII = function(s) {\n for (var i = 0; i < s.length; i++) {\n if (s.charCodeAt(i) >= 128) {\n return false;\n }\n }\n return true;\n};\n\nvar $copyIfRequired = function(v, typ) {\n // interface values\n if (v.constructor.copy) {\n return new v.constructor($clone(v.$val, v.constructor));\n }\n // array and struct values\n if (typ.copy) {\n var clone = typ.zero();\n typ.copy(clone, v);\n return clone;\n }\n return v;\n};\n" diff --git a/compiler/prelude/prelude_min.go b/compiler/prelude/prelude_min.go index 5a14f94da..a2f704514 100644 --- a/compiler/prelude/prelude_min.go +++ b/compiler/prelude/prelude_min.go @@ -3,4 +3,4 @@ package prelude // Minified is an uglifyjs-minified version of Prelude. -const Minified = "var $global,$module;if(Error.stackTraceLimit=1/0,\"undefined\"!=typeof window?$global=window:\"undefined\"!=typeof self?$global=self:\"undefined\"!=typeof global?($global=global).require=require:$global=this,void 0===$global||void 0===$global.Array)throw new Error(\"no global object found\");\"undefined\"!=typeof module&&($module=module);var $throwRuntimeError,$packages={},$idCounter=0,$keys=function(e){return e?Object.keys(e):[]},$flushConsole=function(){},$throwNilPointerError=function(){$throwRuntimeError(\"invalid memory address or nil pointer dereference\")},$call=function(e,n,r){return e.apply(n,r)},$makeFunc=function(e){return function(){return $externalize(e(this,new($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments,[]))),$emptyInterface)}},$unused=function(e){},$mapArray=function(e,n){for(var r=new e.constructor(e.length),t=0;te.$capacity||t>e.$capacity)&&$throwRuntimeError(\"slice bounds out of range\");var i=new e.constructor(e.$array);return i.$offset=e.$offset+n,i.$length=r-n,i.$capacity=t-n,i},$substring=function(e,n,r){return(n<0||re.length)&&$throwRuntimeError(\"slice bounds out of range\"),e.substring(n,r)},$sliceToArray=function(e){return e.$array.constructor!==Array?e.$array.subarray(e.$offset,e.$offset+e.$length):e.$array.slice(e.$offset,e.$offset+e.$length)},$decodeRune=function(e,n){var r=e.charCodeAt(n);if(r<128)return[r,1];if(r!=r||r<192)return[65533,1];var t=e.charCodeAt(n+1);if(t!=t||t<128||192<=t)return[65533,1];if(r<224)return(a=(31&r)<<6|63&t)<=127?[65533,1]:[a,2];var i=e.charCodeAt(n+2);if(i!=i||i<128||192<=i)return[65533,1];if(r<240)return(a=(15&r)<<12|(63&t)<<6|63&i)<=2047?[65533,1]:55296<=a&&a<=57343?[65533,1]:[a,3];var a,o=e.charCodeAt(n+3);return o!=o||o<128||192<=o?[65533,1]:r<248?(a=(7&r)<<18|(63&t)<<12|(63&i)<<6|63&o)<=65535||11141111114111||55296<=e&&e<=57343)&&(e=65533),e<=127?String.fromCharCode(e):e<=2047?String.fromCharCode(192|e>>6,128|63&e):e<=65535?String.fromCharCode(224|e>>12,128|e>>6&63,128|63&e):String.fromCharCode(240|e>>18,128|e>>12&63,128|e>>6&63,128|63&e)},$stringToBytes=function(e){for(var n=new Uint8Array(e.length),r=0;rt){for(var o=i-1;o>=0;o--)a.copy(e[r+o],n[t+o]);return}for(o=0;ot)for(o=i-1;o>=0;o--)e[r+o]=n[t+o];else for(o=0;o$)if(a=0,$=Math.max(o,e.$capacity<1024?2*e.$capacity:Math.floor(5*e.$capacity/4)),e.$array.constructor===Array){(i=e.$array.slice(e.$offset,e.$offset+e.$length)).length=$;for(var c=e.constructor.elem.zero,u=e.$length;u<$;u++)i[u]=c()}else(i=new e.$array.constructor($)).set(e.$array.subarray(e.$offset,e.$offset+e.$length));$copyArray(i,n,a+e.$length,r,t,e.constructor.elem);var l=new e.constructor(i);return l.$offset=a,l.$length=o,l.$capacity=$,l},$equal=function(e,n,r){if(r===$jsObjectPtr)return e===n;switch(r.kind){case $kindComplex64:case $kindComplex128:return e.$real===n.$real&&e.$imag===n.$imag;case $kindInt64:case $kindUint64:return e.$high===n.$high&&e.$low===n.$low;case $kindArray:if(e.length!==n.length)return!1;for(var t=0;t>>16&65535)*t+r*(n>>>16&65535)<<16>>>0)>>0},$floatKey=function(e){return e!=e?\"NaN$\"+ ++$idCounter:String(e)},$flatten64=function(e){return 4294967296*e.$high+e.$low},$shiftLeft64=function(e,n){return 0===n?e:n<32?new e.constructor(e.$high<>>32-n,e.$low<>>0):n<64?new e.constructor(e.$low<>n,(e.$low>>>n|e.$high<<32-n)>>>0):n<64?new e.constructor(e.$high>>31,e.$high>>n-32>>>0):e.$high<0?new e.constructor(-1,4294967295):new e.constructor(0,0)},$shiftRightUint64=function(e,n){return 0===n?e:n<32?new e.constructor(e.$high>>>n,(e.$low>>>n|e.$high<<32-n)>>>0):n<64?new e.constructor(0,e.$high>>>n-32):new e.constructor(0,0)},$mul64=function(e,n){var r=0,t=0;0!=(1&n.$low)&&(r=e.$high,t=e.$low);for(var i=1;i<32;i++)0!=(n.$low&1<>>32-i,t+=e.$low<>>0);for(i=0;i<32;i++)0!=(n.$high&1<$||a===$&&o>c);)$=($<<1|c>>>31)>>>0,c=c<<1>>>0,s++;for(var f=0;f<=s;f++)u=u<<1|l>>>31,l=l<<1>>>0,(a>$||a===$&&o>=c)&&(a-=$,(o-=c)<0&&(a--,o+=4294967296),4294967296===++l&&(u++,l=0)),c=(c>>>1|$<<31)>>>0,$>>>=1;return r?new e.constructor(a*i,o*i):new e.constructor(u*t,l*t)},$divComplex=function(e,n){var r=e.$real===1/0||e.$real===-1/0||e.$imag===1/0||e.$imag===-1/0,t=n.$real===1/0||n.$real===-1/0||n.$imag===1/0||n.$imag===-1/0,i=!r&&(e.$real!=e.$real||e.$imag!=e.$imag),a=!t&&(n.$real!=n.$real||n.$imag!=n.$imag);if(i||a)return new e.constructor(NaN,NaN);if(r&&!t)return new e.constructor(1/0,1/0);if(!r&&t)return new e.constructor(0,0);if(0===n.$real&&0===n.$imag)return 0===e.$real&&0===e.$imag?new e.constructor(NaN,NaN):new e.constructor(1/0,1/0);if(Math.abs(n.$real)<=Math.abs(n.$imag)){var o=n.$real/n.$imag,$=n.$real*o+n.$imag;return new e.constructor((e.$real*o+e.$imag)/$,(e.$imag*o-e.$real)/$)}o=n.$imag/n.$real,$=n.$imag*o+n.$real;return new e.constructor((e.$imag*o+e.$real)/$,(e.$imag-e.$real*o)/$)},$kindBool=1,$kindInt=2,$kindInt8=3,$kindInt16=4,$kindInt32=5,$kindInt64=6,$kindUint=7,$kindUint8=8,$kindUint16=9,$kindUint32=10,$kindUint64=11,$kindUintptr=12,$kindFloat32=13,$kindFloat64=14,$kindComplex64=15,$kindComplex128=16,$kindArray=17,$kindChan=18,$kindFunc=19,$kindInterface=20,$kindMap=21,$kindPtr=22,$kindSlice=23,$kindString=24,$kindStruct=25,$kindUnsafePointer=26,$methodSynthesizers=[],$addMethodSynthesizer=function(e){null!==$methodSynthesizers?$methodSynthesizers.push(e):e()},$synthesizeMethods=function(){$methodSynthesizers.forEach(function(e){e()}),$methodSynthesizers=null},$ifaceKeyFor=function(e){if(e===$ifaceNil)return\"nil\";var n=e.constructor;return n.string+\"$\"+n.keyFor(e.$val)},$identity=function(e){return e},$typeIDCounter=0,$idKey=function(e){return void 0===e.$id&&($idCounter++,e.$id=$idCounter),String(e.$id)},$newType=function(e,n,r,t,i,a,o){var $;switch(n){case $kindBool:case $kindInt:case $kindInt8:case $kindInt16:case $kindInt32:case $kindUint:case $kindUint8:case $kindUint16:case $kindUint32:case $kindUintptr:case $kindUnsafePointer:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=$identity;break;case $kindString:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=function(e){return\"$\"+e};break;case $kindFloat32:case $kindFloat64:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=function(e){return $floatKey(e)};break;case $kindInt64:($=function(e,n){this.$high=e+Math.floor(Math.ceil(n)/4294967296)>>0,this.$low=n>>>0,this.$val=this}).keyFor=function(e){return e.$high+\"$\"+e.$low};break;case $kindUint64:($=function(e,n){this.$high=e+Math.floor(Math.ceil(n)/4294967296)>>>0,this.$low=n>>>0,this.$val=this}).keyFor=function(e){return e.$high+\"$\"+e.$low};break;case $kindComplex64:($=function(e,n){this.$real=$fround(e),this.$imag=$fround(n),this.$val=this}).keyFor=function(e){return e.$real+\"$\"+e.$imag};break;case $kindComplex128:($=function(e,n){this.$real=e,this.$imag=n,this.$val=this}).keyFor=function(e){return e.$real+\"$\"+e.$imag};break;case $kindArray:($=function(e){this.$val=e}).wrapped=!0,$.ptr=$newType(4,$kindPtr,\"*\"+r,!1,\"\",!1,function(e){this.$get=function(){return e},this.$set=function(e){$.copy(this,e)},this.$val=e}),$.init=function(e,n){$.elem=e,$.len=n,$.comparable=e.comparable,$.keyFor=function(n){return Array.prototype.join.call($mapArray(n,function(n){return String(e.keyFor(n)).replace(/\\\\/g,\"\\\\\\\\\").replace(/\\$/g,\"\\\\$\")}),\"$\")},$.copy=function(n,r){$copyArray(n,r,0,0,r.length,e)},$.ptr.init($),Object.defineProperty($.ptr.nil,\"nilCheck\",{get:$throwNilPointerError})};break;case $kindChan:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=$idKey,$.init=function(e,n,r){$.elem=e,$.sendOnly=n,$.recvOnly=r};break;case $kindFunc:($=function(e){this.$val=e}).wrapped=!0,$.init=function(e,n,r){$.params=e,$.results=n,$.variadic=r,$.comparable=!1};break;case $kindInterface:($={implementedBy:{},missingMethodFor:{}}).keyFor=$ifaceKeyFor,$.init=function(e){$.methods=e,e.forEach(function(e){$ifaceNil[e.prop]=$throwNilPointerError})};break;case $kindMap:($=function(e){this.$val=e}).wrapped=!0,$.init=function(e,n){$.key=e,$.elem=n,$.comparable=!1};break;case $kindPtr:($=o||function(e,n,r){this.$get=e,this.$set=n,this.$target=r,this.$val=this}).keyFor=$idKey,$.init=function(e){$.elem=e,$.wrapped=e.kind===$kindArray,$.nil=new $($throwNilPointerError,$throwNilPointerError)};break;case $kindSlice:($=function(e){e.constructor!==$.nativeArray&&(e=new $.nativeArray(e)),this.$array=e,this.$offset=0,this.$length=e.length,this.$capacity=e.length,this.$val=this}).init=function(e){$.elem=e,$.comparable=!1,$.nativeArray=$nativeArray(e.kind),$.nil=new $([])};break;case $kindStruct:($=function(e){this.$val=e}).wrapped=!0,$.ptr=$newType(4,$kindPtr,\"*\"+r,!1,i,a,o),$.ptr.elem=$,$.ptr.prototype.$get=function(){return this},$.ptr.prototype.$set=function(e){$.copy(this,e)},$.init=function(e,n){$.pkgPath=e,$.fields=n,n.forEach(function(e){e.typ.comparable||($.comparable=!1)}),$.keyFor=function(e){var r=e.$val;return $mapArray(n,function(e){return String(e.typ.keyFor(r[e.prop])).replace(/\\\\/g,\"\\\\\\\\\").replace(/\\$/g,\"\\\\$\")}).join(\"$\")},$.copy=function(e,r){for(var t=0;t0;){var a=[],o=[];t.forEach(function(e){if(!i[e.typ.string])switch(i[e.typ.string]=!0,e.typ.named&&(o=o.concat(e.typ.methods),e.indirect&&(o=o.concat($ptrType(e.typ).methods))),e.typ.kind){case $kindStruct:e.typ.fields.forEach(function(n){if(n.anonymous){var r=n.typ,t=r.kind===$kindPtr;a.push({typ:t?r.elem:r,indirect:e.indirect||t})}});break;case $kindInterface:o=o.concat(e.typ.methods)}}),o.forEach(function(e){void 0===n[e.name]&&(n[e.name]=e)}),t=a}return e.methodSetCache=[],Object.keys(n).sort().forEach(function(r){e.methodSetCache.push(n[r])}),e.methodSetCache},$Bool=$newType(1,$kindBool,\"bool\",!0,\"\",!1,null),$Int=$newType(4,$kindInt,\"int\",!0,\"\",!1,null),$Int8=$newType(1,$kindInt8,\"int8\",!0,\"\",!1,null),$Int16=$newType(2,$kindInt16,\"int16\",!0,\"\",!1,null),$Int32=$newType(4,$kindInt32,\"int32\",!0,\"\",!1,null),$Int64=$newType(8,$kindInt64,\"int64\",!0,\"\",!1,null),$Uint=$newType(4,$kindUint,\"uint\",!0,\"\",!1,null),$Uint8=$newType(1,$kindUint8,\"uint8\",!0,\"\",!1,null),$Uint16=$newType(2,$kindUint16,\"uint16\",!0,\"\",!1,null),$Uint32=$newType(4,$kindUint32,\"uint32\",!0,\"\",!1,null),$Uint64=$newType(8,$kindUint64,\"uint64\",!0,\"\",!1,null),$Uintptr=$newType(4,$kindUintptr,\"uintptr\",!0,\"\",!1,null),$Float32=$newType(4,$kindFloat32,\"float32\",!0,\"\",!1,null),$Float64=$newType(8,$kindFloat64,\"float64\",!0,\"\",!1,null),$Complex64=$newType(8,$kindComplex64,\"complex64\",!0,\"\",!1,null),$Complex128=$newType(16,$kindComplex128,\"complex128\",!0,\"\",!1,null),$String=$newType(8,$kindString,\"string\",!0,\"\",!1,null),$UnsafePointer=$newType(4,$kindUnsafePointer,\"unsafe.Pointer\",!0,\"\",!1,null),$nativeArray=function(e){switch(e){case $kindInt:return Int32Array;case $kindInt8:return Int8Array;case $kindInt16:return Int16Array;case $kindInt32:return Int32Array;case $kindUint:return Uint32Array;case $kindUint8:return Uint8Array;case $kindUint16:return Uint16Array;case $kindUint32:case $kindUintptr:return Uint32Array;case $kindFloat32:return Float32Array;case $kindFloat64:return Float64Array;default:return Array}},$toNativeArray=function(e,n){var r=$nativeArray(e);return r===Array?n:new r(n)},$arrayTypes={},$arrayType=function(e,n){var r=e.id+\"$\"+n,t=$arrayTypes[r];return void 0===t&&(t=$newType(12,$kindArray,\"[\"+n+\"]\"+e.string,!1,\"\",!1,null),$arrayTypes[r]=t,t.init(e,n)),t},$chanType=function(e,n,r){var t=(r?\"<-\":\"\")+\"chan\"+(n?\"<- \":\" \")+e.string,i=n?\"SendChan\":r?\"RecvChan\":\"Chan\",a=e[i];return void 0===a&&(a=$newType(4,$kindChan,t,!1,\"\",!1,null),e[i]=a,a.init(e,n,r)),a},$Chan=function(e,n){(n<0||n>2147483647)&&$throwRuntimeError(\"makechan: size out of range\"),this.$elem=e,this.$capacity=n,this.$buffer=[],this.$sendQueue=[],this.$recvQueue=[],this.$closed=!1},$chanNil=new $Chan(null,0);$chanNil.$sendQueue=$chanNil.$recvQueue={length:0,push:function(){},shift:function(){},indexOf:function(){return-1}};var $funcTypes={},$funcType=function(e,n,r){var t=$mapArray(e,function(e){return e.id}).join(\",\")+\"$\"+$mapArray(n,function(e){return e.id}).join(\",\")+\"$\"+r,i=$funcTypes[t];if(void 0===i){var a=$mapArray(e,function(e){return e.string});r&&(a[a.length-1]=\"...\"+a[a.length-1].substr(2));var o=\"func(\"+a.join(\", \")+\")\";1===n.length?o+=\" \"+n[0].string:n.length>1&&(o+=\" (\"+$mapArray(n,function(e){return e.string}).join(\", \")+\")\"),i=$newType(4,$kindFunc,o,!1,\"\",!1,null),$funcTypes[t]=i,i.init(e,n,r)}return i},$interfaceTypes={},$interfaceType=function(e){var n=$mapArray(e,function(e){return e.pkg+\",\"+e.name+\",\"+e.typ.id}).join(\"$\"),r=$interfaceTypes[n];if(void 0===r){var t=\"interface {}\";0!==e.length&&(t=\"interface { \"+$mapArray(e,function(e){return(\"\"!==e.pkg?e.pkg+\".\":\"\")+e.name+e.typ.string.substr(4)}).join(\"; \")+\" }\"),r=$newType(8,$kindInterface,t,!1,\"\",!1,null),$interfaceTypes[n]=r,r.init(e)}return r},$emptyInterface=$interfaceType([]),$ifaceNil={},$error=$newType(8,$kindInterface,\"error\",!0,\"\",!1,null);$error.init([{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],!1)}]);var $panicValue,$jsObjectPtr,$jsErrorPtr,$mapTypes={},$mapType=function(e,n){var r=e.id+\"$\"+n.id,t=$mapTypes[r];return void 0===t&&(t=$newType(4,$kindMap,\"map[\"+e.string+\"]\"+n.string,!1,\"\",!1,null),$mapTypes[r]=t,t.init(e,n)),t},$makeMap=function(e,n){for(var r={},t=0;t2147483647)&&$throwRuntimeError(\"makeslice: len out of range\"),(r<0||r2147483647)&&$throwRuntimeError(\"makeslice: cap out of range\");var t=new e.nativeArray(r);if(e.nativeArray===Array)for(var i=0;i=$curGoroutine.deferStack.length)throw n;if(null!==n){var t=null;try{$curGoroutine.deferStack.push(e),$panic(new $jsErrorPtr(n))}catch(e){t=e}return $curGoroutine.deferStack.pop(),void $callDeferred(e,t)}if(!$curGoroutine.asleep){$stackDepthOffset--;var i=$panicStackDepth,a=$panicValue,o=$curGoroutine.panicStack.pop();void 0!==o&&($panicStackDepth=$getStackDepth(),$panicValue=o);try{for(;;){if(null===e&&void 0===(e=$curGoroutine.deferStack[$curGoroutine.deferStack.length-1])){if($panicStackDepth=null,o.Object instanceof Error)throw o.Object;var $;throw $=o.constructor===$String?o.$val:void 0!==o.Error?o.Error():void 0!==o.String?o.String():o,new Error($)}var c=e.pop();if(void 0===c){if($curGoroutine.deferStack.pop(),void 0!==o){e=null;continue}return}var u=c[0].apply(c[2],c[1]);if(u&&void 0!==u.$blk){if(e.push([u.$blk,[],u]),r)throw null;return}if(void 0!==o&&null===$panicStackDepth)throw null}}finally{void 0!==o&&(null!==$panicStackDepth&&$curGoroutine.panicStack.push(o),$panicStackDepth=i,$panicValue=a),$stackDepthOffset++}}},$panic=function(e){$curGoroutine.panicStack.push(e),$callDeferred(null,null,!0)},$recover=function(){return null===$panicStackDepth||void 0!==$panicStackDepth&&$panicStackDepth!==$getStackDepth()-2?$ifaceNil:($panicStackDepth=null,$panicValue)},$throw=function(e){throw e},$noGoroutine={asleep:!1,exit:!1,deferStack:[],panicStack:[]},$curGoroutine=$noGoroutine,$totalGoroutines=0,$awakeGoroutines=0,$checkForDeadlock=!0,$mainFinished=!1,$go=function(e,n){$totalGoroutines++,$awakeGoroutines++;var r=function(){try{$curGoroutine=r;var t=e.apply(void 0,n);if(t&&void 0!==t.$blk)return e=function(){return t.$blk()},void(n=[]);r.exit=!0}catch(e){if(!r.exit)throw e}finally{$curGoroutine=$noGoroutine,r.exit&&($totalGoroutines--,r.asleep=!0),r.asleep&&($awakeGoroutines--,!$mainFinished&&0===$awakeGoroutines&&$checkForDeadlock&&(console.error(\"fatal error: all goroutines are asleep - deadlock!\"),void 0!==$global.process&&$global.process.exit(2)))}};r.asleep=!1,r.exit=!1,r.deferStack=[],r.panicStack=[],$schedule(r)},$scheduled=[],$runScheduled=function(){try{for(var e;void 0!==(e=$scheduled.shift());)e()}finally{$scheduled.length>0&&setTimeout($runScheduled,0)}},$schedule=function(e){e.asleep&&(e.asleep=!1,$awakeGoroutines++),$scheduled.push(e),$curGoroutine===$noGoroutine&&$runScheduled()},$setTimeout=function(e,n){return $awakeGoroutines++,setTimeout(function(){$awakeGoroutines--,e()},n)},$block=function(){$curGoroutine===$noGoroutine&&$throwRuntimeError(\"cannot block in JavaScript callback, fix by wrapping code in goroutine\"),$curGoroutine.asleep=!0},$send=function(e,n){e.$closed&&$throwRuntimeError(\"send on closed channel\");var r=e.$recvQueue.shift();if(void 0===r){if(!(e.$buffer.length65535){var u=Math.floor((c-65536)/1024)+55296,l=(c-65536)%1024+56320;$+=String.fromCharCode(u,l)}else $+=String.fromCharCode(c)}return $;case $kindStruct:var s=$packages.time;if(void 0!==s&&e.constructor===s.Time.ptr){var f=$div64(e.UnixNano(),new $Int64(0,1e6));return new Date($flatten64(f))}var d={},p=function(e,n){if(n===$jsObjectPtr)return e;switch(n.kind){case $kindPtr:return e===n.nil?d:p(e.$get(),n.elem);case $kindStruct:var r=n.fields[0];return p(e[r.prop],r.typ);case $kindInterface:return p(e.$val,e.constructor);default:return d}},h=p(e,n);if(h!==d)return h;h={};for(i=0;i>24;case $kindInt16:return parseInt(e)<<16>>16;case $kindInt32:return parseInt(e)>>0;case $kindUint:return parseInt(e);case $kindUint8:return parseInt(e)<<24>>>24;case $kindUint16:return parseInt(e)<<16>>>16;case $kindUint32:case $kindUintptr:return parseInt(e)>>>0;case $kindInt64:case $kindUint64:return new n(0,e);case $kindFloat32:case $kindFloat64:return parseFloat(e);case $kindArray:return e.length!==n.len&&$throwRuntimeError(\"got array with wrong size from JavaScript native\"),$mapArray(e,function(e){return $internalize(e,n.elem)});case $kindFunc:return function(){for(var t=[],i=0;i=128)return!1;return!0};\n" +const Minified = "var $global,$module;if(Error.stackTraceLimit=1/0,\"undefined\"!=typeof window?$global=window:\"undefined\"!=typeof self?$global=self:\"undefined\"!=typeof global?($global=global).require=require:$global=this,void 0===$global||void 0===$global.Array)throw new Error(\"no global object found\");\"undefined\"!=typeof module&&($module=module);var $throwRuntimeError,$packages={},$idCounter=0,$keys=function(e){return e?Object.keys(e):[]},$flushConsole=function(){},$throwNilPointerError=function(){$throwRuntimeError(\"invalid memory address or nil pointer dereference\")},$call=function(e,n,r){return e.apply(n,r)},$makeFunc=function(e){return function(){return $externalize(e(this,new($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments,[]))),$emptyInterface)}},$unused=function(e){},$mapArray=function(e,n){for(var r=new e.constructor(e.length),t=0;te.$capacity||t>e.$capacity)&&$throwRuntimeError(\"slice bounds out of range\");var i=new e.constructor(e.$array);return i.$offset=e.$offset+n,i.$length=r-n,i.$capacity=t-n,i},$substring=function(e,n,r){return(n<0||re.length)&&$throwRuntimeError(\"slice bounds out of range\"),e.substring(n,r)},$sliceToArray=function(e){return e.$array.constructor!==Array?e.$array.subarray(e.$offset,e.$offset+e.$length):e.$array.slice(e.$offset,e.$offset+e.$length)},$decodeRune=function(e,n){var r=e.charCodeAt(n);if(r<128)return[r,1];if(r!=r||r<192)return[65533,1];var t=e.charCodeAt(n+1);if(t!=t||t<128||192<=t)return[65533,1];if(r<224)return(a=(31&r)<<6|63&t)<=127?[65533,1]:[a,2];var i=e.charCodeAt(n+2);if(i!=i||i<128||192<=i)return[65533,1];if(r<240)return(a=(15&r)<<12|(63&t)<<6|63&i)<=2047?[65533,1]:55296<=a&&a<=57343?[65533,1]:[a,3];var a,o=e.charCodeAt(n+3);return o!=o||o<128||192<=o?[65533,1]:r<248?(a=(7&r)<<18|(63&t)<<12|(63&i)<<6|63&o)<=65535||11141111114111||55296<=e&&e<=57343)&&(e=65533),e<=127?String.fromCharCode(e):e<=2047?String.fromCharCode(192|e>>6,128|63&e):e<=65535?String.fromCharCode(224|e>>12,128|e>>6&63,128|63&e):String.fromCharCode(240|e>>18,128|e>>12&63,128|e>>6&63,128|63&e)},$stringToBytes=function(e){for(var n=new Uint8Array(e.length),r=0;rt){for(var o=i-1;o>=0;o--)a.copy(e[r+o],n[t+o]);return}for(o=0;ot)for(o=i-1;o>=0;o--)e[r+o]=n[t+o];else for(o=0;o$)if(a=0,$=Math.max(o,e.$capacity<1024?2*e.$capacity:Math.floor(5*e.$capacity/4)),e.$array.constructor===Array){(i=e.$array.slice(e.$offset,e.$offset+e.$length)).length=$;for(var c=e.constructor.elem.zero,u=e.$length;u<$;u++)i[u]=c()}else(i=new e.$array.constructor($)).set(e.$array.subarray(e.$offset,e.$offset+e.$length));$copyArray(i,n,a+e.$length,r,t,e.constructor.elem);var l=new e.constructor(i);return l.$offset=a,l.$length=o,l.$capacity=$,l},$equal=function(e,n,r){if(r===$jsObjectPtr)return e===n;switch(r.kind){case $kindComplex64:case $kindComplex128:return e.$real===n.$real&&e.$imag===n.$imag;case $kindInt64:case $kindUint64:return e.$high===n.$high&&e.$low===n.$low;case $kindArray:if(e.length!==n.length)return!1;for(var t=0;t>>16&65535)*t+r*(n>>>16&65535)<<16>>>0)>>0},$floatKey=function(e){return e!=e?\"NaN$\"+ ++$idCounter:String(e)},$flatten64=function(e){return 4294967296*e.$high+e.$low},$shiftLeft64=function(e,n){return 0===n?e:n<32?new e.constructor(e.$high<>>32-n,e.$low<>>0):n<64?new e.constructor(e.$low<>n,(e.$low>>>n|e.$high<<32-n)>>>0):n<64?new e.constructor(e.$high>>31,e.$high>>n-32>>>0):e.$high<0?new e.constructor(-1,4294967295):new e.constructor(0,0)},$shiftRightUint64=function(e,n){return 0===n?e:n<32?new e.constructor(e.$high>>>n,(e.$low>>>n|e.$high<<32-n)>>>0):n<64?new e.constructor(0,e.$high>>>n-32):new e.constructor(0,0)},$mul64=function(e,n){var r=0,t=0;0!=(1&n.$low)&&(r=e.$high,t=e.$low);for(var i=1;i<32;i++)0!=(n.$low&1<>>32-i,t+=e.$low<>>0);for(i=0;i<32;i++)0!=(n.$high&1<$||a===$&&o>c);)$=($<<1|c>>>31)>>>0,c=c<<1>>>0,s++;for(var f=0;f<=s;f++)u=u<<1|l>>>31,l=l<<1>>>0,(a>$||a===$&&o>=c)&&(a-=$,(o-=c)<0&&(a--,o+=4294967296),4294967296===++l&&(u++,l=0)),c=(c>>>1|$<<31)>>>0,$>>>=1;return r?new e.constructor(a*i,o*i):new e.constructor(u*t,l*t)},$divComplex=function(e,n){var r=e.$real===1/0||e.$real===-1/0||e.$imag===1/0||e.$imag===-1/0,t=n.$real===1/0||n.$real===-1/0||n.$imag===1/0||n.$imag===-1/0,i=!r&&(e.$real!=e.$real||e.$imag!=e.$imag),a=!t&&(n.$real!=n.$real||n.$imag!=n.$imag);if(i||a)return new e.constructor(NaN,NaN);if(r&&!t)return new e.constructor(1/0,1/0);if(!r&&t)return new e.constructor(0,0);if(0===n.$real&&0===n.$imag)return 0===e.$real&&0===e.$imag?new e.constructor(NaN,NaN):new e.constructor(1/0,1/0);if(Math.abs(n.$real)<=Math.abs(n.$imag)){var o=n.$real/n.$imag,$=n.$real*o+n.$imag;return new e.constructor((e.$real*o+e.$imag)/$,(e.$imag*o-e.$real)/$)}o=n.$imag/n.$real,$=n.$imag*o+n.$real;return new e.constructor((e.$imag*o+e.$real)/$,(e.$imag-e.$real*o)/$)},$kindBool=1,$kindInt=2,$kindInt8=3,$kindInt16=4,$kindInt32=5,$kindInt64=6,$kindUint=7,$kindUint8=8,$kindUint16=9,$kindUint32=10,$kindUint64=11,$kindUintptr=12,$kindFloat32=13,$kindFloat64=14,$kindComplex64=15,$kindComplex128=16,$kindArray=17,$kindChan=18,$kindFunc=19,$kindInterface=20,$kindMap=21,$kindPtr=22,$kindSlice=23,$kindString=24,$kindStruct=25,$kindUnsafePointer=26,$methodSynthesizers=[],$addMethodSynthesizer=function(e){null!==$methodSynthesizers?$methodSynthesizers.push(e):e()},$synthesizeMethods=function(){$methodSynthesizers.forEach(function(e){e()}),$methodSynthesizers=null},$ifaceKeyFor=function(e){if(e===$ifaceNil)return\"nil\";var n=e.constructor;return n.string+\"$\"+n.keyFor(e.$val)},$identity=function(e){return e},$typeIDCounter=0,$idKey=function(e){return void 0===e.$id&&($idCounter++,e.$id=$idCounter),String(e.$id)},$newType=function(e,n,r,t,i,a,o){var $;switch(n){case $kindBool:case $kindInt:case $kindInt8:case $kindInt16:case $kindInt32:case $kindUint:case $kindUint8:case $kindUint16:case $kindUint32:case $kindUintptr:case $kindUnsafePointer:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=$identity;break;case $kindString:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=function(e){return\"$\"+e};break;case $kindFloat32:case $kindFloat64:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=function(e){return $floatKey(e)};break;case $kindInt64:($=function(e,n){this.$high=e+Math.floor(Math.ceil(n)/4294967296)>>0,this.$low=n>>>0,this.$val=this}).keyFor=function(e){return e.$high+\"$\"+e.$low};break;case $kindUint64:($=function(e,n){this.$high=e+Math.floor(Math.ceil(n)/4294967296)>>>0,this.$low=n>>>0,this.$val=this}).keyFor=function(e){return e.$high+\"$\"+e.$low};break;case $kindComplex64:($=function(e,n){this.$real=$fround(e),this.$imag=$fround(n),this.$val=this}).keyFor=function(e){return e.$real+\"$\"+e.$imag};break;case $kindComplex128:($=function(e,n){this.$real=e,this.$imag=n,this.$val=this}).keyFor=function(e){return e.$real+\"$\"+e.$imag};break;case $kindArray:($=function(e){this.$val=e}).wrapped=!0,$.ptr=$newType(4,$kindPtr,\"*\"+r,!1,\"\",!1,function(e){this.$get=function(){return e},this.$set=function(e){$.copy(this,e)},this.$val=e}),$.init=function(e,n){$.elem=e,$.len=n,$.comparable=e.comparable,$.keyFor=function(n){return Array.prototype.join.call($mapArray(n,function(n){return String(e.keyFor(n)).replace(/\\\\/g,\"\\\\\\\\\").replace(/\\$/g,\"\\\\$\")}),\"$\")},$.copy=function(n,r){$copyArray(n,r,0,0,r.length,e)},$.ptr.init($),Object.defineProperty($.ptr.nil,\"nilCheck\",{get:$throwNilPointerError})};break;case $kindChan:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=$idKey,$.init=function(e,n,r){$.elem=e,$.sendOnly=n,$.recvOnly=r};break;case $kindFunc:($=function(e){this.$val=e}).wrapped=!0,$.init=function(e,n,r){$.params=e,$.results=n,$.variadic=r,$.comparable=!1};break;case $kindInterface:($={implementedBy:{},missingMethodFor:{}}).keyFor=$ifaceKeyFor,$.init=function(e){$.methods=e,e.forEach(function(e){$ifaceNil[e.prop]=$throwNilPointerError})};break;case $kindMap:($=function(e){this.$val=e}).wrapped=!0,$.init=function(e,n){$.key=e,$.elem=n,$.comparable=!1};break;case $kindPtr:($=o||function(e,n,r){this.$get=e,this.$set=n,this.$target=r,this.$val=this}).keyFor=$idKey,$.init=function(e){$.elem=e,$.wrapped=e.kind===$kindArray,$.nil=new $($throwNilPointerError,$throwNilPointerError)};break;case $kindSlice:($=function(e){e.constructor!==$.nativeArray&&(e=new $.nativeArray(e)),this.$array=e,this.$offset=0,this.$length=e.length,this.$capacity=e.length,this.$val=this}).init=function(e){$.elem=e,$.comparable=!1,$.nativeArray=$nativeArray(e.kind),$.nil=new $([])};break;case $kindStruct:($=function(e){this.$val=e}).wrapped=!0,$.ptr=$newType(4,$kindPtr,\"*\"+r,!1,i,a,o),$.ptr.elem=$,$.ptr.prototype.$get=function(){return this},$.ptr.prototype.$set=function(e){$.copy(this,e)},$.init=function(e,n){$.pkgPath=e,$.fields=n,n.forEach(function(e){e.typ.comparable||($.comparable=!1)}),$.keyFor=function(e){var r=e.$val;return $mapArray(n,function(e){return String(e.typ.keyFor(r[e.prop])).replace(/\\\\/g,\"\\\\\\\\\").replace(/\\$/g,\"\\\\$\")}).join(\"$\")},$.copy=function(e,r){for(var t=0;t0;){var a=[],o=[];t.forEach(function(e){if(!i[e.typ.string])switch(i[e.typ.string]=!0,e.typ.named&&(o=o.concat(e.typ.methods),e.indirect&&(o=o.concat($ptrType(e.typ).methods))),e.typ.kind){case $kindStruct:e.typ.fields.forEach(function(n){if(n.anonymous){var r=n.typ,t=r.kind===$kindPtr;a.push({typ:t?r.elem:r,indirect:e.indirect||t})}});break;case $kindInterface:o=o.concat(e.typ.methods)}}),o.forEach(function(e){void 0===n[e.name]&&(n[e.name]=e)}),t=a}return e.methodSetCache=[],Object.keys(n).sort().forEach(function(r){e.methodSetCache.push(n[r])}),e.methodSetCache},$Bool=$newType(1,$kindBool,\"bool\",!0,\"\",!1,null),$Int=$newType(4,$kindInt,\"int\",!0,\"\",!1,null),$Int8=$newType(1,$kindInt8,\"int8\",!0,\"\",!1,null),$Int16=$newType(2,$kindInt16,\"int16\",!0,\"\",!1,null),$Int32=$newType(4,$kindInt32,\"int32\",!0,\"\",!1,null),$Int64=$newType(8,$kindInt64,\"int64\",!0,\"\",!1,null),$Uint=$newType(4,$kindUint,\"uint\",!0,\"\",!1,null),$Uint8=$newType(1,$kindUint8,\"uint8\",!0,\"\",!1,null),$Uint16=$newType(2,$kindUint16,\"uint16\",!0,\"\",!1,null),$Uint32=$newType(4,$kindUint32,\"uint32\",!0,\"\",!1,null),$Uint64=$newType(8,$kindUint64,\"uint64\",!0,\"\",!1,null),$Uintptr=$newType(4,$kindUintptr,\"uintptr\",!0,\"\",!1,null),$Float32=$newType(4,$kindFloat32,\"float32\",!0,\"\",!1,null),$Float64=$newType(8,$kindFloat64,\"float64\",!0,\"\",!1,null),$Complex64=$newType(8,$kindComplex64,\"complex64\",!0,\"\",!1,null),$Complex128=$newType(16,$kindComplex128,\"complex128\",!0,\"\",!1,null),$String=$newType(8,$kindString,\"string\",!0,\"\",!1,null),$UnsafePointer=$newType(4,$kindUnsafePointer,\"unsafe.Pointer\",!0,\"\",!1,null),$nativeArray=function(e){switch(e){case $kindInt:return Int32Array;case $kindInt8:return Int8Array;case $kindInt16:return Int16Array;case $kindInt32:return Int32Array;case $kindUint:return Uint32Array;case $kindUint8:return Uint8Array;case $kindUint16:return Uint16Array;case $kindUint32:case $kindUintptr:return Uint32Array;case $kindFloat32:return Float32Array;case $kindFloat64:return Float64Array;default:return Array}},$toNativeArray=function(e,n){var r=$nativeArray(e);return r===Array?n:new r(n)},$arrayTypes={},$arrayType=function(e,n){var r=e.id+\"$\"+n,t=$arrayTypes[r];return void 0===t&&(t=$newType(12,$kindArray,\"[\"+n+\"]\"+e.string,!1,\"\",!1,null),$arrayTypes[r]=t,t.init(e,n)),t},$chanType=function(e,n,r){var t=(r?\"<-\":\"\")+\"chan\"+(n?\"<- \":\" \")+e.string,i=n?\"SendChan\":r?\"RecvChan\":\"Chan\",a=e[i];return void 0===a&&(a=$newType(4,$kindChan,t,!1,\"\",!1,null),e[i]=a,a.init(e,n,r)),a},$Chan=function(e,n){(n<0||n>2147483647)&&$throwRuntimeError(\"makechan: size out of range\"),this.$elem=e,this.$capacity=n,this.$buffer=[],this.$sendQueue=[],this.$recvQueue=[],this.$closed=!1},$chanNil=new $Chan(null,0);$chanNil.$sendQueue=$chanNil.$recvQueue={length:0,push:function(){},shift:function(){},indexOf:function(){return-1}};var $funcTypes={},$funcType=function(e,n,r){var t=$mapArray(e,function(e){return e.id}).join(\",\")+\"$\"+$mapArray(n,function(e){return e.id}).join(\",\")+\"$\"+r,i=$funcTypes[t];if(void 0===i){var a=$mapArray(e,function(e){return e.string});r&&(a[a.length-1]=\"...\"+a[a.length-1].substr(2));var o=\"func(\"+a.join(\", \")+\")\";1===n.length?o+=\" \"+n[0].string:n.length>1&&(o+=\" (\"+$mapArray(n,function(e){return e.string}).join(\", \")+\")\"),i=$newType(4,$kindFunc,o,!1,\"\",!1,null),$funcTypes[t]=i,i.init(e,n,r)}return i},$interfaceTypes={},$interfaceType=function(e){var n=$mapArray(e,function(e){return e.pkg+\",\"+e.name+\",\"+e.typ.id}).join(\"$\"),r=$interfaceTypes[n];if(void 0===r){var t=\"interface {}\";0!==e.length&&(t=\"interface { \"+$mapArray(e,function(e){return(\"\"!==e.pkg?e.pkg+\".\":\"\")+e.name+e.typ.string.substr(4)}).join(\"; \")+\" }\"),r=$newType(8,$kindInterface,t,!1,\"\",!1,null),$interfaceTypes[n]=r,r.init(e)}return r},$emptyInterface=$interfaceType([]),$ifaceNil={},$error=$newType(8,$kindInterface,\"error\",!0,\"\",!1,null);$error.init([{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],!1)}]);var $panicValue,$jsObjectPtr,$jsErrorPtr,$mapTypes={},$mapType=function(e,n){var r=e.id+\"$\"+n.id,t=$mapTypes[r];return void 0===t&&(t=$newType(4,$kindMap,\"map[\"+e.string+\"]\"+n.string,!1,\"\",!1,null),$mapTypes[r]=t,t.init(e,n)),t},$makeMap=function(e,n){for(var r={},t=0;t2147483647)&&$throwRuntimeError(\"makeslice: len out of range\"),(r<0||r2147483647)&&$throwRuntimeError(\"makeslice: cap out of range\");var t=new e.nativeArray(r);if(e.nativeArray===Array)for(var i=0;i=$curGoroutine.deferStack.length)throw n;if(null!==n){var t=null;try{$curGoroutine.deferStack.push(e),$panic(new $jsErrorPtr(n))}catch(e){t=e}return $curGoroutine.deferStack.pop(),void $callDeferred(e,t)}if(!$curGoroutine.asleep){$stackDepthOffset--;var i=$panicStackDepth,a=$panicValue,o=$curGoroutine.panicStack.pop();void 0!==o&&($panicStackDepth=$getStackDepth(),$panicValue=o);try{for(;;){if(null===e&&void 0===(e=$curGoroutine.deferStack[$curGoroutine.deferStack.length-1])){if($panicStackDepth=null,o.Object instanceof Error)throw o.Object;var $;throw $=o.constructor===$String?o.$val:void 0!==o.Error?o.Error():void 0!==o.String?o.String():o,new Error($)}var c=e.pop();if(void 0===c){if($curGoroutine.deferStack.pop(),void 0!==o){e=null;continue}return}var u=c[0].apply(c[2],c[1]);if(u&&void 0!==u.$blk){if(e.push([u.$blk,[],u]),r)throw null;return}if(void 0!==o&&null===$panicStackDepth)throw null}}finally{void 0!==o&&(null!==$panicStackDepth&&$curGoroutine.panicStack.push(o),$panicStackDepth=i,$panicValue=a),$stackDepthOffset++}}},$panic=function(e){$curGoroutine.panicStack.push(e),$callDeferred(null,null,!0)},$recover=function(){return null===$panicStackDepth||void 0!==$panicStackDepth&&$panicStackDepth!==$getStackDepth()-2?$ifaceNil:($panicStackDepth=null,$panicValue)},$throw=function(e){throw e},$noGoroutine={asleep:!1,exit:!1,deferStack:[],panicStack:[]},$curGoroutine=$noGoroutine,$totalGoroutines=0,$awakeGoroutines=0,$checkForDeadlock=!0,$mainFinished=!1,$go=function(e,n){$totalGoroutines++,$awakeGoroutines++;var r=function(){try{$curGoroutine=r;var t=e.apply(void 0,n);if(t&&void 0!==t.$blk)return e=function(){return t.$blk()},void(n=[]);r.exit=!0}catch(e){if(!r.exit)throw e}finally{$curGoroutine=$noGoroutine,r.exit&&($totalGoroutines--,r.asleep=!0),r.asleep&&($awakeGoroutines--,!$mainFinished&&0===$awakeGoroutines&&$checkForDeadlock&&(console.error(\"fatal error: all goroutines are asleep - deadlock!\"),void 0!==$global.process&&$global.process.exit(2)))}};r.asleep=!1,r.exit=!1,r.deferStack=[],r.panicStack=[],$schedule(r)},$scheduled=[],$runScheduled=function(){try{for(var e;void 0!==(e=$scheduled.shift());)e()}finally{$scheduled.length>0&&setTimeout($runScheduled,0)}},$schedule=function(e){e.asleep&&(e.asleep=!1,$awakeGoroutines++),$scheduled.push(e),$curGoroutine===$noGoroutine&&$runScheduled()},$setTimeout=function(e,n){return $awakeGoroutines++,setTimeout(function(){$awakeGoroutines--,e()},n)},$block=function(){$curGoroutine===$noGoroutine&&$throwRuntimeError(\"cannot block in JavaScript callback, fix by wrapping code in goroutine\"),$curGoroutine.asleep=!0},$send=function(e,n){e.$closed&&$throwRuntimeError(\"send on closed channel\");var r=e.$recvQueue.shift();if(void 0===r){if(!(e.$buffer.length65535){var l=Math.floor((u-65536)/1024)+55296,s=(u-65536)%1024+56320;c+=String.fromCharCode(l,s)}else c+=String.fromCharCode(u)}return c;case $kindStruct:var f=$packages.time;if(void 0!==f&&e.constructor===f.Time.ptr){var d=$div64(e.UnixNano(),new $Int64(0,1e6));return new Date($flatten64(d))}var p={},h=function(e,n){if(n===$jsObjectPtr)return e;switch(n.kind){case $kindPtr:return e===n.nil?p:h(e.$get(),n.elem);case $kindStruct:var r=n.fields[0];return h(e[r.prop],r.typ);case $kindInterface:return h(e.$val,e.constructor);default:return p}},k=h(e,n);if(k!==p)return k;if(void 0!==r)return r(e);k={};for(a=0;a>24;case $kindInt16:return parseInt(e)<<16>>16;case $kindInt32:return parseInt(e)>>0;case $kindUint:return parseInt(e);case $kindUint8:return parseInt(e)<<24>>>24;case $kindUint16:return parseInt(e)<<16>>>16;case $kindUint32:case $kindUintptr:return parseInt(e)>>>0;case $kindInt64:case $kindUint64:return new n(0,e);case $kindFloat32:case $kindFloat64:return parseFloat(e);case $kindArray:return e.length!==n.len&&$throwRuntimeError(\"got array with wrong size from JavaScript native\"),$mapArray(e,function(e){return $internalize(e,n.elem,t)});case $kindFunc:return function(){for(var i=[],a=0;a=128)return!1;return!0},$copyIfRequired=function(e,n){if(e.constructor.copy)return new e.constructor($clone(e.$val,e.constructor));if(n.copy){var r=n.zero();return n.copy(r,e),r}return e};\n" diff --git a/js/js.go b/js/js.go index 3fbf1d88c..1371567ef 100644 --- a/js/js.go +++ b/js/js.go @@ -1,6 +1,6 @@ // Package js provides functions for interacting with native JavaScript APIs. Calls to these functions are treated specially by GopherJS and translated directly to their corresponding JavaScript syntax. // -// Use MakeWrapper to expose methods to JavaScript. When passing values directly, the following type conversions are performed: +// Use MakeWrapper to expose methods to JavaScript. Use MakeFullWrapper to expose methods AND fields to JavaScript. When passing values directly, the following type conversions are performed: // // | Go type | JavaScript type | Conversions back to interface{} | // | --------------------- | --------------------- | ------------------------------- | @@ -147,6 +147,103 @@ func MakeWrapper(i interface{}) *Object { return o } +// MakeFullWrapper creates a JavaScript object which has wrappers for the exported +// methods of i, and, where i is a (pointer to a) struct value, wrapped getters +// and setters +// (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) +// for the non-embedded exported fields of i. Values accessed via these methods +// and getters are themsevles wrapped when accessed, but an important point to +// note is that a new wrapped value is created on each access. +func MakeFullWrapper(i interface{}) *Object { + v := InternalObject(i) + c := v.Get("constructor") + + o := Global.Get("Object").New() + + defineProperty := func(k string, fns ...func(*Object)) { + op := Global.Get("Object").New() + for _, f := range fns { + f(op) + } + Global.Get("Object").Call("defineProperty", o, k, op) + } + + defineProperty("__internal_object__", func(op *Object) { + op.Set("value", v) + }) + + { + // caculate a sensible type string + + // we don't want to import any packages in this package + // so we do some string operations by hand + + typ := c.Get("string").String() + pkg := c.Get("pkg").String() + + ptr := "" + if typ[0] == '*' { + ptr = "*" + } + + for i := 0; i < len(typ); i++ { + if typ[i] == '.' { + typ = typ[i+1:] + break + } + } + + pkgTyp := pkg + "." + ptr + typ + defineProperty("$type", func(op *Object) { + op.Set("value", pkgTyp) + }) + } + + var fields *Object + methods := Global.Get("Array").New() + if ms := c.Get("methods"); ms != Undefined { + methods = methods.Call("concat", ms) + } + // if we are a pointer value then add fields from element + // else the constructor itself will have them + if e := c.Get("elem"); e != Undefined { + fields = e.Get("fields") + methods = methods.Call("concat", e.Get("methods")) + } else { + fields = c.Get("fields") + } + for i := 0; i < methods.Length(); i++ { + m := methods.Index(i) + if m.Get("pkg").String() != "" { // not exported + continue + } + defineProperty(m.Get("prop").String(), func(op *Object) { + op.Set("value", func(args ...*Object) *Object { + return Global.Call("$externalizeFunction", v.Get(m.Get("prop").String()), m.Get("typ"), true, InternalObject(MakeFullWrapper)).Call("apply", v, args) + }) + }) + } + if fields != Undefined { + for i := 0; i < fields.Length(); i++ { + f := fields.Index(i) + if !f.Get("exported").Bool() { + continue + } + defineProperty(f.Get("prop").String(), func(op *Object) { + op.Set("get", func() *Object { + vc := Global.Call("$copyIfRequired", v.Get("$val").Get(f.Get("prop").String()), f.Get("typ")) + return Global.Call("$externalize", vc, f.Get("typ"), InternalObject(MakeFullWrapper)) + }) + op.Set("set", func(jv *Object) { + gv := Global.Call("$internalize", jv, f.Get("typ"), InternalObject(MakeFullWrapper)) + v.Get("$val").Set(f.Get("prop").String(), gv) + }) + }) + } + } + return o +} + // NewArrayBuffer creates a JavaScript ArrayBuffer from a byte slice. func NewArrayBuffer(b []byte) *Object { slice := InternalObject(b) diff --git a/tests/js_test.go b/tests/js_test.go index a51ee2767..4f3882f4a 100644 --- a/tests/js_test.go +++ b/tests/js_test.go @@ -391,6 +391,14 @@ type F struct { Field int } +func (f F) NonPoint() int { + return 10 +} + +func (f *F) Point() int { + return 20 +} + func TestExternalizeField(t *testing.T) { if dummys.Call("testField", map[string]int{"Field": 42}).Int() != 42 { t.Fail() @@ -423,7 +431,12 @@ func TestMakeFunc(t *testing.T) { } type M struct { - f int + Struct F + Pointer *F + Array [1]F + Slice []*F + Name string + f int } func (m *M) Method(a interface{}) map[string]string { @@ -435,8 +448,28 @@ func (m *M) Method(a interface{}) map[string]string { } } +func (m *M) GetF() F { + return m.Struct +} + +func (m *M) GetFPointer() *F { + return m.Pointer +} + +func (m *M) ParamMethod(v *M) string { + return v.Name +} + +func (m *M) Field() string { + return "rubbish" +} + +func (m M) NonPointField() string { + return "sensible" +} + func TestMakeWrapper(t *testing.T) { - m := &M{42} + m := &M{f: 42} if !js.Global.Call("eval", `(function(m) { return m.Method({x: 1})["y"] === "z"; })`).Invoke(js.MakeWrapper(m)).Bool() { t.Fail() } @@ -445,12 +478,140 @@ func TestMakeWrapper(t *testing.T) { t.Fail() } +} + +func TestMakeFullWrapperType(t *testing.T) { + m := &M{f: 42} f := func(m *M) { if m.f != 42 { t.Fail() } } - js.Global.Call("eval", `(function(f, m) { f(m); })`).Invoke(f, js.MakeWrapper(m)) + + js.Global.Call("eval", `(function(f, m) { f(m); })`).Invoke(f, js.MakeFullWrapper(m)) + want := "github.com/gopherjs/gopherjs/tests_test.*M" + if got := js.MakeFullWrapper(m).Get("$type").String(); got != want { + t.Errorf("wanted type string %q; got %q", want, got) + } +} + +func TestMakeFullWrapperGettersAndSetters(t *testing.T) { + f := &F{Field: 50} + m := &M{ + Name: "Gopher", + Struct: F{Field: 42}, + Pointer: f, + Array: [1]F{F{Field: 42}}, + Slice: []*F{f}, + } + + const globalVar = "TestMakeFullWrapper_w1" + + eval := func(s string, v ...interface{}) *js.Object { + return js.Global.Call("eval", s).Invoke(v...) + } + call := func(s string, v ...interface{}) *js.Object { + return eval(fmt.Sprintf(`(function(g) { return g["%v"]%v; })`, globalVar, s), js.Global).Invoke(v...) + } + get := func(s string) *js.Object { + return eval(fmt.Sprintf(`(function(g) { return g["%v"]%v; })`, globalVar, s), js.Global) + } + set := func(s string, v interface{}) { + eval(fmt.Sprintf(`(function(g, v) { g["%v"]%v = v; })`, globalVar, s), js.Global, v) + } + + w1 := js.MakeFullWrapper(m) + { + w2 := js.MakeFullWrapper(m) + + // we expect that MakeFullWrapper produces a different value each time + if eval(`(function(o, p) { return o === p; })`, w1, w2).Bool() { + t.Fatalf("w1 equalled w2 when we didn't expect it to") + } + } + + set("", w1) + + { + prop := ".Name" + want := m.Name + if got := get(prop).String(); got != want { + t.Fatalf("wanted w1%v to be %v; got %v", prop, want, got) + } + newVal := "JS" + set(prop, newVal) + if got := m.Name; got != newVal { + t.Fatalf("wanted m%v to be %v; got %v", prop, newVal, got) + } + } + { + prop := ".Struct.Field" + want := m.Struct.Field + if got := get(prop).Int(); got != want { + t.Fatalf("wanted w1%v to be %v; got %v", prop, want, got) + } + newVal := 40 + set(prop, newVal) + if got := m.Struct.Field; got == newVal { + t.Fatalf("wanted m%v not to be %v; but was", prop, newVal) + } + } + { + prop := ".Pointer.Field" + want := m.Pointer.Field + if got := get(prop).Int(); got != want { + t.Fatalf("wanted w1%v to be %v; got %v", prop, want, got) + } + newVal := 40 + set(prop, newVal) + if got := m.Pointer.Field; got != newVal { + t.Fatalf("wanted m%v to be %v; got %v", prop, newVal, got) + } + } + { + prop := ".Array[0].Field" + want := m.Array[0].Field + if got := get(prop).Int(); got != want { + t.Fatalf("wanted w1%v to be %v; got %v", prop, want, got) + } + newVal := 40 + set(prop, newVal) + if got := m.Array[0].Field; got == newVal { + t.Fatalf("wanted m%v not to be %v; but was", prop, newVal) + } + } + { + prop := ".Slice[0].Field" + want := m.Slice[0].Field + if got := get(prop).Int(); got != want { + t.Fatalf("wanted w1%v to be %v; got %v", prop, want, got) + } + newVal := 40 + set(prop, newVal) + if got := m.Slice[0].Field; got != newVal { + t.Fatalf("wanted m%v to be %v; got %v", prop, newVal, got) + } + } + { + prop := ".GetF().Field" + want := m.Struct.Field + if got := get(prop).Int(); got != want { + t.Fatalf("wanted w1%v to be %v; got %v", prop, want, got) + } + newVal := 105 + set(prop, newVal) + if got := m.Struct.Field; got == newVal { + t.Fatalf("wanted m%v not to be %v; but was", prop, newVal) + } + } + { + method := ".ParamMethod" + want := method + m.Name = want + if got := call(method, get("")).String(); got != want { + t.Fatalf("wanted w1%v() to be %v; got %v", method, want, got) + } + } } func TestCallWithNull(t *testing.T) { From d07b764d216ed5cd3c182d162149eced5eecca32 Mon Sep 17 00:00:00 2001 From: Paul Jolly Date: Sun, 8 Jul 2018 10:32:43 +0100 Subject: [PATCH 09/10] compiler: fix Make(Full)Wrapper where this is no return value (#10) --- compiler/gopherjspkg/fs_vfsdata.go | 6 +++--- compiler/natives/fs_vfsdata.go | 2 +- compiler/prelude/jsmapping.js | 3 +++ compiler/prelude/prelude.go | 2 +- compiler/prelude/prelude_min.go | 2 +- tests/js_test.go | 8 ++++++++ 6 files changed, 17 insertions(+), 6 deletions(-) diff --git a/compiler/gopherjspkg/fs_vfsdata.go b/compiler/gopherjspkg/fs_vfsdata.go index 3a25a90fd..6c319f7d2 100644 --- a/compiler/gopherjspkg/fs_vfsdata.go +++ b/compiler/gopherjspkg/fs_vfsdata.go @@ -21,15 +21,15 @@ var FS = func() http.FileSystem { fs := vfsgenÛ°FS{ "/": &vfsgenÛ°DirInfo{ name: "/", - modTime: time.Date(2018, 7, 7, 8, 29, 15, 490982724, time.UTC), + modTime: time.Date(2018, 7, 8, 7, 17, 22, 559259010, time.UTC), }, "/js": &vfsgenÛ°DirInfo{ name: "js", - modTime: time.Date(2018, 7, 7, 8, 21, 7, 523593061, time.UTC), + modTime: time.Date(2018, 7, 7, 16, 56, 51, 328524448, time.UTC), }, "/js/js.go": &vfsgenÛ°CompressedFileInfo{ name: "js.go", - modTime: time.Date(2018, 7, 7, 8, 21, 7, 523593061, time.UTC), + modTime: time.Date(2018, 7, 7, 16, 56, 51, 328524448, time.UTC), uncompressedSize: 10926, compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x5a\x5f\x73\xdb\x36\x90\x7f\x16\x3f\xc5\x96\xd3\x19\x8b\x89\x22\xf5\x4f\xc6\xd3\x71\xce\x0f\x69\x73\xcd\xa5\xd7\xb8\x99\xba\xb9\x3e\x64\x32\x1e\x88\x5c\x4a\x88\x29\x80\x05\x20\x29\xaa\xed\xef\x7e\xb3\x58\x80\x22\x45\x2a\x76\x9a\xde\xcc\xf9\xc5\x12\xb1\xf8\xed\x0f\xbb\x8b\xdd\x05\xa8\xd9\x0c\xde\x88\xfc\x5a\x2c\x10\x3e\x58\xa8\x8d\xde\xc8\x02\x2d\x94\x6b\x95\x3b\xa9\x95\x85\x52\x1b\x90\xca\xa1\x11\xb9\x93\x6a\x01\x5b\xe9\x96\xa0\x84\x93\x1b\x84\x5f\xc4\x46\x5c\xe6\x46\xd6\x0e\x9e\xbf\x79\x65\xa7\xf0\x93\xa8\x2a\x0b\x4e\x83\x5b\xa2\xc5\x16\x8a\x30\x08\xce\xa0\x70\x58\x80\xad\x31\x97\xa2\xaa\x76\x30\xdf\xc1\x4b\x5d\x2f\xd1\xfc\x72\x09\x42\x15\xe0\x8c\x50\xb6\xf2\x42\x85\x34\x98\xbb\x6a\x17\xc0\xa4\x81\x5c\x1b\x83\xb6\xd6\xaa\x20\x1a\x2d\xd5\x76\xa7\x9c\xf8\x38\x4d\x66\xb3\x64\x36\x83\xb7\x16\xe1\xb5\xb8\xc6\x3f\x8d\xa8\x6b\x34\x34\x1f\x3f\xd6\xda\x22\xac\xd0\x2d\x75\xe1\xe9\xed\x67\x4f\x9b\x09\x3f\xaf\xab\xea\xf8\xa4\xe7\x17\x2f\xa0\x94\x58\xf5\xe7\xff\xb9\x44\x05\xb5\xb0\x96\x68\x6d\x44\xb5\x46\xdb\xb0\x9f\x10\x77\x28\x75\x55\xe9\x2d\x0d\xbb\x5d\x8d\x90\x6b\xb5\x41\x63\x1b\xbb\xd4\x68\x4a\x6d\x56\x58\x9c\x85\x25\xc0\x2d\xbc\xd4\x2c\xdb\xfd\xbb\x6d\x2f\xbb\x35\x7e\x0b\x3f\xb5\x30\xe7\x22\xbf\x26\x92\xde\x6b\xa5\xc8\xf1\xe6\x0e\x6e\x03\xee\x93\xa1\xbf\xcf\x7d\xde\x96\x08\xb8\x73\xad\x2b\xe8\xfd\xdd\xc2\x8f\x5a\x57\x28\x54\xef\xf9\xb0\x7c\x4b\x22\xe0\xd2\x1a\x16\x68\xac\x0f\x8f\xb2\xd2\xc2\x59\x3f\xff\x62\xbd\x9a\xa3\xe9\xeb\xf3\x22\xa7\x4f\xef\xc5\xb5\xce\x90\x3f\x7a\xf3\x2f\x8f\x3c\x1f\x96\xef\xe3\xbe\x7b\x2f\x95\xfb\xa1\x3f\xff\x95\x72\x3f\x3c\x37\x46\xec\x0e\x9e\x0f\xcb\x1f\xc1\xfd\xf6\x74\x08\xf7\xdb\xd3\x1e\xf0\x31\xf9\x23\xb8\xdf\x7f\x37\xe1\x0f\x1d\xdc\xef\xbf\x3b\x86\x7b\x9c\x6e\x0b\x77\x3d\xb0\xb0\x5b\x78\x2b\x87\x0c\x71\x4c\xfe\x18\xee\xe1\xc2\x18\xb7\x6f\x88\x63\xf2\xc7\x70\xd9\x10\xeb\x66\x89\x8c\xdb\x37\xc4\x6d\x47\xea\xd3\xb8\x3e\x22\xbf\xff\xee\x80\xef\xcf\xfc\xf4\x00\xf8\x98\xfc\x51\xdc\x83\x48\x0f\xb8\xa7\x4f\x8f\xe1\x1e\xdd\x19\x11\x57\x54\x15\x68\xb7\x44\x03\xb6\x92\x39\xda\x38\xbf\x1f\xbb\xb0\x8f\x87\x26\xcb\x7c\x02\x97\xe6\xdb\xfe\x7c\x8b\xc8\x9a\x3a\xe9\xee\xd8\xf3\x3e\xee\xbe\xc2\x1c\xd8\x21\x3c\x3f\xd4\x47\xf2\xe3\xe9\x74\xda\x62\x9d\xc1\xa3\x0f\x76\xfa\xdb\xfc\x03\xe6\xae\xc1\x75\x72\x85\xd3\x3f\xe4\x0a\x0f\xe6\xbf\x10\x6e\x88\xcd\x11\xf9\x3e\xdf\x27\xc3\xa3\x20\x95\x75\x42\xe5\xa8\x4b\xb8\xd0\xc5\x3e\xaf\xb7\xa8\x7d\x12\x77\x25\x6a\x3b\xa1\x2c\xb5\xce\x9d\x1d\xc6\x6d\xc1\x78\xf9\x77\x9c\xd3\x86\x1d\x78\x1b\x4a\xd1\xf3\xa2\x90\x64\x47\x2a\xd7\x13\xdf\x0b\x88\xa0\x85\xca\x98\x13\x52\x51\x5a\x14\x6d\x9e\xbe\x4a\x4e\x40\x2b\x2a\xde\x4b\x5f\xee\x1c\x2a\x07\xba\xe4\x62\x48\xc3\xb0\x95\x55\x05\x73\xf4\x75\x13\x8b\x6e\x49\xf5\xb9\x7e\x43\xbe\xa7\x92\x26\xa6\x49\xdd\x34\x28\x09\x71\x0a\x7a\xa4\x05\x11\x49\xa0\x09\xdc\xfa\x8d\x89\xf6\xd2\xad\xd6\x44\x3a\xdb\x54\xf5\x7f\xa1\x2d\xe9\x37\x22\xf0\x1c\x94\xac\xa0\xd6\xde\xb2\x24\xb9\x67\x8c\x7f\xad\x45\xd5\x5d\xee\x89\x85\x54\xad\xab\x2a\x9d\x46\xb9\x5c\x28\x50\xda\x91\x7d\xd6\x64\x1d\x41\x2b\x5d\x89\x1a\xae\x71\x37\x4d\xfc\x86\x08\x92\xec\x8a\x9b\xb0\x48\x78\x14\x1e\xdf\x79\x3b\xbd\x44\x07\x06\xdd\xda\x28\xeb\x2d\xcf\x42\x27\xbe\xcb\xab\xd1\xb8\x1d\xf7\x72\x34\xb4\x90\x1b\x54\x0c\x4f\x3b\x04\xc6\x3a\x62\x65\x04\x33\xbe\xc6\x5d\x28\x81\x59\xa3\xe4\x26\x80\x83\x9e\x06\x1b\x07\xc9\x2c\xe8\xbf\x44\x07\xd4\x16\x2d\x82\x7e\xdf\x1b\x05\xc3\xfd\x53\x32\x97\x1d\x32\x93\x80\xd9\xd9\xcd\x37\x7b\x42\x41\x3a\x88\x45\x5e\x2f\xb0\x42\x87\x60\x70\xa5\x37\xf8\x45\xa6\x61\xa4\x8e\x75\x5a\xda\xf7\xa3\x51\xf3\xaf\xa8\x16\x6e\x39\xec\x94\xb4\xf2\x83\x69\x43\x61\x12\x1a\x45\xc7\xfb\x43\x2a\x37\xc0\x80\x11\xc7\x19\x0d\x0f\x78\xa4\x19\x66\xfd\xaf\x54\x81\x1f\x3b\xea\xe5\x89\x5b\x02\x56\xb8\x0a\x3b\x54\x28\x4e\xd5\x03\xaa\xfc\xe4\xb1\x24\x4d\x9f\x0a\x82\x20\xd6\x0a\x02\xd6\x6a\xd1\x7d\xb6\xca\x38\x99\xb5\x3e\xc0\xdb\x41\xfa\xc0\xe1\xb4\xf5\x21\xe7\xfd\xdf\x36\x39\x67\x81\x43\x57\x2b\xb1\xc2\x01\x2e\x04\x32\xa6\xb1\x26\xf6\x84\x59\x58\xe8\xd5\x92\xa3\x86\x69\x00\x78\xe6\x74\x3a\xdd\xbb\x65\xa3\xaf\xb1\xc7\x90\x32\x15\x56\xe5\x14\xfe\x58\x4a\xcb\x19\xb3\x14\xb2\x02\x59\x82\xf4\xc9\x84\x72\x84\x68\x4a\xe0\xa0\xcb\x08\x78\xfc\x99\x44\x5b\xb3\x5a\x24\x2f\x70\x0b\xb9\x4f\x95\x94\x8d\x14\x6e\x9b\xda\xc2\x99\x5d\x5a\x2e\xd5\x31\xdf\x0e\x92\xee\x32\x86\x71\xae\x15\xa7\x30\x6d\xb2\x01\xfe\x17\xb8\xfd\x5c\xf2\x71\x4a\x8b\x39\x9d\x41\x06\xf6\x5c\x77\x7b\xf9\x03\x89\xc8\x73\x6d\xfc\xf1\xb2\x5b\x90\x0e\x8f\x6d\x03\x54\x49\xc9\x38\x63\x98\x3e\xab\x30\x1a\xb6\x04\x9f\x25\xee\x63\x14\x8e\x1c\x5f\xc0\x89\x15\x8d\xb3\x08\xd5\xe7\xd5\x48\xc4\x40\x1c\xaa\x18\xbd\x3c\xf4\x60\x4e\x30\xae\x85\xb1\xf8\x4a\xb9\x21\xef\xbe\x52\xee\x68\xe2\xe2\xb1\x86\xd5\xe9\xd3\x87\xf0\x3a\x7d\xfa\xef\x31\x3b\x7d\xca\xdc\x4e\x9f\x0e\xb3\xf3\xe3\xcc\xef\xad\x7c\x10\xc1\xf5\xbf\xc9\x90\x75\x8e\xb3\x88\xda\xe7\xd8\x48\x30\x49\x7f\x30\xb8\x97\x63\x3c\x24\x7c\x26\x49\x0f\x3e\x44\xd3\x0f\x8c\xb3\x06\xb7\x4f\x33\x4a\x34\xae\xe6\x4d\xfe\x10\x77\xc7\x74\x30\x85\x4b\x44\x70\x62\x5e\x51\x6d\x80\xd8\x2d\xe6\x7a\xe5\x4b\x0c\x35\x86\x05\x3a\x21\xab\xa1\x3d\xd2\x68\x64\x77\x37\x9d\xf0\xa0\xd3\x1b\xc9\xe0\x78\x65\x45\x39\x48\x95\x3a\x36\xe5\x7d\x53\x3b\x33\x81\xed\x52\xe6\x4b\xdf\xd6\xcd\xb1\xb5\x8c\x8d\x14\xb0\xf6\x18\xd3\x37\xdc\x2c\x4e\xe1\x42\x3b\xcf\x43\x15\x58\x78\xea\xf5\x7a\x5e\xc9\x9c\x1a\xc1\xa1\x30\xf0\xb3\x43\x18\xd4\xce\x0c\xc5\x41\x14\x61\xce\xff\x69\x8c\x36\x80\x2a\x17\xb5\x5d\x57\x3e\x9b\xb7\xfc\x8b\x34\x6a\x29\x79\x6b\x8b\xdc\x1d\xaf\x8d\xc2\x82\x28\x69\x10\xf0\x52\x43\x2d\x94\xcc\x7d\x5b\xbc\x12\x3b\x5a\x8f\xc1\x5c\x6f\xd0\x60\x31\xa1\x02\xea\x53\x96\x82\x47\xac\xc7\x2d\x85\x83\xa5\xf6\xb7\x66\x4b\xec\x69\x8a\xc5\x82\x7b\x5a\x9e\x12\x4e\x17\x37\xc9\x28\xac\x32\x69\x13\x6f\xdb\x7a\x85\xd6\x92\xa3\xc3\xc1\xa2\xb5\xa6\xe2\xb8\x26\x36\x21\x1a\x13\x28\x66\x0c\xdc\x4a\x92\xc9\x28\x98\x30\x3d\x04\x39\x83\x14\x1e\xd3\x47\xdf\xe9\xa6\x41\x7f\x9a\x35\x69\x34\x89\x09\x5e\xe4\xd7\x1d\xaa\xd6\x3f\x69\x9a\xcb\x2f\x64\xec\xf1\x87\x18\x37\xd4\xbc\xbe\x3e\xb1\x97\x95\x9e\x8b\xca\xf7\x39\xb6\x7b\x02\x59\xf0\x48\x08\xdf\x71\xba\x95\xaa\xd0\xdb\xd4\x47\xe0\xdc\xe8\xad\x8d\x77\x70\xe9\xcb\x5f\x7f\xfb\xf1\xf9\xaf\x3c\x42\x47\xd5\xe9\x07\x9b\x4d\x93\x8d\x30\x11\x3d\xba\x8d\x14\xbe\xd6\xc5\xba\xc2\xa0\x70\x7f\x06\x08\xeb\x4f\x57\x7e\x38\x85\x8d\x30\xd2\x6f\x5f\x8b\x8e\x4e\x5f\x01\x77\x0a\xff\x25\x95\x3b\xe3\x83\x04\xb0\xb0\xbf\x97\x35\x8e\x9b\xb6\x93\x0f\x76\xca\x2a\x78\xd9\x3c\x66\x69\xe1\xfb\xaf\x17\x62\x85\xe9\x84\x5a\x88\xec\x84\x89\x06\x56\x6d\xa2\x6f\x55\x81\xa5\xa4\x48\xdf\x73\x6d\x79\x84\x69\xa7\xeb\x28\x95\x32\xd0\x7e\x56\x1b\xeb\x05\xce\xd7\x8b\x05\x1a\x58\x50\xcb\x9b\xeb\x55\x2d\xab\xc3\x33\x2e\x35\xfc\x45\x90\x7b\x96\x52\x7c\x38\xdf\x10\x07\x77\x47\x88\x71\x06\x37\xad\xcc\xa8\x44\x15\x1a\x9f\x4e\x0f\x1f\x86\xfa\xa7\x5e\xde\x7f\x06\x6b\x83\x16\x95\xb3\x20\x1f\x92\x60\xba\xaa\xb8\xf7\x1e\x68\xbd\x9a\xa8\x53\xb2\x0a\xf1\xc5\xd7\xe8\x2a\x87\xad\x11\xb5\x6d\x77\x7a\x14\x3a\x6c\x59\x91\xe7\x68\xe3\x3b\x82\x78\x5f\xae\xcb\x03\xdb\x50\x3f\x99\x72\xc0\x09\xb3\x58\x93\x69\x6c\x4a\xa7\xb0\xad\x36\x45\xcc\xe3\x51\xdd\xb8\x54\x7c\xb1\xe3\xbb\xd0\x40\xd0\x77\xd9\x3c\x11\xde\xbd\x6f\x32\xe6\x3d\x6b\xe1\x18\xe6\x5e\x3d\xfd\x7a\x15\x14\xa4\x93\x43\xa3\x94\x2a\x8b\x9b\xea\xbf\x71\x67\x3b\xfe\xb8\xa6\x07\x21\xc4\xf9\x48\xd1\xbf\x8e\xe0\x05\xd0\xd4\x76\x3a\x7f\xf7\x7e\xbf\xa5\x65\x09\x1a\xce\xcf\xfd\x55\xc2\xed\x2d\x7f\xde\xc7\xdb\x4d\x32\x6a\x9b\x7f\x74\x97\x8c\x04\x9c\x9d\x47\xfe\x7e\x37\x30\x6a\x9a\x85\xd5\x10\xad\x74\x02\x3a\x4b\x46\x96\x44\x69\x71\xe3\xa8\x71\x02\xa2\x39\x2c\x66\xc9\xc8\xbf\xf4\x21\xa1\x6f\x9e\x81\x84\xff\x68\x0d\x3e\x03\xf9\xf8\xb1\x57\x6f\xdf\xc9\xf7\x70\x0e\xa2\x39\xf1\xed\xb3\x0d\xd1\x09\xec\x6c\x2b\x34\xe2\xdb\x95\xfd\x31\xa2\x1f\xb1\x5c\x2a\x97\xc2\xfa\x18\xaa\x29\xed\x94\xbe\x90\xc4\x9d\x8f\x45\x73\x7b\xa3\x4b\x0a\xe8\xb7\xd6\x0f\x55\x32\x97\x8e\xb6\x9c\x43\xe3\x03\xc7\xf2\xc7\xd6\x5b\x9f\xf0\x4a\x27\x54\x98\xc1\xb7\x39\xfb\xc0\x0a\x64\x3f\x11\xfe\x1b\x32\xd0\xe1\x66\xc9\x92\x91\x3e\xea\x08\x3a\x9c\x90\x00\xa7\xa7\xab\xab\xb8\x73\xaf\x78\xf1\x57\x57\xe9\x04\x36\x59\x32\x8a\x9c\xcf\xce\x61\xc3\x10\xad\x83\x52\x9a\xc5\xf2\xe3\x85\xd2\x01\x77\x85\xa1\x01\xa7\xad\xbc\xe7\xc3\x70\x74\x5c\x32\xa2\x68\x5b\x31\x6c\x7d\xbd\x68\x15\x0e\xf8\xea\x1c\xd2\x14\x6e\x60\x36\xf3\x87\xb7\xe8\x83\x64\x34\x1a\xe5\x5a\x39\xa9\xd6\x98\x8c\xc8\xdf\x61\x55\x01\x85\xce\xb9\x2d\x98\x09\xef\xcf\x78\x96\x6b\x02\xbe\x65\xcd\xd1\xf0\x16\xc4\x8f\x6c\x22\xf9\x37\xc6\x3b\x5d\x32\x92\xd7\x12\x19\x1b\x5d\xb7\x74\x65\x93\xb8\x14\xb7\xab\xd3\x6c\x02\xce\xac\x31\x6e\x02\x51\xd7\xd5\x8e\x00\xf8\x10\x4e\x4b\xbf\xeb\xc4\xab\xee\xa4\xb2\xfd\x1b\xc1\x2f\x8c\x59\x82\x6c\x87\xed\x84\x42\x94\x1a\x43\x34\x08\x92\xef\x32\xc7\xad\x1b\x43\x91\xc5\x30\xf5\x19\x72\x12\x90\x8b\x10\xe0\x96\xf0\xf6\x41\xee\xbf\x8e\x97\xce\xd5\xf6\x6c\x36\x2b\x70\x83\x15\x75\x1a\xd3\x95\xfe\x5b\x56\x95\x98\x6a\xb3\x98\xa1\x7a\xf2\xf6\x72\x56\xe8\xdc\xce\xfe\xc4\xf9\x6c\xbf\x8a\xd9\xef\x58\xa2\x41\x95\xe3\x8c\x4d\x7f\xc5\x4e\xb1\x33\xfe\x3f\xe3\x9c\xf3\x26\x34\x2f\x19\xe9\x8a\xcb\x53\x5a\x3d\xc1\xd5\x1c\x0b\x2a\x26\xcd\xfe\x0c\x3b\x8b\xb7\xe7\xff\x70\x86\xe7\xb4\x1f\x9a\x5e\x7e\x3b\x1c\xec\x11\x97\x12\x56\xc6\x5d\xe7\x12\x57\x16\x37\x15\xda\x66\xe1\xdb\x25\xaa\x06\x65\x02\xf3\xb5\xa3\x3e\x53\xae\x48\xa7\x50\x8e\xaf\x5b\xc1\xe9\x84\x23\x15\xc9\xa6\xbe\xfc\xf1\x65\x45\x84\x09\x57\x48\x36\x38\xb4\x00\xad\x00\x45\xbe\x0c\xd0\x9d\xca\xd2\x78\xff\x1f\x24\x81\xfc\xd8\xe6\x4d\xee\x4f\x10\xc9\xa8\x6b\x72\x12\xf7\xfb\xe7\xba\xb9\x7b\x2a\x95\xdf\x48\xfe\x69\xdc\x4d\x99\xdf\x46\xba\xbe\x2f\xfd\xf8\x74\x71\x35\x81\x92\x04\x8d\x50\x0b\xf4\x70\x7e\x0f\x96\x63\x5d\x67\x61\x43\x7f\xa2\x96\x74\xf9\x51\x55\x99\xc0\xf5\x04\xfc\xdc\xbb\x1e\xff\x63\xa9\xce\xb3\xd7\xf5\xbe\xfe\x31\x7f\xce\x8e\xde\x51\x21\x1f\xde\x91\x4d\x68\x70\x36\x83\x5c\xe4\xbe\x63\x06\x01\x16\x95\x95\xd4\x36\xfa\xe3\x03\x9b\x26\x61\xa9\x2d\x42\xa1\xd5\x89\x83\xad\xf0\x51\x11\x02\x05\x84\xda\xc5\x03\xa2\xa5\xc3\xa2\xef\x18\xc2\x03\x9e\x69\x35\x4f\x06\xab\x9b\xbb\x3e\xa0\x75\x08\x7e\xcf\x34\xdf\xc1\x52\xa8\x82\xf4\xb8\x9d\xb7\x75\x1e\x7b\x6e\x12\x6d\x37\xdd\xa3\x51\x7d\xbd\x68\x49\x74\x53\x2b\x21\xd0\x91\xed\x8c\x32\x2c\xa7\x60\xb7\xab\xdf\x7d\xf3\x9e\x2a\xfd\xc9\xa3\x13\x76\x08\x49\x9c\x43\xfa\x28\xf5\x4e\x09\xce\x6b\xe7\xfa\x0a\xd5\xd8\xed\xea\x56\x8e\x8f\x48\x92\x91\xa6\x01\xc9\xd3\x3d\xe7\x91\xc7\xdf\x9e\xbd\xf7\xcf\xe6\x06\xc5\x35\x7d\xba\x8b\xf8\xf5\xf5\xe2\x0f\x5e\x17\x91\x7f\x0c\xe9\x94\x0e\x3d\x44\xe3\x31\xcd\x4d\x46\x3d\xe7\x7e\x4d\xe6\x3f\xe6\xce\x9e\x3f\x19\x7f\x9f\x78\x93\x11\x75\xd2\x21\x65\xc4\x36\xba\x5d\x01\xdb\x61\xe8\x5f\x43\xee\x23\x99\xaa\x96\x6d\x19\xb8\x29\x89\xcf\xe8\xf9\x57\x87\x0d\x53\x04\xdd\x57\x40\x8e\xe6\x5c\xab\x5c\xb8\x74\x02\x2b\xcb\xb5\x60\x36\x03\x59\x52\x18\x50\x2e\x12\xcd\x9b\x9c\xf0\x02\xc3\x27\xa2\xa2\x49\x73\xa5\xd1\xab\x78\x9f\xed\xa7\x62\x65\x31\xbe\xf9\x8a\xfb\x3e\xdc\xe5\xf2\x85\xe8\x52\x6c\x38\xc5\xf9\x15\x60\x6b\x01\x04\x43\xec\xb1\x4f\x3e\x68\x3b\x87\x70\xd6\xe1\xef\x54\xfd\xef\x5f\x17\x1e\x98\x87\x56\xc9\x34\x3b\xc8\xf9\x21\xf2\xdd\xff\x93\xd6\xe2\x20\xe2\x86\xeb\xfe\x43\x03\xf0\x01\x9d\xc8\xff\x69\x2b\xd2\x3b\x4b\x1c\x14\x9b\xec\x13\xbd\x8a\xdf\x33\xb1\x63\x91\x65\x0c\xc1\x7e\xb0\x1c\x78\x8d\xe5\x06\x9c\x36\xf2\x45\x20\x0c\xb7\x9c\x46\xe0\x5f\x95\xed\x53\x35\x16\x69\x16\xef\xb1\xd9\x48\x2d\x27\x79\x2f\x1d\xba\xa9\xfc\x2c\x37\x35\x7e\x5a\xa0\x8b\x5e\x3a\x74\xcb\x68\x93\xb7\x32\x42\x70\x4b\xae\xeb\xdd\xab\xf2\x77\xfc\x6b\x2d\x0d\x16\x8d\x47\xd2\xaf\x37\xa2\x0a\xbd\xf2\x30\x13\xa2\xd2\xf2\x4e\xc6\x2a\xee\x73\x3d\x29\xc8\xbb\x33\xef\xf7\xa8\x87\xbe\xcb\x3a\xeb\xb4\xfb\x75\x7e\xd8\x1c\x1a\x63\xb4\xd8\xf4\x57\x1a\x6b\x28\xb3\xf8\xb0\xf9\x47\x2c\x46\x5d\xf3\x5c\x1e\x35\xcf\x04\x16\x9b\x36\xf1\xbb\xd0\x17\xf4\x7b\xe5\x0b\xdc\xfa\xc4\xfc\xe3\xba\x2c\x8f\xb5\xca\x6d\x01\x9f\x31\x05\xcc\x77\x2e\xfc\xc8\x23\x74\x5d\x5d\x9c\xf1\x1c\xde\xbd\x27\x99\x4e\x14\xf0\x8f\x42\xfa\x3d\xd7\x9c\xce\x55\x65\x69\xd1\xd1\x20\xa3\xf2\x3a\xf9\x69\x9a\xf1\x3b\x85\x64\xc4\xef\x59\x0f\xa5\xc2\xdb\xd7\x46\x2a\x1e\x5f\x5b\x22\x22\x14\x1f\xff\x6d\xee\x39\x36\x0d\x91\x97\xa3\x3e\xc8\x2b\x8b\xff\x1f\x33\x6a\xbc\x29\x78\xcd\x7d\xbe\x95\xab\xba\x42\xff\x42\x9f\x2a\xe7\x14\x5e\xf9\xb7\x79\xcd\xa5\x8c\x7f\xdd\x6f\x97\xda\xb8\xa5\xff\xd5\x9b\x36\xfd\x33\x87\x85\xf1\x1c\x4b\x6d\xda\xb7\xf1\x59\xb8\x47\x7d\x7d\xe4\xd7\x1d\x7c\x37\xd9\xe1\xb0\xff\x89\xcd\x67\xb2\x08\xbf\xe7\x39\x4e\xe2\xb2\xfb\xd3\xa0\x84\x3d\x2c\x95\x74\x9c\x3f\xa8\xe9\xdf\x68\x59\x40\x81\xa2\x80\x5c\x17\x08\x58\xc9\x95\x54\xbe\xcd\x4a\x46\xde\xc7\xfe\xbe\xf3\xe6\x2e\x19\x5d\x51\xdd\x4b\xee\x92\xff\x0d\x00\x00\xff\xff\x14\x03\x9e\xa4\xae\x2a\x00\x00"), diff --git a/compiler/natives/fs_vfsdata.go b/compiler/natives/fs_vfsdata.go index 8df56ef4f..d68bd90b3 100644 --- a/compiler/natives/fs_vfsdata.go +++ b/compiler/natives/fs_vfsdata.go @@ -21,7 +21,7 @@ var FS = func() http.FileSystem { fs := vfsgenÛ°FS{ "/": &vfsgenÛ°DirInfo{ name: "/", - modTime: time.Date(2018, 7, 7, 8, 21, 7, 519593188, time.UTC), + modTime: time.Date(2018, 7, 7, 16, 56, 51, 328524448, time.UTC), }, "/src": &vfsgenÛ°DirInfo{ name: "src", diff --git a/compiler/prelude/jsmapping.js b/compiler/prelude/jsmapping.js index 1ef7e540d..526e1a6d7 100644 --- a/compiler/prelude/jsmapping.js +++ b/compiler/prelude/jsmapping.js @@ -392,6 +392,9 @@ var $isASCII = function(s) { }; var $copyIfRequired = function(v, typ) { + if (v == undefined) { + return v; + } // interface values if (v.constructor.copy) { return new v.constructor($clone(v.$val, v.constructor)); diff --git a/compiler/prelude/prelude.go b/compiler/prelude/prelude.go index 20ec3725a..dc92f0a68 100644 --- a/compiler/prelude/prelude.go +++ b/compiler/prelude/prelude.go @@ -3,4 +3,4 @@ package prelude // Prelude is the GopherJS JavaScript interop layer. -const Prelude = "Error.stackTraceLimit = Infinity;\n\nvar $global, $module;\nif (typeof window !== \"undefined\") {\n /* web page */\n $global = window;\n} else if (typeof self !== \"undefined\") {\n /* web worker */\n $global = self;\n} else if (typeof global !== \"undefined\") {\n /* Node.js */\n $global = global;\n $global.require = require;\n} else {\n /* others (e.g. Nashorn) */\n $global = this;\n}\n\nif ($global === undefined || $global.Array === undefined) {\n throw new Error(\"no global object found\");\n}\nif (typeof module !== \"undefined\") {\n $module = module;\n}\n\nvar $packages = {},\n $idCounter = 0;\nvar $keys = function(m) {\n return m ? Object.keys(m) : [];\n};\nvar $flushConsole = function() {};\nvar $throwRuntimeError; /* set by package \"runtime\" */\nvar $throwNilPointerError = function() {\n $throwRuntimeError(\"invalid memory address or nil pointer dereference\");\n};\nvar $call = function(fn, rcvr, args) {\n return fn.apply(rcvr, args);\n};\nvar $makeFunc = function(fn) {\n return function() {\n return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface);\n };\n};\nvar $unused = function(v) {};\n\nvar $mapArray = function(array, f) {\n var newArray = new array.constructor(array.length);\n for (var i = 0; i < array.length; i++) {\n newArray[i] = f(array[i]);\n }\n return newArray;\n};\n\nvar $methodVal = function(recv, name) {\n var vals = recv.$methodVals || {};\n recv.$methodVals = vals; /* noop for primitives */\n var f = vals[name];\n if (f !== undefined) {\n return f;\n }\n var method = recv[name];\n f = function() {\n $stackDepthOffset--;\n try {\n return method.apply(recv, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n vals[name] = f;\n return f;\n};\n\nvar $methodExpr = function(typ, name) {\n var method = typ.prototype[name];\n if (method.$expr === undefined) {\n method.$expr = function() {\n $stackDepthOffset--;\n try {\n if (typ.wrapped) {\n arguments[0] = new typ(arguments[0]);\n }\n return Function.call.apply(method, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return method.$expr;\n};\n\nvar $ifaceMethodExprs = {};\nvar $ifaceMethodExpr = function(name) {\n var expr = $ifaceMethodExprs[\"$\" + name];\n if (expr === undefined) {\n expr = $ifaceMethodExprs[\"$\" + name] = function() {\n $stackDepthOffset--;\n try {\n return Function.call.apply(arguments[0][name], arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return expr;\n};\n\nvar $subslice = function(slice, low, high, max) {\n if (high === undefined) {\n high = slice.$length;\n }\n if (max === undefined) {\n max = slice.$capacity;\n }\n if (low < 0 || high < low || max < high || high > slice.$capacity || max > slice.$capacity) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n var s = new slice.constructor(slice.$array);\n s.$offset = slice.$offset + low;\n s.$length = high - low;\n s.$capacity = max - low;\n return s;\n};\n\nvar $substring = function(str, low, high) {\n if (low < 0 || high < low || high > str.length) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n return str.substring(low, high);\n};\n\nvar $sliceToArray = function(slice) {\n if (slice.$array.constructor !== Array) {\n return slice.$array.subarray(slice.$offset, slice.$offset + slice.$length);\n }\n return slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n};\n\nvar $decodeRune = function(str, pos) {\n var c0 = str.charCodeAt(pos);\n\n if (c0 < 0x80) {\n return [c0, 1];\n }\n\n if (c0 !== c0 || c0 < 0xc0) {\n return [0xfffd, 1];\n }\n\n var c1 = str.charCodeAt(pos + 1);\n if (c1 !== c1 || c1 < 0x80 || 0xc0 <= c1) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xe0) {\n var r = ((c0 & 0x1f) << 6) | (c1 & 0x3f);\n if (r <= 0x7f) {\n return [0xfffd, 1];\n }\n return [r, 2];\n }\n\n var c2 = str.charCodeAt(pos + 2);\n if (c2 !== c2 || c2 < 0x80 || 0xc0 <= c2) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xf0) {\n var r = ((c0 & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f);\n if (r <= 0x7ff) {\n return [0xfffd, 1];\n }\n if (0xd800 <= r && r <= 0xdfff) {\n return [0xfffd, 1];\n }\n return [r, 3];\n }\n\n var c3 = str.charCodeAt(pos + 3);\n if (c3 !== c3 || c3 < 0x80 || 0xc0 <= c3) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xf8) {\n var r = ((c0 & 0x07) << 18) | ((c1 & 0x3f) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f);\n if (r <= 0xffff || 0x10ffff < r) {\n return [0xfffd, 1];\n }\n return [r, 4];\n }\n\n return [0xfffd, 1];\n};\n\nvar $encodeRune = function(r) {\n if (r < 0 || r > 0x10ffff || (0xd800 <= r && r <= 0xdfff)) {\n r = 0xfffd;\n }\n if (r <= 0x7f) {\n return String.fromCharCode(r);\n }\n if (r <= 0x7ff) {\n return String.fromCharCode(0xc0 | (r >> 6), 0x80 | (r & 0x3f));\n }\n if (r <= 0xffff) {\n return String.fromCharCode(0xe0 | (r >> 12), 0x80 | ((r >> 6) & 0x3f), 0x80 | (r & 0x3f));\n }\n return String.fromCharCode(0xf0 | (r >> 18), 0x80 | ((r >> 12) & 0x3f), 0x80 | ((r >> 6) & 0x3f), 0x80 | (r & 0x3f));\n};\n\nvar $stringToBytes = function(str) {\n var array = new Uint8Array(str.length);\n for (var i = 0; i < str.length; i++) {\n array[i] = str.charCodeAt(i);\n }\n return array;\n};\n\nvar $bytesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i += 10000) {\n str += String.fromCharCode.apply(undefined, slice.$array.subarray(slice.$offset + i, slice.$offset + Math.min(slice.$length, i + 10000)));\n }\n return str;\n};\n\nvar $stringToRunes = function(str) {\n var array = new Int32Array(str.length);\n var rune,\n j = 0;\n for (var i = 0; i < str.length; i += rune[1], j++) {\n rune = $decodeRune(str, i);\n array[j] = rune[0];\n }\n return array.subarray(0, j);\n};\n\nvar $runesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i++) {\n str += $encodeRune(slice.$array[slice.$offset + i]);\n }\n return str;\n};\n\nvar $copyString = function(dst, src) {\n var n = Math.min(src.length, dst.$length);\n for (var i = 0; i < n; i++) {\n dst.$array[dst.$offset + i] = src.charCodeAt(i);\n }\n return n;\n};\n\nvar $copySlice = function(dst, src) {\n var n = Math.min(src.$length, dst.$length);\n $copyArray(dst.$array, src.$array, dst.$offset, src.$offset, n, dst.constructor.elem);\n return n;\n};\n\nvar $copyArray = function(dst, src, dstOffset, srcOffset, n, elem) {\n if (n === 0 || (dst === src && dstOffset === srcOffset)) {\n return;\n }\n\n if (src.subarray) {\n dst.set(src.subarray(srcOffset, srcOffset + n), dstOffset);\n return;\n }\n\n switch (elem.kind) {\n case $kindArray:\n case $kindStruct:\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n};\n\nvar $clone = function(src, type) {\n var clone = type.zero();\n type.copy(clone, src);\n return clone;\n};\n\nvar $pointerOfStructConversion = function(obj, type) {\n if (obj.$proxies === undefined) {\n obj.$proxies = {};\n obj.$proxies[obj.constructor.string] = obj;\n }\n var proxy = obj.$proxies[type.string];\n if (proxy === undefined) {\n var properties = {};\n for (var i = 0; i < type.elem.fields.length; i++) {\n (function(fieldProp) {\n properties[fieldProp] = {\n get: function() {\n return obj[fieldProp];\n },\n set: function(value) {\n obj[fieldProp] = value;\n },\n };\n })(type.elem.fields[i].prop);\n }\n proxy = Object.create(type.prototype, properties);\n proxy.$val = proxy;\n obj.$proxies[type.string] = proxy;\n proxy.$proxies = obj.$proxies;\n }\n return proxy;\n};\n\nvar $append = function(slice) {\n return $internalAppend(slice, arguments, 1, arguments.length - 1);\n};\n\nvar $appendSlice = function(slice, toAppend) {\n if (toAppend.constructor === String) {\n var bytes = $stringToBytes(toAppend);\n return $internalAppend(slice, bytes, 0, bytes.length);\n }\n return $internalAppend(slice, toAppend.$array, toAppend.$offset, toAppend.$length);\n};\n\nvar $internalAppend = function(slice, array, offset, length) {\n if (length === 0) {\n return slice;\n }\n\n var newArray = slice.$array;\n var newOffset = slice.$offset;\n var newLength = slice.$length + length;\n var newCapacity = slice.$capacity;\n\n if (newLength > newCapacity) {\n newOffset = 0;\n newCapacity = Math.max(newLength, slice.$capacity < 1024 ? slice.$capacity * 2 : Math.floor(slice.$capacity * 5 / 4));\n\n if (slice.$array.constructor === Array) {\n newArray = slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n newArray.length = newCapacity;\n var zero = slice.constructor.elem.zero;\n for (var i = slice.$length; i < newCapacity; i++) {\n newArray[i] = zero();\n }\n } else {\n newArray = new slice.$array.constructor(newCapacity);\n newArray.set(slice.$array.subarray(slice.$offset, slice.$offset + slice.$length));\n }\n }\n\n $copyArray(newArray, array, newOffset + slice.$length, offset, length, slice.constructor.elem);\n\n var newSlice = new slice.constructor(newArray);\n newSlice.$offset = newOffset;\n newSlice.$length = newLength;\n newSlice.$capacity = newCapacity;\n return newSlice;\n};\n\nvar $equal = function(a, b, type) {\n if (type === $jsObjectPtr) {\n return a === b;\n }\n switch (type.kind) {\n case $kindComplex64:\n case $kindComplex128:\n return a.$real === b.$real && a.$imag === b.$imag;\n case $kindInt64:\n case $kindUint64:\n return a.$high === b.$high && a.$low === b.$low;\n case $kindArray:\n if (a.length !== b.length) {\n return false;\n }\n for (var i = 0; i < a.length; i++) {\n if (!$equal(a[i], b[i], type.elem)) {\n return false;\n }\n }\n return true;\n case $kindStruct:\n for (var i = 0; i < type.fields.length; i++) {\n var f = type.fields[i];\n if (!$equal(a[f.prop], b[f.prop], f.typ)) {\n return false;\n }\n }\n return true;\n case $kindInterface:\n return $interfaceIsEqual(a, b);\n default:\n return a === b;\n }\n};\n\nvar $interfaceIsEqual = function(a, b) {\n if (a === $ifaceNil || b === $ifaceNil) {\n return a === b;\n }\n if (a.constructor !== b.constructor) {\n return false;\n }\n if (a.constructor === $jsObjectPtr) {\n return a.object === b.object;\n }\n if (!a.constructor.comparable) {\n $throwRuntimeError(\"comparing uncomparable type \" + a.constructor.string);\n }\n return $equal(a.$val, b.$val, a.constructor);\n};\nvar $min = Math.min;\nvar $mod = function(x, y) {\n return x % y;\n};\nvar $parseInt = parseInt;\nvar $parseFloat = function(f) {\n if (f !== undefined && f !== null && f.constructor === Number) {\n return f;\n }\n return parseFloat(f);\n};\n\nvar $froundBuf = new Float32Array(1);\nvar $fround =\n Math.fround ||\n function(f) {\n $froundBuf[0] = f;\n return $froundBuf[0];\n };\n\nvar $imul =\n Math.imul ||\n function(a, b) {\n var ah = (a >>> 16) & 0xffff;\n var al = a & 0xffff;\n var bh = (b >>> 16) & 0xffff;\n var bl = b & 0xffff;\n return (al * bl + (((ah * bl + al * bh) << 16) >>> 0)) >> 0;\n };\n\nvar $floatKey = function(f) {\n if (f !== f) {\n $idCounter++;\n return \"NaN$\" + $idCounter;\n }\n return String(f);\n};\n\nvar $flatten64 = function(x) {\n return x.$high * 4294967296 + x.$low;\n};\n\nvar $shiftLeft64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor((x.$high << y) | (x.$low >>> (32 - y)), (x.$low << y) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$low << (y - 32), 0);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightInt64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >> y, ((x.$low >>> y) | (x.$high << (32 - y))) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$high >> 31, (x.$high >> (y - 32)) >>> 0);\n }\n if (x.$high < 0) {\n return new x.constructor(-1, 4294967295);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightUint64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >>> y, ((x.$low >>> y) | (x.$high << (32 - y))) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(0, x.$high >>> (y - 32));\n }\n return new x.constructor(0, 0);\n};\n\nvar $mul64 = function(x, y) {\n var high = 0,\n low = 0;\n if ((y.$low & 1) !== 0) {\n high = x.$high;\n low = x.$low;\n }\n for (var i = 1; i < 32; i++) {\n if ((y.$low & (1 << i)) !== 0) {\n high += (x.$high << i) | (x.$low >>> (32 - i));\n low += (x.$low << i) >>> 0;\n }\n }\n for (var i = 0; i < 32; i++) {\n if ((y.$high & (1 << i)) !== 0) {\n high += x.$low << i;\n }\n }\n return new x.constructor(high, low);\n};\n\nvar $div64 = function(x, y, returnRemainder) {\n if (y.$high === 0 && y.$low === 0) {\n $throwRuntimeError(\"integer divide by zero\");\n }\n\n var s = 1;\n var rs = 1;\n\n var xHigh = x.$high;\n var xLow = x.$low;\n if (xHigh < 0) {\n s = -1;\n rs = -1;\n xHigh = -xHigh;\n if (xLow !== 0) {\n xHigh--;\n xLow = 4294967296 - xLow;\n }\n }\n\n var yHigh = y.$high;\n var yLow = y.$low;\n if (y.$high < 0) {\n s *= -1;\n yHigh = -yHigh;\n if (yLow !== 0) {\n yHigh--;\n yLow = 4294967296 - yLow;\n }\n }\n\n var high = 0,\n low = 0,\n n = 0;\n while (yHigh < 2147483648 && (xHigh > yHigh || (xHigh === yHigh && xLow > yLow))) {\n yHigh = ((yHigh << 1) | (yLow >>> 31)) >>> 0;\n yLow = (yLow << 1) >>> 0;\n n++;\n }\n for (var i = 0; i <= n; i++) {\n high = (high << 1) | (low >>> 31);\n low = (low << 1) >>> 0;\n if (xHigh > yHigh || (xHigh === yHigh && xLow >= yLow)) {\n xHigh = xHigh - yHigh;\n xLow = xLow - yLow;\n if (xLow < 0) {\n xHigh--;\n xLow += 4294967296;\n }\n low++;\n if (low === 4294967296) {\n high++;\n low = 0;\n }\n }\n yLow = ((yLow >>> 1) | (yHigh << (32 - 1))) >>> 0;\n yHigh = yHigh >>> 1;\n }\n\n if (returnRemainder) {\n return new x.constructor(xHigh * rs, xLow * rs);\n }\n return new x.constructor(high * s, low * s);\n};\n\nvar $divComplex = function(n, d) {\n var ninf = n.$real === Infinity || n.$real === -Infinity || n.$imag === Infinity || n.$imag === -Infinity;\n var dinf = d.$real === Infinity || d.$real === -Infinity || d.$imag === Infinity || d.$imag === -Infinity;\n var nnan = !ninf && (n.$real !== n.$real || n.$imag !== n.$imag);\n var dnan = !dinf && (d.$real !== d.$real || d.$imag !== d.$imag);\n if (nnan || dnan) {\n return new n.constructor(NaN, NaN);\n }\n if (ninf && !dinf) {\n return new n.constructor(Infinity, Infinity);\n }\n if (!ninf && dinf) {\n return new n.constructor(0, 0);\n }\n if (d.$real === 0 && d.$imag === 0) {\n if (n.$real === 0 && n.$imag === 0) {\n return new n.constructor(NaN, NaN);\n }\n return new n.constructor(Infinity, Infinity);\n }\n var a = Math.abs(d.$real);\n var b = Math.abs(d.$imag);\n if (a <= b) {\n var ratio = d.$real / d.$imag;\n var denom = d.$real * ratio + d.$imag;\n return new n.constructor((n.$real * ratio + n.$imag) / denom, (n.$imag * ratio - n.$real) / denom);\n }\n var ratio = d.$imag / d.$real;\n var denom = d.$imag * ratio + d.$real;\n return new n.constructor((n.$imag * ratio + n.$real) / denom, (n.$imag - n.$real * ratio) / denom);\n};\nvar $kindBool = 1;\nvar $kindInt = 2;\nvar $kindInt8 = 3;\nvar $kindInt16 = 4;\nvar $kindInt32 = 5;\nvar $kindInt64 = 6;\nvar $kindUint = 7;\nvar $kindUint8 = 8;\nvar $kindUint16 = 9;\nvar $kindUint32 = 10;\nvar $kindUint64 = 11;\nvar $kindUintptr = 12;\nvar $kindFloat32 = 13;\nvar $kindFloat64 = 14;\nvar $kindComplex64 = 15;\nvar $kindComplex128 = 16;\nvar $kindArray = 17;\nvar $kindChan = 18;\nvar $kindFunc = 19;\nvar $kindInterface = 20;\nvar $kindMap = 21;\nvar $kindPtr = 22;\nvar $kindSlice = 23;\nvar $kindString = 24;\nvar $kindStruct = 25;\nvar $kindUnsafePointer = 26;\n\nvar $methodSynthesizers = [];\nvar $addMethodSynthesizer = function(f) {\n if ($methodSynthesizers === null) {\n f();\n return;\n }\n $methodSynthesizers.push(f);\n};\nvar $synthesizeMethods = function() {\n $methodSynthesizers.forEach(function(f) {\n f();\n });\n $methodSynthesizers = null;\n};\n\nvar $ifaceKeyFor = function(x) {\n if (x === $ifaceNil) {\n return \"nil\";\n }\n var c = x.constructor;\n return c.string + \"$\" + c.keyFor(x.$val);\n};\n\nvar $identity = function(x) {\n return x;\n};\n\nvar $typeIDCounter = 0;\n\nvar $idKey = function(x) {\n if (x.$id === undefined) {\n $idCounter++;\n x.$id = $idCounter;\n }\n return String(x.$id);\n};\n\nvar $newType = function(size, kind, string, named, pkg, exported, constructor) {\n var typ;\n switch (kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = $identity;\n break;\n\n case $kindString:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = function(x) {\n return \"$\" + x;\n };\n break;\n\n case $kindFloat32:\n case $kindFloat64:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = function(x) {\n return $floatKey(x);\n };\n break;\n\n case $kindInt64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$high + \"$\" + x.$low;\n };\n break;\n\n case $kindUint64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >>> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$high + \"$\" + x.$low;\n };\n break;\n\n case $kindComplex64:\n typ = function(real, imag) {\n this.$real = $fround(real);\n this.$imag = $fround(imag);\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$real + \"$\" + x.$imag;\n };\n break;\n\n case $kindComplex128:\n typ = function(real, imag) {\n this.$real = real;\n this.$imag = imag;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$real + \"$\" + x.$imag;\n };\n break;\n\n case $kindArray:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, \"\", false, function(array) {\n this.$get = function() {\n return array;\n };\n this.$set = function(v) {\n typ.copy(this, v);\n };\n this.$val = array;\n });\n typ.init = function(elem, len) {\n typ.elem = elem;\n typ.len = len;\n typ.comparable = elem.comparable;\n typ.keyFor = function(x) {\n return Array.prototype.join.call(\n $mapArray(x, function(e) {\n return String(elem.keyFor(e))\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\$/g, \"\\\\$\");\n }),\n \"$\"\n );\n };\n typ.copy = function(dst, src) {\n $copyArray(dst, src, 0, 0, src.length, elem);\n };\n typ.ptr.init(typ);\n Object.defineProperty(typ.ptr.nil, \"nilCheck\", { get: $throwNilPointerError });\n };\n break;\n\n case $kindChan:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = $idKey;\n typ.init = function(elem, sendOnly, recvOnly) {\n typ.elem = elem;\n typ.sendOnly = sendOnly;\n typ.recvOnly = recvOnly;\n };\n break;\n\n case $kindFunc:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.init = function(params, results, variadic) {\n typ.params = params;\n typ.results = results;\n typ.variadic = variadic;\n typ.comparable = false;\n };\n break;\n\n case $kindInterface:\n typ = { implementedBy: {}, missingMethodFor: {} };\n typ.keyFor = $ifaceKeyFor;\n typ.init = function(methods) {\n typ.methods = methods;\n methods.forEach(function(m) {\n $ifaceNil[m.prop] = $throwNilPointerError;\n });\n };\n break;\n\n case $kindMap:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.init = function(key, elem) {\n typ.key = key;\n typ.elem = elem;\n typ.comparable = false;\n };\n break;\n\n case $kindPtr:\n typ =\n constructor ||\n function(getter, setter, target) {\n this.$get = getter;\n this.$set = setter;\n this.$target = target;\n this.$val = this;\n };\n typ.keyFor = $idKey;\n typ.init = function(elem) {\n typ.elem = elem;\n typ.wrapped = elem.kind === $kindArray;\n typ.nil = new typ($throwNilPointerError, $throwNilPointerError);\n };\n break;\n\n case $kindSlice:\n typ = function(array) {\n if (array.constructor !== typ.nativeArray) {\n array = new typ.nativeArray(array);\n }\n this.$array = array;\n this.$offset = 0;\n this.$length = array.length;\n this.$capacity = array.length;\n this.$val = this;\n };\n typ.init = function(elem) {\n typ.elem = elem;\n typ.comparable = false;\n typ.nativeArray = $nativeArray(elem.kind);\n typ.nil = new typ([]);\n };\n break;\n\n case $kindStruct:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, pkg, exported, constructor);\n typ.ptr.elem = typ;\n typ.ptr.prototype.$get = function() {\n return this;\n };\n typ.ptr.prototype.$set = function(v) {\n typ.copy(this, v);\n };\n typ.init = function(pkgPath, fields) {\n typ.pkgPath = pkgPath;\n typ.fields = fields;\n fields.forEach(function(f) {\n if (!f.typ.comparable) {\n typ.comparable = false;\n }\n });\n typ.keyFor = function(x) {\n var val = x.$val;\n return $mapArray(fields, function(f) {\n return String(f.typ.keyFor(val[f.prop]))\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\$/g, \"\\\\$\");\n }).join(\"$\");\n };\n typ.copy = function(dst, src) {\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n switch (f.typ.kind) {\n case $kindArray:\n case $kindStruct:\n f.typ.copy(dst[f.prop], src[f.prop]);\n continue;\n default:\n dst[f.prop] = src[f.prop];\n continue;\n }\n }\n };\n /* nil value */\n var properties = {};\n fields.forEach(function(f) {\n properties[f.prop] = { get: $throwNilPointerError, set: $throwNilPointerError };\n });\n typ.ptr.nil = Object.create(constructor.prototype, properties);\n typ.ptr.nil.$val = typ.ptr.nil;\n /* methods for embedded fields */\n $addMethodSynthesizer(function() {\n var synthesizeMethod = function(target, m, f) {\n if (target.prototype[m.prop] !== undefined) {\n return;\n }\n target.prototype[m.prop] = function() {\n var v = this.$val[f.prop];\n if (f.typ === $jsObjectPtr) {\n v = new $jsObjectPtr(v);\n }\n if (v.$val === undefined) {\n v = new f.typ(v);\n }\n return v[m.prop].apply(v, arguments);\n };\n };\n fields.forEach(function(f) {\n if (f.anonymous) {\n $methodSet(f.typ).forEach(function(m) {\n synthesizeMethod(typ, m, f);\n synthesizeMethod(typ.ptr, m, f);\n });\n $methodSet($ptrType(f.typ)).forEach(function(m) {\n synthesizeMethod(typ.ptr, m, f);\n });\n }\n });\n });\n };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n switch (kind) {\n case $kindBool:\n case $kindMap:\n typ.zero = function() {\n return false;\n };\n break;\n\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n case $kindFloat32:\n case $kindFloat64:\n typ.zero = function() {\n return 0;\n };\n break;\n\n case $kindString:\n typ.zero = function() {\n return \"\";\n };\n break;\n\n case $kindInt64:\n case $kindUint64:\n case $kindComplex64:\n case $kindComplex128:\n var zero = new typ(0, 0);\n typ.zero = function() {\n return zero;\n };\n break;\n\n case $kindPtr:\n case $kindSlice:\n typ.zero = function() {\n return typ.nil;\n };\n break;\n\n case $kindChan:\n typ.zero = function() {\n return $chanNil;\n };\n break;\n\n case $kindFunc:\n typ.zero = function() {\n return $throwNilPointerError;\n };\n break;\n\n case $kindInterface:\n typ.zero = function() {\n return $ifaceNil;\n };\n break;\n\n case $kindArray:\n typ.zero = function() {\n var arrayClass = $nativeArray(typ.elem.kind);\n if (arrayClass !== Array) {\n return new arrayClass(typ.len);\n }\n var array = new Array(typ.len);\n for (var i = 0; i < typ.len; i++) {\n array[i] = typ.elem.zero();\n }\n return array;\n };\n break;\n\n case $kindStruct:\n typ.zero = function() {\n return new typ.ptr();\n };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n typ.id = $typeIDCounter;\n $typeIDCounter++;\n typ.size = size;\n typ.kind = kind;\n typ.string = string;\n typ.named = named;\n typ.pkg = pkg;\n typ.exported = exported;\n typ.methods = [];\n typ.methodSetCache = null;\n typ.comparable = true;\n return typ;\n};\n\nvar $methodSet = function(typ) {\n if (typ.methodSetCache !== null) {\n return typ.methodSetCache;\n }\n var base = {};\n\n var isPtr = typ.kind === $kindPtr;\n if (isPtr && typ.elem.kind === $kindInterface) {\n typ.methodSetCache = [];\n return [];\n }\n\n var current = [{ typ: isPtr ? typ.elem : typ, indirect: isPtr }];\n\n var seen = {};\n\n while (current.length > 0) {\n var next = [];\n var mset = [];\n\n current.forEach(function(e) {\n if (seen[e.typ.string]) {\n return;\n }\n seen[e.typ.string] = true;\n\n if (e.typ.named) {\n mset = mset.concat(e.typ.methods);\n if (e.indirect) {\n mset = mset.concat($ptrType(e.typ).methods);\n }\n }\n\n switch (e.typ.kind) {\n case $kindStruct:\n e.typ.fields.forEach(function(f) {\n if (f.anonymous) {\n var fTyp = f.typ;\n var fIsPtr = fTyp.kind === $kindPtr;\n next.push({ typ: fIsPtr ? fTyp.elem : fTyp, indirect: e.indirect || fIsPtr });\n }\n });\n break;\n\n case $kindInterface:\n mset = mset.concat(e.typ.methods);\n break;\n }\n });\n\n mset.forEach(function(m) {\n if (base[m.name] === undefined) {\n base[m.name] = m;\n }\n });\n\n current = next;\n }\n\n typ.methodSetCache = [];\n Object.keys(base)\n .sort()\n .forEach(function(name) {\n typ.methodSetCache.push(base[name]);\n });\n return typ.methodSetCache;\n};\n\nvar $Bool = $newType(1, $kindBool, \"bool\", true, \"\", false, null);\nvar $Int = $newType(4, $kindInt, \"int\", true, \"\", false, null);\nvar $Int8 = $newType(1, $kindInt8, \"int8\", true, \"\", false, null);\nvar $Int16 = $newType(2, $kindInt16, \"int16\", true, \"\", false, null);\nvar $Int32 = $newType(4, $kindInt32, \"int32\", true, \"\", false, null);\nvar $Int64 = $newType(8, $kindInt64, \"int64\", true, \"\", false, null);\nvar $Uint = $newType(4, $kindUint, \"uint\", true, \"\", false, null);\nvar $Uint8 = $newType(1, $kindUint8, \"uint8\", true, \"\", false, null);\nvar $Uint16 = $newType(2, $kindUint16, \"uint16\", true, \"\", false, null);\nvar $Uint32 = $newType(4, $kindUint32, \"uint32\", true, \"\", false, null);\nvar $Uint64 = $newType(8, $kindUint64, \"uint64\", true, \"\", false, null);\nvar $Uintptr = $newType(4, $kindUintptr, \"uintptr\", true, \"\", false, null);\nvar $Float32 = $newType(4, $kindFloat32, \"float32\", true, \"\", false, null);\nvar $Float64 = $newType(8, $kindFloat64, \"float64\", true, \"\", false, null);\nvar $Complex64 = $newType(8, $kindComplex64, \"complex64\", true, \"\", false, null);\nvar $Complex128 = $newType(16, $kindComplex128, \"complex128\", true, \"\", false, null);\nvar $String = $newType(8, $kindString, \"string\", true, \"\", false, null);\nvar $UnsafePointer = $newType(4, $kindUnsafePointer, \"unsafe.Pointer\", true, \"\", false, null);\n\nvar $nativeArray = function(elemKind) {\n switch (elemKind) {\n case $kindInt:\n return Int32Array;\n case $kindInt8:\n return Int8Array;\n case $kindInt16:\n return Int16Array;\n case $kindInt32:\n return Int32Array;\n case $kindUint:\n return Uint32Array;\n case $kindUint8:\n return Uint8Array;\n case $kindUint16:\n return Uint16Array;\n case $kindUint32:\n return Uint32Array;\n case $kindUintptr:\n return Uint32Array;\n case $kindFloat32:\n return Float32Array;\n case $kindFloat64:\n return Float64Array;\n default:\n return Array;\n }\n};\nvar $toNativeArray = function(elemKind, array) {\n var nativeArray = $nativeArray(elemKind);\n if (nativeArray === Array) {\n return array;\n }\n return new nativeArray(array);\n};\nvar $arrayTypes = {};\nvar $arrayType = function(elem, len) {\n var typeKey = elem.id + \"$\" + len;\n var typ = $arrayTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(12, $kindArray, \"[\" + len + \"]\" + elem.string, false, \"\", false, null);\n $arrayTypes[typeKey] = typ;\n typ.init(elem, len);\n }\n return typ;\n};\n\nvar $chanType = function(elem, sendOnly, recvOnly) {\n var string = (recvOnly ? \"<-\" : \"\") + \"chan\" + (sendOnly ? \"<- \" : \" \") + elem.string;\n var field = sendOnly ? \"SendChan\" : recvOnly ? \"RecvChan\" : \"Chan\";\n var typ = elem[field];\n if (typ === undefined) {\n typ = $newType(4, $kindChan, string, false, \"\", false, null);\n elem[field] = typ;\n typ.init(elem, sendOnly, recvOnly);\n }\n return typ;\n};\nvar $Chan = function(elem, capacity) {\n if (capacity < 0 || capacity > 2147483647) {\n $throwRuntimeError(\"makechan: size out of range\");\n }\n this.$elem = elem;\n this.$capacity = capacity;\n this.$buffer = [];\n this.$sendQueue = [];\n this.$recvQueue = [];\n this.$closed = false;\n};\nvar $chanNil = new $Chan(null, 0);\n$chanNil.$sendQueue = $chanNil.$recvQueue = {\n length: 0,\n push: function() {},\n shift: function() {\n return undefined;\n },\n indexOf: function() {\n return -1;\n },\n};\n\nvar $funcTypes = {};\nvar $funcType = function(params, results, variadic) {\n var typeKey =\n $mapArray(params, function(p) {\n return p.id;\n }).join(\",\") +\n \"$\" +\n $mapArray(results, function(r) {\n return r.id;\n }).join(\",\") +\n \"$\" +\n variadic;\n var typ = $funcTypes[typeKey];\n if (typ === undefined) {\n var paramTypes = $mapArray(params, function(p) {\n return p.string;\n });\n if (variadic) {\n paramTypes[paramTypes.length - 1] = \"...\" + paramTypes[paramTypes.length - 1].substr(2);\n }\n var string = \"func(\" + paramTypes.join(\", \") + \")\";\n if (results.length === 1) {\n string += \" \" + results[0].string;\n } else if (results.length > 1) {\n string +=\n \" (\" +\n $mapArray(results, function(r) {\n return r.string;\n }).join(\", \") +\n \")\";\n }\n typ = $newType(4, $kindFunc, string, false, \"\", false, null);\n $funcTypes[typeKey] = typ;\n typ.init(params, results, variadic);\n }\n return typ;\n};\n\nvar $interfaceTypes = {};\nvar $interfaceType = function(methods) {\n var typeKey = $mapArray(methods, function(m) {\n return m.pkg + \",\" + m.name + \",\" + m.typ.id;\n }).join(\"$\");\n var typ = $interfaceTypes[typeKey];\n if (typ === undefined) {\n var string = \"interface {}\";\n if (methods.length !== 0) {\n string =\n \"interface { \" +\n $mapArray(methods, function(m) {\n return (m.pkg !== \"\" ? m.pkg + \".\" : \"\") + m.name + m.typ.string.substr(4);\n }).join(\"; \") +\n \" }\";\n }\n typ = $newType(8, $kindInterface, string, false, \"\", false, null);\n $interfaceTypes[typeKey] = typ;\n typ.init(methods);\n }\n return typ;\n};\nvar $emptyInterface = $interfaceType([]);\nvar $ifaceNil = {};\nvar $error = $newType(8, $kindInterface, \"error\", true, \"\", false, null);\n$error.init([{ prop: \"Error\", name: \"Error\", pkg: \"\", typ: $funcType([], [$String], false) }]);\n\nvar $mapTypes = {};\nvar $mapType = function(key, elem) {\n var typeKey = key.id + \"$\" + elem.id;\n var typ = $mapTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(4, $kindMap, \"map[\" + key.string + \"]\" + elem.string, false, \"\", false, null);\n $mapTypes[typeKey] = typ;\n typ.init(key, elem);\n }\n return typ;\n};\nvar $makeMap = function(keyForFunc, entries) {\n var m = {};\n for (var i = 0; i < entries.length; i++) {\n var e = entries[i];\n m[keyForFunc(e.k)] = e;\n }\n return m;\n};\n\nvar $ptrType = function(elem) {\n var typ = elem.ptr;\n if (typ === undefined) {\n typ = $newType(4, $kindPtr, \"*\" + elem.string, false, \"\", elem.exported, null);\n elem.ptr = typ;\n typ.init(elem);\n }\n return typ;\n};\n\nvar $newDataPointer = function(data, constructor) {\n if (constructor.elem.kind === $kindStruct) {\n return data;\n }\n return new constructor(\n function() {\n return data;\n },\n function(v) {\n data = v;\n }\n );\n};\n\nvar $indexPtr = function(array, index, constructor) {\n array.$ptr = array.$ptr || {};\n return (\n array.$ptr[index] ||\n (array.$ptr[index] = new constructor(\n function() {\n return array[index];\n },\n function(v) {\n array[index] = v;\n }\n ))\n );\n};\n\nvar $sliceType = function(elem) {\n var typ = elem.slice;\n if (typ === undefined) {\n typ = $newType(12, $kindSlice, \"[]\" + elem.string, false, \"\", false, null);\n elem.slice = typ;\n typ.init(elem);\n }\n return typ;\n};\nvar $makeSlice = function(typ, length, capacity) {\n capacity = capacity || length;\n if (length < 0 || length > 2147483647) {\n $throwRuntimeError(\"makeslice: len out of range\");\n }\n if (capacity < 0 || capacity < length || capacity > 2147483647) {\n $throwRuntimeError(\"makeslice: cap out of range\");\n }\n var array = new typ.nativeArray(capacity);\n if (typ.nativeArray === Array) {\n for (var i = 0; i < capacity; i++) {\n array[i] = typ.elem.zero();\n }\n }\n var slice = new typ(array);\n slice.$length = length;\n return slice;\n};\n\nvar $structTypes = {};\nvar $structType = function(pkgPath, fields) {\n var typeKey = $mapArray(fields, function(f) {\n return f.name + \",\" + f.typ.id + \",\" + f.tag;\n }).join(\"$\");\n var typ = $structTypes[typeKey];\n if (typ === undefined) {\n var string =\n \"struct { \" +\n $mapArray(fields, function(f) {\n return f.name + \" \" + f.typ.string + (f.tag !== \"\" ? ' \"' + f.tag.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"') + '\"' : \"\");\n }).join(\"; \") +\n \" }\";\n if (fields.length === 0) {\n string = \"struct {}\";\n }\n typ = $newType(0, $kindStruct, string, false, \"\", false, function() {\n this.$val = this;\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n var arg = arguments[i];\n this[f.prop] = arg !== undefined ? arg : f.typ.zero();\n }\n });\n $structTypes[typeKey] = typ;\n typ.init(pkgPath, fields);\n }\n return typ;\n};\n\nvar $assertType = function(value, type, returnTuple) {\n var isInterface = type.kind === $kindInterface,\n ok,\n missingMethod = \"\";\n if (value === $ifaceNil) {\n ok = false;\n } else if (!isInterface) {\n ok = value.constructor === type;\n } else {\n var valueTypeString = value.constructor.string;\n ok = type.implementedBy[valueTypeString];\n if (ok === undefined) {\n ok = true;\n var valueMethodSet = $methodSet(value.constructor);\n var interfaceMethods = type.methods;\n for (var i = 0; i < interfaceMethods.length; i++) {\n var tm = interfaceMethods[i];\n var found = false;\n for (var j = 0; j < valueMethodSet.length; j++) {\n var vm = valueMethodSet[j];\n if (vm.name === tm.name && vm.pkg === tm.pkg && vm.typ === tm.typ) {\n found = true;\n break;\n }\n }\n if (!found) {\n ok = false;\n type.missingMethodFor[valueTypeString] = tm.name;\n break;\n }\n }\n type.implementedBy[valueTypeString] = ok;\n }\n if (!ok) {\n missingMethod = type.missingMethodFor[valueTypeString];\n }\n }\n\n if (!ok) {\n if (returnTuple) {\n return [type.zero(), false];\n }\n $panic(new $packages[\"runtime\"].TypeAssertionError.ptr(\"\", value === $ifaceNil ? \"\" : value.constructor.string, type.string, missingMethod));\n }\n\n if (!isInterface) {\n value = value.$val;\n }\n if (type === $jsObjectPtr) {\n value = value.object;\n }\n return returnTuple ? [value, true] : value;\n};\nvar $stackDepthOffset = 0;\nvar $getStackDepth = function() {\n var err = new Error();\n if (err.stack === undefined) {\n return undefined;\n }\n return $stackDepthOffset + err.stack.split(\"\\n\").length;\n};\n\nvar $panicStackDepth = null,\n $panicValue;\nvar $callDeferred = function(deferred, jsErr, fromPanic) {\n if (!fromPanic && deferred !== null && deferred.index >= $curGoroutine.deferStack.length) {\n throw jsErr;\n }\n if (jsErr !== null) {\n var newErr = null;\n try {\n $curGoroutine.deferStack.push(deferred);\n $panic(new $jsErrorPtr(jsErr));\n } catch (err) {\n newErr = err;\n }\n $curGoroutine.deferStack.pop();\n $callDeferred(deferred, newErr);\n return;\n }\n if ($curGoroutine.asleep) {\n return;\n }\n\n $stackDepthOffset--;\n var outerPanicStackDepth = $panicStackDepth;\n var outerPanicValue = $panicValue;\n\n var localPanicValue = $curGoroutine.panicStack.pop();\n if (localPanicValue !== undefined) {\n $panicStackDepth = $getStackDepth();\n $panicValue = localPanicValue;\n }\n\n try {\n while (true) {\n if (deferred === null) {\n deferred = $curGoroutine.deferStack[$curGoroutine.deferStack.length - 1];\n if (deferred === undefined) {\n /* The panic reached the top of the stack. Clear it and throw it as a JavaScript error. */\n $panicStackDepth = null;\n if (localPanicValue.Object instanceof Error) {\n throw localPanicValue.Object;\n }\n var msg;\n if (localPanicValue.constructor === $String) {\n msg = localPanicValue.$val;\n } else if (localPanicValue.Error !== undefined) {\n msg = localPanicValue.Error();\n } else if (localPanicValue.String !== undefined) {\n msg = localPanicValue.String();\n } else {\n msg = localPanicValue;\n }\n throw new Error(msg);\n }\n }\n var call = deferred.pop();\n if (call === undefined) {\n $curGoroutine.deferStack.pop();\n if (localPanicValue !== undefined) {\n deferred = null;\n continue;\n }\n return;\n }\n var r = call[0].apply(call[2], call[1]);\n if (r && r.$blk !== undefined) {\n deferred.push([r.$blk, [], r]);\n if (fromPanic) {\n throw null;\n }\n return;\n }\n\n if (localPanicValue !== undefined && $panicStackDepth === null) {\n throw null; /* error was recovered */\n }\n }\n } finally {\n if (localPanicValue !== undefined) {\n if ($panicStackDepth !== null) {\n $curGoroutine.panicStack.push(localPanicValue);\n }\n $panicStackDepth = outerPanicStackDepth;\n $panicValue = outerPanicValue;\n }\n $stackDepthOffset++;\n }\n};\n\nvar $panic = function(value) {\n $curGoroutine.panicStack.push(value);\n $callDeferred(null, null, true);\n};\nvar $recover = function() {\n if ($panicStackDepth === null || ($panicStackDepth !== undefined && $panicStackDepth !== $getStackDepth() - 2)) {\n return $ifaceNil;\n }\n $panicStackDepth = null;\n return $panicValue;\n};\nvar $throw = function(err) {\n throw err;\n};\n\nvar $noGoroutine = {\n asleep: false,\n exit: false,\n deferStack: [],\n panicStack: [],\n};\nvar $curGoroutine = $noGoroutine,\n $totalGoroutines = 0,\n $awakeGoroutines = 0,\n $checkForDeadlock = true;\nvar $mainFinished = false;\nvar $go = function(fun, args) {\n $totalGoroutines++;\n $awakeGoroutines++;\n var $goroutine = function() {\n try {\n $curGoroutine = $goroutine;\n var r = fun.apply(undefined, args);\n if (r && r.$blk !== undefined) {\n fun = function() {\n return r.$blk();\n };\n args = [];\n return;\n }\n $goroutine.exit = true;\n } catch (err) {\n if (!$goroutine.exit) {\n throw err;\n }\n } finally {\n $curGoroutine = $noGoroutine;\n if ($goroutine.exit) {\n /* also set by runtime.Goexit() */\n $totalGoroutines--;\n $goroutine.asleep = true;\n }\n if ($goroutine.asleep) {\n $awakeGoroutines--;\n if (!$mainFinished && $awakeGoroutines === 0 && $checkForDeadlock) {\n console.error(\"fatal error: all goroutines are asleep - deadlock!\");\n if ($global.process !== undefined) {\n $global.process.exit(2);\n }\n }\n }\n }\n };\n $goroutine.asleep = false;\n $goroutine.exit = false;\n $goroutine.deferStack = [];\n $goroutine.panicStack = [];\n $schedule($goroutine);\n};\n\nvar $scheduled = [];\nvar $runScheduled = function() {\n try {\n var r;\n while ((r = $scheduled.shift()) !== undefined) {\n r();\n }\n } finally {\n if ($scheduled.length > 0) {\n setTimeout($runScheduled, 0);\n }\n }\n};\n\nvar $schedule = function(goroutine) {\n if (goroutine.asleep) {\n goroutine.asleep = false;\n $awakeGoroutines++;\n }\n $scheduled.push(goroutine);\n if ($curGoroutine === $noGoroutine) {\n $runScheduled();\n }\n};\n\nvar $setTimeout = function(f, t) {\n $awakeGoroutines++;\n return setTimeout(function() {\n $awakeGoroutines--;\n f();\n }, t);\n};\n\nvar $block = function() {\n if ($curGoroutine === $noGoroutine) {\n $throwRuntimeError(\"cannot block in JavaScript callback, fix by wrapping code in goroutine\");\n }\n $curGoroutine.asleep = true;\n};\n\nvar $send = function(chan, value) {\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv !== undefined) {\n queuedRecv([value, true]);\n return;\n }\n if (chan.$buffer.length < chan.$capacity) {\n chan.$buffer.push(value);\n return;\n }\n\n var thisGoroutine = $curGoroutine;\n var closedDuringSend;\n chan.$sendQueue.push(function(closed) {\n closedDuringSend = closed;\n $schedule(thisGoroutine);\n return value;\n });\n $block();\n return {\n $blk: function() {\n if (closedDuringSend) {\n $throwRuntimeError(\"send on closed channel\");\n }\n },\n };\n};\nvar $recv = function(chan) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend !== undefined) {\n chan.$buffer.push(queuedSend(false));\n }\n var bufferedValue = chan.$buffer.shift();\n if (bufferedValue !== undefined) {\n return [bufferedValue, true];\n }\n if (chan.$closed) {\n return [chan.$elem.zero(), false];\n }\n\n var thisGoroutine = $curGoroutine;\n var f = {\n $blk: function() {\n return this.value;\n },\n };\n var queueEntry = function(v) {\n f.value = v;\n $schedule(thisGoroutine);\n };\n chan.$recvQueue.push(queueEntry);\n $block();\n return f;\n};\nvar $close = function(chan) {\n if (chan.$closed) {\n $throwRuntimeError(\"close of closed channel\");\n }\n chan.$closed = true;\n while (true) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend === undefined) {\n break;\n }\n queuedSend(true); /* will panic */\n }\n while (true) {\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv === undefined) {\n break;\n }\n queuedRecv([chan.$elem.zero(), false]);\n }\n};\nvar $select = function(comms) {\n var ready = [];\n var selection = -1;\n for (var i = 0; i < comms.length; i++) {\n var comm = comms[i];\n var chan = comm[0];\n switch (comm.length) {\n case 0 /* default */:\n selection = i;\n break;\n case 1 /* recv */:\n if (chan.$sendQueue.length !== 0 || chan.$buffer.length !== 0 || chan.$closed) {\n ready.push(i);\n }\n break;\n case 2 /* send */:\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n if (chan.$recvQueue.length !== 0 || chan.$buffer.length < chan.$capacity) {\n ready.push(i);\n }\n break;\n }\n }\n\n if (ready.length !== 0) {\n selection = ready[Math.floor(Math.random() * ready.length)];\n }\n if (selection !== -1) {\n var comm = comms[selection];\n switch (comm.length) {\n case 0 /* default */:\n return [selection];\n case 1 /* recv */:\n return [selection, $recv(comm[0])];\n case 2 /* send */:\n $send(comm[0], comm[1]);\n return [selection];\n }\n }\n\n var entries = [];\n var thisGoroutine = $curGoroutine;\n var f = {\n $blk: function() {\n return this.selection;\n },\n };\n var removeFromQueues = function() {\n for (var i = 0; i < entries.length; i++) {\n var entry = entries[i];\n var queue = entry[0];\n var index = queue.indexOf(entry[1]);\n if (index !== -1) {\n queue.splice(index, 1);\n }\n }\n };\n for (var i = 0; i < comms.length; i++) {\n (function(i) {\n var comm = comms[i];\n switch (comm.length) {\n case 1 /* recv */:\n var queueEntry = function(value) {\n f.selection = [i, value];\n removeFromQueues();\n $schedule(thisGoroutine);\n };\n entries.push([comm[0].$recvQueue, queueEntry]);\n comm[0].$recvQueue.push(queueEntry);\n break;\n case 2 /* send */:\n var queueEntry = function() {\n if (comm[0].$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n f.selection = [i];\n removeFromQueues();\n $schedule(thisGoroutine);\n return comm[1];\n };\n entries.push([comm[0].$sendQueue, queueEntry]);\n comm[0].$sendQueue.push(queueEntry);\n break;\n }\n })(i);\n }\n $block();\n return f;\n};\nvar $jsObjectPtr, $jsErrorPtr;\n\nvar $needsExternalization = function(t) {\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return false;\n default:\n return t !== $jsObjectPtr;\n }\n};\n\nvar $externalize = function(v, t, makeWrapper) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return v;\n case $kindInt64:\n case $kindUint64:\n return $flatten64(v);\n case $kindArray:\n if ($needsExternalization(t.elem)) {\n return $mapArray(v, function(e) {\n return $externalize(e, t.elem, makeWrapper);\n });\n }\n return v;\n case $kindFunc:\n return $externalizeFunction(v, t, false, makeWrapper);\n case $kindInterface:\n if (v === $ifaceNil) {\n return null;\n }\n if (v.constructor === $jsObjectPtr) {\n return v.$val.object;\n }\n return $externalize(v.$val, v.constructor, makeWrapper);\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var entry = v[keys[i]];\n m[$externalize(entry.k, t.key, makeWrapper)] = $externalize(entry.v, t.elem, makeWrapper);\n }\n return m;\n case $kindPtr:\n if (v === t.nil) {\n return null;\n }\n return $externalize(v.$get(), t.elem, makeWrapper);\n case $kindSlice:\n if ($needsExternalization(t.elem)) {\n return $mapArray($sliceToArray(v), function(e) {\n return $externalize(e, t.elem, makeWrapper);\n });\n }\n return $sliceToArray(v);\n case $kindString:\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\",\n r;\n for (var i = 0; i < v.length; i += r[1]) {\n r = $decodeRune(v, i);\n var c = r[0];\n if (c > 0xffff) {\n var h = Math.floor((c - 0x10000) / 0x400) + 0xd800;\n var l = (c - 0x10000) % 0x400 + 0xdc00;\n s += String.fromCharCode(h, l);\n continue;\n }\n s += String.fromCharCode(c);\n }\n return s;\n case $kindStruct:\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && v.constructor === timePkg.Time.ptr) {\n var milli = $div64(v.UnixNano(), new $Int64(0, 1000000));\n return new Date($flatten64(milli));\n }\n\n var noJsObject = {};\n var searchJsObject = function(v, t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindPtr:\n if (v === t.nil) {\n return noJsObject;\n }\n return searchJsObject(v.$get(), t.elem);\n case $kindStruct:\n var f = t.fields[0];\n return searchJsObject(v[f.prop], f.typ);\n case $kindInterface:\n return searchJsObject(v.$val, v.constructor);\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(v, t);\n if (o !== noJsObject) {\n return o;\n }\n\n if (makeWrapper !== undefined) {\n return makeWrapper(v);\n }\n\n o = {};\n for (var i = 0; i < t.fields.length; i++) {\n var f = t.fields[i];\n if (!f.exported) {\n continue;\n }\n o[f.name] = $externalize(v[f.prop], f.typ, makeWrapper);\n }\n return o;\n }\n $throwRuntimeError(\"cannot externalize \" + t.string);\n};\n\nvar $externalizeFunction = function(v, t, passThis, makeWrapper) {\n if (v === $throwNilPointerError) {\n return null;\n }\n if (v.$externalizeWrapper === undefined) {\n $checkForDeadlock = false;\n v.$externalizeWrapper = function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem,\n varargs = [];\n for (var j = i; j < arguments.length; j++) {\n varargs.push($internalize(arguments[j], vt, makeWrapper));\n }\n args.push(new t.params[i](varargs));\n break;\n }\n args.push($internalize(arguments[i], t.params[i], makeWrapper));\n }\n var result = v.apply(passThis ? this : undefined, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $externalize($copyIfRequired(result, t.results[0]), t.results[0], makeWrapper);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $externalize($copyIfRequired(result[i], t.results[i]), t.results[i], makeWrapper);\n }\n return result;\n }\n };\n }\n return v.$externalizeWrapper;\n};\n\nvar $internalize = function(v, t, recv, makeWrapper) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n if (v && v.__internal_object__ !== undefined) {\n return $assertType(v.__internal_object__, t, false);\n }\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && t === timePkg.Time) {\n if (!(v !== null && v !== undefined && v.constructor === Date)) {\n $throwRuntimeError(\"cannot internalize time.Time from \" + typeof v + \", must be Date\");\n }\n return timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000));\n }\n switch (t.kind) {\n case $kindBool:\n return !!v;\n case $kindInt:\n return parseInt(v);\n case $kindInt8:\n return (parseInt(v) << 24) >> 24;\n case $kindInt16:\n return (parseInt(v) << 16) >> 16;\n case $kindInt32:\n return parseInt(v) >> 0;\n case $kindUint:\n return parseInt(v);\n case $kindUint8:\n return (parseInt(v) << 24) >>> 24;\n case $kindUint16:\n return (parseInt(v) << 16) >>> 16;\n case $kindUint32:\n case $kindUintptr:\n return parseInt(v) >>> 0;\n case $kindInt64:\n case $kindUint64:\n return new t(0, v);\n case $kindFloat32:\n case $kindFloat64:\n return parseFloat(v);\n case $kindArray:\n if (v.length !== t.len) {\n $throwRuntimeError(\"got array with wrong size from JavaScript native\");\n }\n return $mapArray(v, function(e) {\n return $internalize(e, t.elem, makeWrapper);\n });\n case $kindFunc:\n return function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem,\n varargs = arguments[i];\n for (var j = 0; j < varargs.$length; j++) {\n args.push($externalize(varargs.$array[varargs.$offset + j], vt, makeWrapper));\n }\n break;\n }\n args.push($externalize(arguments[i], t.params[i], makeWrapper));\n }\n var result = v.apply(recv, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $internalize(result, t.results[0], makeWrapper);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $internalize(result[i], t.results[i], makeWrapper);\n }\n return result;\n }\n };\n case $kindInterface:\n if (t.methods.length !== 0) {\n $throwRuntimeError(\"cannot internalize \" + t.string);\n }\n if (v === null) {\n return $ifaceNil;\n }\n if (v === undefined) {\n return new $jsObjectPtr(undefined);\n }\n switch (v.constructor) {\n case Int8Array:\n return new ($sliceType($Int8))(v);\n case Int16Array:\n return new ($sliceType($Int16))(v);\n case Int32Array:\n return new ($sliceType($Int))(v);\n case Uint8Array:\n return new ($sliceType($Uint8))(v);\n case Uint16Array:\n return new ($sliceType($Uint16))(v);\n case Uint32Array:\n return new ($sliceType($Uint))(v);\n case Float32Array:\n return new ($sliceType($Float32))(v);\n case Float64Array:\n return new ($sliceType($Float64))(v);\n case Array:\n return $internalize(v, $sliceType($emptyInterface), makeWrapper);\n case Boolean:\n return new $Bool(!!v);\n case Date:\n if (timePkg === undefined) {\n /* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */\n return new $jsObjectPtr(v);\n }\n return new timePkg.Time($internalize(v, timePkg.Time, makeWrapper));\n case Function:\n var funcType = $funcType([$sliceType($emptyInterface)], [$jsObjectPtr], true);\n return new funcType($internalize(v, funcType, makeWrapper));\n case Number:\n return new $Float64(parseFloat(v));\n case String:\n return new $String($internalize(v, $String, makeWrapper));\n default:\n if ($global.Node && v instanceof $global.Node) {\n return new $jsObjectPtr(v);\n }\n var mapType = $mapType($String, $emptyInterface);\n return new mapType($internalize(v, mapType, makeWrapper));\n }\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var k = $internalize(keys[i], t.key, makeWrapper);\n m[t.key.keyFor(k)] = { k: k, v: $internalize(v[keys[i]], t.elem, makeWrapper) };\n }\n return m;\n case $kindPtr:\n if (t.elem.kind === $kindStruct) {\n return $internalize(v, t.elem, makeWrapper);\n }\n case $kindSlice:\n return new t(\n $mapArray(v, function(e) {\n return $internalize(e, t.elem, makeWrapper);\n })\n );\n case $kindString:\n v = String(v);\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\";\n var i = 0;\n while (i < v.length) {\n var h = v.charCodeAt(i);\n if (0xd800 <= h && h <= 0xdbff) {\n var l = v.charCodeAt(i + 1);\n var c = (h - 0xd800) * 0x400 + l - 0xdc00 + 0x10000;\n s += $encodeRune(c);\n i += 2;\n continue;\n }\n s += $encodeRune(h);\n i++;\n }\n return s;\n case $kindStruct:\n var noJsObject = {};\n var searchJsObject = function(t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n switch (t.kind) {\n case $kindPtr:\n return searchJsObject(t.elem);\n case $kindStruct:\n var f = t.fields[0];\n var o = searchJsObject(f.typ);\n if (o !== noJsObject) {\n var n = new t.ptr();\n n[f.prop] = o;\n return n;\n }\n return noJsObject;\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(t);\n if (o !== noJsObject) {\n return o;\n }\n }\n $throwRuntimeError(\"cannot internalize \" + t.string);\n};\n\n/* $isASCII reports whether string s contains only ASCII characters. */\nvar $isASCII = function(s) {\n for (var i = 0; i < s.length; i++) {\n if (s.charCodeAt(i) >= 128) {\n return false;\n }\n }\n return true;\n};\n\nvar $copyIfRequired = function(v, typ) {\n // interface values\n if (v.constructor.copy) {\n return new v.constructor($clone(v.$val, v.constructor));\n }\n // array and struct values\n if (typ.copy) {\n var clone = typ.zero();\n typ.copy(clone, v);\n return clone;\n }\n return v;\n};\n" +const Prelude = "Error.stackTraceLimit = Infinity;\n\nvar $global, $module;\nif (typeof window !== \"undefined\") {\n /* web page */\n $global = window;\n} else if (typeof self !== \"undefined\") {\n /* web worker */\n $global = self;\n} else if (typeof global !== \"undefined\") {\n /* Node.js */\n $global = global;\n $global.require = require;\n} else {\n /* others (e.g. Nashorn) */\n $global = this;\n}\n\nif ($global === undefined || $global.Array === undefined) {\n throw new Error(\"no global object found\");\n}\nif (typeof module !== \"undefined\") {\n $module = module;\n}\n\nvar $packages = {},\n $idCounter = 0;\nvar $keys = function(m) {\n return m ? Object.keys(m) : [];\n};\nvar $flushConsole = function() {};\nvar $throwRuntimeError; /* set by package \"runtime\" */\nvar $throwNilPointerError = function() {\n $throwRuntimeError(\"invalid memory address or nil pointer dereference\");\n};\nvar $call = function(fn, rcvr, args) {\n return fn.apply(rcvr, args);\n};\nvar $makeFunc = function(fn) {\n return function() {\n return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface);\n };\n};\nvar $unused = function(v) {};\n\nvar $mapArray = function(array, f) {\n var newArray = new array.constructor(array.length);\n for (var i = 0; i < array.length; i++) {\n newArray[i] = f(array[i]);\n }\n return newArray;\n};\n\nvar $methodVal = function(recv, name) {\n var vals = recv.$methodVals || {};\n recv.$methodVals = vals; /* noop for primitives */\n var f = vals[name];\n if (f !== undefined) {\n return f;\n }\n var method = recv[name];\n f = function() {\n $stackDepthOffset--;\n try {\n return method.apply(recv, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n vals[name] = f;\n return f;\n};\n\nvar $methodExpr = function(typ, name) {\n var method = typ.prototype[name];\n if (method.$expr === undefined) {\n method.$expr = function() {\n $stackDepthOffset--;\n try {\n if (typ.wrapped) {\n arguments[0] = new typ(arguments[0]);\n }\n return Function.call.apply(method, arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return method.$expr;\n};\n\nvar $ifaceMethodExprs = {};\nvar $ifaceMethodExpr = function(name) {\n var expr = $ifaceMethodExprs[\"$\" + name];\n if (expr === undefined) {\n expr = $ifaceMethodExprs[\"$\" + name] = function() {\n $stackDepthOffset--;\n try {\n return Function.call.apply(arguments[0][name], arguments);\n } finally {\n $stackDepthOffset++;\n }\n };\n }\n return expr;\n};\n\nvar $subslice = function(slice, low, high, max) {\n if (high === undefined) {\n high = slice.$length;\n }\n if (max === undefined) {\n max = slice.$capacity;\n }\n if (low < 0 || high < low || max < high || high > slice.$capacity || max > slice.$capacity) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n var s = new slice.constructor(slice.$array);\n s.$offset = slice.$offset + low;\n s.$length = high - low;\n s.$capacity = max - low;\n return s;\n};\n\nvar $substring = function(str, low, high) {\n if (low < 0 || high < low || high > str.length) {\n $throwRuntimeError(\"slice bounds out of range\");\n }\n return str.substring(low, high);\n};\n\nvar $sliceToArray = function(slice) {\n if (slice.$array.constructor !== Array) {\n return slice.$array.subarray(slice.$offset, slice.$offset + slice.$length);\n }\n return slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n};\n\nvar $decodeRune = function(str, pos) {\n var c0 = str.charCodeAt(pos);\n\n if (c0 < 0x80) {\n return [c0, 1];\n }\n\n if (c0 !== c0 || c0 < 0xc0) {\n return [0xfffd, 1];\n }\n\n var c1 = str.charCodeAt(pos + 1);\n if (c1 !== c1 || c1 < 0x80 || 0xc0 <= c1) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xe0) {\n var r = ((c0 & 0x1f) << 6) | (c1 & 0x3f);\n if (r <= 0x7f) {\n return [0xfffd, 1];\n }\n return [r, 2];\n }\n\n var c2 = str.charCodeAt(pos + 2);\n if (c2 !== c2 || c2 < 0x80 || 0xc0 <= c2) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xf0) {\n var r = ((c0 & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f);\n if (r <= 0x7ff) {\n return [0xfffd, 1];\n }\n if (0xd800 <= r && r <= 0xdfff) {\n return [0xfffd, 1];\n }\n return [r, 3];\n }\n\n var c3 = str.charCodeAt(pos + 3);\n if (c3 !== c3 || c3 < 0x80 || 0xc0 <= c3) {\n return [0xfffd, 1];\n }\n\n if (c0 < 0xf8) {\n var r = ((c0 & 0x07) << 18) | ((c1 & 0x3f) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f);\n if (r <= 0xffff || 0x10ffff < r) {\n return [0xfffd, 1];\n }\n return [r, 4];\n }\n\n return [0xfffd, 1];\n};\n\nvar $encodeRune = function(r) {\n if (r < 0 || r > 0x10ffff || (0xd800 <= r && r <= 0xdfff)) {\n r = 0xfffd;\n }\n if (r <= 0x7f) {\n return String.fromCharCode(r);\n }\n if (r <= 0x7ff) {\n return String.fromCharCode(0xc0 | (r >> 6), 0x80 | (r & 0x3f));\n }\n if (r <= 0xffff) {\n return String.fromCharCode(0xe0 | (r >> 12), 0x80 | ((r >> 6) & 0x3f), 0x80 | (r & 0x3f));\n }\n return String.fromCharCode(0xf0 | (r >> 18), 0x80 | ((r >> 12) & 0x3f), 0x80 | ((r >> 6) & 0x3f), 0x80 | (r & 0x3f));\n};\n\nvar $stringToBytes = function(str) {\n var array = new Uint8Array(str.length);\n for (var i = 0; i < str.length; i++) {\n array[i] = str.charCodeAt(i);\n }\n return array;\n};\n\nvar $bytesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i += 10000) {\n str += String.fromCharCode.apply(undefined, slice.$array.subarray(slice.$offset + i, slice.$offset + Math.min(slice.$length, i + 10000)));\n }\n return str;\n};\n\nvar $stringToRunes = function(str) {\n var array = new Int32Array(str.length);\n var rune,\n j = 0;\n for (var i = 0; i < str.length; i += rune[1], j++) {\n rune = $decodeRune(str, i);\n array[j] = rune[0];\n }\n return array.subarray(0, j);\n};\n\nvar $runesToString = function(slice) {\n if (slice.$length === 0) {\n return \"\";\n }\n var str = \"\";\n for (var i = 0; i < slice.$length; i++) {\n str += $encodeRune(slice.$array[slice.$offset + i]);\n }\n return str;\n};\n\nvar $copyString = function(dst, src) {\n var n = Math.min(src.length, dst.$length);\n for (var i = 0; i < n; i++) {\n dst.$array[dst.$offset + i] = src.charCodeAt(i);\n }\n return n;\n};\n\nvar $copySlice = function(dst, src) {\n var n = Math.min(src.$length, dst.$length);\n $copyArray(dst.$array, src.$array, dst.$offset, src.$offset, n, dst.constructor.elem);\n return n;\n};\n\nvar $copyArray = function(dst, src, dstOffset, srcOffset, n, elem) {\n if (n === 0 || (dst === src && dstOffset === srcOffset)) {\n return;\n }\n\n if (src.subarray) {\n dst.set(src.subarray(srcOffset, srcOffset + n), dstOffset);\n return;\n }\n\n switch (elem.kind) {\n case $kindArray:\n case $kindStruct:\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n elem.copy(dst[dstOffset + i], src[srcOffset + i]);\n }\n return;\n }\n\n if (dst === src && dstOffset > srcOffset) {\n for (var i = n - 1; i >= 0; i--) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n return;\n }\n for (var i = 0; i < n; i++) {\n dst[dstOffset + i] = src[srcOffset + i];\n }\n};\n\nvar $clone = function(src, type) {\n var clone = type.zero();\n type.copy(clone, src);\n return clone;\n};\n\nvar $pointerOfStructConversion = function(obj, type) {\n if (obj.$proxies === undefined) {\n obj.$proxies = {};\n obj.$proxies[obj.constructor.string] = obj;\n }\n var proxy = obj.$proxies[type.string];\n if (proxy === undefined) {\n var properties = {};\n for (var i = 0; i < type.elem.fields.length; i++) {\n (function(fieldProp) {\n properties[fieldProp] = {\n get: function() {\n return obj[fieldProp];\n },\n set: function(value) {\n obj[fieldProp] = value;\n },\n };\n })(type.elem.fields[i].prop);\n }\n proxy = Object.create(type.prototype, properties);\n proxy.$val = proxy;\n obj.$proxies[type.string] = proxy;\n proxy.$proxies = obj.$proxies;\n }\n return proxy;\n};\n\nvar $append = function(slice) {\n return $internalAppend(slice, arguments, 1, arguments.length - 1);\n};\n\nvar $appendSlice = function(slice, toAppend) {\n if (toAppend.constructor === String) {\n var bytes = $stringToBytes(toAppend);\n return $internalAppend(slice, bytes, 0, bytes.length);\n }\n return $internalAppend(slice, toAppend.$array, toAppend.$offset, toAppend.$length);\n};\n\nvar $internalAppend = function(slice, array, offset, length) {\n if (length === 0) {\n return slice;\n }\n\n var newArray = slice.$array;\n var newOffset = slice.$offset;\n var newLength = slice.$length + length;\n var newCapacity = slice.$capacity;\n\n if (newLength > newCapacity) {\n newOffset = 0;\n newCapacity = Math.max(newLength, slice.$capacity < 1024 ? slice.$capacity * 2 : Math.floor(slice.$capacity * 5 / 4));\n\n if (slice.$array.constructor === Array) {\n newArray = slice.$array.slice(slice.$offset, slice.$offset + slice.$length);\n newArray.length = newCapacity;\n var zero = slice.constructor.elem.zero;\n for (var i = slice.$length; i < newCapacity; i++) {\n newArray[i] = zero();\n }\n } else {\n newArray = new slice.$array.constructor(newCapacity);\n newArray.set(slice.$array.subarray(slice.$offset, slice.$offset + slice.$length));\n }\n }\n\n $copyArray(newArray, array, newOffset + slice.$length, offset, length, slice.constructor.elem);\n\n var newSlice = new slice.constructor(newArray);\n newSlice.$offset = newOffset;\n newSlice.$length = newLength;\n newSlice.$capacity = newCapacity;\n return newSlice;\n};\n\nvar $equal = function(a, b, type) {\n if (type === $jsObjectPtr) {\n return a === b;\n }\n switch (type.kind) {\n case $kindComplex64:\n case $kindComplex128:\n return a.$real === b.$real && a.$imag === b.$imag;\n case $kindInt64:\n case $kindUint64:\n return a.$high === b.$high && a.$low === b.$low;\n case $kindArray:\n if (a.length !== b.length) {\n return false;\n }\n for (var i = 0; i < a.length; i++) {\n if (!$equal(a[i], b[i], type.elem)) {\n return false;\n }\n }\n return true;\n case $kindStruct:\n for (var i = 0; i < type.fields.length; i++) {\n var f = type.fields[i];\n if (!$equal(a[f.prop], b[f.prop], f.typ)) {\n return false;\n }\n }\n return true;\n case $kindInterface:\n return $interfaceIsEqual(a, b);\n default:\n return a === b;\n }\n};\n\nvar $interfaceIsEqual = function(a, b) {\n if (a === $ifaceNil || b === $ifaceNil) {\n return a === b;\n }\n if (a.constructor !== b.constructor) {\n return false;\n }\n if (a.constructor === $jsObjectPtr) {\n return a.object === b.object;\n }\n if (!a.constructor.comparable) {\n $throwRuntimeError(\"comparing uncomparable type \" + a.constructor.string);\n }\n return $equal(a.$val, b.$val, a.constructor);\n};\nvar $min = Math.min;\nvar $mod = function(x, y) {\n return x % y;\n};\nvar $parseInt = parseInt;\nvar $parseFloat = function(f) {\n if (f !== undefined && f !== null && f.constructor === Number) {\n return f;\n }\n return parseFloat(f);\n};\n\nvar $froundBuf = new Float32Array(1);\nvar $fround =\n Math.fround ||\n function(f) {\n $froundBuf[0] = f;\n return $froundBuf[0];\n };\n\nvar $imul =\n Math.imul ||\n function(a, b) {\n var ah = (a >>> 16) & 0xffff;\n var al = a & 0xffff;\n var bh = (b >>> 16) & 0xffff;\n var bl = b & 0xffff;\n return (al * bl + (((ah * bl + al * bh) << 16) >>> 0)) >> 0;\n };\n\nvar $floatKey = function(f) {\n if (f !== f) {\n $idCounter++;\n return \"NaN$\" + $idCounter;\n }\n return String(f);\n};\n\nvar $flatten64 = function(x) {\n return x.$high * 4294967296 + x.$low;\n};\n\nvar $shiftLeft64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor((x.$high << y) | (x.$low >>> (32 - y)), (x.$low << y) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$low << (y - 32), 0);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightInt64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >> y, ((x.$low >>> y) | (x.$high << (32 - y))) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(x.$high >> 31, (x.$high >> (y - 32)) >>> 0);\n }\n if (x.$high < 0) {\n return new x.constructor(-1, 4294967295);\n }\n return new x.constructor(0, 0);\n};\n\nvar $shiftRightUint64 = function(x, y) {\n if (y === 0) {\n return x;\n }\n if (y < 32) {\n return new x.constructor(x.$high >>> y, ((x.$low >>> y) | (x.$high << (32 - y))) >>> 0);\n }\n if (y < 64) {\n return new x.constructor(0, x.$high >>> (y - 32));\n }\n return new x.constructor(0, 0);\n};\n\nvar $mul64 = function(x, y) {\n var high = 0,\n low = 0;\n if ((y.$low & 1) !== 0) {\n high = x.$high;\n low = x.$low;\n }\n for (var i = 1; i < 32; i++) {\n if ((y.$low & (1 << i)) !== 0) {\n high += (x.$high << i) | (x.$low >>> (32 - i));\n low += (x.$low << i) >>> 0;\n }\n }\n for (var i = 0; i < 32; i++) {\n if ((y.$high & (1 << i)) !== 0) {\n high += x.$low << i;\n }\n }\n return new x.constructor(high, low);\n};\n\nvar $div64 = function(x, y, returnRemainder) {\n if (y.$high === 0 && y.$low === 0) {\n $throwRuntimeError(\"integer divide by zero\");\n }\n\n var s = 1;\n var rs = 1;\n\n var xHigh = x.$high;\n var xLow = x.$low;\n if (xHigh < 0) {\n s = -1;\n rs = -1;\n xHigh = -xHigh;\n if (xLow !== 0) {\n xHigh--;\n xLow = 4294967296 - xLow;\n }\n }\n\n var yHigh = y.$high;\n var yLow = y.$low;\n if (y.$high < 0) {\n s *= -1;\n yHigh = -yHigh;\n if (yLow !== 0) {\n yHigh--;\n yLow = 4294967296 - yLow;\n }\n }\n\n var high = 0,\n low = 0,\n n = 0;\n while (yHigh < 2147483648 && (xHigh > yHigh || (xHigh === yHigh && xLow > yLow))) {\n yHigh = ((yHigh << 1) | (yLow >>> 31)) >>> 0;\n yLow = (yLow << 1) >>> 0;\n n++;\n }\n for (var i = 0; i <= n; i++) {\n high = (high << 1) | (low >>> 31);\n low = (low << 1) >>> 0;\n if (xHigh > yHigh || (xHigh === yHigh && xLow >= yLow)) {\n xHigh = xHigh - yHigh;\n xLow = xLow - yLow;\n if (xLow < 0) {\n xHigh--;\n xLow += 4294967296;\n }\n low++;\n if (low === 4294967296) {\n high++;\n low = 0;\n }\n }\n yLow = ((yLow >>> 1) | (yHigh << (32 - 1))) >>> 0;\n yHigh = yHigh >>> 1;\n }\n\n if (returnRemainder) {\n return new x.constructor(xHigh * rs, xLow * rs);\n }\n return new x.constructor(high * s, low * s);\n};\n\nvar $divComplex = function(n, d) {\n var ninf = n.$real === Infinity || n.$real === -Infinity || n.$imag === Infinity || n.$imag === -Infinity;\n var dinf = d.$real === Infinity || d.$real === -Infinity || d.$imag === Infinity || d.$imag === -Infinity;\n var nnan = !ninf && (n.$real !== n.$real || n.$imag !== n.$imag);\n var dnan = !dinf && (d.$real !== d.$real || d.$imag !== d.$imag);\n if (nnan || dnan) {\n return new n.constructor(NaN, NaN);\n }\n if (ninf && !dinf) {\n return new n.constructor(Infinity, Infinity);\n }\n if (!ninf && dinf) {\n return new n.constructor(0, 0);\n }\n if (d.$real === 0 && d.$imag === 0) {\n if (n.$real === 0 && n.$imag === 0) {\n return new n.constructor(NaN, NaN);\n }\n return new n.constructor(Infinity, Infinity);\n }\n var a = Math.abs(d.$real);\n var b = Math.abs(d.$imag);\n if (a <= b) {\n var ratio = d.$real / d.$imag;\n var denom = d.$real * ratio + d.$imag;\n return new n.constructor((n.$real * ratio + n.$imag) / denom, (n.$imag * ratio - n.$real) / denom);\n }\n var ratio = d.$imag / d.$real;\n var denom = d.$imag * ratio + d.$real;\n return new n.constructor((n.$imag * ratio + n.$real) / denom, (n.$imag - n.$real * ratio) / denom);\n};\nvar $kindBool = 1;\nvar $kindInt = 2;\nvar $kindInt8 = 3;\nvar $kindInt16 = 4;\nvar $kindInt32 = 5;\nvar $kindInt64 = 6;\nvar $kindUint = 7;\nvar $kindUint8 = 8;\nvar $kindUint16 = 9;\nvar $kindUint32 = 10;\nvar $kindUint64 = 11;\nvar $kindUintptr = 12;\nvar $kindFloat32 = 13;\nvar $kindFloat64 = 14;\nvar $kindComplex64 = 15;\nvar $kindComplex128 = 16;\nvar $kindArray = 17;\nvar $kindChan = 18;\nvar $kindFunc = 19;\nvar $kindInterface = 20;\nvar $kindMap = 21;\nvar $kindPtr = 22;\nvar $kindSlice = 23;\nvar $kindString = 24;\nvar $kindStruct = 25;\nvar $kindUnsafePointer = 26;\n\nvar $methodSynthesizers = [];\nvar $addMethodSynthesizer = function(f) {\n if ($methodSynthesizers === null) {\n f();\n return;\n }\n $methodSynthesizers.push(f);\n};\nvar $synthesizeMethods = function() {\n $methodSynthesizers.forEach(function(f) {\n f();\n });\n $methodSynthesizers = null;\n};\n\nvar $ifaceKeyFor = function(x) {\n if (x === $ifaceNil) {\n return \"nil\";\n }\n var c = x.constructor;\n return c.string + \"$\" + c.keyFor(x.$val);\n};\n\nvar $identity = function(x) {\n return x;\n};\n\nvar $typeIDCounter = 0;\n\nvar $idKey = function(x) {\n if (x.$id === undefined) {\n $idCounter++;\n x.$id = $idCounter;\n }\n return String(x.$id);\n};\n\nvar $newType = function(size, kind, string, named, pkg, exported, constructor) {\n var typ;\n switch (kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = $identity;\n break;\n\n case $kindString:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = function(x) {\n return \"$\" + x;\n };\n break;\n\n case $kindFloat32:\n case $kindFloat64:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = function(x) {\n return $floatKey(x);\n };\n break;\n\n case $kindInt64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$high + \"$\" + x.$low;\n };\n break;\n\n case $kindUint64:\n typ = function(high, low) {\n this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >>> 0;\n this.$low = low >>> 0;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$high + \"$\" + x.$low;\n };\n break;\n\n case $kindComplex64:\n typ = function(real, imag) {\n this.$real = $fround(real);\n this.$imag = $fround(imag);\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$real + \"$\" + x.$imag;\n };\n break;\n\n case $kindComplex128:\n typ = function(real, imag) {\n this.$real = real;\n this.$imag = imag;\n this.$val = this;\n };\n typ.keyFor = function(x) {\n return x.$real + \"$\" + x.$imag;\n };\n break;\n\n case $kindArray:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, \"\", false, function(array) {\n this.$get = function() {\n return array;\n };\n this.$set = function(v) {\n typ.copy(this, v);\n };\n this.$val = array;\n });\n typ.init = function(elem, len) {\n typ.elem = elem;\n typ.len = len;\n typ.comparable = elem.comparable;\n typ.keyFor = function(x) {\n return Array.prototype.join.call(\n $mapArray(x, function(e) {\n return String(elem.keyFor(e))\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\$/g, \"\\\\$\");\n }),\n \"$\"\n );\n };\n typ.copy = function(dst, src) {\n $copyArray(dst, src, 0, 0, src.length, elem);\n };\n typ.ptr.init(typ);\n Object.defineProperty(typ.ptr.nil, \"nilCheck\", { get: $throwNilPointerError });\n };\n break;\n\n case $kindChan:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.keyFor = $idKey;\n typ.init = function(elem, sendOnly, recvOnly) {\n typ.elem = elem;\n typ.sendOnly = sendOnly;\n typ.recvOnly = recvOnly;\n };\n break;\n\n case $kindFunc:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.init = function(params, results, variadic) {\n typ.params = params;\n typ.results = results;\n typ.variadic = variadic;\n typ.comparable = false;\n };\n break;\n\n case $kindInterface:\n typ = { implementedBy: {}, missingMethodFor: {} };\n typ.keyFor = $ifaceKeyFor;\n typ.init = function(methods) {\n typ.methods = methods;\n methods.forEach(function(m) {\n $ifaceNil[m.prop] = $throwNilPointerError;\n });\n };\n break;\n\n case $kindMap:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.init = function(key, elem) {\n typ.key = key;\n typ.elem = elem;\n typ.comparable = false;\n };\n break;\n\n case $kindPtr:\n typ =\n constructor ||\n function(getter, setter, target) {\n this.$get = getter;\n this.$set = setter;\n this.$target = target;\n this.$val = this;\n };\n typ.keyFor = $idKey;\n typ.init = function(elem) {\n typ.elem = elem;\n typ.wrapped = elem.kind === $kindArray;\n typ.nil = new typ($throwNilPointerError, $throwNilPointerError);\n };\n break;\n\n case $kindSlice:\n typ = function(array) {\n if (array.constructor !== typ.nativeArray) {\n array = new typ.nativeArray(array);\n }\n this.$array = array;\n this.$offset = 0;\n this.$length = array.length;\n this.$capacity = array.length;\n this.$val = this;\n };\n typ.init = function(elem) {\n typ.elem = elem;\n typ.comparable = false;\n typ.nativeArray = $nativeArray(elem.kind);\n typ.nil = new typ([]);\n };\n break;\n\n case $kindStruct:\n typ = function(v) {\n this.$val = v;\n };\n typ.wrapped = true;\n typ.ptr = $newType(4, $kindPtr, \"*\" + string, false, pkg, exported, constructor);\n typ.ptr.elem = typ;\n typ.ptr.prototype.$get = function() {\n return this;\n };\n typ.ptr.prototype.$set = function(v) {\n typ.copy(this, v);\n };\n typ.init = function(pkgPath, fields) {\n typ.pkgPath = pkgPath;\n typ.fields = fields;\n fields.forEach(function(f) {\n if (!f.typ.comparable) {\n typ.comparable = false;\n }\n });\n typ.keyFor = function(x) {\n var val = x.$val;\n return $mapArray(fields, function(f) {\n return String(f.typ.keyFor(val[f.prop]))\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\$/g, \"\\\\$\");\n }).join(\"$\");\n };\n typ.copy = function(dst, src) {\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n switch (f.typ.kind) {\n case $kindArray:\n case $kindStruct:\n f.typ.copy(dst[f.prop], src[f.prop]);\n continue;\n default:\n dst[f.prop] = src[f.prop];\n continue;\n }\n }\n };\n /* nil value */\n var properties = {};\n fields.forEach(function(f) {\n properties[f.prop] = { get: $throwNilPointerError, set: $throwNilPointerError };\n });\n typ.ptr.nil = Object.create(constructor.prototype, properties);\n typ.ptr.nil.$val = typ.ptr.nil;\n /* methods for embedded fields */\n $addMethodSynthesizer(function() {\n var synthesizeMethod = function(target, m, f) {\n if (target.prototype[m.prop] !== undefined) {\n return;\n }\n target.prototype[m.prop] = function() {\n var v = this.$val[f.prop];\n if (f.typ === $jsObjectPtr) {\n v = new $jsObjectPtr(v);\n }\n if (v.$val === undefined) {\n v = new f.typ(v);\n }\n return v[m.prop].apply(v, arguments);\n };\n };\n fields.forEach(function(f) {\n if (f.anonymous) {\n $methodSet(f.typ).forEach(function(m) {\n synthesizeMethod(typ, m, f);\n synthesizeMethod(typ.ptr, m, f);\n });\n $methodSet($ptrType(f.typ)).forEach(function(m) {\n synthesizeMethod(typ.ptr, m, f);\n });\n }\n });\n });\n };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n switch (kind) {\n case $kindBool:\n case $kindMap:\n typ.zero = function() {\n return false;\n };\n break;\n\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindUnsafePointer:\n case $kindFloat32:\n case $kindFloat64:\n typ.zero = function() {\n return 0;\n };\n break;\n\n case $kindString:\n typ.zero = function() {\n return \"\";\n };\n break;\n\n case $kindInt64:\n case $kindUint64:\n case $kindComplex64:\n case $kindComplex128:\n var zero = new typ(0, 0);\n typ.zero = function() {\n return zero;\n };\n break;\n\n case $kindPtr:\n case $kindSlice:\n typ.zero = function() {\n return typ.nil;\n };\n break;\n\n case $kindChan:\n typ.zero = function() {\n return $chanNil;\n };\n break;\n\n case $kindFunc:\n typ.zero = function() {\n return $throwNilPointerError;\n };\n break;\n\n case $kindInterface:\n typ.zero = function() {\n return $ifaceNil;\n };\n break;\n\n case $kindArray:\n typ.zero = function() {\n var arrayClass = $nativeArray(typ.elem.kind);\n if (arrayClass !== Array) {\n return new arrayClass(typ.len);\n }\n var array = new Array(typ.len);\n for (var i = 0; i < typ.len; i++) {\n array[i] = typ.elem.zero();\n }\n return array;\n };\n break;\n\n case $kindStruct:\n typ.zero = function() {\n return new typ.ptr();\n };\n break;\n\n default:\n $panic(new $String(\"invalid kind: \" + kind));\n }\n\n typ.id = $typeIDCounter;\n $typeIDCounter++;\n typ.size = size;\n typ.kind = kind;\n typ.string = string;\n typ.named = named;\n typ.pkg = pkg;\n typ.exported = exported;\n typ.methods = [];\n typ.methodSetCache = null;\n typ.comparable = true;\n return typ;\n};\n\nvar $methodSet = function(typ) {\n if (typ.methodSetCache !== null) {\n return typ.methodSetCache;\n }\n var base = {};\n\n var isPtr = typ.kind === $kindPtr;\n if (isPtr && typ.elem.kind === $kindInterface) {\n typ.methodSetCache = [];\n return [];\n }\n\n var current = [{ typ: isPtr ? typ.elem : typ, indirect: isPtr }];\n\n var seen = {};\n\n while (current.length > 0) {\n var next = [];\n var mset = [];\n\n current.forEach(function(e) {\n if (seen[e.typ.string]) {\n return;\n }\n seen[e.typ.string] = true;\n\n if (e.typ.named) {\n mset = mset.concat(e.typ.methods);\n if (e.indirect) {\n mset = mset.concat($ptrType(e.typ).methods);\n }\n }\n\n switch (e.typ.kind) {\n case $kindStruct:\n e.typ.fields.forEach(function(f) {\n if (f.anonymous) {\n var fTyp = f.typ;\n var fIsPtr = fTyp.kind === $kindPtr;\n next.push({ typ: fIsPtr ? fTyp.elem : fTyp, indirect: e.indirect || fIsPtr });\n }\n });\n break;\n\n case $kindInterface:\n mset = mset.concat(e.typ.methods);\n break;\n }\n });\n\n mset.forEach(function(m) {\n if (base[m.name] === undefined) {\n base[m.name] = m;\n }\n });\n\n current = next;\n }\n\n typ.methodSetCache = [];\n Object.keys(base)\n .sort()\n .forEach(function(name) {\n typ.methodSetCache.push(base[name]);\n });\n return typ.methodSetCache;\n};\n\nvar $Bool = $newType(1, $kindBool, \"bool\", true, \"\", false, null);\nvar $Int = $newType(4, $kindInt, \"int\", true, \"\", false, null);\nvar $Int8 = $newType(1, $kindInt8, \"int8\", true, \"\", false, null);\nvar $Int16 = $newType(2, $kindInt16, \"int16\", true, \"\", false, null);\nvar $Int32 = $newType(4, $kindInt32, \"int32\", true, \"\", false, null);\nvar $Int64 = $newType(8, $kindInt64, \"int64\", true, \"\", false, null);\nvar $Uint = $newType(4, $kindUint, \"uint\", true, \"\", false, null);\nvar $Uint8 = $newType(1, $kindUint8, \"uint8\", true, \"\", false, null);\nvar $Uint16 = $newType(2, $kindUint16, \"uint16\", true, \"\", false, null);\nvar $Uint32 = $newType(4, $kindUint32, \"uint32\", true, \"\", false, null);\nvar $Uint64 = $newType(8, $kindUint64, \"uint64\", true, \"\", false, null);\nvar $Uintptr = $newType(4, $kindUintptr, \"uintptr\", true, \"\", false, null);\nvar $Float32 = $newType(4, $kindFloat32, \"float32\", true, \"\", false, null);\nvar $Float64 = $newType(8, $kindFloat64, \"float64\", true, \"\", false, null);\nvar $Complex64 = $newType(8, $kindComplex64, \"complex64\", true, \"\", false, null);\nvar $Complex128 = $newType(16, $kindComplex128, \"complex128\", true, \"\", false, null);\nvar $String = $newType(8, $kindString, \"string\", true, \"\", false, null);\nvar $UnsafePointer = $newType(4, $kindUnsafePointer, \"unsafe.Pointer\", true, \"\", false, null);\n\nvar $nativeArray = function(elemKind) {\n switch (elemKind) {\n case $kindInt:\n return Int32Array;\n case $kindInt8:\n return Int8Array;\n case $kindInt16:\n return Int16Array;\n case $kindInt32:\n return Int32Array;\n case $kindUint:\n return Uint32Array;\n case $kindUint8:\n return Uint8Array;\n case $kindUint16:\n return Uint16Array;\n case $kindUint32:\n return Uint32Array;\n case $kindUintptr:\n return Uint32Array;\n case $kindFloat32:\n return Float32Array;\n case $kindFloat64:\n return Float64Array;\n default:\n return Array;\n }\n};\nvar $toNativeArray = function(elemKind, array) {\n var nativeArray = $nativeArray(elemKind);\n if (nativeArray === Array) {\n return array;\n }\n return new nativeArray(array);\n};\nvar $arrayTypes = {};\nvar $arrayType = function(elem, len) {\n var typeKey = elem.id + \"$\" + len;\n var typ = $arrayTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(12, $kindArray, \"[\" + len + \"]\" + elem.string, false, \"\", false, null);\n $arrayTypes[typeKey] = typ;\n typ.init(elem, len);\n }\n return typ;\n};\n\nvar $chanType = function(elem, sendOnly, recvOnly) {\n var string = (recvOnly ? \"<-\" : \"\") + \"chan\" + (sendOnly ? \"<- \" : \" \") + elem.string;\n var field = sendOnly ? \"SendChan\" : recvOnly ? \"RecvChan\" : \"Chan\";\n var typ = elem[field];\n if (typ === undefined) {\n typ = $newType(4, $kindChan, string, false, \"\", false, null);\n elem[field] = typ;\n typ.init(elem, sendOnly, recvOnly);\n }\n return typ;\n};\nvar $Chan = function(elem, capacity) {\n if (capacity < 0 || capacity > 2147483647) {\n $throwRuntimeError(\"makechan: size out of range\");\n }\n this.$elem = elem;\n this.$capacity = capacity;\n this.$buffer = [];\n this.$sendQueue = [];\n this.$recvQueue = [];\n this.$closed = false;\n};\nvar $chanNil = new $Chan(null, 0);\n$chanNil.$sendQueue = $chanNil.$recvQueue = {\n length: 0,\n push: function() {},\n shift: function() {\n return undefined;\n },\n indexOf: function() {\n return -1;\n },\n};\n\nvar $funcTypes = {};\nvar $funcType = function(params, results, variadic) {\n var typeKey =\n $mapArray(params, function(p) {\n return p.id;\n }).join(\",\") +\n \"$\" +\n $mapArray(results, function(r) {\n return r.id;\n }).join(\",\") +\n \"$\" +\n variadic;\n var typ = $funcTypes[typeKey];\n if (typ === undefined) {\n var paramTypes = $mapArray(params, function(p) {\n return p.string;\n });\n if (variadic) {\n paramTypes[paramTypes.length - 1] = \"...\" + paramTypes[paramTypes.length - 1].substr(2);\n }\n var string = \"func(\" + paramTypes.join(\", \") + \")\";\n if (results.length === 1) {\n string += \" \" + results[0].string;\n } else if (results.length > 1) {\n string +=\n \" (\" +\n $mapArray(results, function(r) {\n return r.string;\n }).join(\", \") +\n \")\";\n }\n typ = $newType(4, $kindFunc, string, false, \"\", false, null);\n $funcTypes[typeKey] = typ;\n typ.init(params, results, variadic);\n }\n return typ;\n};\n\nvar $interfaceTypes = {};\nvar $interfaceType = function(methods) {\n var typeKey = $mapArray(methods, function(m) {\n return m.pkg + \",\" + m.name + \",\" + m.typ.id;\n }).join(\"$\");\n var typ = $interfaceTypes[typeKey];\n if (typ === undefined) {\n var string = \"interface {}\";\n if (methods.length !== 0) {\n string =\n \"interface { \" +\n $mapArray(methods, function(m) {\n return (m.pkg !== \"\" ? m.pkg + \".\" : \"\") + m.name + m.typ.string.substr(4);\n }).join(\"; \") +\n \" }\";\n }\n typ = $newType(8, $kindInterface, string, false, \"\", false, null);\n $interfaceTypes[typeKey] = typ;\n typ.init(methods);\n }\n return typ;\n};\nvar $emptyInterface = $interfaceType([]);\nvar $ifaceNil = {};\nvar $error = $newType(8, $kindInterface, \"error\", true, \"\", false, null);\n$error.init([{ prop: \"Error\", name: \"Error\", pkg: \"\", typ: $funcType([], [$String], false) }]);\n\nvar $mapTypes = {};\nvar $mapType = function(key, elem) {\n var typeKey = key.id + \"$\" + elem.id;\n var typ = $mapTypes[typeKey];\n if (typ === undefined) {\n typ = $newType(4, $kindMap, \"map[\" + key.string + \"]\" + elem.string, false, \"\", false, null);\n $mapTypes[typeKey] = typ;\n typ.init(key, elem);\n }\n return typ;\n};\nvar $makeMap = function(keyForFunc, entries) {\n var m = {};\n for (var i = 0; i < entries.length; i++) {\n var e = entries[i];\n m[keyForFunc(e.k)] = e;\n }\n return m;\n};\n\nvar $ptrType = function(elem) {\n var typ = elem.ptr;\n if (typ === undefined) {\n typ = $newType(4, $kindPtr, \"*\" + elem.string, false, \"\", elem.exported, null);\n elem.ptr = typ;\n typ.init(elem);\n }\n return typ;\n};\n\nvar $newDataPointer = function(data, constructor) {\n if (constructor.elem.kind === $kindStruct) {\n return data;\n }\n return new constructor(\n function() {\n return data;\n },\n function(v) {\n data = v;\n }\n );\n};\n\nvar $indexPtr = function(array, index, constructor) {\n array.$ptr = array.$ptr || {};\n return (\n array.$ptr[index] ||\n (array.$ptr[index] = new constructor(\n function() {\n return array[index];\n },\n function(v) {\n array[index] = v;\n }\n ))\n );\n};\n\nvar $sliceType = function(elem) {\n var typ = elem.slice;\n if (typ === undefined) {\n typ = $newType(12, $kindSlice, \"[]\" + elem.string, false, \"\", false, null);\n elem.slice = typ;\n typ.init(elem);\n }\n return typ;\n};\nvar $makeSlice = function(typ, length, capacity) {\n capacity = capacity || length;\n if (length < 0 || length > 2147483647) {\n $throwRuntimeError(\"makeslice: len out of range\");\n }\n if (capacity < 0 || capacity < length || capacity > 2147483647) {\n $throwRuntimeError(\"makeslice: cap out of range\");\n }\n var array = new typ.nativeArray(capacity);\n if (typ.nativeArray === Array) {\n for (var i = 0; i < capacity; i++) {\n array[i] = typ.elem.zero();\n }\n }\n var slice = new typ(array);\n slice.$length = length;\n return slice;\n};\n\nvar $structTypes = {};\nvar $structType = function(pkgPath, fields) {\n var typeKey = $mapArray(fields, function(f) {\n return f.name + \",\" + f.typ.id + \",\" + f.tag;\n }).join(\"$\");\n var typ = $structTypes[typeKey];\n if (typ === undefined) {\n var string =\n \"struct { \" +\n $mapArray(fields, function(f) {\n return f.name + \" \" + f.typ.string + (f.tag !== \"\" ? ' \"' + f.tag.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"') + '\"' : \"\");\n }).join(\"; \") +\n \" }\";\n if (fields.length === 0) {\n string = \"struct {}\";\n }\n typ = $newType(0, $kindStruct, string, false, \"\", false, function() {\n this.$val = this;\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n var arg = arguments[i];\n this[f.prop] = arg !== undefined ? arg : f.typ.zero();\n }\n });\n $structTypes[typeKey] = typ;\n typ.init(pkgPath, fields);\n }\n return typ;\n};\n\nvar $assertType = function(value, type, returnTuple) {\n var isInterface = type.kind === $kindInterface,\n ok,\n missingMethod = \"\";\n if (value === $ifaceNil) {\n ok = false;\n } else if (!isInterface) {\n ok = value.constructor === type;\n } else {\n var valueTypeString = value.constructor.string;\n ok = type.implementedBy[valueTypeString];\n if (ok === undefined) {\n ok = true;\n var valueMethodSet = $methodSet(value.constructor);\n var interfaceMethods = type.methods;\n for (var i = 0; i < interfaceMethods.length; i++) {\n var tm = interfaceMethods[i];\n var found = false;\n for (var j = 0; j < valueMethodSet.length; j++) {\n var vm = valueMethodSet[j];\n if (vm.name === tm.name && vm.pkg === tm.pkg && vm.typ === tm.typ) {\n found = true;\n break;\n }\n }\n if (!found) {\n ok = false;\n type.missingMethodFor[valueTypeString] = tm.name;\n break;\n }\n }\n type.implementedBy[valueTypeString] = ok;\n }\n if (!ok) {\n missingMethod = type.missingMethodFor[valueTypeString];\n }\n }\n\n if (!ok) {\n if (returnTuple) {\n return [type.zero(), false];\n }\n $panic(new $packages[\"runtime\"].TypeAssertionError.ptr(\"\", value === $ifaceNil ? \"\" : value.constructor.string, type.string, missingMethod));\n }\n\n if (!isInterface) {\n value = value.$val;\n }\n if (type === $jsObjectPtr) {\n value = value.object;\n }\n return returnTuple ? [value, true] : value;\n};\nvar $stackDepthOffset = 0;\nvar $getStackDepth = function() {\n var err = new Error();\n if (err.stack === undefined) {\n return undefined;\n }\n return $stackDepthOffset + err.stack.split(\"\\n\").length;\n};\n\nvar $panicStackDepth = null,\n $panicValue;\nvar $callDeferred = function(deferred, jsErr, fromPanic) {\n if (!fromPanic && deferred !== null && deferred.index >= $curGoroutine.deferStack.length) {\n throw jsErr;\n }\n if (jsErr !== null) {\n var newErr = null;\n try {\n $curGoroutine.deferStack.push(deferred);\n $panic(new $jsErrorPtr(jsErr));\n } catch (err) {\n newErr = err;\n }\n $curGoroutine.deferStack.pop();\n $callDeferred(deferred, newErr);\n return;\n }\n if ($curGoroutine.asleep) {\n return;\n }\n\n $stackDepthOffset--;\n var outerPanicStackDepth = $panicStackDepth;\n var outerPanicValue = $panicValue;\n\n var localPanicValue = $curGoroutine.panicStack.pop();\n if (localPanicValue !== undefined) {\n $panicStackDepth = $getStackDepth();\n $panicValue = localPanicValue;\n }\n\n try {\n while (true) {\n if (deferred === null) {\n deferred = $curGoroutine.deferStack[$curGoroutine.deferStack.length - 1];\n if (deferred === undefined) {\n /* The panic reached the top of the stack. Clear it and throw it as a JavaScript error. */\n $panicStackDepth = null;\n if (localPanicValue.Object instanceof Error) {\n throw localPanicValue.Object;\n }\n var msg;\n if (localPanicValue.constructor === $String) {\n msg = localPanicValue.$val;\n } else if (localPanicValue.Error !== undefined) {\n msg = localPanicValue.Error();\n } else if (localPanicValue.String !== undefined) {\n msg = localPanicValue.String();\n } else {\n msg = localPanicValue;\n }\n throw new Error(msg);\n }\n }\n var call = deferred.pop();\n if (call === undefined) {\n $curGoroutine.deferStack.pop();\n if (localPanicValue !== undefined) {\n deferred = null;\n continue;\n }\n return;\n }\n var r = call[0].apply(call[2], call[1]);\n if (r && r.$blk !== undefined) {\n deferred.push([r.$blk, [], r]);\n if (fromPanic) {\n throw null;\n }\n return;\n }\n\n if (localPanicValue !== undefined && $panicStackDepth === null) {\n throw null; /* error was recovered */\n }\n }\n } finally {\n if (localPanicValue !== undefined) {\n if ($panicStackDepth !== null) {\n $curGoroutine.panicStack.push(localPanicValue);\n }\n $panicStackDepth = outerPanicStackDepth;\n $panicValue = outerPanicValue;\n }\n $stackDepthOffset++;\n }\n};\n\nvar $panic = function(value) {\n $curGoroutine.panicStack.push(value);\n $callDeferred(null, null, true);\n};\nvar $recover = function() {\n if ($panicStackDepth === null || ($panicStackDepth !== undefined && $panicStackDepth !== $getStackDepth() - 2)) {\n return $ifaceNil;\n }\n $panicStackDepth = null;\n return $panicValue;\n};\nvar $throw = function(err) {\n throw err;\n};\n\nvar $noGoroutine = {\n asleep: false,\n exit: false,\n deferStack: [],\n panicStack: [],\n};\nvar $curGoroutine = $noGoroutine,\n $totalGoroutines = 0,\n $awakeGoroutines = 0,\n $checkForDeadlock = true;\nvar $mainFinished = false;\nvar $go = function(fun, args) {\n $totalGoroutines++;\n $awakeGoroutines++;\n var $goroutine = function() {\n try {\n $curGoroutine = $goroutine;\n var r = fun.apply(undefined, args);\n if (r && r.$blk !== undefined) {\n fun = function() {\n return r.$blk();\n };\n args = [];\n return;\n }\n $goroutine.exit = true;\n } catch (err) {\n if (!$goroutine.exit) {\n throw err;\n }\n } finally {\n $curGoroutine = $noGoroutine;\n if ($goroutine.exit) {\n /* also set by runtime.Goexit() */\n $totalGoroutines--;\n $goroutine.asleep = true;\n }\n if ($goroutine.asleep) {\n $awakeGoroutines--;\n if (!$mainFinished && $awakeGoroutines === 0 && $checkForDeadlock) {\n console.error(\"fatal error: all goroutines are asleep - deadlock!\");\n if ($global.process !== undefined) {\n $global.process.exit(2);\n }\n }\n }\n }\n };\n $goroutine.asleep = false;\n $goroutine.exit = false;\n $goroutine.deferStack = [];\n $goroutine.panicStack = [];\n $schedule($goroutine);\n};\n\nvar $scheduled = [];\nvar $runScheduled = function() {\n try {\n var r;\n while ((r = $scheduled.shift()) !== undefined) {\n r();\n }\n } finally {\n if ($scheduled.length > 0) {\n setTimeout($runScheduled, 0);\n }\n }\n};\n\nvar $schedule = function(goroutine) {\n if (goroutine.asleep) {\n goroutine.asleep = false;\n $awakeGoroutines++;\n }\n $scheduled.push(goroutine);\n if ($curGoroutine === $noGoroutine) {\n $runScheduled();\n }\n};\n\nvar $setTimeout = function(f, t) {\n $awakeGoroutines++;\n return setTimeout(function() {\n $awakeGoroutines--;\n f();\n }, t);\n};\n\nvar $block = function() {\n if ($curGoroutine === $noGoroutine) {\n $throwRuntimeError(\"cannot block in JavaScript callback, fix by wrapping code in goroutine\");\n }\n $curGoroutine.asleep = true;\n};\n\nvar $send = function(chan, value) {\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv !== undefined) {\n queuedRecv([value, true]);\n return;\n }\n if (chan.$buffer.length < chan.$capacity) {\n chan.$buffer.push(value);\n return;\n }\n\n var thisGoroutine = $curGoroutine;\n var closedDuringSend;\n chan.$sendQueue.push(function(closed) {\n closedDuringSend = closed;\n $schedule(thisGoroutine);\n return value;\n });\n $block();\n return {\n $blk: function() {\n if (closedDuringSend) {\n $throwRuntimeError(\"send on closed channel\");\n }\n },\n };\n};\nvar $recv = function(chan) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend !== undefined) {\n chan.$buffer.push(queuedSend(false));\n }\n var bufferedValue = chan.$buffer.shift();\n if (bufferedValue !== undefined) {\n return [bufferedValue, true];\n }\n if (chan.$closed) {\n return [chan.$elem.zero(), false];\n }\n\n var thisGoroutine = $curGoroutine;\n var f = {\n $blk: function() {\n return this.value;\n },\n };\n var queueEntry = function(v) {\n f.value = v;\n $schedule(thisGoroutine);\n };\n chan.$recvQueue.push(queueEntry);\n $block();\n return f;\n};\nvar $close = function(chan) {\n if (chan.$closed) {\n $throwRuntimeError(\"close of closed channel\");\n }\n chan.$closed = true;\n while (true) {\n var queuedSend = chan.$sendQueue.shift();\n if (queuedSend === undefined) {\n break;\n }\n queuedSend(true); /* will panic */\n }\n while (true) {\n var queuedRecv = chan.$recvQueue.shift();\n if (queuedRecv === undefined) {\n break;\n }\n queuedRecv([chan.$elem.zero(), false]);\n }\n};\nvar $select = function(comms) {\n var ready = [];\n var selection = -1;\n for (var i = 0; i < comms.length; i++) {\n var comm = comms[i];\n var chan = comm[0];\n switch (comm.length) {\n case 0 /* default */:\n selection = i;\n break;\n case 1 /* recv */:\n if (chan.$sendQueue.length !== 0 || chan.$buffer.length !== 0 || chan.$closed) {\n ready.push(i);\n }\n break;\n case 2 /* send */:\n if (chan.$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n if (chan.$recvQueue.length !== 0 || chan.$buffer.length < chan.$capacity) {\n ready.push(i);\n }\n break;\n }\n }\n\n if (ready.length !== 0) {\n selection = ready[Math.floor(Math.random() * ready.length)];\n }\n if (selection !== -1) {\n var comm = comms[selection];\n switch (comm.length) {\n case 0 /* default */:\n return [selection];\n case 1 /* recv */:\n return [selection, $recv(comm[0])];\n case 2 /* send */:\n $send(comm[0], comm[1]);\n return [selection];\n }\n }\n\n var entries = [];\n var thisGoroutine = $curGoroutine;\n var f = {\n $blk: function() {\n return this.selection;\n },\n };\n var removeFromQueues = function() {\n for (var i = 0; i < entries.length; i++) {\n var entry = entries[i];\n var queue = entry[0];\n var index = queue.indexOf(entry[1]);\n if (index !== -1) {\n queue.splice(index, 1);\n }\n }\n };\n for (var i = 0; i < comms.length; i++) {\n (function(i) {\n var comm = comms[i];\n switch (comm.length) {\n case 1 /* recv */:\n var queueEntry = function(value) {\n f.selection = [i, value];\n removeFromQueues();\n $schedule(thisGoroutine);\n };\n entries.push([comm[0].$recvQueue, queueEntry]);\n comm[0].$recvQueue.push(queueEntry);\n break;\n case 2 /* send */:\n var queueEntry = function() {\n if (comm[0].$closed) {\n $throwRuntimeError(\"send on closed channel\");\n }\n f.selection = [i];\n removeFromQueues();\n $schedule(thisGoroutine);\n return comm[1];\n };\n entries.push([comm[0].$sendQueue, queueEntry]);\n comm[0].$sendQueue.push(queueEntry);\n break;\n }\n })(i);\n }\n $block();\n return f;\n};\nvar $jsObjectPtr, $jsErrorPtr;\n\nvar $needsExternalization = function(t) {\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return false;\n default:\n return t !== $jsObjectPtr;\n }\n};\n\nvar $externalize = function(v, t, makeWrapper) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindBool:\n case $kindInt:\n case $kindInt8:\n case $kindInt16:\n case $kindInt32:\n case $kindUint:\n case $kindUint8:\n case $kindUint16:\n case $kindUint32:\n case $kindUintptr:\n case $kindFloat32:\n case $kindFloat64:\n return v;\n case $kindInt64:\n case $kindUint64:\n return $flatten64(v);\n case $kindArray:\n if ($needsExternalization(t.elem)) {\n return $mapArray(v, function(e) {\n return $externalize(e, t.elem, makeWrapper);\n });\n }\n return v;\n case $kindFunc:\n return $externalizeFunction(v, t, false, makeWrapper);\n case $kindInterface:\n if (v === $ifaceNil) {\n return null;\n }\n if (v.constructor === $jsObjectPtr) {\n return v.$val.object;\n }\n return $externalize(v.$val, v.constructor, makeWrapper);\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var entry = v[keys[i]];\n m[$externalize(entry.k, t.key, makeWrapper)] = $externalize(entry.v, t.elem, makeWrapper);\n }\n return m;\n case $kindPtr:\n if (v === t.nil) {\n return null;\n }\n return $externalize(v.$get(), t.elem, makeWrapper);\n case $kindSlice:\n if ($needsExternalization(t.elem)) {\n return $mapArray($sliceToArray(v), function(e) {\n return $externalize(e, t.elem, makeWrapper);\n });\n }\n return $sliceToArray(v);\n case $kindString:\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\",\n r;\n for (var i = 0; i < v.length; i += r[1]) {\n r = $decodeRune(v, i);\n var c = r[0];\n if (c > 0xffff) {\n var h = Math.floor((c - 0x10000) / 0x400) + 0xd800;\n var l = (c - 0x10000) % 0x400 + 0xdc00;\n s += String.fromCharCode(h, l);\n continue;\n }\n s += String.fromCharCode(c);\n }\n return s;\n case $kindStruct:\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && v.constructor === timePkg.Time.ptr) {\n var milli = $div64(v.UnixNano(), new $Int64(0, 1000000));\n return new Date($flatten64(milli));\n }\n\n var noJsObject = {};\n var searchJsObject = function(v, t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n switch (t.kind) {\n case $kindPtr:\n if (v === t.nil) {\n return noJsObject;\n }\n return searchJsObject(v.$get(), t.elem);\n case $kindStruct:\n var f = t.fields[0];\n return searchJsObject(v[f.prop], f.typ);\n case $kindInterface:\n return searchJsObject(v.$val, v.constructor);\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(v, t);\n if (o !== noJsObject) {\n return o;\n }\n\n if (makeWrapper !== undefined) {\n return makeWrapper(v);\n }\n\n o = {};\n for (var i = 0; i < t.fields.length; i++) {\n var f = t.fields[i];\n if (!f.exported) {\n continue;\n }\n o[f.name] = $externalize(v[f.prop], f.typ, makeWrapper);\n }\n return o;\n }\n $throwRuntimeError(\"cannot externalize \" + t.string);\n};\n\nvar $externalizeFunction = function(v, t, passThis, makeWrapper) {\n if (v === $throwNilPointerError) {\n return null;\n }\n if (v.$externalizeWrapper === undefined) {\n $checkForDeadlock = false;\n v.$externalizeWrapper = function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem,\n varargs = [];\n for (var j = i; j < arguments.length; j++) {\n varargs.push($internalize(arguments[j], vt, makeWrapper));\n }\n args.push(new t.params[i](varargs));\n break;\n }\n args.push($internalize(arguments[i], t.params[i], makeWrapper));\n }\n var result = v.apply(passThis ? this : undefined, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $externalize($copyIfRequired(result, t.results[0]), t.results[0], makeWrapper);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $externalize($copyIfRequired(result[i], t.results[i]), t.results[i], makeWrapper);\n }\n return result;\n }\n };\n }\n return v.$externalizeWrapper;\n};\n\nvar $internalize = function(v, t, recv, makeWrapper) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n if (v && v.__internal_object__ !== undefined) {\n return $assertType(v.__internal_object__, t, false);\n }\n var timePkg = $packages[\"time\"];\n if (timePkg !== undefined && t === timePkg.Time) {\n if (!(v !== null && v !== undefined && v.constructor === Date)) {\n $throwRuntimeError(\"cannot internalize time.Time from \" + typeof v + \", must be Date\");\n }\n return timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000));\n }\n switch (t.kind) {\n case $kindBool:\n return !!v;\n case $kindInt:\n return parseInt(v);\n case $kindInt8:\n return (parseInt(v) << 24) >> 24;\n case $kindInt16:\n return (parseInt(v) << 16) >> 16;\n case $kindInt32:\n return parseInt(v) >> 0;\n case $kindUint:\n return parseInt(v);\n case $kindUint8:\n return (parseInt(v) << 24) >>> 24;\n case $kindUint16:\n return (parseInt(v) << 16) >>> 16;\n case $kindUint32:\n case $kindUintptr:\n return parseInt(v) >>> 0;\n case $kindInt64:\n case $kindUint64:\n return new t(0, v);\n case $kindFloat32:\n case $kindFloat64:\n return parseFloat(v);\n case $kindArray:\n if (v.length !== t.len) {\n $throwRuntimeError(\"got array with wrong size from JavaScript native\");\n }\n return $mapArray(v, function(e) {\n return $internalize(e, t.elem, makeWrapper);\n });\n case $kindFunc:\n return function() {\n var args = [];\n for (var i = 0; i < t.params.length; i++) {\n if (t.variadic && i === t.params.length - 1) {\n var vt = t.params[i].elem,\n varargs = arguments[i];\n for (var j = 0; j < varargs.$length; j++) {\n args.push($externalize(varargs.$array[varargs.$offset + j], vt, makeWrapper));\n }\n break;\n }\n args.push($externalize(arguments[i], t.params[i], makeWrapper));\n }\n var result = v.apply(recv, args);\n switch (t.results.length) {\n case 0:\n return;\n case 1:\n return $internalize(result, t.results[0], makeWrapper);\n default:\n for (var i = 0; i < t.results.length; i++) {\n result[i] = $internalize(result[i], t.results[i], makeWrapper);\n }\n return result;\n }\n };\n case $kindInterface:\n if (t.methods.length !== 0) {\n $throwRuntimeError(\"cannot internalize \" + t.string);\n }\n if (v === null) {\n return $ifaceNil;\n }\n if (v === undefined) {\n return new $jsObjectPtr(undefined);\n }\n switch (v.constructor) {\n case Int8Array:\n return new ($sliceType($Int8))(v);\n case Int16Array:\n return new ($sliceType($Int16))(v);\n case Int32Array:\n return new ($sliceType($Int))(v);\n case Uint8Array:\n return new ($sliceType($Uint8))(v);\n case Uint16Array:\n return new ($sliceType($Uint16))(v);\n case Uint32Array:\n return new ($sliceType($Uint))(v);\n case Float32Array:\n return new ($sliceType($Float32))(v);\n case Float64Array:\n return new ($sliceType($Float64))(v);\n case Array:\n return $internalize(v, $sliceType($emptyInterface), makeWrapper);\n case Boolean:\n return new $Bool(!!v);\n case Date:\n if (timePkg === undefined) {\n /* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */\n return new $jsObjectPtr(v);\n }\n return new timePkg.Time($internalize(v, timePkg.Time, makeWrapper));\n case Function:\n var funcType = $funcType([$sliceType($emptyInterface)], [$jsObjectPtr], true);\n return new funcType($internalize(v, funcType, makeWrapper));\n case Number:\n return new $Float64(parseFloat(v));\n case String:\n return new $String($internalize(v, $String, makeWrapper));\n default:\n if ($global.Node && v instanceof $global.Node) {\n return new $jsObjectPtr(v);\n }\n var mapType = $mapType($String, $emptyInterface);\n return new mapType($internalize(v, mapType, makeWrapper));\n }\n case $kindMap:\n var m = {};\n var keys = $keys(v);\n for (var i = 0; i < keys.length; i++) {\n var k = $internalize(keys[i], t.key, makeWrapper);\n m[t.key.keyFor(k)] = { k: k, v: $internalize(v[keys[i]], t.elem, makeWrapper) };\n }\n return m;\n case $kindPtr:\n if (t.elem.kind === $kindStruct) {\n return $internalize(v, t.elem, makeWrapper);\n }\n case $kindSlice:\n return new t(\n $mapArray(v, function(e) {\n return $internalize(e, t.elem, makeWrapper);\n })\n );\n case $kindString:\n v = String(v);\n if ($isASCII(v)) {\n return v;\n }\n var s = \"\";\n var i = 0;\n while (i < v.length) {\n var h = v.charCodeAt(i);\n if (0xd800 <= h && h <= 0xdbff) {\n var l = v.charCodeAt(i + 1);\n var c = (h - 0xd800) * 0x400 + l - 0xdc00 + 0x10000;\n s += $encodeRune(c);\n i += 2;\n continue;\n }\n s += $encodeRune(h);\n i++;\n }\n return s;\n case $kindStruct:\n var noJsObject = {};\n var searchJsObject = function(t) {\n if (t === $jsObjectPtr) {\n return v;\n }\n if (t === $jsObjectPtr.elem) {\n $throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\");\n }\n switch (t.kind) {\n case $kindPtr:\n return searchJsObject(t.elem);\n case $kindStruct:\n var f = t.fields[0];\n var o = searchJsObject(f.typ);\n if (o !== noJsObject) {\n var n = new t.ptr();\n n[f.prop] = o;\n return n;\n }\n return noJsObject;\n default:\n return noJsObject;\n }\n };\n var o = searchJsObject(t);\n if (o !== noJsObject) {\n return o;\n }\n }\n $throwRuntimeError(\"cannot internalize \" + t.string);\n};\n\n/* $isASCII reports whether string s contains only ASCII characters. */\nvar $isASCII = function(s) {\n for (var i = 0; i < s.length; i++) {\n if (s.charCodeAt(i) >= 128) {\n return false;\n }\n }\n return true;\n};\n\nvar $copyIfRequired = function(v, typ) {\n if (v == undefined) {\n return v;\n }\n // interface values\n if (v.constructor.copy) {\n return new v.constructor($clone(v.$val, v.constructor));\n }\n // array and struct values\n if (typ.copy) {\n var clone = typ.zero();\n typ.copy(clone, v);\n return clone;\n }\n return v;\n};\n" diff --git a/compiler/prelude/prelude_min.go b/compiler/prelude/prelude_min.go index a2f704514..0f4d0a222 100644 --- a/compiler/prelude/prelude_min.go +++ b/compiler/prelude/prelude_min.go @@ -3,4 +3,4 @@ package prelude // Minified is an uglifyjs-minified version of Prelude. -const Minified = "var $global,$module;if(Error.stackTraceLimit=1/0,\"undefined\"!=typeof window?$global=window:\"undefined\"!=typeof self?$global=self:\"undefined\"!=typeof global?($global=global).require=require:$global=this,void 0===$global||void 0===$global.Array)throw new Error(\"no global object found\");\"undefined\"!=typeof module&&($module=module);var $throwRuntimeError,$packages={},$idCounter=0,$keys=function(e){return e?Object.keys(e):[]},$flushConsole=function(){},$throwNilPointerError=function(){$throwRuntimeError(\"invalid memory address or nil pointer dereference\")},$call=function(e,n,r){return e.apply(n,r)},$makeFunc=function(e){return function(){return $externalize(e(this,new($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments,[]))),$emptyInterface)}},$unused=function(e){},$mapArray=function(e,n){for(var r=new e.constructor(e.length),t=0;te.$capacity||t>e.$capacity)&&$throwRuntimeError(\"slice bounds out of range\");var i=new e.constructor(e.$array);return i.$offset=e.$offset+n,i.$length=r-n,i.$capacity=t-n,i},$substring=function(e,n,r){return(n<0||re.length)&&$throwRuntimeError(\"slice bounds out of range\"),e.substring(n,r)},$sliceToArray=function(e){return e.$array.constructor!==Array?e.$array.subarray(e.$offset,e.$offset+e.$length):e.$array.slice(e.$offset,e.$offset+e.$length)},$decodeRune=function(e,n){var r=e.charCodeAt(n);if(r<128)return[r,1];if(r!=r||r<192)return[65533,1];var t=e.charCodeAt(n+1);if(t!=t||t<128||192<=t)return[65533,1];if(r<224)return(a=(31&r)<<6|63&t)<=127?[65533,1]:[a,2];var i=e.charCodeAt(n+2);if(i!=i||i<128||192<=i)return[65533,1];if(r<240)return(a=(15&r)<<12|(63&t)<<6|63&i)<=2047?[65533,1]:55296<=a&&a<=57343?[65533,1]:[a,3];var a,o=e.charCodeAt(n+3);return o!=o||o<128||192<=o?[65533,1]:r<248?(a=(7&r)<<18|(63&t)<<12|(63&i)<<6|63&o)<=65535||11141111114111||55296<=e&&e<=57343)&&(e=65533),e<=127?String.fromCharCode(e):e<=2047?String.fromCharCode(192|e>>6,128|63&e):e<=65535?String.fromCharCode(224|e>>12,128|e>>6&63,128|63&e):String.fromCharCode(240|e>>18,128|e>>12&63,128|e>>6&63,128|63&e)},$stringToBytes=function(e){for(var n=new Uint8Array(e.length),r=0;rt){for(var o=i-1;o>=0;o--)a.copy(e[r+o],n[t+o]);return}for(o=0;ot)for(o=i-1;o>=0;o--)e[r+o]=n[t+o];else for(o=0;o$)if(a=0,$=Math.max(o,e.$capacity<1024?2*e.$capacity:Math.floor(5*e.$capacity/4)),e.$array.constructor===Array){(i=e.$array.slice(e.$offset,e.$offset+e.$length)).length=$;for(var c=e.constructor.elem.zero,u=e.$length;u<$;u++)i[u]=c()}else(i=new e.$array.constructor($)).set(e.$array.subarray(e.$offset,e.$offset+e.$length));$copyArray(i,n,a+e.$length,r,t,e.constructor.elem);var l=new e.constructor(i);return l.$offset=a,l.$length=o,l.$capacity=$,l},$equal=function(e,n,r){if(r===$jsObjectPtr)return e===n;switch(r.kind){case $kindComplex64:case $kindComplex128:return e.$real===n.$real&&e.$imag===n.$imag;case $kindInt64:case $kindUint64:return e.$high===n.$high&&e.$low===n.$low;case $kindArray:if(e.length!==n.length)return!1;for(var t=0;t>>16&65535)*t+r*(n>>>16&65535)<<16>>>0)>>0},$floatKey=function(e){return e!=e?\"NaN$\"+ ++$idCounter:String(e)},$flatten64=function(e){return 4294967296*e.$high+e.$low},$shiftLeft64=function(e,n){return 0===n?e:n<32?new e.constructor(e.$high<>>32-n,e.$low<>>0):n<64?new e.constructor(e.$low<>n,(e.$low>>>n|e.$high<<32-n)>>>0):n<64?new e.constructor(e.$high>>31,e.$high>>n-32>>>0):e.$high<0?new e.constructor(-1,4294967295):new e.constructor(0,0)},$shiftRightUint64=function(e,n){return 0===n?e:n<32?new e.constructor(e.$high>>>n,(e.$low>>>n|e.$high<<32-n)>>>0):n<64?new e.constructor(0,e.$high>>>n-32):new e.constructor(0,0)},$mul64=function(e,n){var r=0,t=0;0!=(1&n.$low)&&(r=e.$high,t=e.$low);for(var i=1;i<32;i++)0!=(n.$low&1<>>32-i,t+=e.$low<>>0);for(i=0;i<32;i++)0!=(n.$high&1<$||a===$&&o>c);)$=($<<1|c>>>31)>>>0,c=c<<1>>>0,s++;for(var f=0;f<=s;f++)u=u<<1|l>>>31,l=l<<1>>>0,(a>$||a===$&&o>=c)&&(a-=$,(o-=c)<0&&(a--,o+=4294967296),4294967296===++l&&(u++,l=0)),c=(c>>>1|$<<31)>>>0,$>>>=1;return r?new e.constructor(a*i,o*i):new e.constructor(u*t,l*t)},$divComplex=function(e,n){var r=e.$real===1/0||e.$real===-1/0||e.$imag===1/0||e.$imag===-1/0,t=n.$real===1/0||n.$real===-1/0||n.$imag===1/0||n.$imag===-1/0,i=!r&&(e.$real!=e.$real||e.$imag!=e.$imag),a=!t&&(n.$real!=n.$real||n.$imag!=n.$imag);if(i||a)return new e.constructor(NaN,NaN);if(r&&!t)return new e.constructor(1/0,1/0);if(!r&&t)return new e.constructor(0,0);if(0===n.$real&&0===n.$imag)return 0===e.$real&&0===e.$imag?new e.constructor(NaN,NaN):new e.constructor(1/0,1/0);if(Math.abs(n.$real)<=Math.abs(n.$imag)){var o=n.$real/n.$imag,$=n.$real*o+n.$imag;return new e.constructor((e.$real*o+e.$imag)/$,(e.$imag*o-e.$real)/$)}o=n.$imag/n.$real,$=n.$imag*o+n.$real;return new e.constructor((e.$imag*o+e.$real)/$,(e.$imag-e.$real*o)/$)},$kindBool=1,$kindInt=2,$kindInt8=3,$kindInt16=4,$kindInt32=5,$kindInt64=6,$kindUint=7,$kindUint8=8,$kindUint16=9,$kindUint32=10,$kindUint64=11,$kindUintptr=12,$kindFloat32=13,$kindFloat64=14,$kindComplex64=15,$kindComplex128=16,$kindArray=17,$kindChan=18,$kindFunc=19,$kindInterface=20,$kindMap=21,$kindPtr=22,$kindSlice=23,$kindString=24,$kindStruct=25,$kindUnsafePointer=26,$methodSynthesizers=[],$addMethodSynthesizer=function(e){null!==$methodSynthesizers?$methodSynthesizers.push(e):e()},$synthesizeMethods=function(){$methodSynthesizers.forEach(function(e){e()}),$methodSynthesizers=null},$ifaceKeyFor=function(e){if(e===$ifaceNil)return\"nil\";var n=e.constructor;return n.string+\"$\"+n.keyFor(e.$val)},$identity=function(e){return e},$typeIDCounter=0,$idKey=function(e){return void 0===e.$id&&($idCounter++,e.$id=$idCounter),String(e.$id)},$newType=function(e,n,r,t,i,a,o){var $;switch(n){case $kindBool:case $kindInt:case $kindInt8:case $kindInt16:case $kindInt32:case $kindUint:case $kindUint8:case $kindUint16:case $kindUint32:case $kindUintptr:case $kindUnsafePointer:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=$identity;break;case $kindString:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=function(e){return\"$\"+e};break;case $kindFloat32:case $kindFloat64:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=function(e){return $floatKey(e)};break;case $kindInt64:($=function(e,n){this.$high=e+Math.floor(Math.ceil(n)/4294967296)>>0,this.$low=n>>>0,this.$val=this}).keyFor=function(e){return e.$high+\"$\"+e.$low};break;case $kindUint64:($=function(e,n){this.$high=e+Math.floor(Math.ceil(n)/4294967296)>>>0,this.$low=n>>>0,this.$val=this}).keyFor=function(e){return e.$high+\"$\"+e.$low};break;case $kindComplex64:($=function(e,n){this.$real=$fround(e),this.$imag=$fround(n),this.$val=this}).keyFor=function(e){return e.$real+\"$\"+e.$imag};break;case $kindComplex128:($=function(e,n){this.$real=e,this.$imag=n,this.$val=this}).keyFor=function(e){return e.$real+\"$\"+e.$imag};break;case $kindArray:($=function(e){this.$val=e}).wrapped=!0,$.ptr=$newType(4,$kindPtr,\"*\"+r,!1,\"\",!1,function(e){this.$get=function(){return e},this.$set=function(e){$.copy(this,e)},this.$val=e}),$.init=function(e,n){$.elem=e,$.len=n,$.comparable=e.comparable,$.keyFor=function(n){return Array.prototype.join.call($mapArray(n,function(n){return String(e.keyFor(n)).replace(/\\\\/g,\"\\\\\\\\\").replace(/\\$/g,\"\\\\$\")}),\"$\")},$.copy=function(n,r){$copyArray(n,r,0,0,r.length,e)},$.ptr.init($),Object.defineProperty($.ptr.nil,\"nilCheck\",{get:$throwNilPointerError})};break;case $kindChan:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=$idKey,$.init=function(e,n,r){$.elem=e,$.sendOnly=n,$.recvOnly=r};break;case $kindFunc:($=function(e){this.$val=e}).wrapped=!0,$.init=function(e,n,r){$.params=e,$.results=n,$.variadic=r,$.comparable=!1};break;case $kindInterface:($={implementedBy:{},missingMethodFor:{}}).keyFor=$ifaceKeyFor,$.init=function(e){$.methods=e,e.forEach(function(e){$ifaceNil[e.prop]=$throwNilPointerError})};break;case $kindMap:($=function(e){this.$val=e}).wrapped=!0,$.init=function(e,n){$.key=e,$.elem=n,$.comparable=!1};break;case $kindPtr:($=o||function(e,n,r){this.$get=e,this.$set=n,this.$target=r,this.$val=this}).keyFor=$idKey,$.init=function(e){$.elem=e,$.wrapped=e.kind===$kindArray,$.nil=new $($throwNilPointerError,$throwNilPointerError)};break;case $kindSlice:($=function(e){e.constructor!==$.nativeArray&&(e=new $.nativeArray(e)),this.$array=e,this.$offset=0,this.$length=e.length,this.$capacity=e.length,this.$val=this}).init=function(e){$.elem=e,$.comparable=!1,$.nativeArray=$nativeArray(e.kind),$.nil=new $([])};break;case $kindStruct:($=function(e){this.$val=e}).wrapped=!0,$.ptr=$newType(4,$kindPtr,\"*\"+r,!1,i,a,o),$.ptr.elem=$,$.ptr.prototype.$get=function(){return this},$.ptr.prototype.$set=function(e){$.copy(this,e)},$.init=function(e,n){$.pkgPath=e,$.fields=n,n.forEach(function(e){e.typ.comparable||($.comparable=!1)}),$.keyFor=function(e){var r=e.$val;return $mapArray(n,function(e){return String(e.typ.keyFor(r[e.prop])).replace(/\\\\/g,\"\\\\\\\\\").replace(/\\$/g,\"\\\\$\")}).join(\"$\")},$.copy=function(e,r){for(var t=0;t0;){var a=[],o=[];t.forEach(function(e){if(!i[e.typ.string])switch(i[e.typ.string]=!0,e.typ.named&&(o=o.concat(e.typ.methods),e.indirect&&(o=o.concat($ptrType(e.typ).methods))),e.typ.kind){case $kindStruct:e.typ.fields.forEach(function(n){if(n.anonymous){var r=n.typ,t=r.kind===$kindPtr;a.push({typ:t?r.elem:r,indirect:e.indirect||t})}});break;case $kindInterface:o=o.concat(e.typ.methods)}}),o.forEach(function(e){void 0===n[e.name]&&(n[e.name]=e)}),t=a}return e.methodSetCache=[],Object.keys(n).sort().forEach(function(r){e.methodSetCache.push(n[r])}),e.methodSetCache},$Bool=$newType(1,$kindBool,\"bool\",!0,\"\",!1,null),$Int=$newType(4,$kindInt,\"int\",!0,\"\",!1,null),$Int8=$newType(1,$kindInt8,\"int8\",!0,\"\",!1,null),$Int16=$newType(2,$kindInt16,\"int16\",!0,\"\",!1,null),$Int32=$newType(4,$kindInt32,\"int32\",!0,\"\",!1,null),$Int64=$newType(8,$kindInt64,\"int64\",!0,\"\",!1,null),$Uint=$newType(4,$kindUint,\"uint\",!0,\"\",!1,null),$Uint8=$newType(1,$kindUint8,\"uint8\",!0,\"\",!1,null),$Uint16=$newType(2,$kindUint16,\"uint16\",!0,\"\",!1,null),$Uint32=$newType(4,$kindUint32,\"uint32\",!0,\"\",!1,null),$Uint64=$newType(8,$kindUint64,\"uint64\",!0,\"\",!1,null),$Uintptr=$newType(4,$kindUintptr,\"uintptr\",!0,\"\",!1,null),$Float32=$newType(4,$kindFloat32,\"float32\",!0,\"\",!1,null),$Float64=$newType(8,$kindFloat64,\"float64\",!0,\"\",!1,null),$Complex64=$newType(8,$kindComplex64,\"complex64\",!0,\"\",!1,null),$Complex128=$newType(16,$kindComplex128,\"complex128\",!0,\"\",!1,null),$String=$newType(8,$kindString,\"string\",!0,\"\",!1,null),$UnsafePointer=$newType(4,$kindUnsafePointer,\"unsafe.Pointer\",!0,\"\",!1,null),$nativeArray=function(e){switch(e){case $kindInt:return Int32Array;case $kindInt8:return Int8Array;case $kindInt16:return Int16Array;case $kindInt32:return Int32Array;case $kindUint:return Uint32Array;case $kindUint8:return Uint8Array;case $kindUint16:return Uint16Array;case $kindUint32:case $kindUintptr:return Uint32Array;case $kindFloat32:return Float32Array;case $kindFloat64:return Float64Array;default:return Array}},$toNativeArray=function(e,n){var r=$nativeArray(e);return r===Array?n:new r(n)},$arrayTypes={},$arrayType=function(e,n){var r=e.id+\"$\"+n,t=$arrayTypes[r];return void 0===t&&(t=$newType(12,$kindArray,\"[\"+n+\"]\"+e.string,!1,\"\",!1,null),$arrayTypes[r]=t,t.init(e,n)),t},$chanType=function(e,n,r){var t=(r?\"<-\":\"\")+\"chan\"+(n?\"<- \":\" \")+e.string,i=n?\"SendChan\":r?\"RecvChan\":\"Chan\",a=e[i];return void 0===a&&(a=$newType(4,$kindChan,t,!1,\"\",!1,null),e[i]=a,a.init(e,n,r)),a},$Chan=function(e,n){(n<0||n>2147483647)&&$throwRuntimeError(\"makechan: size out of range\"),this.$elem=e,this.$capacity=n,this.$buffer=[],this.$sendQueue=[],this.$recvQueue=[],this.$closed=!1},$chanNil=new $Chan(null,0);$chanNil.$sendQueue=$chanNil.$recvQueue={length:0,push:function(){},shift:function(){},indexOf:function(){return-1}};var $funcTypes={},$funcType=function(e,n,r){var t=$mapArray(e,function(e){return e.id}).join(\",\")+\"$\"+$mapArray(n,function(e){return e.id}).join(\",\")+\"$\"+r,i=$funcTypes[t];if(void 0===i){var a=$mapArray(e,function(e){return e.string});r&&(a[a.length-1]=\"...\"+a[a.length-1].substr(2));var o=\"func(\"+a.join(\", \")+\")\";1===n.length?o+=\" \"+n[0].string:n.length>1&&(o+=\" (\"+$mapArray(n,function(e){return e.string}).join(\", \")+\")\"),i=$newType(4,$kindFunc,o,!1,\"\",!1,null),$funcTypes[t]=i,i.init(e,n,r)}return i},$interfaceTypes={},$interfaceType=function(e){var n=$mapArray(e,function(e){return e.pkg+\",\"+e.name+\",\"+e.typ.id}).join(\"$\"),r=$interfaceTypes[n];if(void 0===r){var t=\"interface {}\";0!==e.length&&(t=\"interface { \"+$mapArray(e,function(e){return(\"\"!==e.pkg?e.pkg+\".\":\"\")+e.name+e.typ.string.substr(4)}).join(\"; \")+\" }\"),r=$newType(8,$kindInterface,t,!1,\"\",!1,null),$interfaceTypes[n]=r,r.init(e)}return r},$emptyInterface=$interfaceType([]),$ifaceNil={},$error=$newType(8,$kindInterface,\"error\",!0,\"\",!1,null);$error.init([{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],!1)}]);var $panicValue,$jsObjectPtr,$jsErrorPtr,$mapTypes={},$mapType=function(e,n){var r=e.id+\"$\"+n.id,t=$mapTypes[r];return void 0===t&&(t=$newType(4,$kindMap,\"map[\"+e.string+\"]\"+n.string,!1,\"\",!1,null),$mapTypes[r]=t,t.init(e,n)),t},$makeMap=function(e,n){for(var r={},t=0;t2147483647)&&$throwRuntimeError(\"makeslice: len out of range\"),(r<0||r2147483647)&&$throwRuntimeError(\"makeslice: cap out of range\");var t=new e.nativeArray(r);if(e.nativeArray===Array)for(var i=0;i=$curGoroutine.deferStack.length)throw n;if(null!==n){var t=null;try{$curGoroutine.deferStack.push(e),$panic(new $jsErrorPtr(n))}catch(e){t=e}return $curGoroutine.deferStack.pop(),void $callDeferred(e,t)}if(!$curGoroutine.asleep){$stackDepthOffset--;var i=$panicStackDepth,a=$panicValue,o=$curGoroutine.panicStack.pop();void 0!==o&&($panicStackDepth=$getStackDepth(),$panicValue=o);try{for(;;){if(null===e&&void 0===(e=$curGoroutine.deferStack[$curGoroutine.deferStack.length-1])){if($panicStackDepth=null,o.Object instanceof Error)throw o.Object;var $;throw $=o.constructor===$String?o.$val:void 0!==o.Error?o.Error():void 0!==o.String?o.String():o,new Error($)}var c=e.pop();if(void 0===c){if($curGoroutine.deferStack.pop(),void 0!==o){e=null;continue}return}var u=c[0].apply(c[2],c[1]);if(u&&void 0!==u.$blk){if(e.push([u.$blk,[],u]),r)throw null;return}if(void 0!==o&&null===$panicStackDepth)throw null}}finally{void 0!==o&&(null!==$panicStackDepth&&$curGoroutine.panicStack.push(o),$panicStackDepth=i,$panicValue=a),$stackDepthOffset++}}},$panic=function(e){$curGoroutine.panicStack.push(e),$callDeferred(null,null,!0)},$recover=function(){return null===$panicStackDepth||void 0!==$panicStackDepth&&$panicStackDepth!==$getStackDepth()-2?$ifaceNil:($panicStackDepth=null,$panicValue)},$throw=function(e){throw e},$noGoroutine={asleep:!1,exit:!1,deferStack:[],panicStack:[]},$curGoroutine=$noGoroutine,$totalGoroutines=0,$awakeGoroutines=0,$checkForDeadlock=!0,$mainFinished=!1,$go=function(e,n){$totalGoroutines++,$awakeGoroutines++;var r=function(){try{$curGoroutine=r;var t=e.apply(void 0,n);if(t&&void 0!==t.$blk)return e=function(){return t.$blk()},void(n=[]);r.exit=!0}catch(e){if(!r.exit)throw e}finally{$curGoroutine=$noGoroutine,r.exit&&($totalGoroutines--,r.asleep=!0),r.asleep&&($awakeGoroutines--,!$mainFinished&&0===$awakeGoroutines&&$checkForDeadlock&&(console.error(\"fatal error: all goroutines are asleep - deadlock!\"),void 0!==$global.process&&$global.process.exit(2)))}};r.asleep=!1,r.exit=!1,r.deferStack=[],r.panicStack=[],$schedule(r)},$scheduled=[],$runScheduled=function(){try{for(var e;void 0!==(e=$scheduled.shift());)e()}finally{$scheduled.length>0&&setTimeout($runScheduled,0)}},$schedule=function(e){e.asleep&&(e.asleep=!1,$awakeGoroutines++),$scheduled.push(e),$curGoroutine===$noGoroutine&&$runScheduled()},$setTimeout=function(e,n){return $awakeGoroutines++,setTimeout(function(){$awakeGoroutines--,e()},n)},$block=function(){$curGoroutine===$noGoroutine&&$throwRuntimeError(\"cannot block in JavaScript callback, fix by wrapping code in goroutine\"),$curGoroutine.asleep=!0},$send=function(e,n){e.$closed&&$throwRuntimeError(\"send on closed channel\");var r=e.$recvQueue.shift();if(void 0===r){if(!(e.$buffer.length65535){var l=Math.floor((u-65536)/1024)+55296,s=(u-65536)%1024+56320;c+=String.fromCharCode(l,s)}else c+=String.fromCharCode(u)}return c;case $kindStruct:var f=$packages.time;if(void 0!==f&&e.constructor===f.Time.ptr){var d=$div64(e.UnixNano(),new $Int64(0,1e6));return new Date($flatten64(d))}var p={},h=function(e,n){if(n===$jsObjectPtr)return e;switch(n.kind){case $kindPtr:return e===n.nil?p:h(e.$get(),n.elem);case $kindStruct:var r=n.fields[0];return h(e[r.prop],r.typ);case $kindInterface:return h(e.$val,e.constructor);default:return p}},k=h(e,n);if(k!==p)return k;if(void 0!==r)return r(e);k={};for(a=0;a>24;case $kindInt16:return parseInt(e)<<16>>16;case $kindInt32:return parseInt(e)>>0;case $kindUint:return parseInt(e);case $kindUint8:return parseInt(e)<<24>>>24;case $kindUint16:return parseInt(e)<<16>>>16;case $kindUint32:case $kindUintptr:return parseInt(e)>>>0;case $kindInt64:case $kindUint64:return new n(0,e);case $kindFloat32:case $kindFloat64:return parseFloat(e);case $kindArray:return e.length!==n.len&&$throwRuntimeError(\"got array with wrong size from JavaScript native\"),$mapArray(e,function(e){return $internalize(e,n.elem,t)});case $kindFunc:return function(){for(var i=[],a=0;a=128)return!1;return!0},$copyIfRequired=function(e,n){if(e.constructor.copy)return new e.constructor($clone(e.$val,e.constructor));if(n.copy){var r=n.zero();return n.copy(r,e),r}return e};\n" +const Minified = "var $global,$module;if(Error.stackTraceLimit=1/0,\"undefined\"!=typeof window?$global=window:\"undefined\"!=typeof self?$global=self:\"undefined\"!=typeof global?($global=global).require=require:$global=this,void 0===$global||void 0===$global.Array)throw new Error(\"no global object found\");\"undefined\"!=typeof module&&($module=module);var $throwRuntimeError,$packages={},$idCounter=0,$keys=function(e){return e?Object.keys(e):[]},$flushConsole=function(){},$throwNilPointerError=function(){$throwRuntimeError(\"invalid memory address or nil pointer dereference\")},$call=function(e,n,r){return e.apply(n,r)},$makeFunc=function(e){return function(){return $externalize(e(this,new($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments,[]))),$emptyInterface)}},$unused=function(e){},$mapArray=function(e,n){for(var r=new e.constructor(e.length),t=0;te.$capacity||t>e.$capacity)&&$throwRuntimeError(\"slice bounds out of range\");var i=new e.constructor(e.$array);return i.$offset=e.$offset+n,i.$length=r-n,i.$capacity=t-n,i},$substring=function(e,n,r){return(n<0||re.length)&&$throwRuntimeError(\"slice bounds out of range\"),e.substring(n,r)},$sliceToArray=function(e){return e.$array.constructor!==Array?e.$array.subarray(e.$offset,e.$offset+e.$length):e.$array.slice(e.$offset,e.$offset+e.$length)},$decodeRune=function(e,n){var r=e.charCodeAt(n);if(r<128)return[r,1];if(r!=r||r<192)return[65533,1];var t=e.charCodeAt(n+1);if(t!=t||t<128||192<=t)return[65533,1];if(r<224)return(a=(31&r)<<6|63&t)<=127?[65533,1]:[a,2];var i=e.charCodeAt(n+2);if(i!=i||i<128||192<=i)return[65533,1];if(r<240)return(a=(15&r)<<12|(63&t)<<6|63&i)<=2047?[65533,1]:55296<=a&&a<=57343?[65533,1]:[a,3];var a,o=e.charCodeAt(n+3);return o!=o||o<128||192<=o?[65533,1]:r<248?(a=(7&r)<<18|(63&t)<<12|(63&i)<<6|63&o)<=65535||11141111114111||55296<=e&&e<=57343)&&(e=65533),e<=127?String.fromCharCode(e):e<=2047?String.fromCharCode(192|e>>6,128|63&e):e<=65535?String.fromCharCode(224|e>>12,128|e>>6&63,128|63&e):String.fromCharCode(240|e>>18,128|e>>12&63,128|e>>6&63,128|63&e)},$stringToBytes=function(e){for(var n=new Uint8Array(e.length),r=0;rt){for(var o=i-1;o>=0;o--)a.copy(e[r+o],n[t+o]);return}for(o=0;ot)for(o=i-1;o>=0;o--)e[r+o]=n[t+o];else for(o=0;o$)if(a=0,$=Math.max(o,e.$capacity<1024?2*e.$capacity:Math.floor(5*e.$capacity/4)),e.$array.constructor===Array){(i=e.$array.slice(e.$offset,e.$offset+e.$length)).length=$;for(var c=e.constructor.elem.zero,u=e.$length;u<$;u++)i[u]=c()}else(i=new e.$array.constructor($)).set(e.$array.subarray(e.$offset,e.$offset+e.$length));$copyArray(i,n,a+e.$length,r,t,e.constructor.elem);var l=new e.constructor(i);return l.$offset=a,l.$length=o,l.$capacity=$,l},$equal=function(e,n,r){if(r===$jsObjectPtr)return e===n;switch(r.kind){case $kindComplex64:case $kindComplex128:return e.$real===n.$real&&e.$imag===n.$imag;case $kindInt64:case $kindUint64:return e.$high===n.$high&&e.$low===n.$low;case $kindArray:if(e.length!==n.length)return!1;for(var t=0;t>>16&65535)*t+r*(n>>>16&65535)<<16>>>0)>>0},$floatKey=function(e){return e!=e?\"NaN$\"+ ++$idCounter:String(e)},$flatten64=function(e){return 4294967296*e.$high+e.$low},$shiftLeft64=function(e,n){return 0===n?e:n<32?new e.constructor(e.$high<>>32-n,e.$low<>>0):n<64?new e.constructor(e.$low<>n,(e.$low>>>n|e.$high<<32-n)>>>0):n<64?new e.constructor(e.$high>>31,e.$high>>n-32>>>0):e.$high<0?new e.constructor(-1,4294967295):new e.constructor(0,0)},$shiftRightUint64=function(e,n){return 0===n?e:n<32?new e.constructor(e.$high>>>n,(e.$low>>>n|e.$high<<32-n)>>>0):n<64?new e.constructor(0,e.$high>>>n-32):new e.constructor(0,0)},$mul64=function(e,n){var r=0,t=0;0!=(1&n.$low)&&(r=e.$high,t=e.$low);for(var i=1;i<32;i++)0!=(n.$low&1<>>32-i,t+=e.$low<>>0);for(i=0;i<32;i++)0!=(n.$high&1<$||a===$&&o>c);)$=($<<1|c>>>31)>>>0,c=c<<1>>>0,s++;for(var f=0;f<=s;f++)u=u<<1|l>>>31,l=l<<1>>>0,(a>$||a===$&&o>=c)&&(a-=$,(o-=c)<0&&(a--,o+=4294967296),4294967296===++l&&(u++,l=0)),c=(c>>>1|$<<31)>>>0,$>>>=1;return r?new e.constructor(a*i,o*i):new e.constructor(u*t,l*t)},$divComplex=function(e,n){var r=e.$real===1/0||e.$real===-1/0||e.$imag===1/0||e.$imag===-1/0,t=n.$real===1/0||n.$real===-1/0||n.$imag===1/0||n.$imag===-1/0,i=!r&&(e.$real!=e.$real||e.$imag!=e.$imag),a=!t&&(n.$real!=n.$real||n.$imag!=n.$imag);if(i||a)return new e.constructor(NaN,NaN);if(r&&!t)return new e.constructor(1/0,1/0);if(!r&&t)return new e.constructor(0,0);if(0===n.$real&&0===n.$imag)return 0===e.$real&&0===e.$imag?new e.constructor(NaN,NaN):new e.constructor(1/0,1/0);if(Math.abs(n.$real)<=Math.abs(n.$imag)){var o=n.$real/n.$imag,$=n.$real*o+n.$imag;return new e.constructor((e.$real*o+e.$imag)/$,(e.$imag*o-e.$real)/$)}o=n.$imag/n.$real,$=n.$imag*o+n.$real;return new e.constructor((e.$imag*o+e.$real)/$,(e.$imag-e.$real*o)/$)},$kindBool=1,$kindInt=2,$kindInt8=3,$kindInt16=4,$kindInt32=5,$kindInt64=6,$kindUint=7,$kindUint8=8,$kindUint16=9,$kindUint32=10,$kindUint64=11,$kindUintptr=12,$kindFloat32=13,$kindFloat64=14,$kindComplex64=15,$kindComplex128=16,$kindArray=17,$kindChan=18,$kindFunc=19,$kindInterface=20,$kindMap=21,$kindPtr=22,$kindSlice=23,$kindString=24,$kindStruct=25,$kindUnsafePointer=26,$methodSynthesizers=[],$addMethodSynthesizer=function(e){null!==$methodSynthesizers?$methodSynthesizers.push(e):e()},$synthesizeMethods=function(){$methodSynthesizers.forEach(function(e){e()}),$methodSynthesizers=null},$ifaceKeyFor=function(e){if(e===$ifaceNil)return\"nil\";var n=e.constructor;return n.string+\"$\"+n.keyFor(e.$val)},$identity=function(e){return e},$typeIDCounter=0,$idKey=function(e){return void 0===e.$id&&($idCounter++,e.$id=$idCounter),String(e.$id)},$newType=function(e,n,r,t,i,a,o){var $;switch(n){case $kindBool:case $kindInt:case $kindInt8:case $kindInt16:case $kindInt32:case $kindUint:case $kindUint8:case $kindUint16:case $kindUint32:case $kindUintptr:case $kindUnsafePointer:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=$identity;break;case $kindString:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=function(e){return\"$\"+e};break;case $kindFloat32:case $kindFloat64:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=function(e){return $floatKey(e)};break;case $kindInt64:($=function(e,n){this.$high=e+Math.floor(Math.ceil(n)/4294967296)>>0,this.$low=n>>>0,this.$val=this}).keyFor=function(e){return e.$high+\"$\"+e.$low};break;case $kindUint64:($=function(e,n){this.$high=e+Math.floor(Math.ceil(n)/4294967296)>>>0,this.$low=n>>>0,this.$val=this}).keyFor=function(e){return e.$high+\"$\"+e.$low};break;case $kindComplex64:($=function(e,n){this.$real=$fround(e),this.$imag=$fround(n),this.$val=this}).keyFor=function(e){return e.$real+\"$\"+e.$imag};break;case $kindComplex128:($=function(e,n){this.$real=e,this.$imag=n,this.$val=this}).keyFor=function(e){return e.$real+\"$\"+e.$imag};break;case $kindArray:($=function(e){this.$val=e}).wrapped=!0,$.ptr=$newType(4,$kindPtr,\"*\"+r,!1,\"\",!1,function(e){this.$get=function(){return e},this.$set=function(e){$.copy(this,e)},this.$val=e}),$.init=function(e,n){$.elem=e,$.len=n,$.comparable=e.comparable,$.keyFor=function(n){return Array.prototype.join.call($mapArray(n,function(n){return String(e.keyFor(n)).replace(/\\\\/g,\"\\\\\\\\\").replace(/\\$/g,\"\\\\$\")}),\"$\")},$.copy=function(n,r){$copyArray(n,r,0,0,r.length,e)},$.ptr.init($),Object.defineProperty($.ptr.nil,\"nilCheck\",{get:$throwNilPointerError})};break;case $kindChan:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=$idKey,$.init=function(e,n,r){$.elem=e,$.sendOnly=n,$.recvOnly=r};break;case $kindFunc:($=function(e){this.$val=e}).wrapped=!0,$.init=function(e,n,r){$.params=e,$.results=n,$.variadic=r,$.comparable=!1};break;case $kindInterface:($={implementedBy:{},missingMethodFor:{}}).keyFor=$ifaceKeyFor,$.init=function(e){$.methods=e,e.forEach(function(e){$ifaceNil[e.prop]=$throwNilPointerError})};break;case $kindMap:($=function(e){this.$val=e}).wrapped=!0,$.init=function(e,n){$.key=e,$.elem=n,$.comparable=!1};break;case $kindPtr:($=o||function(e,n,r){this.$get=e,this.$set=n,this.$target=r,this.$val=this}).keyFor=$idKey,$.init=function(e){$.elem=e,$.wrapped=e.kind===$kindArray,$.nil=new $($throwNilPointerError,$throwNilPointerError)};break;case $kindSlice:($=function(e){e.constructor!==$.nativeArray&&(e=new $.nativeArray(e)),this.$array=e,this.$offset=0,this.$length=e.length,this.$capacity=e.length,this.$val=this}).init=function(e){$.elem=e,$.comparable=!1,$.nativeArray=$nativeArray(e.kind),$.nil=new $([])};break;case $kindStruct:($=function(e){this.$val=e}).wrapped=!0,$.ptr=$newType(4,$kindPtr,\"*\"+r,!1,i,a,o),$.ptr.elem=$,$.ptr.prototype.$get=function(){return this},$.ptr.prototype.$set=function(e){$.copy(this,e)},$.init=function(e,n){$.pkgPath=e,$.fields=n,n.forEach(function(e){e.typ.comparable||($.comparable=!1)}),$.keyFor=function(e){var r=e.$val;return $mapArray(n,function(e){return String(e.typ.keyFor(r[e.prop])).replace(/\\\\/g,\"\\\\\\\\\").replace(/\\$/g,\"\\\\$\")}).join(\"$\")},$.copy=function(e,r){for(var t=0;t0;){var a=[],o=[];t.forEach(function(e){if(!i[e.typ.string])switch(i[e.typ.string]=!0,e.typ.named&&(o=o.concat(e.typ.methods),e.indirect&&(o=o.concat($ptrType(e.typ).methods))),e.typ.kind){case $kindStruct:e.typ.fields.forEach(function(n){if(n.anonymous){var r=n.typ,t=r.kind===$kindPtr;a.push({typ:t?r.elem:r,indirect:e.indirect||t})}});break;case $kindInterface:o=o.concat(e.typ.methods)}}),o.forEach(function(e){void 0===n[e.name]&&(n[e.name]=e)}),t=a}return e.methodSetCache=[],Object.keys(n).sort().forEach(function(r){e.methodSetCache.push(n[r])}),e.methodSetCache},$Bool=$newType(1,$kindBool,\"bool\",!0,\"\",!1,null),$Int=$newType(4,$kindInt,\"int\",!0,\"\",!1,null),$Int8=$newType(1,$kindInt8,\"int8\",!0,\"\",!1,null),$Int16=$newType(2,$kindInt16,\"int16\",!0,\"\",!1,null),$Int32=$newType(4,$kindInt32,\"int32\",!0,\"\",!1,null),$Int64=$newType(8,$kindInt64,\"int64\",!0,\"\",!1,null),$Uint=$newType(4,$kindUint,\"uint\",!0,\"\",!1,null),$Uint8=$newType(1,$kindUint8,\"uint8\",!0,\"\",!1,null),$Uint16=$newType(2,$kindUint16,\"uint16\",!0,\"\",!1,null),$Uint32=$newType(4,$kindUint32,\"uint32\",!0,\"\",!1,null),$Uint64=$newType(8,$kindUint64,\"uint64\",!0,\"\",!1,null),$Uintptr=$newType(4,$kindUintptr,\"uintptr\",!0,\"\",!1,null),$Float32=$newType(4,$kindFloat32,\"float32\",!0,\"\",!1,null),$Float64=$newType(8,$kindFloat64,\"float64\",!0,\"\",!1,null),$Complex64=$newType(8,$kindComplex64,\"complex64\",!0,\"\",!1,null),$Complex128=$newType(16,$kindComplex128,\"complex128\",!0,\"\",!1,null),$String=$newType(8,$kindString,\"string\",!0,\"\",!1,null),$UnsafePointer=$newType(4,$kindUnsafePointer,\"unsafe.Pointer\",!0,\"\",!1,null),$nativeArray=function(e){switch(e){case $kindInt:return Int32Array;case $kindInt8:return Int8Array;case $kindInt16:return Int16Array;case $kindInt32:return Int32Array;case $kindUint:return Uint32Array;case $kindUint8:return Uint8Array;case $kindUint16:return Uint16Array;case $kindUint32:case $kindUintptr:return Uint32Array;case $kindFloat32:return Float32Array;case $kindFloat64:return Float64Array;default:return Array}},$toNativeArray=function(e,n){var r=$nativeArray(e);return r===Array?n:new r(n)},$arrayTypes={},$arrayType=function(e,n){var r=e.id+\"$\"+n,t=$arrayTypes[r];return void 0===t&&(t=$newType(12,$kindArray,\"[\"+n+\"]\"+e.string,!1,\"\",!1,null),$arrayTypes[r]=t,t.init(e,n)),t},$chanType=function(e,n,r){var t=(r?\"<-\":\"\")+\"chan\"+(n?\"<- \":\" \")+e.string,i=n?\"SendChan\":r?\"RecvChan\":\"Chan\",a=e[i];return void 0===a&&(a=$newType(4,$kindChan,t,!1,\"\",!1,null),e[i]=a,a.init(e,n,r)),a},$Chan=function(e,n){(n<0||n>2147483647)&&$throwRuntimeError(\"makechan: size out of range\"),this.$elem=e,this.$capacity=n,this.$buffer=[],this.$sendQueue=[],this.$recvQueue=[],this.$closed=!1},$chanNil=new $Chan(null,0);$chanNil.$sendQueue=$chanNil.$recvQueue={length:0,push:function(){},shift:function(){},indexOf:function(){return-1}};var $funcTypes={},$funcType=function(e,n,r){var t=$mapArray(e,function(e){return e.id}).join(\",\")+\"$\"+$mapArray(n,function(e){return e.id}).join(\",\")+\"$\"+r,i=$funcTypes[t];if(void 0===i){var a=$mapArray(e,function(e){return e.string});r&&(a[a.length-1]=\"...\"+a[a.length-1].substr(2));var o=\"func(\"+a.join(\", \")+\")\";1===n.length?o+=\" \"+n[0].string:n.length>1&&(o+=\" (\"+$mapArray(n,function(e){return e.string}).join(\", \")+\")\"),i=$newType(4,$kindFunc,o,!1,\"\",!1,null),$funcTypes[t]=i,i.init(e,n,r)}return i},$interfaceTypes={},$interfaceType=function(e){var n=$mapArray(e,function(e){return e.pkg+\",\"+e.name+\",\"+e.typ.id}).join(\"$\"),r=$interfaceTypes[n];if(void 0===r){var t=\"interface {}\";0!==e.length&&(t=\"interface { \"+$mapArray(e,function(e){return(\"\"!==e.pkg?e.pkg+\".\":\"\")+e.name+e.typ.string.substr(4)}).join(\"; \")+\" }\"),r=$newType(8,$kindInterface,t,!1,\"\",!1,null),$interfaceTypes[n]=r,r.init(e)}return r},$emptyInterface=$interfaceType([]),$ifaceNil={},$error=$newType(8,$kindInterface,\"error\",!0,\"\",!1,null);$error.init([{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],!1)}]);var $panicValue,$jsObjectPtr,$jsErrorPtr,$mapTypes={},$mapType=function(e,n){var r=e.id+\"$\"+n.id,t=$mapTypes[r];return void 0===t&&(t=$newType(4,$kindMap,\"map[\"+e.string+\"]\"+n.string,!1,\"\",!1,null),$mapTypes[r]=t,t.init(e,n)),t},$makeMap=function(e,n){for(var r={},t=0;t2147483647)&&$throwRuntimeError(\"makeslice: len out of range\"),(r<0||r2147483647)&&$throwRuntimeError(\"makeslice: cap out of range\");var t=new e.nativeArray(r);if(e.nativeArray===Array)for(var i=0;i=$curGoroutine.deferStack.length)throw n;if(null!==n){var t=null;try{$curGoroutine.deferStack.push(e),$panic(new $jsErrorPtr(n))}catch(e){t=e}return $curGoroutine.deferStack.pop(),void $callDeferred(e,t)}if(!$curGoroutine.asleep){$stackDepthOffset--;var i=$panicStackDepth,a=$panicValue,o=$curGoroutine.panicStack.pop();void 0!==o&&($panicStackDepth=$getStackDepth(),$panicValue=o);try{for(;;){if(null===e&&void 0===(e=$curGoroutine.deferStack[$curGoroutine.deferStack.length-1])){if($panicStackDepth=null,o.Object instanceof Error)throw o.Object;var $;throw $=o.constructor===$String?o.$val:void 0!==o.Error?o.Error():void 0!==o.String?o.String():o,new Error($)}var c=e.pop();if(void 0===c){if($curGoroutine.deferStack.pop(),void 0!==o){e=null;continue}return}var u=c[0].apply(c[2],c[1]);if(u&&void 0!==u.$blk){if(e.push([u.$blk,[],u]),r)throw null;return}if(void 0!==o&&null===$panicStackDepth)throw null}}finally{void 0!==o&&(null!==$panicStackDepth&&$curGoroutine.panicStack.push(o),$panicStackDepth=i,$panicValue=a),$stackDepthOffset++}}},$panic=function(e){$curGoroutine.panicStack.push(e),$callDeferred(null,null,!0)},$recover=function(){return null===$panicStackDepth||void 0!==$panicStackDepth&&$panicStackDepth!==$getStackDepth()-2?$ifaceNil:($panicStackDepth=null,$panicValue)},$throw=function(e){throw e},$noGoroutine={asleep:!1,exit:!1,deferStack:[],panicStack:[]},$curGoroutine=$noGoroutine,$totalGoroutines=0,$awakeGoroutines=0,$checkForDeadlock=!0,$mainFinished=!1,$go=function(e,n){$totalGoroutines++,$awakeGoroutines++;var r=function(){try{$curGoroutine=r;var t=e.apply(void 0,n);if(t&&void 0!==t.$blk)return e=function(){return t.$blk()},void(n=[]);r.exit=!0}catch(e){if(!r.exit)throw e}finally{$curGoroutine=$noGoroutine,r.exit&&($totalGoroutines--,r.asleep=!0),r.asleep&&($awakeGoroutines--,!$mainFinished&&0===$awakeGoroutines&&$checkForDeadlock&&(console.error(\"fatal error: all goroutines are asleep - deadlock!\"),void 0!==$global.process&&$global.process.exit(2)))}};r.asleep=!1,r.exit=!1,r.deferStack=[],r.panicStack=[],$schedule(r)},$scheduled=[],$runScheduled=function(){try{for(var e;void 0!==(e=$scheduled.shift());)e()}finally{$scheduled.length>0&&setTimeout($runScheduled,0)}},$schedule=function(e){e.asleep&&(e.asleep=!1,$awakeGoroutines++),$scheduled.push(e),$curGoroutine===$noGoroutine&&$runScheduled()},$setTimeout=function(e,n){return $awakeGoroutines++,setTimeout(function(){$awakeGoroutines--,e()},n)},$block=function(){$curGoroutine===$noGoroutine&&$throwRuntimeError(\"cannot block in JavaScript callback, fix by wrapping code in goroutine\"),$curGoroutine.asleep=!0},$send=function(e,n){e.$closed&&$throwRuntimeError(\"send on closed channel\");var r=e.$recvQueue.shift();if(void 0===r){if(!(e.$buffer.length65535){var l=Math.floor((u-65536)/1024)+55296,s=(u-65536)%1024+56320;c+=String.fromCharCode(l,s)}else c+=String.fromCharCode(u)}return c;case $kindStruct:var f=$packages.time;if(void 0!==f&&e.constructor===f.Time.ptr){var d=$div64(e.UnixNano(),new $Int64(0,1e6));return new Date($flatten64(d))}var p={},h=function(e,n){if(n===$jsObjectPtr)return e;switch(n.kind){case $kindPtr:return e===n.nil?p:h(e.$get(),n.elem);case $kindStruct:var r=n.fields[0];return h(e[r.prop],r.typ);case $kindInterface:return h(e.$val,e.constructor);default:return p}},k=h(e,n);if(k!==p)return k;if(void 0!==r)return r(e);k={};for(a=0;a>24;case $kindInt16:return parseInt(e)<<16>>16;case $kindInt32:return parseInt(e)>>0;case $kindUint:return parseInt(e);case $kindUint8:return parseInt(e)<<24>>>24;case $kindUint16:return parseInt(e)<<16>>>16;case $kindUint32:case $kindUintptr:return parseInt(e)>>>0;case $kindInt64:case $kindUint64:return new n(0,e);case $kindFloat32:case $kindFloat64:return parseFloat(e);case $kindArray:return e.length!==n.len&&$throwRuntimeError(\"got array with wrong size from JavaScript native\"),$mapArray(e,function(e){return $internalize(e,n.elem,t)});case $kindFunc:return function(){for(var i=[],a=0;a=128)return!1;return!0},$copyIfRequired=function(e,n){if(void 0==e)return e;if(e.constructor.copy)return new e.constructor($clone(e.$val,e.constructor));if(n.copy){var r=n.zero();return n.copy(r,e),r}return e};\n" diff --git a/tests/js_test.go b/tests/js_test.go index 4f3882f4a..fd2b9454b 100644 --- a/tests/js_test.go +++ b/tests/js_test.go @@ -468,6 +468,11 @@ func (m M) NonPointField() string { return "sensible" } +func (m *M) IncF() { + // no return value + m.f++ +} + func TestMakeWrapper(t *testing.T) { m := &M{f: 42} if !js.Global.Call("eval", `(function(m) { return m.Method({x: 1})["y"] === "z"; })`).Invoke(js.MakeWrapper(m)).Bool() { @@ -478,6 +483,9 @@ func TestMakeWrapper(t *testing.T) { t.Fail() } + if !js.Global.Call("eval", `(function(m) { return m.IncF() === undefined })`).Invoke(js.MakeWrapper(m)).Bool() { + t.Fail() + } } func TestMakeFullWrapperType(t *testing.T) { From 38b413be41873781f31533708fcd6025dff71d46 Mon Sep 17 00:00:00 2001 From: Paul Jolly Date: Sun, 8 Jul 2018 18:00:36 +0100 Subject: [PATCH 10/10] doc: update README with instructions on how to install this fork. (#11) --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 47e2fcf49..935e932f1 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,23 @@ Give GopherJS a try on the [GopherJS Playground](http://gopherjs.github.io/playg Nearly everything, including Goroutines ([compatibility table](https://github.com/gopherjs/gopherjs/blob/master/doc/packages.md)). Performance is quite good in most cases, see [HTML5 game engine benchmark](https://ajhager.github.io/engi/demos/botmark.html). Cgo is not supported. ### Installation and Usage -Get or update GopherJS and dependencies with: + +If you already have `github.com/gopherjs/gopherjs` installed: + +``` +cd $(go list -f "{{.Dir}}" github.com/gopherjs/gopherjs) +git remote add myitcv https://github.com/myitcv/gopherjs +git fetch myitcv +git checkout -f master +git reset --hard myitcv/master +git branch --set-upstream-to=myitcv/master +go get -u github.com/gopherjs/gopherjs +``` + +Or for a fresh install: ``` +git clone https://github.com/myitcv/gopherjs "$(cut -d':' -f1 <<< $GOPATH)/src/github.com/gopherjs/gopherjs" go get -u github.com/gopherjs/gopherjs ```