[dev.garbage] all: merge default into dev.garbage

This picks up the selectdone dangling pointer fix, among others.

LGTM=rlh
R=rlh
CC=golang-codereviews
https://golang.org/cl/153070045
This commit is contained in:
Russ Cox 2014-10-06 14:18:56 -04:00
commit 9ba99011fa
19 changed files with 786 additions and 928 deletions

View File

@ -21,6 +21,7 @@ cmd/go: compile and link all _test.go files during 'go test', even in packages w
asm: make textflag.h available outside of cmd/ld (CL 128050043)
crypto/tls: add support for ALPN (RFC 7301) (CL 108710046)
crypto/tls: support programmatic selection of server certificates (CL 107400043)
fmt: print type *map[T]T as &map[k:v] (CL 154870043)
encoding/gob: remove unsafe (CL 102680045)
misc: deleted editor support; refer to https://code.google.com/p/go-wiki/wiki/IDEsAndTextEditorPlugins instead (CL 105470043)
net/http: add Request.BasicAuth method (CL 76540043)
@ -29,9 +30,10 @@ net/http/httputil: add ReverseProxy.ErrorLog (CL 132750043)
os: implement symlink support for windows (CL 86160044)
reflect: add type.Comparable (CL 144020043)
runtime: implement monotonic clocks on windows (CL 108700045)
runtime: stack size 2K (4K on plan 9 and windows) (CL 145790043)
runtime: memory consumption is reduced by 10-30% (CL 106260045 removes type info from heap, CL 145790043 reduces stack size to 2K (4K on plan 9 and windows))
runtime: MemStats.Mallocs now counts very small allocations missed in Go 1.3. This may break tests using runtime.ReadMemStats or testing.AllocsPerRun by giving a more accurate answer than Go 1.3 did (CL 143150043).
runtime/race: freebsd is supported (CL 107270043)
swig: Due to runtime changes Go 1.4 will require SWIG 3.0.3 (not yet released)
sync/atomic: add Value (CL 136710045)
syscall: Setuid, Setgid are disabled on linux platforms. On linux those syscalls operate on the calling thread, not the whole process. This does not match the semantics of other platforms, nor the expectations of the caller, so the operations have been disabled until issue 1435 is resolved (CL 106170043)
syscall: now frozen (CL 129820043)

View File

