libgo: Update to weekly.2012-03-27 aka go1 release.

From-SVN: r186030
This commit is contained in:
Ian Lance Taylor 2012-03-30 22:37:03 +00:00
parent 9af958f4cd
commit b5a7c91b3b
17 changed files with 225 additions and 122 deletions

View File

@ -1,4 +1,4 @@
bce220d03774
dc5e410f0b4c
The first line of this file holds the Mercurial revision number of the
last merge done from the master library sources.

View File

@ -60,21 +60,23 @@ FindCipherSuite:
for _, id := range clientHello.cipherSuites {
for _, supported := range config.cipherSuites() {
if id == supported {
suite = nil
var candidate *cipherSuite
for _, s := range cipherSuites {
if s.id == id {
suite = s
candidate = s
break
}
}
if suite == nil {
if candidate == nil {
continue
}
// Don't select a ciphersuite which we can't
// support for this client.
if suite.elliptic && !ellipticOk {
if candidate.elliptic && !ellipticOk {
continue
}
suite = candidate
break FindCipherSuite
}
}

View File

@ -130,6 +130,10 @@ Curve:
}
}
if curveid == 0 {
return nil, errors.New("tls: no supported elliptic curves offered")
}
var x, y *big.Int
var err error
ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand())

View File

@ -171,7 +171,7 @@ func processFiles(filenames []string, allFiles bool) {
func processPackage(fset *token.FileSet, files map[string]*ast.File) {
// make a package (resolve all identifiers)
pkg, err := ast.NewPackage(fset, files, types.GcImporter, types.Universe)
pkg, err := ast.NewPackage(fset, files, types.GcImport, types.Universe)
if err != nil {
report(err)
return

View File

@ -184,7 +184,7 @@ func check(t *testing.T, testname string, testfiles []string) {
eliminate(t, errors, err)
// verify errors returned after resolving identifiers
pkg, err := ast.NewPackage(fset, files, GcImporter, Universe)
pkg, err := ast.NewPackage(fset, files, GcImport, Universe)
eliminate(t, errors, err)
// verify errors returned by the typechecker

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file implements ExportData.
// This file implements FindGcExportData.
package types
@ -11,15 +11,14 @@ import (
"errors"
"fmt"
"io"
"os"
"strconv"
"strings"
)
func readGopackHeader(buf *bufio.Reader) (name string, size int, err error) {
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(buf, hdr)
_, err = io.ReadFull(r, hdr)
if err != nil {
return
}
@ -36,33 +35,14 @@ func readGopackHeader(buf *bufio.Reader) (name string, size int, err error) {
return
}
type dataReader struct {
*bufio.Reader
io.Closer
}
// ExportData returns a readCloser positioned at the beginning of the
// export data section of the given object/archive file, or an error.
// It is the caller's responsibility to close the readCloser.
// FindGcExportData 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.
//
func ExportData(filename string) (rc io.ReadCloser, err error) {
file, err := os.Open(filename)
if err != nil {
return
}
defer func() {
if err != nil {
file.Close()
// Add file name to error.
err = fmt.Errorf("reading export data: %s: %v", filename, err)
}
}()
buf := bufio.NewReader(file)
func FindGcExportData(r *bufio.Reader) (err error) {
// Read first line to make sure this is an object file.
line, err := buf.ReadSlice('\n')
line, err := r.ReadSlice('\n')
if err != nil {
return
}
@ -74,7 +54,7 @@ func ExportData(filename string) (rc io.ReadCloser, err error) {
// First entry should be __.SYMDEF.
// Read and discard.
if name, size, err = readGopackHeader(buf); err != nil {
if name, size, err = readGopackHeader(r); err != nil {
return
}
if name != "__.SYMDEF" {
@ -88,15 +68,14 @@ func ExportData(filename string) (rc io.ReadCloser, err error) {
if n > block {
n = block
}
_, err = io.ReadFull(buf, tmp[:n])
if err != nil {
if _, err = io.ReadFull(r, tmp[:n]); err != nil {
return
}
size -= n
}
// Second entry should be __.PKGDEF.
if name, size, err = readGopackHeader(buf); err != nil {
if name, size, err = readGopackHeader(r); err != nil {
return
}
if name != "__.PKGDEF" {
@ -106,8 +85,7 @@ func ExportData(filename string) (rc io.ReadCloser, err error) {
// Read first line of __.PKGDEF data, so that line
// is once again the first line of the input.
line, err = buf.ReadSlice('\n')
if err != nil {
if line, err = r.ReadSlice('\n'); err != nil {
return
}
}
@ -122,12 +100,10 @@ func ExportData(filename string) (rc io.ReadCloser, err error) {
// Skip over object header to export data.
// Begins after first line with $$.
for line[0] != '$' {
line, err = buf.ReadSlice('\n')
if err != nil {
if line, err = r.ReadSlice('\n'); err != nil {
return
}
}
rc = &dataReader{buf, file}
return
}

View File

@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file implements an ast.Importer for gc generated object files.
// This file implements an ast.Importer for gc-generated object files.
// TODO(gri) Eventually move this into a separate package outside types.
package types
import (
"bufio"
"errors"
"fmt"
"go/ast"
@ -24,41 +25,40 @@ import (
const trace = false // set to true for debugging
var (
pkgExts = [...]string{".a", ".5", ".6", ".8"}
)
var pkgExts = [...]string{".a", ".5", ".6", ".8"}
// findPkg returns the filename and package id for an import path.
// 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).
// If no file was found, an empty filename is returned.
func findPkg(path string) (filename, id string) {
//
func FindPkg(path, srcDir string) (filename, id string) {
if len(path) == 0 {
return
}
id = path
var noext string
switch path[0] {
switch {
default:
// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
bp, _ := build.Import(path, "", build.FindOnly)
bp, _ := build.Import(path, srcDir, build.FindOnly)
if bp.PkgObj == "" {
return
}
noext = bp.PkgObj
if strings.HasSuffix(noext, ".a") {
noext = noext[:len(noext)-2]
noext = noext[:len(noext)-len(".a")]
}
case '.':
case build.IsLocalImport(path):
// "./x" -> "/this/directory/x.ext", "/this/directory/x"
cwd, err := os.Getwd()
if err != nil {
return
}
noext = filepath.Join(cwd, path)
noext = filepath.Join(srcDir, path)
id = noext
case '/':
case filepath.IsAbs(path):
// for completeness only - go/build.Import
// does not support absolute imports
// "/x" -> "/x.ext", "/x"
noext = path
}
@ -75,6 +75,89 @@ func findPkg(path string) (filename, id string) {
return
}
// GcImportData imports a package by reading the gc-generated export data,
// adds the corresponding package object to the imports map indexed by id,
// and returns the object.
//
// The imports map must contains all packages already imported, and no map
// entry with id as the key must be present. The data reader position must
// be the beginning of the export data section. The filename is only used
// in error messages.
//
func GcImportData(imports map[string]*ast.Object, filename, id string, data *bufio.Reader) (pkg *ast.Object, err error) {
if trace {
fmt.Printf("importing %s (%s)\n", id, filename)
}
if imports[id] != nil {
panic(fmt.Sprintf("package %s already imported", id))
}
// support for gcParser error handling
defer func() {
if r := recover(); r != nil {
err = r.(importError) // will re-panic if r is not an importError
}
}()
var p gcParser
p.init(filename, id, data, imports)
pkg = p.parseExport()
return
}
// GcImport imports a gc-generated package given its import path, adds the
// corresponding package object to the imports map, and returns the object.
// Local import paths are interpreted relative to the current working directory.
// The imports map must contains all packages already imported.
// GcImport satisfies the ast.Importer signature.
//
func GcImport(imports map[string]*ast.Object, path string) (pkg *ast.Object, err error) {
if path == "unsafe" {
return Unsafe, nil
}
srcDir, err := os.Getwd()
if err != nil {
return
}
filename, id := FindPkg(path, srcDir)
if filename == "" {
err = errors.New("can't find import: " + id)
return
}
if pkg = imports[id]; pkg != nil {
return // package was imported before
}
// 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)
}
}()
buf := bufio.NewReader(f)
if err = FindGcExportData(buf); err != nil {
return
}
pkg, err = GcImportData(imports, filename, id, buf)
return
}
// ----------------------------------------------------------------------------
// gcParser
// gcParser parses the exports inside a gc compiler-produced
// object/archive file and populates its scope with the results.
type gcParser struct {
@ -109,47 +192,6 @@ func (p *gcParser) next() {
}
}
// GcImporter implements the ast.Importer signature.
func GcImporter(imports map[string]*ast.Object, path string) (pkg *ast.Object, err error) {
if path == "unsafe" {
return Unsafe, nil
}
defer func() {
if r := recover(); r != nil {
err = r.(importError) // will re-panic if r is not an importError
if trace {
panic(err) // force a stack trace
}
}
}()
filename, id := findPkg(path)
if filename == "" {
err = errors.New("can't find import: " + id)
return
}
if pkg = imports[id]; pkg != nil {
return // package was imported before
}
buf, err := ExportData(filename)
if err != nil {
return
}
defer buf.Close()
if trace {
fmt.Printf("importing %s (%s)\n", id, filename)
}
var p gcParser
p.init(filename, id, buf, imports)
pkg = p.parseExport()
return
}
// Declare inserts a named object of the given kind in scope.
func (p *gcParser) declare(scope *ast.Scope, kind ast.ObjKind, name string) *ast.Object {
// the object may have been imported before - if it exists
@ -707,7 +749,6 @@ func (p *gcParser) parseConstDecl() {
p.next()
typ = String.Underlying
default:
println(p.tok)
p.errorf("expected literal got %s", scanner.TokenString(p.tok))
}
if obj.Type == nil {

View File

@ -17,23 +17,23 @@ import (
"time"
)
var gcName, gcPath string // compiler name and path
var gcPath string // Go compiler path
func init() {
// determine compiler
var gc string
switch runtime.GOARCH {
case "386":
gcName = "8g"
gc = "8g"
case "amd64":
gcName = "6g"
gc = "6g"
case "arm":
gcName = "5g"
gc = "5g"
default:
gcName = "unknown-GOARCH-compiler"
gcPath = gcName
gcPath = "unknown-GOARCH-compiler"
return
}
gcPath = filepath.Join(build.ToolDir, gcName)
gcPath = filepath.Join(build.ToolDir, gc)
}
func compile(t *testing.T, dirname, filename string) {
@ -41,7 +41,7 @@ func compile(t *testing.T, dirname, filename string) {
cmd.Dir = dirname
out, err := cmd.CombinedOutput()
if err != nil {
t.Errorf("%s %s failed: %s", gcName, filename, err)
t.Errorf("%s %s failed: %s", gcPath, filename, err)
return
}
t.Logf("%s", string(out))
@ -52,7 +52,7 @@ func compile(t *testing.T, dirname, filename string) {
var imports = make(map[string]*ast.Object)
func testPath(t *testing.T, path string) bool {
_, err := GcImporter(imports, path)
_, err := GcImport(imports, path)
if err != nil {
t.Errorf("testPath(%s): %s", path, err)
return false

View File

@ -210,7 +210,6 @@ func (ctxt *Context) SrcDirs() []string {
// if set, or else the compiled code's GOARCH, GOOS, and GOROOT.
var Default Context = defaultContext()
// This list is also known to ../../../cmd/dist/build.c.
var cgoEnabled = map[string]bool{
"darwin/386": true,
"darwin/amd64": true,
@ -388,7 +387,7 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa
// but check that using it wouldn't find something
// else first.
if ctxt.GOROOT != "" {
if dir := ctxt.joinPath(ctxt.GOROOT, "src", sub); ctxt.isDir(dir) {
if dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg", sub); ctxt.isDir(dir) {
goto Found
}
}

View File

@ -18,7 +18,7 @@
// initialization side effects.
//
// See "The Go image package" for more details:
// http://blog.golang.org/2011/09/go-image-package.html
// http://golang.org/doc/articles/image_package.html
package image
import (

View File

@ -623,6 +623,10 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err e
continue
}
}
} else if err == syscall.ECONNABORTED {
// This means that a socket on the listen queue was closed
// before we Accept()ed it; it's a silly error, so try again.
continue
}
return nil, &OpError{"accept", fd.net, fd.laddr, err}
}

View File

@ -58,7 +58,7 @@ const (
func (m FileMode) String() string {
const str = "dalTLDpSugct"
var buf [20]byte
var buf [32]byte // Mode is uint32.
w := 0
for i, c := range str {
if m&(1<<uint(32-1-i)) != 0 {

View File

@ -814,6 +814,7 @@ type VolumeNameTest struct {
var volumenametests = []VolumeNameTest{
{`c:/foo/bar`, `c:`},
{`c:`, `c:`},
{`2:`, ``},
{``, ``},
{`\\\host`, ``},
{`\\\host\`, ``},
@ -845,3 +846,26 @@ func TestVolumeName(t *testing.T) {
}
}
}
func TestDriveLetterInEvalSymlinks(t *testing.T) {
if runtime.GOOS != "windows" {
return
}
wd, _ := os.Getwd()
if len(wd) < 3 {
t.Errorf("Current directory path %q is too short", wd)
}
lp := strings.ToLower(wd)
up := strings.ToUpper(wd)
flp, err := filepath.EvalSymlinks(lp)
if err != nil {
t.Fatalf("EvalSymlinks(%q) failed: %q", lp, err)
}
fup, err := filepath.EvalSymlinks(up)
if err != nil {
t.Fatalf("EvalSymlinks(%q) failed: %q", up, err)
}
if flp != fup {
t.Errorf("Results of EvalSymlinks do not match: %q and %q", flp, fup)
}
}

View File

@ -35,9 +35,7 @@ func VolumeName(path string) (v string) {
}
// with drive letter
c := path[0]
if path[1] == ':' &&
('0' <= c && c <= '9' || 'a' <= c && c <= 'z' ||
'A' <= c && c <= 'Z') {
if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
return path[:2]
}
// is it UNC

View File

@ -8,7 +8,24 @@ import (
"syscall"
)
func evalSymlinks(path string) (string, error) {
func toShort(path string) (string, error) {
p := syscall.StringToUTF16(path)
b := p // GetShortPathName says we can reuse buffer
n, err := syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
if err != nil {
return "", err
}
if n > uint32(len(b)) {
b = make([]uint16, n)
n, err = syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
if err != nil {
return "", err
}
}
return syscall.UTF16ToString(b), nil
}
func toLong(path string) (string, error) {
p := syscall.StringToUTF16(path)
b := p // GetLongPathName says we can reuse buffer
n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
@ -23,5 +40,24 @@ func evalSymlinks(path string) (string, error) {
}
}
b = b[:n]
return Clean(syscall.UTF16ToString(b)), nil
return syscall.UTF16ToString(b), nil
}
func evalSymlinks(path string) (string, error) {
p, err := toShort(path)
if err != nil {
return "", err
}
p, err = toLong(p)
if err != nil {
return "", err
}
// syscall.GetLongPathName does not change the case of the drive letter,
// but the result of EvalSymlinks must be unique, so we have
// EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`).
// Make drive letter upper case.
if len(p) >= 2 && p[1] == ':' && 'a' <= p[0] && p[0] <= 'z' {
p = string(p[0]+'A'-'a') + p[1:]
}
return Clean(p), nil
}

View File

@ -244,7 +244,7 @@ Functions
During execution functions are found in two function maps: first in the
template, then in the global function map. By default, no functions are defined
in the template but the Funcs methods can be used to add them.
in the template but the Funcs method can be used to add them.
Predefined global functions are named as follows.

View File

@ -448,6 +448,11 @@ runtime_main(void)
// roots.
mstats.enablegc = 1;
// The deadlock detection has false negatives.
// Let scvg start up, to eliminate the false negative
// for the trivial program func main() { select{} }.
runtime_gosched();
main_main();
runtime_exit(0);
for(;;)
@ -795,6 +800,20 @@ top:
}
// Look for deadlock situation.
// There is a race with the scavenger that causes false negatives:
// if the scavenger is just starting, then we have
// scvg != nil && grunning == 0 && gwait == 0
// and we do not detect a deadlock. It is possible that we should
// add that case to the if statement here, but it is too close to Go 1
// to make such a subtle change. Instead, we work around the
// false negative in trivial programs by calling runtime.gosched
// from the main goroutine just before main.main.
// See runtime_main above.
//
// On a related note, it is also possible that the scvg == nil case is
// wrong and should include gwait, but that does not happen in
// standard Go programs, which all start the scavenger.
//
if((scvg == nil && runtime_sched.grunning == 0) ||
(scvg != nil && runtime_sched.grunning == 1 && runtime_sched.gwait == 0 &&
(scvg->status == Grunning || scvg->status == Gsyscall))) {