@ -29,6 +29,7 @@ static void issue7978c(uint32_t *sync) {
import "C"
import (
"os"
"runtime"
"strings"
"sync/atomic"
@ -81,6 +82,9 @@ func issue7978go() {
}
func test7978(t *testing.T) {
if os.Getenv("GOTRACEBACK") != "2" {
t.Fatalf("GOTRACEBACK must be 2")
}
issue7978sync = 0
go issue7978go()
// test in c code, before callback

View File

@ -1043,6 +1043,7 @@ complex:
}
| LSTRUCT sbody
{
diag(Z, "struct must have tag");
taggen++;
sprint(symb, "_%d_", taggen);
$$ = dotag(lookup(), TSTRUCT, autobn);

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,24 @@
/* A Bison parser, made by GNU Bison 2.7.12-4996. */
/* A Bison parser, made by GNU Bison 2.3. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@ -26,20 +29,10 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef YY_YY_Y_TAB_H_INCLUDED
# define YY_YY_Y_TAB_H_INCLUDED
/* Enabling traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int yydebug;
#endif
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@ -196,12 +189,11 @@ extern int yydebug;
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
/* Line 2053 of yacc.c */
#line 36 "cc.y"
{
Node* node;
Sym* sym;
Type* type;
@ -225,30 +217,14 @@ typedef union YYSTYPE
int32 lval;
double dval;
vlong vval;
/* Line 2053 of yacc.c */
#line 232 "y.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
}
/* Line 1529 of yacc.c. */
#line 223 "y.tab.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval;
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
#else
int yyparse ();
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
int yyparse (void);
#else
int yyparse ();
#endif
#endif /* ! YYPARSE_PARAM */
#endif /* !YY_YY_Y_TAB_H_INCLUDED */

View File

@ -15,6 +15,7 @@ var certFiles = []string{
"/etc/ssl/ca-bundle.pem", // OpenSUSE
"/etc/ssl/cert.pem", // OpenBSD
"/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly
"/etc/pki/tls/cacert.pem", // OpenELEC
}
// Possible directories with certificate files; stop after successfully

View File

@ -13,7 +13,7 @@
The verbs:
General:
%v the value in a default format.
%v the value in a default format
when printing structs, the plus flag (%+v) adds field names
%#v a Go-syntax representation of the value
%T a Go-syntax representation of the type of the value
@ -51,6 +51,21 @@
There is no 'u' flag. Integers are printed unsigned if they have unsigned type.
Similarly, there is no need to specify the size of the operand (int8, int64).
The default format for %v is:
bool: %t
int, int8 etc.: %d
uint, uint8 etc.: %d, %x if printed with %#v
float32, complex64, etc: %g
string: %s
chan: %p
pointer: %p
For compound objects, the elements are printed using these rules, recursively,
laid out like this:
struct: {field0 field1 ...}
array, slice: [elem0 elem1 ...]
maps: map[key1:value1 key2:value2]
pointer to above: &{}, &[], &map[]
Width is specified by an optional decimal number immediately following the verb.
If absent, the width is whatever is necessary to represent the value.
Precision is specified after the (optional) width by a period followed by a

View File

@ -919,7 +919,7 @@ func TestCountMallocs(t *testing.T) {
type flagPrinter struct{}
func (*flagPrinter) Format(f State, c rune) {
func (flagPrinter) Format(f State, c rune) {
s := "%"
for i := 0; i < 128; i++ {
if f.Flag(i) {
@ -965,11 +965,12 @@ func TestFlagParser(t *testing.T) {
}
func TestStructPrinter(t *testing.T) {
var s struct {
type T struct {
a string
b string
c int
}
var s T
s.a = "abc"
s.b = "def"
s.c = 123
@ -979,12 +980,35 @@ func TestStructPrinter(t *testing.T) {
}{
{"%v", "{abc def 123}"},
{"%+v", "{a:abc b:def c:123}"},
{"%#v", `fmt_test.T{a:"abc", b:"def", c:123}`},
}
for _, tt := range tests {
out := Sprintf(tt.fmt, s)
if out != tt.out {
t.Errorf("Sprintf(%q, &s) = %q, want %q", tt.fmt, out, tt.out)
t.Errorf("Sprintf(%q, s) = %#q, want %#q", tt.fmt, out, tt.out)
}
// The same but with a pointer.
out = Sprintf(tt.fmt, &s)
if out != "&"+tt.out {
t.Errorf("Sprintf(%q, &s) = %#q, want %#q", tt.fmt, out, "&"+tt.out)
}
}
}
func TestSlicePrinter(t *testing.T) {
slice := []int{}
s := Sprint(slice)
if s != "[]" {
t.Errorf("empty slice printed as %q not %q", s, "[]")
}
slice = []int{1, 2, 3}
s = Sprint(slice)
if s != "[1 2 3]" {
t.Errorf("slice: got %q expected %q", s, "[1 2 3]")
}
s = Sprint(&slice)
if s != "&[1 2 3]" {
t.Errorf("&slice: got %q expected %q", s, "&[1 2 3]")
}
}
@ -1014,6 +1038,12 @@ func TestMapPrinter(t *testing.T) {
a := []string{"1:one", "2:two", "3:three"}
presentInMap(Sprintf("%v", m1), a, t)
presentInMap(Sprint(m1), a, t)
// Pointer to map prints the same but with initial &.
if !strings.HasPrefix(Sprint(&m1), "&") {
t.Errorf("no initial & for address of map")
}
presentInMap(Sprintf("%v", &m1), a, t)
presentInMap(Sprint(&m1), a, t)
}
func TestEmptyMap(t *testing.T) {
@ -1208,86 +1238,66 @@ func TestNilDoesNotBecomeTyped(t *testing.T) {
}
}
// Formatters did not get delivered flags correctly in all cases. Issue 8835.
type fp struct{}
func (fp) Format(f State, c rune) {
s := "%"
for i := 0; i < 128; i++ {
if f.Flag(i) {
s += string(i)
}
}
if w, ok := f.Width(); ok {
s += Sprintf("%d", w)
}
if p, ok := f.Precision(); ok {
s += Sprintf(".%d", p)
}
s += string(c)
io.WriteString(f, "["+s+"]")
}
var formatterFlagTests = []struct {
in string
val interface{}
out string
}{
// scalar values with the (unused by fmt) 'a' verb.
{"%a", fp{}, "[%a]"},
{"%-a", fp{}, "[%-a]"},
{"%+a", fp{}, "[%+a]"},
{"%#a", fp{}, "[%#a]"},
{"% a", fp{}, "[% a]"},
{"%0a", fp{}, "[%0a]"},
{"%1.2a", fp{}, "[%1.2a]"},
{"%-1.2a", fp{}, "[%-1.2a]"},
{"%+1.2a", fp{}, "[%+1.2a]"},
{"%-+1.2a", fp{}, "[%+-1.2a]"},
{"%-+1.2abc", fp{}, "[%+-1.2a]bc"},
{"%-1.2abc", fp{}, "[%-1.2a]bc"},
{"%a", flagPrinter{}, "[%a]"},
{"%-a", flagPrinter{}, "[%-a]"},
{"%+a", flagPrinter{}, "[%+a]"},
{"%#a", flagPrinter{}, "[%#a]"},
{"% a", flagPrinter{}, "[% a]"},
{"%0a", flagPrinter{}, "[%0a]"},
{"%1.2a", flagPrinter{}, "[%1.2a]"},
{"%-1.2a", flagPrinter{}, "[%-1.2a]"},
{"%+1.2a", flagPrinter{}, "[%+1.2a]"},
{"%-+1.2a", flagPrinter{}, "[%+-1.2a]"},
{"%-+1.2abc", flagPrinter{}, "[%+-1.2a]bc"},
{"%-1.2abc", flagPrinter{}, "[%-1.2a]bc"},
// composite values with the 'a' verb
{"%a", [1]fp{}, "[[%a]]"},
{"%-a", [1]fp{}, "[[%-a]]"},
{"%+a", [1]fp{}, "[[%+a]]"},
{"%#a", [1]fp{}, "[[%#a]]"},
{"% a", [1]fp{}, "[[% a]]"},
{"%0a", [1]fp{}, "[[%0a]]"},
{"%1.2a", [1]fp{}, "[[%1.2a]]"},
{"%-1.2a", [1]fp{}, "[[%-1.2a]]"},
{"%+1.2a", [1]fp{}, "[[%+1.2a]]"},
{"%-+1.2a", [1]fp{}, "[[%+-1.2a]]"},
{"%-+1.2abc", [1]fp{}, "[[%+-1.2a]]bc"},
{"%-1.2abc", [1]fp{}, "[[%-1.2a]]bc"},
{"%a", [1]flagPrinter{}, "[[%a]]"},
{"%-a", [1]flagPrinter{}, "[[%-a]]"},
{"%+a", [1]flagPrinter{}, "[[%+a]]"},
{"%#a", [1]flagPrinter{}, "[[%#a]]"},
{"% a", [1]flagPrinter{}, "[[% a]]"},
{"%0a", [1]flagPrinter{}, "[[%0a]]"},
{"%1.2a", [1]flagPrinter{}, "[[%1.2a]]"},
{"%-1.2a", [1]flagPrinter{}, "[[%-1.2a]]"},
{"%+1.2a", [1]flagPrinter{}, "[[%+1.2a]]"},
{"%-+1.2a", [1]flagPrinter{}, "[[%+-1.2a]]"},
{"%-+1.2abc", [1]flagPrinter{}, "[[%+-1.2a]]bc"},
{"%-1.2abc", [1]flagPrinter{}, "[[%-1.2a]]bc"},
// simple values with the 'v' verb
{"%v", fp{}, "[%v]"},
{"%-v", fp{}, "[%-v]"},
{"%+v", fp{}, "[%+v]"},
{"%#v", fp{}, "[%#v]"},
{"% v", fp{}, "[% v]"},
{"%0v", fp{}, "[%0v]"},
{"%1.2v", fp{}, "[%1.2v]"},
{"%-1.2v", fp{}, "[%-1.2v]"},
{"%+1.2v", fp{}, "[%+1.2v]"},
{"%-+1.2v", fp{}, "[%+-1.2v]"},
{"%-+1.2vbc", fp{}, "[%+-1.2v]bc"},
{"%-1.2vbc", fp{}, "[%-1.2v]bc"},
{"%v", flagPrinter{}, "[%v]"},
{"%-v", flagPrinter{}, "[%-v]"},
{"%+v", flagPrinter{}, "[%+v]"},
{"%#v", flagPrinter{}, "[%#v]"},
{"% v", flagPrinter{}, "[% v]"},
{"%0v", flagPrinter{}, "[%0v]"},
{"%1.2v", flagPrinter{}, "[%1.2v]"},
{"%-1.2v", flagPrinter{}, "[%-1.2v]"},
{"%+1.2v", flagPrinter{}, "[%+1.2v]"},
{"%-+1.2v", flagPrinter{}, "[%+-1.2v]"},
{"%-+1.2vbc", flagPrinter{}, "[%+-1.2v]bc"},
{"%-1.2vbc", flagPrinter{}, "[%-1.2v]bc"},
// composite values with the 'v' verb. Some are still broken.
{"%v", [1]fp{}, "[[%v]]"},
{"%-v", [1]fp{}, "[[%-v]]"},
//{"%+v", [1]fp{}, "[[%+v]]"},
{"%#v", [1]fp{}, "[1]fmt_test.fp{[%#v]}"},
{"% v", [1]fp{}, "[[% v]]"},
{"%0v", [1]fp{}, "[[%0v]]"},
{"%1.2v", [1]fp{}, "[[%1.2v]]"},
{"%-1.2v", [1]fp{}, "[[%-1.2v]]"},
//{"%+1.2v", [1]fp{}, "[[%+1.2v]]"},
//{"%-+1.2v", [1]fp{}, "[[%+-1.2v]]"},
//{"%-+1.2vbc", [1]fp{}, "[[%+-1.2v]]bc"},
{"%-1.2vbc", [1]fp{}, "[[%-1.2v]]bc"},
// composite values with the 'v' verb.
{"%v", [1]flagPrinter{}, "[[%v]]"},
{"%-v", [1]flagPrinter{}, "[[%-v]]"},
{"%+v", [1]flagPrinter{}, "[[%+v]]"},
{"%#v", [1]flagPrinter{}, "[1]fmt_test.flagPrinter{[%#v]}"},
{"% v", [1]flagPrinter{}, "[[% v]]"},
{"%0v", [1]flagPrinter{}, "[[%0v]]"},
{"%1.2v", [1]flagPrinter{}, "[[%1.2v]]"},
{"%-1.2v", [1]flagPrinter{}, "[[%-1.2v]]"},
{"%+1.2v", [1]flagPrinter{}, "[[%+1.2v]]"},
{"%-+1.2v", [1]flagPrinter{}, "[[%+-1.2v]]"},
{"%-+1.2vbc", [1]flagPrinter{}, "[[%+-1.2v]]bc"},
{"%-1.2vbc", [1]flagPrinter{}, "[[%-1.2v]]bc"},
}
func TestFormatterFlags(t *testing.T) {

View File

@ -34,6 +34,25 @@ func init() {
}
}
// flags placed in a separate struct for easy clearing.
type fmtFlags struct {
widPresent bool
precPresent bool
minus bool
plus bool
sharp bool
space bool
unicode bool
uniQuote bool // Use 'x'= prefix for %U if printable.
zero bool
// For the formats %+v %#v, we set the plusV/sharpV flags
// and clear the plus/sharp flags since %+v and %#v are in effect
// different, flagless formats set at the top level.
plusV bool
sharpV bool
}
// A fmt is the raw formatter used by Printf etc.
// It prints into a buffer that must be set up separately.
type fmt struct {
@ -42,36 +61,11 @@ type fmt struct {
// width, precision
wid int
prec int
// flags
widPresent bool
precPresent bool
minus bool
plus bool
sharp bool
space bool
// For the format %#v, we set this flag and
// clear the plus flag, since it is in effect
// a different, flagless format set at the top level.
// TODO: plusV could use this too.
sharpV bool
unicode bool
uniQuote bool // Use 'x'= prefix for %U if printable.
zero bool
fmtFlags
}
func (f *fmt) clearflags() {
f.wid = 0
f.widPresent = false
f.prec = 0
f.precPresent = false
f.minus = false
f.plus = false
f.sharp = false
f.space = false
f.sharpV = false
f.unicode = false
f.uniQuote = false
f.zero = false
f.fmtFlags = fmtFlags{}
}
func (f *fmt) init(buf *buffer) {

View File

@ -128,7 +128,7 @@ var ppFree = sync.Pool{
New: func() interface{} { return new(pp) },
}
// newPrinter allocates a new pp struct or grab a cached one.
// newPrinter allocates a new pp struct or grabs a cached one.
func newPrinter() *pp {
p := ppFree.Get().(*pp)
p.panicking = false
@ -317,11 +317,11 @@ func (p *pp) badVerb(verb rune) {
case p.arg != nil:
p.buf.WriteString(reflect.TypeOf(p.arg).String())
p.add('=')
p.printArg(p.arg, 'v', false, 0)
p.printArg(p.arg, 'v', 0)
case p.value.IsValid():
p.buf.WriteString(p.value.Type().String())
p.add('=')
p.printValue(p.value, 'v', false, 0)
p.printValue(p.value, 'v', 0)
default:
p.buf.Write(nilAngleBytes)
}
@ -549,7 +549,7 @@ func (p *pp) fmtBytes(v []byte, verb rune, typ reflect.Type, depth int) {
p.buf.WriteByte(' ')
}
}
p.printArg(c, 'v', p.fmt.plus, depth+1)
p.printArg(c, 'v', depth+1)
}
if p.fmt.sharpV {
p.buf.WriteByte('}')
@ -641,32 +641,41 @@ func (p *pp) catchPanic(arg interface{}, verb rune) {
p.add(verb)
p.buf.Write(panicBytes)
p.panicking = true
p.printArg(err, 'v', false, 0)
p.printArg(err, 'v', 0)
p.panicking = false
p.buf.WriteByte(')')
}
}
// clearSpecialFlags pushes %#v back into the regular flags and returns their old state.
func (p *pp) clearSpecialFlags() bool {
ret := p.fmt.sharpV
if ret {
func (p *pp) clearSpecialFlags() (plusV, sharpV bool) {
plusV = p.fmt.plusV
if plusV {
p.fmt.plus = true
p.fmt.plusV = false
}
sharpV = p.fmt.sharpV
if sharpV {
p.fmt.sharp = true
p.fmt.sharpV = false
}
return ret
return
}
// restoreSpecialFlags, whose argument should be a call to clearSpecialFlags,
// restores the setting of the sharpV flag.
func (p *pp) restoreSpecialFlags(sharpV bool) {
// restores the setting of the plusV and sharpV flags.
func (p *pp) restoreSpecialFlags(plusV, sharpV bool) {
if plusV {
p.fmt.plus = false
p.fmt.plusV = true
}
if sharpV {
p.fmt.sharp = false
p.fmt.sharpV = true
}
}
func (p *pp) handleMethods(verb rune, plus bool, depth int) (handled bool) {
func (p *pp) handleMethods(verb rune, depth int) (handled bool) {
if p.erroring {
return
}
@ -678,19 +687,14 @@ func (p *pp) handleMethods(verb rune, plus bool, depth int) (handled bool) {
formatter.Format(p, verb)
return
}
// Must not touch flags before Formatter looks at them.
if plus {
p.fmt.plus = false
}
// If we're doing Go syntax and the argument knows how to supply it, take care of it now.
if p.fmt.sharpV {
if stringer, ok := p.arg.(GoStringer); ok {
handled = true
defer p.restoreSpecialFlags(p.clearSpecialFlags())
defer p.catchPanic(p.arg, verb)
// Print the result of GoString unadorned.
p.fmtString(stringer.GoString(), 's')
p.fmt.fmt_s(stringer.GoString())
return
}
} else {
@ -707,13 +711,13 @@ func (p *pp) handleMethods(verb rune, plus bool, depth int) (handled bool) {
case error:
handled = true
defer p.catchPanic(p.arg, verb)
p.printArg(v.Error(), verb, plus, depth)
p.printArg(v.Error(), verb, depth)
return
case Stringer:
handled = true
defer p.catchPanic(p.arg, verb)
p.printArg(v.String(), verb, plus, depth)
p.printArg(v.String(), verb, depth)
return
}
}
@ -721,7 +725,7 @@ func (p *pp) handleMethods(verb rune, plus bool, depth int) (handled bool) {
return false
}
func (p *pp) printArg(arg interface{}, verb rune, plus bool, depth int) (wasString bool) {
func (p *pp) printArg(arg interface{}, verb rune, depth int) (wasString bool) {
p.arg = arg
p.value = reflect.Value{}
@ -738,22 +742,13 @@ func (p *pp) printArg(arg interface{}, verb rune, plus bool, depth int) (wasStri
// %T (the value's type) and %p (its address) are special; we always do them first.
switch verb {
case 'T':
p.printArg(reflect.TypeOf(arg).String(), 's', false, 0)
p.printArg(reflect.TypeOf(arg).String(), 's', 0)
return false
case 'p':
p.fmtPointer(reflect.ValueOf(arg), verb)
return false
}
// Clear flags for base formatters.
// handleMethods needs them, so we must restore them later.
// We could call handleMethods here and avoid this work, but
// handleMethods is expensive enough to be worth delaying.
oldPlus := p.fmt.plus
if plus {
p.fmt.plus = false
}
// Some types can be done without reflection.
switch f := arg.(type) {
case bool:
@ -795,21 +790,19 @@ func (p *pp) printArg(arg interface{}, verb rune, plus bool, depth int) (wasStri
p.fmtBytes(f, verb, nil, depth)
wasString = verb == 's'
default:
// Restore flags in case handleMethods finds a Formatter.
p.fmt.plus = oldPlus
// If the type is not simple, it might have methods.
if handled := p.handleMethods(verb, plus, depth); handled {
if handled := p.handleMethods(verb, depth); handled {
return false
}
// Need to use reflection
return p.printReflectValue(reflect.ValueOf(arg), verb, plus, depth)
return p.printReflectValue(reflect.ValueOf(arg), verb, depth)
}
p.arg = nil
return
}
// printValue is like printArg but starts with a reflect value, not an interface{} value.
func (p *pp) printValue(value reflect.Value, verb rune, plus bool, depth int) (wasString bool) {
func (p *pp) printValue(value reflect.Value, verb rune, depth int) (wasString bool) {
if !value.IsValid() {
if verb == 'T' || verb == 'v' {
p.buf.Write(nilAngleBytes)
@ -823,7 +816,7 @@ func (p *pp) printValue(value reflect.Value, verb rune, plus bool, depth int) (w
// %T (the value's type) and %p (its address) are special; we always do them first.
switch verb {
case 'T':
p.printArg(value.Type().String(), 's', false, 0)
p.printArg(value.Type().String(), 's', 0)
return false
case 'p':
p.fmtPointer(value, verb)
@ -836,18 +829,18 @@ func (p *pp) printValue(value reflect.Value, verb rune, plus bool, depth int) (w
if value.CanInterface() {
p.arg = value.Interface()
}
if handled := p.handleMethods(verb, plus, depth); handled {
if handled := p.handleMethods(verb, depth); handled {
return false
}
return p.printReflectValue(value, verb, plus, depth)
return p.printReflectValue(value, verb, depth)
}
var byteType = reflect.TypeOf(byte(0))
// printReflectValue is the fallback for both printArg and printValue.
// It uses reflect to print the value.
func (p *pp) printReflectValue(value reflect.Value, verb rune, plus bool, depth int) (wasString bool) {
func (p *pp) printReflectValue(value reflect.Value, verb rune, depth int) (wasString bool) {
oldValue := p.value
p.value = value
BigSwitch:
@ -892,9 +885,9 @@ BigSwitch:
p.buf.WriteByte(' ')
}
}
p.printValue(key, verb, plus, depth+1)
p.printValue(key, verb, depth+1)
p.buf.WriteByte(':')
p.printValue(f.MapIndex(key), verb, plus, depth+1)
p.printValue(f.MapIndex(key), verb, depth+1)
}
if p.fmt.sharpV {
p.buf.WriteByte('}')
@ -916,13 +909,13 @@ BigSwitch:
p.buf.WriteByte(' ')
}
}
if plus || p.fmt.sharpV {
if p.fmt.plusV || p.fmt.sharpV {
if f := t.Field(i); f.Name != "" {
p.buf.WriteString(f.Name)
p.buf.WriteByte(':')
}
}
p.printValue(getField(v, i), verb, plus, depth+1)
p.printValue(getField(v, i), verb, depth+1)
}
p.buf.WriteByte('}')
case reflect.Interface:
@ -935,7 +928,7 @@ BigSwitch:
p.buf.Write(nilAngleBytes)
}
} else {
wasString = p.printValue(value, verb, plus, depth+1)
wasString = p.printValue(value, verb, depth+1)
}
case reflect.Array, reflect.Slice:
// Byte slices are special:
@ -980,7 +973,7 @@ BigSwitch:
p.buf.WriteByte(' ')
}
}
p.printValue(f.Index(i), verb, plus, depth+1)
p.printValue(f.Index(i), verb, depth+1)
}
if p.fmt.sharpV {
p.buf.WriteByte('}')
@ -995,11 +988,15 @@ BigSwitch:
switch a := f.Elem(); a.Kind() {
case reflect.Array, reflect.Slice:
p.buf.WriteByte('&')
p.printValue(a, verb, plus, depth+1)
p.printValue(a, verb, depth+1)
break BigSwitch
case reflect.Struct:
p.buf.WriteByte('&')
p.printValue(a, verb, plus, depth+1)
p.printValue(a, verb, depth+1)
break BigSwitch
case reflect.Map:
p.buf.WriteByte('&')
p.printValue(a, verb, depth+1)
break BigSwitch
}
}
@ -1171,13 +1168,19 @@ func (p *pp) doPrintf(format string, a []interface{}) {
arg := a[argNum]
argNum++
if c == 'v' && p.fmt.sharp {
// Go syntax. Set the flag in the fmt and clear the sharp flag.
p.fmt.sharp = false
p.fmt.sharpV = true
if c == 'v' {
if p.fmt.sharp {
// Go syntax. Set the flag in the fmt and clear the sharp flag.
p.fmt.sharp = false
p.fmt.sharpV = true
}
if p.fmt.plus {
// Struct-field syntax. Set the flag in the fmt and clear the plus flag.
p.fmt.plus = false
p.fmt.plusV = true
}
}
plus := c == 'v' && p.fmt.plus
p.printArg(arg, c, plus, 0)
p.printArg(arg, c, 0)
}
// Check for extra arguments unless the call accessed the arguments
@ -1191,7 +1194,7 @@ func (p *pp) doPrintf(format string, a []interface{}) {
p.buf.WriteString(reflect.TypeOf(arg).String())
p.buf.WriteByte('=')
}
p.printArg(arg, 'v', false, 0)
p.printArg(arg, 'v', 0)
if argNum+1 < len(a) {
p.buf.Write(commaSpaceBytes)
}
@ -1212,7 +1215,7 @@ func (p *pp) doPrint(a []interface{}, addspace, addnewline bool) {
p.buf.WriteByte(' ')
}
}
prevString = p.printArg(arg, 'v', false, 0)
prevString = p.printArg(arg, 'v', 0)
}
if addnewline {
p.buf.WriteByte('\n')

View File

@ -274,7 +274,8 @@ struct MStats
bool debuggc;
// Statistics about allocation size classes.
struct {
struct MStatsBySize {
uint32 size;
uint64 nmalloc;
uint64 nfree;
@ -283,6 +284,7 @@ struct MStats
uint64 tinyallocs; // number of tiny allocations that didn't cause actual allocation; not exported to Go directly
};
#define mstats runtime·memstats
extern MStats mstats;
void runtime·updatememstats(GCStats *stats);
@ -493,7 +495,7 @@ struct MHeap
// the padding makes sure that the MCentrals are
// spaced CacheLineSize bytes apart, so that each MCentral.lock
// gets its own cache line.
struct {
struct MHeapCentral {
MCentral mcentral;
byte pad[CacheLineSize];
} central[NumSizeClasses];

View File

@ -63,7 +63,7 @@ typedef struct Tos Tos;
typedef intptr _Plink;
struct Tos {
struct /* Per process profiling */
struct TosProf /* Per process profiling */
{
_Plink *pp; /* known to be 0(ptr) */
_Plink *next; /* known to be 4(ptr) */

View File

@ -2422,7 +2422,7 @@ runtime·mcount(void)
return runtime·sched.mcount;
}
static struct {
static struct ProfState {
uint32 lock;
int32 hz;
} prof;

View File

@ -177,6 +177,9 @@ func releaseSudog(s *sudog) {
if s.elem != nil {
gothrow("runtime: sudog with non-nil elem")
}
if s.selectdone != nil {
gothrow("runtime: sudog with non-nil selectdone")
}
gp := getg()
if gp.param != nil {
gothrow("runtime: releaseSudog with non-nil gp.param")

View File

@ -385,11 +385,11 @@ struct M
// these are here because they are too large to be on the stack
// of low-level NOSPLIT functions.
LibCall libcall;
struct {
struct MTs {
int64 tv_sec;
int64 tv_nsec;
} ts;
struct {
struct MScratch {
uintptr v[6];
} scratch;
#endif

View File

@ -379,6 +379,7 @@ loop:
sglist = gp.waiting
// Clear all elem before unlinking from gp.waiting.
for sg1 := gp.waiting; sg1 != nil; sg1 = sg1.waitlink {
sg1.selectdone = nil
sg1.elem = nil
}
gp.waiting = nil

View File

@ -52,7 +52,7 @@ typedef uint16 Elf64_Section;
typedef Elf64_Half Elf64_Versym;
typedef struct
typedef struct Elf64_Sym
{
Elf64_Word st_name;
byte st_info;
@ -62,7 +62,7 @@ typedef struct
Elf64_Xword st_size;
} Elf64_Sym;
typedef struct
typedef struct Elf64_Verdef
{
Elf64_Half vd_version; /* Version revision */
Elf64_Half vd_flags; /* Version information */
@ -73,7 +73,7 @@ typedef struct
Elf64_Word vd_next; /* Offset in bytes to next verdef entry */
} Elf64_Verdef;
typedef struct
typedef struct Elf64_Ehdr
{
byte e_ident[EI_NIDENT]; /* Magic number and other info */
Elf64_Half e_type; /* Object file type */
@ -91,7 +91,7 @@ typedef struct
Elf64_Half e_shstrndx; /* Section header string table index */
} Elf64_Ehdr;
typedef struct
typedef struct Elf64_Phdr
{
Elf64_Word p_type; /* Segment type */
Elf64_Word p_flags; /* Segment flags */
@ -103,7 +103,7 @@ typedef struct
Elf64_Xword p_align; /* Segment alignment */
} Elf64_Phdr;
typedef struct
typedef struct Elf64_Shdr
{
Elf64_Word sh_name; /* Section name (string tbl index) */
Elf64_Word sh_type; /* Section type */
@ -117,7 +117,7 @@ typedef struct
Elf64_Xword sh_entsize; /* Entry size if section holds table */
} Elf64_Shdr;
typedef struct
typedef struct Elf64_Dyn
{
Elf64_Sxword d_tag; /* Dynamic entry type */
union
@ -127,13 +127,13 @@ typedef struct
} d_un;
} Elf64_Dyn;
typedef struct
typedef struct Elf64_Verdaux
{
Elf64_Word vda_name; /* Version or dependency names */
Elf64_Word vda_next; /* Offset in bytes to next verdaux entry */
} Elf64_Verdaux;
typedef struct
typedef struct Elf64_auxv_t
{
uint64 a_type; /* Entry type */
union
@ -143,13 +143,13 @@ typedef struct
} Elf64_auxv_t;
typedef struct {
typedef struct symbol_key {
byte* name;
int32 sym_hash;
void** var_ptr;
} symbol_key;
typedef struct {
typedef struct version_key {
byte* version;
int32 ver_hash;
} version_key;

View File

@ -138,8 +138,6 @@ func (p *Param) StringTmpVarCode() string {
// TmpVarCode returns source code for temp variable.
func (p *Param) TmpVarCode() string {
switch {
case p.Type == "string":
return p.StringTmpVarCode()
case p.Type == "bool":
return p.BoolTmpVarCode()
case strings.HasPrefix(p.Type, "[]"):
@ -149,19 +147,26 @@ func (p *Param) TmpVarCode() string {
}
}
// TmpVarHelperCode returns source code for helper's temp variable.
func (p *Param) TmpVarHelperCode() string {
if p.Type != "string" {
return ""
}
return p.StringTmpVarCode()
}
// SyscallArgList returns source code fragments representing p parameter
// in syscall. Slices are translated into 2 syscall parameters: pointer to
// the first element and length.
func (p *Param) SyscallArgList() []string {
t := p.HelperType()
var s string
switch {
case p.Type[0] == '*':
case t[0] == '*':
s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name)
case p.Type == "string":
s = fmt.Sprintf("unsafe.Pointer(%s)", p.tmpVar())
case p.Type == "bool":
case t == "bool":
s = p.tmpVar()
case strings.HasPrefix(p.Type, "[]"):
case strings.HasPrefix(t, "[]"):
return []string{
fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.tmpVar()),
fmt.Sprintf("uintptr(len(%s))", p.Name),
@ -177,6 +182,14 @@ func (p *Param) IsError() bool {
return p.Name == "err" && p.Type == "error"
}
// HelperType returns type of parameter p used in helper function.
func (p *Param) HelperType() string {
if p.Type == "string" {
return p.fn.StrconvType()
}
return p.Type
}
// join concatenates parameters ps into a string with sep separator.
// Each parameter is converted into string by applying fn to it
// before conversion.
@ -454,6 +467,11 @@ func (f *Fn) ParamList() string {
return join(f.Params, func(p *Param) string { return p.Name + " " + p.Type }, ", ")
}
// HelperParamList returns source code for helper function f parameters.
func (f *Fn) HelperParamList() string {
return join(f.Params, func(p *Param) string { return p.Name + " " + p.HelperType() }, ", ")
}
// ParamPrintList returns source code of trace printing part correspondent
// to syscall input parameters.
func (f *Fn) ParamPrintList() string {
@ -510,6 +528,19 @@ func (f *Fn) SyscallParamList() string {
return strings.Join(a, ", ")
}
// HelperCallParamList returns source code of call into function f helper.
func (f *Fn) HelperCallParamList() string {
a := make([]string, 0, len(f.Params))
for _, p := range f.Params {
s := p.Name
if p.Type == "string" {
s = p.tmpVar()
}
a = append(a, s)
}
return strings.Join(a, ", ")
}
// IsUTF16 is true, if f is W (utf16) function. It is false
// for all A (ascii) functions.
func (f *Fn) IsUTF16() bool {
@ -533,6 +564,25 @@ func (f *Fn) StrconvType() string {
return "*byte"
}
// HasStringParam is true, if f has at least one string parameter.
// Otherwise it is false.
func (f *Fn) HasStringParam() bool {
for _, p := range f.Params {
if p.Type == "string" {
return true
}
}
return false
}
// HelperName returns name of function f helper.
func (f *Fn) HelperName() string {
if !f.HasStringParam() {
return f.Name
}
return "_" + f.Name
}
// Source files and functions.
type Source struct {
Funcs []*Fn
@ -666,7 +716,7 @@ import "syscall"{{end}}
var (
{{template "dlls" .}}
{{template "funcnames" .}})
{{range .Funcs}}{{template "funcbody" .}}{{end}}
{{range .Funcs}}{{if .HasStringParam}}{{template "helperbody" .}}{{end}}{{template "funcbody" .}}{{end}}
{{end}}
{{/* help functions */}}
@ -677,16 +727,27 @@ var (
{{define "funcnames"}}{{range .Funcs}} proc{{.DLLFuncName}} = mod{{.DLLName}}.NewProc("{{.DLLFuncName}}")
{{end}}{{end}}
{{define "helperbody"}}
func {{.Name}}({{.ParamList}}) {{template "results" .}}{
{{template "helpertmpvars" .}} return {{.HelperName}}({{.HelperCallParamList}})
}
{{end}}
{{define "funcbody"}}
func {{.Name}}({{.ParamList}}) {{if .Rets.List}}{{.Rets.List}} {{end}}{
func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{
{{template "tmpvars" .}} {{template "syscall" .}}
{{template "seterror" .}}{{template "printtrace" .}} return
}
{{end}}
{{define "helpertmpvars"}}{{range .Params}}{{if .TmpVarHelperCode}} {{.TmpVarHelperCode}}
{{end}}{{end}}{{end}}
{{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}}
{{end}}{{end}}{{end}}
{{define "results"}}{{if .Rets.List}}{{.Rets.List}} {{end}}{{end}}
{{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}}
{{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}}

View File

@ -176,7 +176,11 @@ func LoadLibrary(libname string) (handle Handle, err error) {
if err != nil {
return
}
r0, _, e1 := Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0)
return _LoadLibrary(_p0)
}
func _LoadLibrary(libname *uint16) (handle Handle, err error) {
r0, _, e1 := Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0)
handle = Handle(r0)
if handle == 0 {
if e1 != 0 {
@ -206,7 +210,11 @@ func GetProcAddress(module Handle, procname string) (proc uintptr, err error) {
if err != nil {
return
}
r0, _, e1 := Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(_p0)), 0)
return _GetProcAddress(module, _p0)
}
func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) {
r0, _, e1 := Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0)
proc = uintptr(r0)
if proc == 0 {
if e1 != 0 {
@ -1558,7 +1566,11 @@ func GetHostByName(name string) (h *Hostent, err error) {
if err != nil {
return
}
r0, _, e1 := Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0)
return _GetHostByName(_p0)
}
func _GetHostByName(name *byte) (h *Hostent, err error) {
r0, _, e1 := Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
h = (*Hostent)(unsafe.Pointer(r0))
if h == nil {
if e1 != 0 {
@ -1581,7 +1593,11 @@ func GetServByName(name string, proto string) (s *Servent, err error) {
if err != nil {
return
}
r0, _, e1 := Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
return _GetServByName(_p0, _p1)
}
func _GetServByName(name *byte, proto *byte) (s *Servent, err error) {
r0, _, e1 := Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0)
s = (*Servent)(unsafe.Pointer(r0))
if s == nil {
if e1 != 0 {
@ -1605,7 +1621,11 @@ func GetProtoByName(name string) (p *Protoent, err error) {
if err != nil {
return
}
r0, _, e1 := Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0)
return _GetProtoByName(_p0)
}
func _GetProtoByName(name *byte) (p *Protoent, err error) {
r0, _, e1 := Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
p = (*Protoent)(unsafe.Pointer(r0))
if p == nil {
if e1 != 0 {
@ -1623,7 +1643,11 @@ func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSR
if status != nil {
return
}
r0, _, _ := Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(_p0)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr)))
return _DnsQuery(_p0, qtype, options, extra, qrs, pr)
}
func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
r0, _, _ := Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr)))
if r0 != 0 {
status = Errno(r0)
}