[dev.boringcrypto] all: merge master into dev.boringcrypto

Conflicts due to simple variable renames (d <-> d0):
    src/crypto/sha1/sha1.go
    src/crypto/sha256/sha256.go
    src/crypto/sha512/sha512.go

Change-Id: I437df180a527fb3ec8b47927ee71960d5d200b76
This commit is contained in:
Filippo Valsorda 2018-05-17 21:04:07 -04:00
commit a3f9ce3313
1997 changed files with 211360 additions and 117222 deletions

View file

@ -1,7 +1,25 @@
Please do not send pull requests to the golang/* repositories.
This PR will be imported into Gerrit with the title and first
comment (this text) used to generate the subject and body of
the Gerrit change.
We do, however, take contributions gladly.
**Please ensure you adhere to every item in this list.**
See https://golang.org/doc/contribute.html
More info can be found at https://github.com/golang/go/wiki/CommitMessage
Thanks!
+ The PR title is formatted as follows: `net/http: frob the quux before blarfing`
+ The package name goes before the colon
+ The part after the colon uses the verb tense + phrase that completes the blank in,
"This change modifies Go to ___________"
+ Lowercase verb after the colon
+ No trailing period
+ Keep the title as short as possible. ideally under 76 characters or shorter
+ No Markdown
+ The first PR comment (this one) is wrapped at 76 characters, unless it's
really needed (ASCII art, table, or long link)
+ If there is a corresponding issue, add either `Fixes #1234` or `Updates #1234`
(the latter if this is not a complete fix) to this comment
+ If referring to a repo other than `golang/go` you can use the
`owner/repo#issue_number` syntax: `Fixes golang/tools#1234`
+ We do not use Signed-off-by lines in Go. Please don't add them.
Our Gerrit server & GitHub bots enforce CLA compliance instead.
+ Delete these instructions once you have read and applied them

159
AUTHORS
View file

@ -18,13 +18,18 @@ Abe Haskins <abeisgreat@abeisgreat.com>
Abhinav Gupta <abhinav.g90@gmail.com>
Adam Eijdenberg <adam@continusec.com>
Adam Kisala <adam.kisala@gmail.com>
Adam Thomason <athomason@gmail.com>
Aditya Mukerjee <dev@chimeracoder.net>
Adrian Hesketh <adrianhesketh@hushmail.com>
Adrian Nos <nos.adrian@gmail.com>
Adrian O'Grady <elpollouk@gmail.com>
Adrien Bustany <adrien-xx-google@bustany.org>
Aécio Júnior <aeciodantasjunior@gmail.com>
Aeneas Rekkas (arekkas) <aeneas@ory.am>
Afanasev Stanislav <phpprogger@gmail.com>
Agis Anastasopoulos <agis.anast@gmail.com>
Ahmed Waheed Moanes <oneofone@gmail.com>
Agniva De Sarker <agnivade@yahoo.co.in>
Ahmed Wahed <oneofone@gmail.com>
Ahmy Yulrizka <yulrizka@gmail.com>
Aiden Scandella <ai@uber.com>
Ainar Garipov <gugl.zadolbal@gmail.com>
@ -60,6 +65,7 @@ Alexander Menzhinsky <amenzhinsky@gmail.com>
Alexander Morozov <lk4d4math@gmail.com>
Alexander Neumann <alexander@bumpern.de>
Alexander Orlov <alexander.orlov@loxal.net>
Alexander Pantyukhin <apantykhin@gmail.com>
Alexander Reece <awreece@gmail.com>
Alexander Surma <surma@surmair.de>
Alexander Zhavnerchik <alex.vizor@gmail.com>
@ -67,6 +73,7 @@ Alexander Zolotov <goldifit@gmail.com>
Alexandre Cesaro <alexandre.cesaro@gmail.com>
Alexandre Fiori <fiorix@gmail.com>
Alexandre Normand <alexandre.normand@gmail.com>
Alexandre Parentea <aubonbeurre@gmail.com>
Alexei Sholik <alcosholik@gmail.com>
Alexey Borzenkov <snaury@gmail.com>
Alexey Neganov <neganovalexey@gmail.com>
@ -76,9 +83,11 @@ Aliaksandr Valialkin <valyala@gmail.com>
Alif Rachmawadi <subosito@gmail.com>
Allan Simon <allan.simon@supinfo.com>
Alok Menghrajani <alok.menghrajani@gmail.com>
Aman Gupta <aman@tmm1.net>
Amazon.com, Inc
Amir Mohammad Saied <amir@gluegadget.com>
Amrut Joshi <amrut.joshi@gmail.com>
Anand K. Mistry <anand@mistry.ninja>
Anders Pearson <anders@columbia.edu>
André Carvalho <asantostc@gmail.com>
Andre Nathan <andrenth@gmail.com>
@ -104,7 +113,10 @@ Andrew Wilkins <axwalk@gmail.com>
Andrew Williams <williams.andrew@gmail.com>
Andrey Mirtchovski <mirtchovski@gmail.com>
Andrey Petrov <andrey.petrov@shazow.net>
Andrii Soldatenko <andrii.soldatenko@gmail.com>
Andrii Soluk <isoluchok@gmail.com>
Andriy Lytvynov <lytvynov.a.v@gmail.com>
Andrzej Żeżel <andrii.zhezhel@gmail.com>
Andy Balholm <andy@balholm.com>
Andy Davis <andy@bigandian.com>
Andy Finkenstadt <afinkenstadt@zynga.com>
@ -115,9 +127,11 @@ Angelo Bulfone <mbulfone@gmail.com>
Anh Hai Trinh <anh.hai.trinh@gmail.com>
Anmol Sethi <anmol@aubble.com>
Anschel Schaffer-Cohen <anschelsc@gmail.com>
Anthony Alves <cvballa3g0@gmail.com>
Anthony Canino <anthony.canino1@gmail.com>
Anthony Eufemio <anthony.eufemio@gmail.com>
Anthony Martin <ality@pbrane.org>
Anthony Sottile <asottile@umich.edu>
Anthony Starks <ajstarks@gmail.com>
Anthony Voutas <voutasaurus@gmail.com>
Anthony Woods <awoods@raintank.io>
@ -128,6 +142,7 @@ Apisak Darakananda <pongad@gmail.com>
Apsalar
Aram Hăvărneanu <aram@mgk.ro>
Areski Belaid <areski@gmail.com>
Ariel Mashraki <ariel@mashraki.co.il>
Arlo Breault <arlolra@gmail.com>
ARM Ltd.
Arnaud Ysmal <arnaud.ysmal@gmail.com>
@ -143,12 +158,14 @@ Augusto Roman <aroman@gmail.com>
Aulus Egnatius Varialus <varialus@gmail.com>
awaw fumin <awawfumin@gmail.com>
Awn Umar <awn@cryptolosophy.io>
Axel Wagner <axel.wagner.hh@googlemail.com>
Ayanamist Yang <ayanamist@gmail.com>
Aymerick Jéhanne <aymerick@jehanne.org>
Baiju Muthukadan <baiju.m.mail@gmail.com>
Bartosz Grzybowski <melkorm@gmail.com>
Bastian Ike <bastian.ike@gmail.com>
Ben Burkert <ben@benburkert.com>
Ben Haines <bhainesva@gmail.com>
Ben Lubar <ben.lubar@gmail.com>
Ben Olive <sionide21@gmail.com>
Ben Shi <powerman1st@163.com>
@ -159,26 +176,33 @@ Berengar Lehr <berengar.lehr@gmx.de>
Billie Harold Cleek <bhcleek@gmail.com>
Bjorn Tillenius <bjorn@tillenius.me>
Bjorn Tipling <bjorn.tipling@gmail.com>
Blain Smith <rebelgeek@blainsmith.com>
Blake Gentry <blakesgentry@gmail.com>
Blake Mesdag <blakemesdag@gmail.com>
Blake Mizerany <blake.mizerany@gmail.com>
Blixt <me@blixt.nyc>
Bobby Powers <bobbypowers@gmail.com>
Bolt
Borja Clemente <borja.clemente@gmail.com>
Brad Burch <brad.burch@gmail.com>
Brady Catherman <brady@gmail.com>
Brady Sullivan <brady@bsull.com>
Brendan Daniel Tracey <tracey.brendan@gmail.com>
Brett Cannon <bcannon@gmail.com>
Brett Merrill <brett.j.merrill94@gmail.com>
Brian Dellisanti <briandellisanti@gmail.com>
Brian Downs <brian.downs@gmail.com>
Brian G. Merrell <bgmerrell@gmail.com>
Brian Gitonga Marete <marete@toshnix.com> <bgmarete@gmail.com>
Brian Kennedy <btkennedy@gmail.com>
Brian Kessler <brian.m.kessler@gmail.com>
Brian Ketelsen <bketelsen@gmail.com>
Brian Smith <ohohvi@gmail.com>
Brian Starke <brian.starke@gmail.com>
Bryan Alexander <Kozical@msn.com>
Bryan Ford <brynosaurus@gmail.com>
Bulat Gaifullin <gaifullinbf@gmail.com>
Burak Guven <bguven@gmail.com>
Caine Tighe <arctanofyourface@gmail.com>
Caleb Spare <cespare@gmail.com>
Carl Chatfield <carlchatfield@gmail.com>
@ -193,9 +217,12 @@ Case Nelson <case.nelson@gmail.com>
Casey Marshall <casey.marshall@gmail.com>
Cezar Sá Espinola <cezarsa@gmail.com>
ChaiShushan <chaishushan@gmail.com>
Charles Fenwick Elliott <Charles@FenwickElliott.io>
Charles L. Dorian <cldorian@gmail.com>
Charles Lee <zombie.fml@gmail.com>
Chew Choon Keat <choonkeat@gmail.com>
Cholerae Hu <choleraehyq@gmail.com>
Chris Ball <chris@printf.net>
Chris Biscardi <chris@christopherbiscardi.com>
Chris Dollin <ehog.hedge@gmail.com>
Chris Farmiloe <chrisfarms@gmail.com>
@ -207,6 +234,7 @@ Chris Lennert <calennert@gmail.com>
Chris McGee <sirnewton_01@yahoo.ca> <newton688@gmail.com>
Chris Roche <rodaine@gmail.com>
Chris Stockton <chrisstocktonaz@gmail.com>
Christian Alexander <christian@linux.com>
Christian Couder <chriscool@tuxfamily.org>
Christian Himpel <chressie@googlemail.com>
Christine Hansmann <chhansmann@gmail.com>
@ -214,10 +242,12 @@ Christoffer Buchholz <christoffer.buchholz@gmail.com>
Christoph Hack <christoph@tux21b.org>
Christopher Cahoon <chris.cahoon@gmail.com>
Christopher Guiney <chris@guiney.net>
Christopher Henderson <chris@chenderson.org>
Christopher Nelson <nadiasvertex@gmail.com>
Christopher Nielsen <m4dh4tt3r@gmail.com>
Christopher Redden <christopher.redden@gmail.com>
Christopher Wedgwood <cw@f00f.org>
Christos Zoulas <christos@zoulas.com> <zoulasc@gmail.com>
CL Sung <clsung@gmail.com> <cl_sung@htc.com>
Clement Skau <clementskau@gmail.com>
CloudFlare Inc.
@ -251,6 +281,8 @@ Daniel Skinner <daniel@dasa.cc>
Daniel Speichert <daniel@speichert.pl>
Daniel Theophanes <kardianos@gmail.com>
Daniel Upton <daniel@floppy.co>
Daniela Petruzalek <daniela.petruzalek@gmail.com>
Danny Rosseau <daniel.rosseau@gmail.com>
Darren Elwood <darren@textnode.com>
Datong Sun <dndx@idndx.com>
Dave Cheney <dave@cheney.net>
@ -272,6 +304,7 @@ David Thomas <davidthomas426@gmail.com>
David Titarenco <david.titarenco@gmail.com>
David Volquartz Lebech <david@lebech.info>
Davies Liu <davies.liu@gmail.com>
Davor Kapsa <davor.kapsa@gmail.com>
Dean Prichard <dean.prichard@gmail.com>
Deepak Jois <deepak.jois@gmail.com>
Denis Bernard <db047h@gmail.com>
@ -308,15 +341,19 @@ Dustin Sallings <dsallings@gmail.com>
Dustin Shields-Cloues <dcloues@gmail.com>
Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
Dylan Waits <dylan@waits.io>
Edan Bedrik <3d4nb3@gmail.com>
Eden Li <eden.li@gmail.com>
Edward Muller <edwardam@interlix.com>
Egon Elbre <egonelbre@gmail.com>
Ehren Kret <ehren.kret@gmail.com>
Eitan Adler <lists@eitanadler.com>
Eivind Uggedal <eivind@uggedal.com>
Elbert Fliek <efliek@gmail.com>
Elena Grahovac <elena@grahovac.me>
Elias Naur <elias.naur@gmail.com>
Elliot Morrison-Reed <elliotmr@gmail.com>
Emil Hessman <c.emil.hessman@gmail.com> <emil@hessman.se>
Emerson Lin <linyintor@gmail.com>
Emil Hessman <emil@hessman.se>
Emilien Kenler <hello@emilienkenler.com>
Emmanuel Odeke <emm.odeke@gmail.com> <odeke@ualberta.ca>
Empirical Interfaces Inc.
@ -326,6 +363,7 @@ Eric Clark <zerohp@gmail.com>
Eric Engestrom <eric@engestrom.ch>
Eric Lagergren <ericscottlagergren@gmail.com>
Eric Milliken <emilliken@gmail.com>
Eric Rescorla <ekr@rtfm.com>
Eric Roshan-Eisner <eric.d.eisner@gmail.com>
Erik Aigner <aigner.erik@gmail.com>
Erik Dubbelboer <erik@dubbelboer.com>
@ -335,6 +373,7 @@ Ernest Chiang <ernest_chiang@htc.com>
Esko Luontola <esko.luontola@gmail.com>
Euan Kemp <euank@euank.com>
Evan Hicks <evan.hicks2@gmail.com>
Evan Jones <ej@evanjones.ca>
Evan Phoenix <evan@phx.io>
Evan Shaw <chickencha@gmail.com>
Evgeniy Polyakov <zbr@ioremap.net>
@ -363,6 +402,8 @@ Ford Hurley <ford.hurley@gmail.com>
Francisco Claude <fclaude@recoded.cl>
Francisco Rojas <francisco.rojas.gallegos@gmail.com>
Francisco Souza <franciscossouza@gmail.com>
Frank Somers <fsomers@arista.com>
Frederic Guillot <frederic.guillot@gmail.com>
Frederick Kelly Mayle III <frederickmayle@gmail.com>
Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com>
Fredrik Forsmo <fredrik.forsmo@gmail.com>
@ -391,9 +432,12 @@ Google Inc.
Gordon Klaus <gordon.klaus@gmail.com>
Graham King <graham4king@gmail.com>
Graham Miller <graham.miller@gmail.com>
Grant Griffiths <ggp493@gmail.com>
Greg Poirier <greg.istehbest@gmail.com>
Greg Ward <greg@gerg.ca>
Gregory Man <man.gregory@gmail.com>
Guilherme Garnier <guilherme.garnier@gmail.com>
Guilherme Rezende <guilhermebr@gmail.com>
Guillaume J. Charmes <guillaume@charmes.net>
Guobiao Mei <meiguobiao@gmail.com>
Gustav Paul <gustav.paul@gmail.com>
@ -404,6 +448,7 @@ Gyu-Ho Lee <gyuhox@gmail.com>
H. İbrahim Güngör <igungor@gmail.com>
Hajime Hoshi <hajimehoshi@gmail.com>
Hang Qian <hangqian90@gmail.com>
Hanjun Kim <hallazzang@gmail.com>
Hari haran <hariharan.uno@gmail.com>
Hariharan Srinath <srinathh@gmail.com>
Harley Laue <losinggeneration@gmail.com>
@ -416,8 +461,12 @@ Hector Martin Cantero <hector@marcansoft.com>
Henning Schmiedehausen <henning@schmiedehausen.org>
Henrik Edwards <henrik.edwards@gmail.com>
Henrik Hodne <henrik@hodne.io>
Henry Adi Sumarto <henry.adisumarto@gmail.com>
Henry Bubert <google@mindeco.de>
Henry Chang <mr.changyuheng@gmail.com>
Herbert Georg Fischer <herbert.fischer@gmail.com>
Hilko Bengen <bengen@hilluzination.de>
Hiroaki Nakamura <hnakamur@gmail.com>
Hironao OTSUBO <motemen@gmail.com>
Hiroshi Ioka <hirochachacha@gmail.com>
Hitoshi Mitake <mitake.hitoshi@gmail.com>
@ -428,6 +477,7 @@ Hsin-Ho Yeh <yhh92u@gmail.com>
Hu Keping <hukeping@huawei.com>
Hugues Bruant <hugues.bruant@gmail.com>
Ian Gudger <ian@loosescre.ws>
Ian Kent <iankent85@gmail.com>
IBM
Ibrahim AshShohail <ibra.sho@gmail.com>
Icarus Sparry <golang@icarus.freeuk.com>
@ -435,13 +485,16 @@ Iccha Sethi <icchasethi@gmail.com>
Idora Shinatose <idora.shinatose@gmail.com>
Igneous Systems, Inc.
Igor Dolzhikov <bluesriverz@gmail.com>
Igor Vashyst <ivashyst@gmail.com>
INADA Naoki <songofacandy@gmail.com>
Inanc Gumus <m@inanc.io>
Ingo Krabbe <ikrabbe.ask@gmail.com>
Ingo Oeser <nightlyone@googlemail.com>
Intel Corporation
Irieda Noboru <irieda@gmail.com>
Isaac Wagner <ibw@isaacwagner.me>
Ivan Babrou <ivan@cloudflare.com>
Ivan Bertona <ivan.bertona@gmail.com>
Ivan Moscoso <moscoso@gmail.com>
Ivan Ukhov <ivan.ukhov@gmail.com>
Jacob Hoffman-Andrews <github@hoffman-andrews.com>
@ -455,6 +508,7 @@ James David Chalfant <james.chalfant@gmail.com>
James Fysh <james.fysh@gmail.com>
James Gray <james@james4k.com>
James Hartig <fastest963@gmail.com>
James Lawrence <jljatone@gmail.com>
James Meneghello <rawrz0r@gmail.com>
James Myers <jfmyers9@gmail.com>
James Neve <jamesoneve@gmail.com>
@ -463,6 +517,7 @@ James Schofield <james@shoeboxapp.com>
James Smith <jrs1995@icloud.com>
James Sweet <james.sweet88@googlemail.com>
James Toy <nil@opensesame.st>
James Treanor <jtreanor3@gmail.com>
James Whitehead <jnwhiteh@gmail.com>
Jamie Beverly <jamie.r.beverly@gmail.com>
Jamie Kerr <jkerr113@googlemail.com>
@ -474,19 +529,25 @@ Jan Mercl <0xjnml@gmail.com> <befelemepeseveze@gmail.com>
Jan Newmarch <jan.newmarch@gmail.com>
Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
Jani Monoses <jani.monoses@ubuntu.com>
Jared Culp <jculp14@gmail.com>
Jaroslavas Počepko <jp@webmaster.ms>
Jason Barnett <jason.w.barnett@gmail.com>
Jason Chu <jasonchujc@gmail.com>
Jason Del Ponte <delpontej@gmail.com>
Jason Smale <jsmale@zendesk.com>
Jason Travis <infomaniac7@gmail.com>
Jason Wangsadinata <jwangsadinata@gmail.com>
Javier Segura <javism@gmail.com>
Jay Weisskopf <jay@jayschwa.net>
Jean-Francois Cantin <jfcantin@gmail.com>
Jean-Nicolas Moal <jn.moal@gmail.com>
Jeet Parekh <jeetparekh96@gmail.com>
Jeff Hodges <jeff@somethingsimilar.com>
Jeff R. Allen <jra@nella.org>
Jeff Sickel <jas@corpus-callosum.com>
Jeff Wendling <jeff@spacemonkey.com>
Jeffrey H <jeffreyh192@gmail.com>
Jelte Fennema <github-tech@jeltef.nl>
Jens Frederich <jfrederich@gmail.com>
Jeremy Jackins <jeremyjackins@gmail.com>
Jeroen Bobbeldijk <jerbob92@gmail.com>
@ -494,12 +555,14 @@ Jess Frazelle <me@jessfraz.com>
Jesse Szwedko <jesse.szwedko@gmail.com>
Jihyun Yu <yjh0502@gmail.com>
Jim McGrath <jimmc2@gmail.com>
Jimmy Frasche <soapboxcicero@gmail.com>
Jimmy Zelinskie <jimmyzelinskie@gmail.com>
Jin-wook Jeong <jeweljar@hanmail.net>
Jingcheng Zhang <diogin@gmail.com>
Jingguo Yao <yaojingguo@gmail.com>
Jiong Du <londevil@gmail.com>
Jirka Daněk <dnk@mail.muni.cz>
Jiulong Wang <jiulongw@gmail.com>
Joakim Sernbrant <serbaut@gmail.com>
Joe Farrell <joe2farrell@gmail.com>
Joe Harrison <joehazzers@gmail.com>
@ -545,14 +608,18 @@ Josh Goebel <dreamer3@gmail.com>
Josh Holland <jrh@joshh.co.uk>
Josh Roppo <joshroppo@gmail.com>
Joshua Chase <jcjoshuachase@gmail.com>
Joshua Rubin <joshua@rubixconsulting.com>
Josselin Costanzi <josselin@costanzi.fr>
Jostein Stuhaug <js@solidsystem.no>
Joyent, Inc.
JT Olds <jtolds@xnet5.com>
Juan Carlos <juanjcsr@gmail.com>
Jude Pereira <judebpereira@gmail.com>
Jukka-Pekka Kekkonen <karatepekka@gmail.com>
Julian Kornberger <jk+github@digineo.de>
Julian Phillips <julian@quantumfyre.co.uk>
Julien Schmidt <google@julienschmidt.com>
Junya Hayashi <ledmonster@gmail.com>
Justin Nuß <nuss.justin@gmail.com>
Justyn Temme <justyntemme@gmail.com>
Kai Backman <kaib@golang.org>
@ -562,7 +629,9 @@ Kaleb Elwert <kelwert@atlassian.com>
Kamil Chmielewski <kamil.chm@gmail.com>
Kamil Kisiel <kamil@kamilkisiel.net> <kamil.kisiel@gmail.com>
Kang Hu <hukangustc@gmail.com>
Karel Pazdera <pazderak@gmail.com>
Karoly Negyesi <chx1975@gmail.com>
Karsten Köhler <karsten.koehler95@gmail.com>
Kashav Madan <kshvmdn@gmail.com>
Kate Manson <kate.manson@izettle.com>
Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
@ -579,13 +648,17 @@ Ken Friedenbach <kenliz@cruzio.com>
Ken Rockot <ken@oz.gs>
Ken Sedgwick <ken@bonsai.com>
Kenji Kaneda <kenji.kaneda@gmail.com>
Kenji Yano <kenji.yano@gmail.com>
Kenneth Shaw <kenshaw@gmail.com>
Kenny Grant <kennygrant@gmail.com>
Kevin Ballard <kevin@sb.org>
Kevin Burke <kev@inburke.com>
Kevin Kirsche <kev.kirsche@gmail.com>
Kevin Ruffin <kruffin@gmail.com>
Kevin Vu <kevin.m.vu@gmail.com>
Kieran Colford <kieran@kcolford.com>
Kim Yongbin <kybinz@gmail.com>
Kirk Han <kirk91.han@gmail.com>
Klaus Post <klauspost@gmail.com>
Kodie Goodwin <kodiegoodwin@gmail.com>
Koichi Shiraishi <zchee.io@gmail.com>
@ -596,20 +669,26 @@ KPCompass, Inc.
Kris Nova <kris@nivenly.com>
Kristopher Watts <traetox@gmail.com>
Kun Li <likunarmstrong@gmail.com>
Kunpei Sakai <namusyaka@gmail.com>
Kyle Consalus <consalus@gmail.com>
Kyle Isom <kyle@gokyle.net>
Kyle Jones <kyle@kyledj.com>
Kyle Lemons <kyle@kylelemons.net>
Kyle Shannon <kyle@pobox.com>
Kyohei Kadota <lufia@lufia.org>
Kyrylo Silin <silin@kyrylo.org>
L Campbell <unpantsu@gmail.com>
Lai Jiangshan <eag0628@gmail.com>
Lakshay Garg <lakshay.garg.1996@gmail.com>
Lars Jeppesen <jeppesen.lars@gmail.com>
Lars Wiegman <lars@namsral.com>
Larz Conwell <larzconwell@gmail.com>
Laurent Voisin <lpvoisin@gmail.com>
Laurie Clark-Michalek <laurie@qubit.com>
LE Manh Cuong <cuong.manhle.vn@gmail.com>
Lee Hinman <hinman@gmail.com>
Lee Packham <lpackham@gmail.com>
Leigh McCulloch <leighmcc@gmail.com>
Leon Klingele <git@leonklingele.de>
Lev Shamardin <shamardin@gmail.com>
Lewin Bormann <lewin.bormann@gmail.com>
@ -629,10 +708,15 @@ Luigi Riefolo <luigi.riefolo@gmail.com>
Luit van Drongelen <luitvd@gmail.com>
Luka Zakrajšek <tr00.g33k@gmail.com>
Luke Curley <qpingu@gmail.com>
Luke Granger-Brown <git@lukegb.com>
Lyle Franklin <lylejfranklin@gmail.com>
Ma Peiqi <mapeiqi2017@gmail.com>
Maicon Costa <maiconscosta@gmail.com>
Maksym Trykur <maksym.trykur@gmail.com>
Mal Curtis <mal@mal.co.nz>
Manfred Touron <m@42.am>
Manish Goregaokar <manishsmail@gmail.com>
Mansour Rahimi <rahimi.mnr@gmail.com>
Manu S Ajith <neo@codingarena.in>
Manuel Mendez <mmendez534@gmail.com>
Marc Weistroff <marc@weistroff.net>
@ -642,8 +726,11 @@ Marco Hennings <marco.hennings@freiheit.com>
Marin Bašić <marin.basic02@gmail.com>
Mark Adams <mark@markadams.me>
Mark Bucciarelli <mkbucc@gmail.com>
Mark Percival <m@mdp.im>
Mark Pulford <mark@kyne.com.au>
Mark Severson <miquella@gmail.com>
Mark Theunissen <mark.theunissen@gmail.com>
Mark Wolfe <mark@wolfe.id.au>
Marko Juhani Silokunnas <marko.silokunnas@gmail.com>
Marko Mudrinic <mudrinic.mare@gmail.com>
Marko Tiikkaja <marko@joh.to>
@ -661,13 +748,17 @@ Martin Neubauer <m.ne@gmx.net>
Martin Olsen <github.com@martinolsen.net>
Martin Olsson <martin@minimum.se>
Martin Probst <martin@probst.io>
Martins Sipenko <martins.sipenko@gmail.com>
Marvin Stenger <marvin.stenger94@gmail.com>
Marwan Sulaiman <marwan.sulaiman@work.co>
Maryan Hratson <gmarik@gmail.com>
Masahiro Furudate <masahiro.furudate@gmail.com>
Masahiro Wakame <vvakame@gmail.com>
Masaki Yoshida <yoshida.masaki@gmail.com>
Mat Byczkowski <mbyczkowski@gmail.com>
Máté Gulyás <mgulyas86@gmail.com>
Matej Baćo <matejbaco@gmail.com>
Mateus Amin <mateus.amin@gmail.com>
Mateusz Czapliński <czapkofan@gmail.com>
Mathias Beke <git@denbeke.be>
Mathias Hall-Andersen <mathias@hall-andersen.dk>
@ -677,6 +768,7 @@ Mats Lidell <mats.lidell@cag.se>
Matt Aimonetti <mattaimonetti@gmail.com>
Matt Blair <me@matthewblair.net>
Matt Bostock <matt@mattbostock.com>
Matt Dee <mdee@hioscar.com>
Matt Drollette <matt@drollette.com>
Matt Harden <matt.harden@gmail.com>
Matt Jibson <matt.jibson@gmail.com>
@ -688,23 +780,28 @@ Matt Strong <mstrong1341@gmail.com>
Matt T. Proud <matt.proud@gmail.com>
Matt Williams <gh@mattyw.net>
Matthew Brennan <matty.brennan@gmail.com>
Matthew Broberg <matthewbbroberg@gmail.com>
Matthew Cottingham <mattcottingham@gmail.com>
Matthew Denton <mdenton@skyportsystems.com>
Matthew Holt <Matthew.Holt+git@gmail.com>
Matthew Horsnell <matthew.horsnell@gmail.com>
Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
Matthieu Olivier <olivier.matthieu@gmail.com>
Matthijs Kooijman <matthijs@stdin.nl>
Max Riveiro <kavu13@gmail.com>
Max Schmitt <max@schmitt.mx>
Maxim Khitrov <max@mxcrypt.com>
Maxime de Roucy <maxime.deroucy@gmail.com>
Máximo Cuadros Ortiz <mcuadros@gmail.com>
Maxwell Krohn <themax@gmail.com>
Mayank Kumar <krmayankk@gmail.com>
MediaMath, Inc
Meir Fischer <meirfischer@gmail.com>
Meng Zhuo <mengzhuo1203@gmail.com>
Meteor Development Group
Mhd Sulhan <m.shulhan@gmail.com>
Micah Stetson <micah.stetson@gmail.com>
Michael Brandenburg <mbrandenburg@bolste.com>
Michael Chaten <mchaten@gmail.com>
Michael Edwards <medwards@walledcity.ca>
Michael Elkins <michael.elkins@gmail.com>
@ -716,17 +813,22 @@ Michael Käufl <golang@c.michael-kaeufl.de>
Michael Lewis <mikelikespie@gmail.com>
Michael MacInnis <Michael.P.MacInnis@gmail.com>
Michael McConville <momcconville@gmail.com>
Michael McLoughlin <mmcloughlin@gmail.com>
Michael Pearson <mipearson@gmail.com>
Michael Schaller <michael@5challer.de>
Michael Schurter <michael.schurter@gmail.com>
Michael Stapelberg <michael@stapelberg.de>
Michael Steinert <mike.steinert@gmail.com>
Michael Teichgräber <mteichgraeber@gmx.de>
Michael Vetter <g.bluehut@gmail.com>
Michal Bohuslávek <mbohuslavek@gmail.com>
Michał Derkacz <ziutek@lnet.pl>
Michal Pristas <michal.pristas@gmail.com>
Miek Gieben <miek@miek.nl>
Miguel Mendez <stxmendez@gmail.com>
Miguel Molina <hi@mvader.me>
Mihai Borobocea <MihaiBorobocea@gmail.com>
Mihail Minaev <minaev.mike@gmail.com>
Mikael Tillenius <mikti42@gmail.com>
Mike Andrews <mra@xoba.com>
Mike Appleby <mike@app.leby.org>
@ -748,9 +850,11 @@ Moriyoshi Koizumi <mozo@mozo.jp>
Morten Siebuhr <sbhr@sbhr.dk>
Môshe van der Sterre <moshevds@gmail.com>
Mostyn Bramley-Moore <mostyn@antipode.se>
Muhammad Falak R Wani <falakreyaz@gmail.com>
Muhammed Uluyol <uluyol0@gmail.com>
Mura Li <mura_li@castech.com.tw>
Nan Deng <monnand@gmail.com>
Naoki Kanatani <k12naoki@gmail.com>
Nathan Caza <mastercactapus@gmail.com>
Nathan Humphreys <nkhumphreys@gmail.com>
Nathan John Youngman <nj@nathany.com>
@ -779,6 +883,7 @@ Nick Miyake <nmiyake@users.noreply.github.com>
Nick Patavalis <nick.patavalis@gmail.com>
Nick Petroni <npetroni@cs.umd.edu>
Nick Robinson <nrobinson13@gmail.com>
Nicolas BRULEZ <n.brulez@gmail.com>
Nicolas Kaiser <nikai@nikai.net>
Nicolas Owens <mischief@offblast.org>
Nicolas S. Dade <nic.dade@gmail.com>
@ -788,8 +893,10 @@ Nik Nyby <nnyby@columbia.edu>
Niklas Schnelle <niklas.schnelle@gmail.com>
Niko Dziemba <niko@dziemba.com>
Nikolay Turpitko <nikolay@turpitko.com>
Nils Larsgård <nilsmagnus@gmail.com>
Niranjan Godbole <niranjan8192@gmail.com>
Noah Campbell <noahcampbell@gmail.com>
Noble Johnson <noblepoly@gmail.com>
Norberto Lopes <nlopes.ml@gmail.com>
Odin Ugedal <odin@ugedal.com>
Oleg Bulatov <dmage@yandex-team.ru>
@ -823,12 +930,15 @@ Patrick Mylund Nielsen <patrick@patrickmn.com>
Patrick Pelletier <pp.pelletier@gmail.com>
Patrick Smith <pat42smith@gmail.com>
Paul A Querna <paul.querna@gmail.com>
Paul Boyd <boyd.paul2@gmail.com>
Paul Hammond <paul@paulhammond.org>
Paul Jolly <paul@myitcv.org.uk>
Paul Lalonde <paul.a.lalonde@gmail.com>
Paul Meyer <paul.meyer@microsoft.com>
Paul PISCUC <paul.piscuc@gmail.com>
Paul Querna <pquerna@apache.org>
Paul Rosania <paul.rosania@gmail.com>
Paul Ruest <pruest@gmail.com>
Paul Sbarra <Sbarra.Paul@gmail.com>
Paul Smith <paulsmith@pobox.com> <paulsmith@gmail.com>
Paul van Brouwershaven <paul@vanbrouwershaven.com>
@ -853,6 +963,7 @@ Péter Szilágyi <peterke@gmail.com>
Peter Waldschmidt <peter@waldschmidt.com>
Peter Waller <peter.waller@gmail.com>
Peter Williams <pwil3058@gmail.com>
Petrica Voicu <pvoicu@paypal.com>
Philip Børgesen <philip.borgesen@gmail.com>
Philip Hofer <phofer@umich.edu>
Philip K. Warren <pkwarren@gmail.com>
@ -861,26 +972,34 @@ Pierre Roullon <pierre.roullon@gmail.com>
Piers <google@hellopiers.pro>
Pieter Droogendijk <pieter@binky.org.uk>
Pietro Gagliardi <pietro10@mac.com>
Pontus Leitzler <leitzler@gmail.com>
Prashant Varanasi <prashant@prashantv.com>
Pravendra Singh <hackpravj@gmail.com>
Preetam Jinka <pj@preet.am>
Qiuxuan Zhu <ilsh1022@gmail.com>
Qualcomm Data Center, Inc.
Quan Tran <qeed.quan@gmail.com>
Quan Yong Zhai <qyzhai@gmail.com>
Quentin Perez <qperez@ocs.online.net>
Quentin Renard <contact@asticode.com>
Quoc-Viet Nguyen <afelion@gmail.com>
RackTop Systems Inc.
Radek Sohlich <sohlich@gmail.com>
Radu Berinde <radu@cockroachlabs.com>
Rafal Jeczalik <rjeczalik@gmail.com>
Raif S. Naffah <go@naffah-raif.name>
RainTank
Rajat Goel <rajat.goel2010@gmail.com>
Rajath Agasthya <rajathagasthya@gmail.com>
Rajender Reddy Kompally <rajenderreddykompally@gmail.com>
Ralph Corderoy <ralph@inputplus.co.uk>
Ramazan AYYILDIZ <rayyildiz@gmail.com>
Raphael Geronimi <raphael.geronimi@gmail.com>
RaviTeja Pothana <ravi.tezu@gmail.com>
Ray Tung <rtung@thoughtworks.com>
Raymond Kazlauskas <raima220@gmail.com>
Red Hat, Inc.
Reilly Watson <reillywatson@gmail.com>
Reinaldo de Souza Jr <juniorz@gmail.com>
Remi Gillig <remigillig@gmail.com>
Rémy Oudompheng <oudomphe@phare.normalesup.org>
@ -909,10 +1028,13 @@ Rodrigo Rafael Monti Kochenburger <divoxx@gmail.com>
Roger Pau Monné <royger@gmail.com>
Roger Peppe <rogpeppe@gmail.com>
Roland Shoemaker <rolandshoemaker@gmail.com>
Roman Budnikov <romanyx90@yandex.ru>
Ron Hashimoto <mail@h2so5.net>
Ron Minnich <rminnich@gmail.com>
Ross Chater <rdchater@gmail.com>
Ross Light <rlight2@gmail.com>
Rowan Worth <sqweek@gmail.com>
Rudi Kramer <rudi.kramer@gmail.com>
Russell Haering <russellhaering@gmail.com>
Ryan Bagwell <ryanbagwell@outlook.com>
Ryan Boehning <ryan.boehning@apcera.com>
@ -920,6 +1042,8 @@ Ryan Hitchman <hitchmanr@gmail.com>
Ryan Lower <rpjlower@gmail.com>
Ryan Seys <ryan@ryanseys.com>
Ryan Slade <ryanslade@gmail.com>
Ryoichi KATO <ryo1kato@gmail.com>
Ryuji Iwata <qt.luigi@gmail.com>
Ryuzo Yamamoto <ryuzo.yamamoto@gmail.com>
S.Çağlar Onur <caglar@10ur.org>
Sakeven Jiang <jc5930@sina.cn>
@ -933,15 +1057,19 @@ Sascha Brawer <sascha@brawer.ch>
Sasha Sobol <sasha@scaledinference.com>
Scott Barron <scott.barron@github.com>
Scott Bell <scott@sctsm.com>
Scott Crunkleton <crunk1@gmail.com>
Scott Ferguson <scottwferg@gmail.com>
Scott Lawrence <bytbox@gmail.com>
Sean Rees <sean@erifax.org>
Sebastien Binet <seb.binet@gmail.com>
Sébastien Paolacci <sebastien.paolacci@gmail.com>
Seiji Takahashi <timaki.st@gmail.com>
Sergei Skorobogatov <skorobo@rambler.ru>
Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
Sergey Mishin <sergeymishine@gmail.com>
Sergey Semin <gray12511@gmail.com>
Sergio Luis O. B. Correia <sergio@correia.cc>
Sergiusz Bazanski <bazanski@gmail.com>
Seth Hoenig <seth.a.hoenig@gmail.com>
Seth Vargo <sethvargo@gmail.com>
Shahar Kohanim <skohanim@gmail.com>
@ -968,11 +1096,13 @@ Square, Inc.
Sridhar Venkatakrishnan <sridhar@laddoo.net>
StalkR <stalkr@stalkr.net>
Stan Schwertly <stan@schwertly.com>
Stanislav Afanasev <php.progger@gmail.com>
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
Stéphane Travostino <stephane.travostino@gmail.com>
Stephen McQuay <stephen@mcquay.me>
Stephen Searles <stephens2424@gmail.com>
Stephen Weinberg <stephen@q5comm.com>
Steve Gilbert <stevegilbert23@gmail.com>
Steve McCoy <mccoyst@gmail.com>
Steve Phillips <elimisteve@gmail.com>
Steve Streeting <steve@stevestreeting.com>
@ -981,46 +1111,57 @@ Steven Erenst <stevenerenst@gmail.com>
Steven Hartland <steven.hartland@multiplay.co.uk>
Steven Wilkin <stevenwilkin@gmail.com>
Stripe, Inc.
Sukrit Handa <sukrit.handa@utoronto.ca>
Sunny <me@darkowlzz.space>
Suyash <dextrous93@gmail.com>
Sven Almgren <sven@tras.se>
Sylvain Zimmer <sylvain@sylvainzimmer.com>
Syohei YOSHIDA <syohex@gmail.com>
Szabolcs Nagy <nsz@port70.net>
Tad Fisher <tadfisher@gmail.com>
Tad Glines <tad.glines@gmail.com>
Taj Khattra <taj.khattra@gmail.com>
Takeshi YAMANASHI <9.nashi@gmail.com>
Takuya Ueda <uedatakuya@gmail.com>
Tal Shprecher <tshprecher@gmail.com>
Tamir Duberstein <tamird@gmail.com>
Tao Wang <twang2218@gmail.com>
Tarmigan Casebolt <tarmigan@gmail.com>
Taro Aoki <aizu.s1230022@gmail.com>
Taru Karttunen <taruti@taruti.net>
Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Ted Kornish <golang@tedkornish.com>
Teleport Inc.
Terin Stock <terinjokes@gmail.com>
Terrel Shumway <gopher@shumway.us>
Tetsuo Kiso <tetsuokiso9@gmail.com>
Thanatat Tamtan <acoshift@gmail.com>
Thiago Avelino <t@avelino.xxx>
Thiago Fransosi Farina <thiago.farina@gmail.com>
Thomas Alan Copeland <talan.copeland@gmail.com>
Thomas Bonfort <thomas.bonfort@gmail.com>
Thomas de Zeeuw <thomasdezeeuw@gmail.com>
Thomas Desrosiers <thomasdesr@gmail.com>
Thomas Kappler <tkappler@gmail.com>
Thomas Wanielista <tomwans@gmail.com>
Thorben Krueger <thorben.krueger@gmail.com>
Thordur Bjornsson <thorduri@secnorth.net>
Tilman Dilo <tilman.dilo@gmail.com>
Tim Cooijmans <timcooijmans@gmail.com>
Tim Cooper <tim.cooper@layeh.com>
Tim Ebringer <tim.ebringer@gmail.com>
Tim Heckman <t@heckman.io>
Tim Henderson <tim.tadh@gmail.com>
Tim Wright <tenortim@gmail.com>
Timo Savola <timo.savola@gmail.com>
Timo Truyts <alkaloid.btx@gmail.com>
Timothy Studd <tim@timstudd.com>
Tobias Assarsson <tobias.assarsson@gmail.com>
Tobias Columbus <tobias.columbus@gmail.com>
Tobias Klauser <tklauser@distanz.ch>
Todd Neal <todd@tneal.org>
Tom Heng <zhm20070928@gmail.com>
Tom Levy <tomlevy93@gmail.com>
Tom Linford <tomlinford@gmail.com>
Tommy Schaefer <tommy.schaefer@teecom.com>
Tonis Tiigi <tonistiigi@gmail.com>
@ -1035,8 +1176,10 @@ Trey Roessig <trey.roessig@gmail.com>
Trey Tacon <ttacon@gmail.com>
Tristan Colgate <tcolgate@gmail.com>
Tristan Ooohry <ooohry@gmail.com>
Troels Thomsen <troels@thomsen.io>
Trung Nguyen <trung.n.k@gmail.com>
Tudor Golubenco <tudor.g@gmail.com>
Tugdual Saunier <tugdual.saunier@gmail.com>
Tuo Shan <sturbo89@gmail.com>
Tyler Bunnell <tylerbunnell@gmail.com>
Tyler Treat <ttreat31@gmail.com>
@ -1063,14 +1206,18 @@ Volker Dobler <dr.volker.dobler@gmail.com>
Wade Simmons <wade@wades.im>
Wander Lairson Costa <wcosta@mozilla.com>
Weaveworks
Wèi Cōngruì <crvv.mail@gmail.com>
Wei Guangjing <vcc.163@gmail.com>
Weichao Tang <tevic.tt@gmail.com>
Wembley G. Leach, Jr <wembley.gl@gmail.com>
Will Faught <will.faught@gmail.com>
Will Storey <will@summercat.com>
Willem van der Schyff <willemvds@gmail.com>
William Josephson <wjosephson@gmail.com>
William Orr <will@worrbase.com> <ay1244@gmail.com>
Wisdom Omuya <deafgoat@gmail.com>
Wu Yunzhou <yunzhouwu@gmail.com>
Xi Ruoyao <xry23333@gmail.com>
Xia Bin <snyh@snyh.org>
Xing Xing <mikespook@gmail.com>
Xu Fei <badgangkiller@gmail.com>
@ -1078,30 +1225,36 @@ Xudong Zhang <felixmelon@gmail.com>
Xuyang Kang <xuyangkang@gmail.com>
Yahoo Inc.
Yann Kerhervé <yann.kerherve@gmail.com>
Yann Salaün <yannsalaun1@gmail.com>
Yao Zhang <lunaria21@gmail.com>
Yasha Bubnov <girokompass@gmail.com>
Yasuharu Goto <matope.ono@gmail.com>
Yasuhiro Matsumoto <mattn.jp@gmail.com>
Yestin Sun <ylh@pdx.edu>
Yesudeep Mangalapilly <yesudeep@google.com>
Yissakhar Z. Beck <yissakhar.beck@gmail.com>
Yo-An Lin <yoanlin93@gmail.com>
Yongjian Xu <i3dmaster@gmail.com>
Yorman Arias <cixtords@gmail.com>
Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp>
Yosuke Akatsuka <yosuke.akatsuka@gmail.com>
Yukihiro Nishinaka <6elpinal@gmail.com>
Yusuke Kagiwada <block.rxckin.beats@gmail.com>
Yuusei Kuwana <kuwana@kumama.org>
Yuval Pavel Zholkover <paulzhol@gmail.com>
Zac Bergquist <zbergquist99@gmail.com>
Zach Bintliff <zbintliff@gmail.com>
Zach Gershman <zachgersh@gmail.com>
Zak <zrjknill@gmail.com>
Zakatell Kanda <hi@zkanda.io>
Zellyn Hunter <zellyn@gmail.com>
Zemanta d.o.o.
Zev Goldstein <zev.goldstein@gmail.com>
Zhongtao Chen <chenzhongtao@126.com>
Ziad Hatahet <hatahet@gmail.com>
Zorion Arrizabalaga <zorionk@gmail.com>
Максим Федосеев <max.faceless.frei@gmail.com>
Роман Хавроненко <hagen1778@gmail.com>
Тарас Буник <tbunyk@gmail.com>
Фахриддин Балтаев <faxriddinjon@gmail.com>
张嵩 <zs349596@gmail.com>
申习之 <bronze1man@gmail.com>

View file

@ -30,11 +30,6 @@ For change proposals, see [Proposing Changes To Go](https://github.com/golang/pr
Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) before sending patches.
**We do not accept GitHub pull requests**
(we use [an instance](https://go-review.googlesource.com/) of the
[Gerrit](https://www.gerritcodereview.com/) code review system instead).
Also, please do not post patches on the issue tracker.
Unless otherwise noted, the Go source files are distributed under
the BSD-style license found in the LICENSE file.

View file

@ -44,13 +44,18 @@ Adam Bender <abender@google.com>
Adam Eijdenberg <adam@continusec.com>
Adam Kisala <adam.kisala@gmail.com>
Adam Langley <agl@golang.org>
Adam Thomason <athomason@gmail.com>
Aditya Mukerjee <dev@chimeracoder.net>
Adrian Hesketh <adrianhesketh@hushmail.com>
Adrian Nos <nos.adrian@gmail.com>
Adrian O'Grady <elpollouk@gmail.com>
Adrien Bustany <adrien-xx-google@bustany.org>
Aécio Júnior <aeciodantasjunior@gmail.com>
Aeneas Rekkas (arekkas) <aeneas@ory.am>
Afanasev Stanislav <phpprogger@gmail.com>
Agis Anastasopoulos <agis.anast@gmail.com>
Ahmed Waheed Moanes <oneofone@gmail.com>
Agniva De Sarker <agnivade@yahoo.co.in>
Ahmed Wahed <oneofone@gmail.com>
Ahmet Alp Balkan <ahmetb@google.com>
Ahmy Yulrizka <yulrizka@gmail.com>
Aiden Scandella <ai@uber.com>
@ -90,6 +95,7 @@ Alexander Menzhinsky <amenzhinsky@gmail.com>
Alexander Morozov <lk4d4math@gmail.com>
Alexander Neumann <alexander@bumpern.de>
Alexander Orlov <alexander.orlov@loxal.net>
Alexander Pantyukhin <apantykhin@gmail.com>
Alexander Polcyn <apolcyn@google.com>
Alexander Reece <awreece@gmail.com>
Alexander Surma <surma@surmair.de>
@ -98,6 +104,7 @@ Alexander Zolotov <goldifit@gmail.com>
Alexandre Cesaro <alexandre.cesaro@gmail.com>
Alexandre Fiori <fiorix@gmail.com>
Alexandre Normand <alexandre.normand@gmail.com>
Alexandre Parentea <aubonbeurre@gmail.com>
Alexandru Moșoi <brtzsnr@gmail.com>
Alexei Sholik <alcosholik@gmail.com>
Alexey Borzenkov <snaury@gmail.com>
@ -110,8 +117,10 @@ Aliaksandr Valialkin <valyala@gmail.com>
Alif Rachmawadi <subosito@gmail.com>
Allan Simon <allan.simon@supinfo.com>
Alok Menghrajani <alok.menghrajani@gmail.com>
Aman Gupta <aman@tmm1.net>
Amir Mohammad Saied <amir@gluegadget.com>
Amrut Joshi <amrut.joshi@gmail.com>
Anand K. Mistry <anand@mistry.ninja>
Anders Pearson <anders@columbia.edu>
André Carvalho <asantostc@gmail.com>
Andre Nathan <andrenth@gmail.com>
@ -144,7 +153,10 @@ Andrew Wilkins <axwalk@gmail.com>
Andrew Williams <williams.andrew@gmail.com>
Andrey Mirtchovski <mirtchovski@gmail.com>
Andrey Petrov <andrey.petrov@shazow.net>
Andrii Soldatenko <andrii.soldatenko@gmail.com>
Andrii Soluk <isoluchok@gmail.com>
Andriy Lytvynov <lytvynov.a.v@gmail.com>
Andrzej Żeżel <andrii.zhezhel@gmail.com>
Andy Balholm <andy@balholm.com>
Andy Davis <andy@bigandian.com>
Andy Finkenstadt <afinkenstadt@zynga.com>
@ -155,9 +167,11 @@ Angelo Bulfone <mbulfone@gmail.com>
Anh Hai Trinh <anh.hai.trinh@gmail.com>
Anmol Sethi <anmol@aubble.com>
Anschel Schaffer-Cohen <anschelsc@gmail.com>
Anthony Alves <cvballa3g0@gmail.com>
Anthony Canino <anthony.canino1@gmail.com>
Anthony Eufemio <anthony.eufemio@gmail.com>
Anthony Martin <ality@pbrane.org>
Anthony Sottile <asottile@umich.edu>
Anthony Starks <ajstarks@gmail.com>
Anthony Voutas <voutasaurus@gmail.com>
Anthony Woods <awoods@raintank.io>
@ -168,6 +182,7 @@ Antonio Troina <thoeni@gmail.com>
Apisak Darakananda <pongad@gmail.com>
Aram Hăvărneanu <aram@mgk.ro>
Areski Belaid <areski@gmail.com>
Ariel Mashraki <ariel@mashraki.co.il>
Arkadi Pyuro <arkadi@google.com>
Arlo Breault <arlolra@gmail.com>
Arnaud Ysmal <arnaud.ysmal@gmail.com>
@ -185,6 +200,7 @@ Aulus Egnatius Varialus <varialus@gmail.com>
Austin Clements <austin@google.com> <aclements@csail.mit.edu>
awaw fumin <awawfumin@gmail.com>
Awn Umar <awn@cryptolosophy.io>
Axel Wagner <axel.wagner.hh@googlemail.com>
Ayanamist Yang <ayanamist@gmail.com>
Aymerick Jéhanne <aymerick@jehanne.org>
Baiju Muthukadan <baiju.m.mail@gmail.com>
@ -194,9 +210,12 @@ Bastian Ike <bastian.ike@gmail.com>
Ben Burkert <ben@benburkert.com>
Ben Eitzen <eitzenb@golang.org>
Ben Fried <ben.fried@gmail.com>
Ben Haines <bhainesva@gmail.com>
Ben Laurie <ben@links.org> <benl@google.com>
Ben Lubar <ben.lubar@gmail.com>
Ben Lynn <benlynn@gmail.com>
Ben Olive <sionide21@gmail.com>
Ben Schwartz <bemasc@google.com>
Ben Shi <powerman1st@163.com>
Benjamin Black <b@b3k.us>
Benjamin Prosnitz <bprosnitz@google.com>
@ -212,11 +231,15 @@ Billie Harold Cleek <bhcleek@gmail.com>
Billy Lynch <wlynch@google.com>
Bjorn Tillenius <bjorn@tillenius.me>
Bjorn Tipling <bjorn.tipling@gmail.com>
Blain Smith <rebelgeek@blainsmith.com>
Blake Gentry <blakesgentry@gmail.com>
Blake Mesdag <blakemesdag@gmail.com>
Blake Mizerany <blake.mizerany@gmail.com>
Blixt <me@blixt.nyc>
Bobby Powers <bobbypowers@gmail.com>
Boris Nagaev <nagaev@google.com>
Borja Clemente <borja.clemente@gmail.com>
Brad Burch <brad.burch@gmail.com>
Brad Fitzpatrick <bradfitz@golang.org> <bradfitz@gmail.com>
Brad Garcia <bgarcia@golang.org>
Brad Jones <rbjones@google.com>
@ -229,11 +252,13 @@ Brandon Gilmore <varz@google.com>
Brendan Daniel Tracey <tracey.brendan@gmail.com>
Brendan O'Dea <bod@golang.org>
Brett Cannon <bcannon@gmail.com>
Brett Merrill <brett.j.merrill94@gmail.com>
Brian Dellisanti <briandellisanti@gmail.com>
Brian Downs <brian.downs@gmail.com>
Brian G. Merrell <bgmerrell@gmail.com>
Brian Gitonga Marete <marete@toshnix.com> <bgmarete@gmail.com> <bgm@google.com>
Brian Kennedy <btkennedy@gmail.com>
Brian Kessler <brian.m.kessler@gmail.com>
Brian Ketelsen <bketelsen@gmail.com>
Brian Slesinsky <skybrian@google.com>
Brian Smith <ohohvi@gmail.com>
@ -243,6 +268,7 @@ Bryan C. Mills <bcmills@google.com>
Bryan Chan <bryan.chan@ca.ibm.com>
Bryan Ford <brynosaurus@gmail.com>
Bulat Gaifullin <gaifullinbf@gmail.com>
Burak Guven <bguven@gmail.com>
Caine Tighe <arctanofyourface@gmail.com>
Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Caleb Spare <cespare@gmail.com>
@ -266,11 +292,14 @@ Catalin Patulea <catalinp@google.com>
Cedric Staub <cs@squareup.com>
Cezar Sá Espinola <cezarsa@gmail.com>
ChaiShushan <chaishushan@gmail.com>
Charles Fenwick Elliott <Charles@FenwickElliott.io>
Charles L. Dorian <cldorian@gmail.com>
Charles Lee <zombie.fml@gmail.com>
Charles Weill <weill@google.com>
Cherry Zhang <cherryyz@google.com>
Chew Choon Keat <choonkeat@gmail.com>
Cholerae Hu <choleraehyq@gmail.com>
Chris Ball <chris@printf.net>
Chris Biscardi <chris@christopherbiscardi.com>
Chris Broadfoot <cbro@golang.org>
Chris Dollin <ehog.hedge@gmail.com>
@ -287,6 +316,7 @@ Chris Raynor <raynor@google.com>
Chris Roche <rodaine@gmail.com>
Chris Stockton <chrisstocktonaz@gmail.com>
Chris Zou <chriszou@ca.ibm.com>
Christian Alexander <christian@linux.com>
Christian Couder <chriscool@tuxfamily.org>
Christian Himpel <chressie@googlemail.com> <chressie@gmail.com>
Christine Hansmann <chhansmann@gmail.com>
@ -294,11 +324,14 @@ Christoffer Buchholz <christoffer.buchholz@gmail.com>
Christoph Hack <christoph@tux21b.org>
Christopher Cahoon <chris.cahoon@gmail.com>
Christopher Guiney <chris@guiney.net>
Christopher Henderson <chris@chenderson.org>
Christopher Koch <chrisko@google.com>
Christopher Nelson <nadiasvertex@gmail.com>
Christopher Nielsen <m4dh4tt3r@gmail.com>
Christopher Redden <christopher.redden@gmail.com>
Christopher Swenson <cswenson@google.com>
Christopher Wedgwood <cw@f00f.org>
Christos Zoulas <christos@zoulas.com> <zoulasc@gmail.com>
Christy Perez <christy@linux.vnet.ibm.com>
CL Sung <clsung@gmail.com> <cl_sung@htc.com>
Clement Skau <clementskau@gmail.com>
@ -341,6 +374,8 @@ Daniel Skinner <daniel@dasa.cc>
Daniel Speichert <daniel@speichert.pl>
Daniel Theophanes <kardianos@gmail.com>
Daniel Upton <daniel@floppy.co>
Daniela Petruzalek <daniela.petruzalek@gmail.com>
Danny Rosseau <daniel.rosseau@gmail.com>
Daria Kolistratova <daria.kolistratova@intel.com>
Darren Elwood <darren@textnode.com>
Datong Sun <dndx@idndx.com>
@ -379,6 +414,7 @@ David Thomas <davidthomas426@gmail.com>
David Titarenco <david.titarenco@gmail.com>
David Volquartz Lebech <david@lebech.info>
Davies Liu <davies.liu@gmail.com>
Davor Kapsa <davor.kapsa@gmail.com>
Dean Prichard <dean.prichard@gmail.com>
Deepak Jois <deepak.jois@gmail.com>
Denis Bernard <db047h@gmail.com>
@ -425,15 +461,19 @@ Dustin Sallings <dsallings@gmail.com>
Dustin Shields-Cloues <dcloues@gmail.com>
Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
Dylan Waits <dylan@waits.io>
Edan Bedrik <3d4nb3@gmail.com>
Eden Li <eden.li@gmail.com>
Edward Muller <edwardam@interlix.com>
Egon Elbre <egonelbre@gmail.com>
Ehren Kret <ehren.kret@gmail.com>
Eitan Adler <lists@eitanadler.com>
Eivind Uggedal <eivind@uggedal.com>
Elbert Fliek <efliek@gmail.com>
Elena Grahovac <elena@grahovac.me>
Elias Naur <elias.naur@gmail.com>
Elliot Morrison-Reed <elliotmr@gmail.com>
Emil Hessman <c.emil.hessman@gmail.com> <emil@hessman.se>
Emerson Lin <linyintor@gmail.com>
Emil Hessman <emil@hessman.se>
Emilien Kenler <hello@emilienkenler.com>
Emmanuel Odeke <emm.odeke@gmail.com> <odeke@ualberta.ca>
Eoghan Sherry <ejsherry@gmail.com>
@ -444,6 +484,7 @@ Eric Garrido <ekg@google.com>
Eric Koleda <ekoleda+devrel@google.com>
Eric Lagergren <ericscottlagergren@gmail.com>
Eric Milliken <emilliken@gmail.com>
Eric Rescorla <ekr@rtfm.com>
Eric Roshan-Eisner <eric.d.eisner@gmail.com>
Erik Aigner <aigner.erik@gmail.com>
Erik Dubbelboer <erik@dubbelboer.com>
@ -458,6 +499,7 @@ Euan Kemp <euank@euank.com>
Evan Broder <evan@stripe.com>
Evan Brown <evanbrown@google.com>
Evan Hicks <evan.hicks2@gmail.com>
Evan Jones <ej@evanjones.ca>
Evan Kroske <evankroske@google.com>
Evan Martin <evan.martin@gmail.com>
Evan Phoenix <evan@phx.io>
@ -481,7 +523,7 @@ Fedor Indutny <fedor@indutny.com>
Felipe Oliveira <felipeweb.programador@gmail.com>
Felix Geisendörfer <haimuiba@gmail.com>
Filip Gruszczyński <gruszczy@gmail.com>
Filippo Valsorda <filippo@cloudflare.com> <hi@filippo.io>
Filippo Valsorda <filippo@golang.org> <filippo@cloudflare.com> <hi@filippo.io>
Firmansyah Adiputra <frm.adiputra@gmail.com>
Florian Uekermann <florian@uekermann-online.de> <f1@uekermann-online.de>
Florian Weimer <fw@deneb.enyo.de>
@ -492,6 +534,8 @@ Francesc Campoy <campoy@golang.org>
Francisco Claude <fclaude@recoded.cl>
Francisco Rojas <francisco.rojas.gallegos@gmail.com>
Francisco Souza <franciscossouza@gmail.com>
Frank Somers <fsomers@arista.com>
Frederic Guillot <frederic.guillot@gmail.com>
Frederick Kelly Mayle III <frederickmayle@gmail.com>
Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com>
Fredrik Forsmo <fredrik.forsmo@gmail.com>
@ -504,6 +548,7 @@ Gabriel Aszalos <gabriel.aszalos@gmail.com>
Gabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com>
Gabriel Russell <gabriel.russell@gmail.com>
Gareth Paul Jones <gpj@foursquare.com>
Garret Kelly <gdk@google.com>
Garrick Evans <garrick@google.com>
Gary Burd <gary@beagledreams.com> <gary.burd@gmail.com>
Gary Elliott <garyelliott@google.com>
@ -511,6 +556,7 @@ Gaurish Sharma <contact@gaurishsharma.com>
Gautham Thambidorai <gautham.dorai@gmail.com>
Geert-Johan Riemer <gjr19912@gmail.com>
Gengliang Wang <ltnwgl@gmail.com>
Geoff Berry <gberry.qdt@qualcommdatacenter.com>
Geoffroy Lorieux <lorieux.g@gmail.com>
Georg Reinke <guelfey@gmail.com>
George Gkirtsou <ggirtsou@gmail.com>
@ -526,9 +572,12 @@ Glenn Lewis <gmlewis@google.com>
Gordon Klaus <gordon.klaus@gmail.com>
Graham King <graham4king@gmail.com>
Graham Miller <graham.miller@gmail.com>
Grant Griffiths <ggp493@gmail.com>
Greg Poirier <greg.istehbest@gmail.com>
Greg Ward <greg@gerg.ca>
Gregory Man <man.gregory@gmail.com>
Guilherme Garnier <guilherme.garnier@gmail.com>
Guilherme Rezende <guilhermebr@gmail.com>
Guillaume J. Charmes <guillaume@charmes.net>
Guobiao Mei <meiguobiao@gmail.com>
Gustav Paul <gustav.paul@gmail.com>
@ -542,6 +591,7 @@ Hajime Hoshi <hajimehoshi@gmail.com>
Hallgrimur Gunnarsson <halg@google.com>
Han-Wen Nienhuys <hanwen@google.com>
Hang Qian <hangqian90@gmail.com>
Hanjun Kim <hallazzang@gmail.com>
Hari haran <hariharan.uno@gmail.com>
Hariharan Srinath <srinathh@gmail.com>
Harley Laue <losinggeneration@gmail.com>
@ -554,9 +604,14 @@ Hector Martin Cantero <hector@marcansoft.com>
Henning Schmiedehausen <henning@schmiedehausen.org>
Henrik Edwards <henrik.edwards@gmail.com>
Henrik Hodne <henrik@hodne.io>
Henry Adi Sumarto <henry.adisumarto@gmail.com>
Henry Bubert <google@mindeco.de>
Henry Chang <mr.changyuheng@gmail.com>
Herbert Georg Fischer <herbert.fischer@gmail.com>
Herbie Ong <herbie@google.com>
Heschi Kreinick <heschi@google.com>
Hilko Bengen <bengen@hilluzination.de>
Hiroaki Nakamura <hnakamur@gmail.com>
Hironao OTSUBO <motemen@gmail.com>
Hiroshi Ioka <hirochachacha@gmail.com>
Hitoshi Mitake <mitake.hitoshi@gmail.com>
@ -570,6 +625,7 @@ Hu Keping <hukeping@huawei.com>
Hugues Bruant <hugues.bruant@gmail.com>
Hyang-Ah Hana Kim <hakim@google.com> <hyangah@gmail.com>
Ian Gudger <ian@loosescre.ws>
Ian Kent <iankent85@gmail.com>
Ian Lance Taylor <iant@golang.org>
Ibrahim AshShohail <ibra.sho@gmail.com>
Icarus Sparry <golang@icarus.freeuk.com>
@ -577,13 +633,17 @@ Iccha Sethi <icchasethi@gmail.com>
Idora Shinatose <idora.shinatose@gmail.com>
Igor Bernstein <igorbernstein@google.com>
Igor Dolzhikov <bluesriverz@gmail.com>
Igor Vashyst <ivashyst@gmail.com>
Ilya Tocar <ilya.tocar@intel.com>
INADA Naoki <songofacandy@gmail.com>
Inanc Gumus <m@inanc.io>
Ingo Krabbe <ikrabbe.ask@gmail.com>
Ingo Oeser <nightlyone@googlemail.com> <nightlyone@gmail.com>
Irieda Noboru <irieda@gmail.com>
Isaac Wagner <ibw@isaacwagner.me>
Iskander Sharipov <iskander.sharipov@intel.com> <quasilyte@gmail.com>
Ivan Babrou <ivan@cloudflare.com>
Ivan Bertona <ivan.bertona@gmail.com>
Ivan Krasin <krasin@golang.org>
Ivan Moscoso <moscoso@gmail.com>
Ivan Ukhov <ivan.ukhov@gmail.com>
@ -605,6 +665,7 @@ James David Chalfant <james.chalfant@gmail.com>
James Fysh <james.fysh@gmail.com>
James Gray <james@james4k.com>
James Hartig <fastest963@gmail.com>
James Lawrence <jljatone@gmail.com>
James Meneghello <rawrz0r@gmail.com>
James Myers <jfmyers9@gmail.com>
James Neve <jamesoneve@gmail.com>
@ -614,11 +675,13 @@ James Schofield <james@shoeboxapp.com>
James Smith <jrs1995@icloud.com>
James Sweet <james.sweet88@googlemail.com>
James Toy <nil@opensesame.st>
James Treanor <jtreanor3@gmail.com>
James Tucker <raggi@google.com>
James Whitehead <jnwhiteh@gmail.com>
Jamie Beverly <jamie.r.beverly@gmail.com>
Jamie Gennis <jgennis@google.com> <jgennis@gmail.com>
Jamie Kerr <jkerr113@googlemail.com>
Jamie Liu <jamieliu@google.com>
Jamie Stackhouse <contin673@gmail.com>
Jamie Turner <jamwt@dropbox.com>
Jamie Wilkinson <jaq@spacepants.org>
@ -630,6 +693,7 @@ Jan Mercl <0xjnml@gmail.com> <befelemepeseveze@gmail.com>
Jan Newmarch <jan.newmarch@gmail.com>
Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
Jani Monoses <jani.monoses@ubuntu.com> <jani.monoses@gmail.com>
Jared Culp <jculp14@gmail.com>
Jaroslavas Počepko <jp@webmaster.ms>
Jason Barnett <jason.w.barnett@gmail.com>
Jason Buberel <jbuberel@google.com>
@ -638,11 +702,15 @@ Jason Del Ponte <delpontej@gmail.com>
Jason Hall <jasonhall@google.com>
Jason Smale <jsmale@zendesk.com>
Jason Travis <infomaniac7@gmail.com>
Jason Wangsadinata <jwangsadinata@gmail.com>
Javier Segura <javism@gmail.com>
Jay Conrod <jayconrod@google.com>
Jay Weisskopf <jay@jayschwa.net>
Jean-Francois Cantin <jfcantin@gmail.com>
Jean-Marc Eurin <jmeurin@google.com>
Jean-Nicolas Moal <jn.moal@gmail.com>
Jed Denlea <jed@fastly.com>
Jeet Parekh <jeetparekh96@gmail.com>
Jeff (Zhefu) Jiang <jeffjiang@google.com>
Jeff Craig <jeffcraig@google.com>
Jeff Hodges <jeff@somethingsimilar.com>
@ -651,6 +719,7 @@ Jeff R. Allen <jra@nella.org> <jeff.allen@gmail.com>
Jeff Sickel <jas@corpus-callosum.com>
Jeff Wendling <jeff@spacemonkey.com>
Jeffrey H <jeffreyh192@gmail.com>
Jelte Fennema <github-tech@jeltef.nl>
Jens Frederich <jfrederich@gmail.com>
Jeremiah Harmsen <jeremiah@google.com>
Jeremy Jackins <jeremyjackins@gmail.com>
@ -664,12 +733,14 @@ Jihyun Yu <yjh0502@gmail.com>
Jim Cote <jfcote87@gmail.com>
Jim Kingdon <jim@bolt.me>
Jim McGrath <jimmc2@gmail.com>
Jimmy Frasche <soapboxcicero@gmail.com>
Jimmy Zelinskie <jimmyzelinskie@gmail.com>
Jin-wook Jeong <jeweljar@hanmail.net>
Jingcheng Zhang <diogin@gmail.com>
Jingguo Yao <yaojingguo@gmail.com>
Jiong Du <londevil@gmail.com>
Jirka Daněk <dnk@mail.muni.cz>
Jiulong Wang <jiulongw@gmail.com>
Joakim Sernbrant <serbaut@gmail.com>
Joe Farrell <joe2farrell@gmail.com>
Joe Harrison <joehazzers@gmail.com>
@ -734,10 +805,13 @@ Josh Holland <jrh@joshh.co.uk>
Josh Roppo <joshroppo@gmail.com>
Joshua Boelter <joshua.boelter@intel.com>
Joshua Chase <jcjoshuachase@gmail.com>
Joshua Rubin <joshua@rubixconsulting.com>
Josselin Costanzi <josselin@costanzi.fr>
Jostein Stuhaug <js@solidsystem.no>
JP Sugarbroad <jpsugar@google.com>
JT Olds <jtolds@xnet5.com>
Juan Carlos <juanjcsr@gmail.com>
Jude Pereira <judebpereira@gmail.com>
Jukka-Pekka Kekkonen <karatepekka@gmail.com>
Julia Hansbrough <flowerhack@google.com>
Julian Kornberger <jk+github@digineo.de>
@ -746,6 +820,7 @@ Julian Phillips <julian@quantumfyre.co.uk>
Julien Schmidt <google@julienschmidt.com>
Julio Montes <julio.montes@intel.com>
Jungho Ahn <jhahn@google.com>
Junya Hayashi <ledmonster@gmail.com>
Jure Ham <jure.ham@zemanta.com>
Justin Nuß <nuss.justin@gmail.com>
Justyn Temme <justyntemme@gmail.com>
@ -758,7 +833,9 @@ Kamil Chmielewski <kamil.chm@gmail.com>
Kamil Kisiel <kamil@kamilkisiel.net> <kamil.kisiel@gmail.com>
Kang Hu <hukangustc@gmail.com>
Karan Dhiman <karandhi@ca.ibm.com>
Karel Pazdera <pazderak@gmail.com>
Karoly Negyesi <chx1975@gmail.com>
Karsten Köhler <karsten.koehler95@gmail.com>
Kashav Madan <kshvmdn@gmail.com>
Kate Manson <kate.manson@izettle.com>
Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
@ -779,6 +856,7 @@ Ken Rockot <ken@oz.gs> <ken.rockot@gmail.com>
Ken Sedgwick <ken@bonsai.com>
Ken Thompson <ken@golang.org>
Kenji Kaneda <kenji.kaneda@gmail.com>
Kenji Yano <kenji.yano@gmail.com>
Kenneth Shaw <kenshaw@gmail.com>
Kenny Grant <kennygrant@gmail.com>
Kevin Ballard <kevin@sb.org>
@ -786,10 +864,13 @@ Kevin Burke <kev@inburke.com>
Kevin Kirsche <kev.kirsche@gmail.com>
Kevin Klues <klueska@gmail.com> <klueska@google.com>
Kevin Malachowski <chowski@google.com>
Kevin Ruffin <kruffin@gmail.com>
Kevin Vu <kevin.m.vu@gmail.com>
Kieran Colford <kieran@kcolford.com>
Kim Shrier <kshrier@racktopsystems.com>
Kim Yongbin <kybinz@gmail.com>
Kirill Smelkov <kirr@nexedi.com>
Kirk Han <kirk91.han@gmail.com>
Kirklin McDonald <kirklin.mcdonald@gmail.com>
Klaus Post <klauspost@gmail.com>
Kodie Goodwin <kodiegoodwin@gmail.com>
@ -801,31 +882,40 @@ Kris Nova <kris@nivenly.com>
Kris Rousey <krousey@google.com>
Kristopher Watts <traetox@gmail.com>
Kun Li <likunarmstrong@gmail.com>
Kunpei Sakai <namusyaka@gmail.com>
Kyle Consalus <consalus@gmail.com>
Kyle Isom <kyle@gokyle.net>
Kyle Jones <kyle@kyledj.com>
Kyle Lemons <kyle@kylelemons.net> <kevlar@google.com>
Kyle Shannon <kyle@pobox.com>
Kyohei Kadota <lufia@lufia.org>
Kyrylo Silin <silin@kyrylo.org>
L Campbell <unpantsu@gmail.com>
Lai Jiangshan <eag0628@gmail.com>
Lakshay Garg <lakshay.garg.1996@gmail.com>
Lann Martin <lannm@google.com>
Larry Hosken <lahosken@golang.org>
Lars Jeppesen <jeppesen.lars@gmail.com>
Lars Wiegman <lars@namsral.com>
Larz Conwell <larzconwell@gmail.com>
Laurent Voisin <lpvoisin@gmail.com>
Laurie Clark-Michalek <laurie@qubit.com>
LE Manh Cuong <cuong.manhle.vn@gmail.com>
Lee Hinman <hinman@gmail.com>
Lee Packham <lpackham@gmail.com>
Leigh McCulloch <leighmcc@gmail.com>
Leo Rudberg <ljr@google.com>
Leon Klingele <git@leonklingele.de>
Lev Shamardin <shamardin@gmail.com>
Lewin Bormann <lewin.bormann@gmail.com>
Lion Yang <lion@aosc.xyz>
Lloyd Dewolf <foolswisdom@gmail.com>
Lorenz Bauer <lmb@cloudflare.com>
Lorenzo Masini <rugginoso@develer.com>
Lorenzo Stoakes <lstoakes@gmail.com>
Louis Kruger <louisk@google.com>
Luan Santos <cfcluan@gmail.com>
Luca Bruno <luca.bruno@coreos.com>
Luca Greco <luca.greco@alcacoop.it>
Lucas Bremgartner <lucas.bremgartner@gmail.com>
Lucas Clemente <lclemente@google.com>
@ -837,15 +927,20 @@ Luit van Drongelen <luitvd@gmail.com>
Luka Zakrajšek <tr00.g33k@gmail.com>
Lukasz Milewski <lmmilewski@gmail.com>
Luke Curley <qpingu@gmail.com>
Luke Granger-Brown <git@lukegb.com>
Luna Duclos <luna.duclos@palmstonegames.com>
Luuk van Dijk <lvd@golang.org> <lvd@google.com>
Lyle Franklin <lylejfranklin@gmail.com>
Lynn Boger <laboger@linux.vnet.ibm.com>
Ma Peiqi <mapeiqi2017@gmail.com>
Magnus Hiie <magnus.hiie@gmail.com>
Maicon Costa <maiconscosta@gmail.com>
Maksym Trykur <maksym.trykur@gmail.com>
Mal Curtis <mal@mal.co.nz>
Manfred Touron <m@42.am>
Manish Goregaokar <manishsmail@gmail.com>
Manoj Dayaram <platform-dev@moovweb.com> <manoj.dayaram@moovweb.com>
Mansour Rahimi <rahimi.mnr@gmail.com>
Manu Garg <manugarg@google.com>
Manu S Ajith <neo@codingarena.in>
Manuel Mendez <mmendez534@gmail.com>
@ -861,9 +956,12 @@ Marius Nuennerich <mnu@google.com>
Mark Adams <mark@markadams.me>
Mark Bucciarelli <mkbucc@gmail.com>
Mark Harrison <marhar@google.com>
Mark Percival <m@mdp.im>
Mark Pulford <mark@kyne.com.au>
Mark Ryan <mark.d.ryan@intel.com>
Mark Severson <miquella@gmail.com>
Mark Theunissen <mark.theunissen@gmail.com>
Mark Wolfe <mark@wolfe.id.au>
Mark Zavislak <zavislak@google.com>
Marko Juhani Silokunnas <marko.silokunnas@gmail.com>
Marko Mikulicic <mkm@google.com>
@ -884,6 +982,7 @@ Martin Neubauer <m.ne@gmx.net>
Martin Olsen <github.com@martinolsen.net>
Martin Olsson <martin@minimum.se>
Martin Probst <martin@probst.io>
Martins Sipenko <martins.sipenko@gmail.com>
Martynas Budriūnas <mabu@google.com>
Marvin Stenger <marvin.stenger94@gmail.com>
Marwan Sulaiman <marwan.sulaiman@work.co>
@ -891,7 +990,10 @@ Maryan Hratson <gmarik@gmail.com>
Masahiro Furudate <masahiro.furudate@gmail.com>
Masahiro Wakame <vvakame@gmail.com>
Masaki Yoshida <yoshida.masaki@gmail.com>
Mat Byczkowski <mbyczkowski@gmail.com>
Máté Gulyás <mgulyas86@gmail.com>
Matej Baćo <matejbaco@gmail.com>
Mateus Amin <mateus.amin@gmail.com>
Mateusz Czapliński <czapkofan@gmail.com>
Mathias Beke <git@denbeke.be>
Mathias Hall-Andersen <mathias@hall-andersen.dk>
@ -902,6 +1004,7 @@ Matt Aimonetti <mattaimonetti@gmail.com>
Matt Blair <me@matthewblair.net>
Matt Bostock <matt@mattbostock.com>
Matt Brown <mdbrown@google.com>
Matt Dee <mdee@hioscar.com>
Matt Drollette <matt@drollette.com>
Matt Harden <matt.harden@gmail.com>
Matt Jibson <matt.jibson@gmail.com>
@ -914,6 +1017,7 @@ Matt Strong <mstrong1341@gmail.com>
Matt T. Proud <matt.proud@gmail.com>
Matt Williams <gh@mattyw.net> <mattyjwilliams@gmail.com>
Matthew Brennan <matty.brennan@gmail.com>
Matthew Broberg <matthewbbroberg@gmail.com>
Matthew Cottingham <mattcottingham@gmail.com>
Matthew Dempsky <mdempsky@google.com>
Matthew Denton <mdenton@skyportsystems.com>
@ -921,17 +1025,21 @@ Matthew Holt <Matthew.Holt+git@gmail.com>
Matthew Horsnell <matthew.horsnell@gmail.com>
Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
Matthieu Olivier <olivier.matthieu@gmail.com>
Matthijs Kooijman <matthijs@stdin.nl>
Max Riveiro <kavu13@gmail.com>
Max Schmitt <max@schmitt.mx>
Maxim Khitrov <max@mxcrypt.com>
Maxim Pimenov <mpimenov@google.com>
Maxim Ushakov <ushakov@google.com>
Maxime de Roucy <maxime.deroucy@gmail.com>
Máximo Cuadros Ortiz <mcuadros@gmail.com>
Maxwell Krohn <themax@gmail.com>
Mayank Kumar <krmayankk@gmail.com>
Meir Fischer <meirfischer@gmail.com>
Meng Zhuo <mengzhuo1203@gmail.com>
Mhd Sulhan <m.shulhan@gmail.com>
Micah Stetson <micah.stetson@gmail.com>
Michael Brandenburg <mbrandenburg@bolste.com>
Michael Chaten <mchaten@gmail.com>
Michael Darakananda <pongad@google.com>
Michael Edwards <medwards@walledcity.ca>
@ -949,25 +1057,30 @@ Michael Marineau <michael.marineau@coreos.com>
Michael Matloob <matloob@google.com>
Michael McConville <momcconville@gmail.com>
Michael McGreevy <mcgreevy@golang.org>
Michael McLoughlin <mmcloughlin@gmail.com>
Michael Munday <munday@ca.ibm.com>
Michael Pearson <mipearson@gmail.com>
Michael Piatek <piatek@google.com>
Michael Pratt <mpratt@google.com>
Michael Schaller <michael@5challer.de>
Michael Schurter <michael.schurter@gmail.com>
Michael Shields <mshields@google.com>
Michael Stapelberg <michael@stapelberg.de> <mstplbrg@googlemail.com>
Michael Steinert <mike.steinert@gmail.com>
Michael T. Jones <mtj@google.com> <michael.jones@gmail.com>
Michael Teichgräber <mteichgraeber@gmx.de> <mt4swm@googlemail.com>
Michael Vetter <g.bluehut@gmail.com>
Michal Bohuslávek <mbohuslavek@gmail.com>
Michal Cierniak <cierniak@google.com>
Michał Derkacz <ziutek@lnet.pl>
Michal Pristas <michal.pristas@gmail.com>
Michalis Kargakis <michaliskargakis@gmail.com>
Michel Lespinasse <walken@google.com>
Miek Gieben <miek@miek.nl> <remigius.gieben@gmail.com>
Miguel Mendez <stxmendez@gmail.com>
Miguel Molina <hi@mvader.me>
Mihai Borobocea <MihaiBorobocea@gmail.com>
Mihail Minaev <minaev.mike@gmail.com>
Mikael Tillenius <mikti42@gmail.com>
Mike Andrews <mra@xoba.com>
Mike Appleby <mike@app.leby.org>
@ -995,9 +1108,11 @@ Morten Siebuhr <sbhr@sbhr.dk>
Môshe van der Sterre <moshevds@gmail.com>
Mostyn Bramley-Moore <mostyn@antipode.se>
Mrunal Patel <mrunalp@gmail.com>
Muhammad Falak R Wani <falakreyaz@gmail.com>
Muhammed Uluyol <uluyol0@gmail.com>
Mura Li <mura_li@castech.com.tw>
Nan Deng <monnand@gmail.com>
Naoki Kanatani <k12naoki@gmail.com>
Nathan Caza <mastercactapus@gmail.com>
Nathan Humphreys <nkhumphreys@gmail.com>
Nathan John Youngman <nj@nathany.com>
@ -1027,6 +1142,7 @@ Nick Miyake <nmiyake@users.noreply.github.com>
Nick Patavalis <nick.patavalis@gmail.com>
Nick Petroni <npetroni@cs.umd.edu>
Nick Robinson <nrobinson13@gmail.com>
Nicolas BRULEZ <n.brulez@gmail.com>
Nicolas Kaiser <nikai@nikai.net>
Nicolas Owens <mischief@offblast.org>
Nicolas S. Dade <nic.dade@gmail.com>
@ -1037,8 +1153,10 @@ Nik Nyby <nnyby@columbia.edu>
Niklas Schnelle <niklas.schnelle@gmail.com>
Niko Dziemba <niko@dziemba.com>
Nikolay Turpitko <nikolay@turpitko.com>
Nils Larsgård <nilsmagnus@gmail.com>
Niranjan Godbole <niranjan8192@gmail.com>
Noah Campbell <noahcampbell@gmail.com>
Noble Johnson <noblepoly@gmail.com>
Nodir Turakulov <nodir@google.com>
Norberto Lopes <nlopes.ml@gmail.com>
Odin Ugedal <odin@ugedal.com>
@ -1073,6 +1191,7 @@ Patrick Riley <pfr@google.com>
Patrick Smith <pat42smith@gmail.com>
Paul A Querna <paul.querna@gmail.com>
Paul Borman <borman@google.com>
Paul Boyd <boyd.paul2@gmail.com>
Paul Chang <paulchang@google.com>
Paul Hammond <paul@paulhammond.org>
Paul Hankin <paulhankin@google.com>
@ -1081,8 +1200,10 @@ Paul Lalonde <paul.a.lalonde@gmail.com>
Paul Marks <pmarks@google.com>
Paul Meyer <paul.meyer@microsoft.com>
Paul Nasrat <pnasrat@google.com>
Paul PISCUC <paul.piscuc@gmail.com>
Paul Querna <pquerna@apache.org>
Paul Rosania <paul.rosania@gmail.com>
Paul Ruest <pruest@gmail.com>
Paul Sbarra <Sbarra.Paul@gmail.com>
Paul Smith <paulsmith@pobox.com> <paulsmith@gmail.com>
Paul van Brouwershaven <paul@vanbrouwershaven.com>
@ -1116,6 +1237,8 @@ Peter Waldschmidt <peter@waldschmidt.com>
Peter Waller <peter.waller@gmail.com>
Peter Weinberger <pjw@golang.org>
Peter Williams <pwil3058@gmail.com>
Peter Wu <pwu@cloudflare.com>
Petrica Voicu <pvoicu@paypal.com>
Phil Pennock <pdp@golang.org>
Philip Børgesen <philip.borgesen@gmail.com>
Philip Hofer <phofer@umich.edu>
@ -1125,6 +1248,7 @@ Pierre Roullon <pierre.roullon@gmail.com>
Piers <google@hellopiers.pro>
Pieter Droogendijk <pieter@binky.org.uk>
Pietro Gagliardi <pietro10@mac.com>
Pontus Leitzler <leitzler@gmail.com>
Prasanna Swaminathan <prasanna@mediamath.com>
Prashant Varanasi <prashant@prashantv.com>
Pravendra Singh <hackpravj@gmail.com>
@ -1137,19 +1261,25 @@ Quentin Renard <contact@asticode.com>
Quentin Smith <quentin@golang.org>
Quinn Slack <sqs@sourcegraph.com>
Quoc-Viet Nguyen <afelion@gmail.com>
Radek Sohlich <sohlich@gmail.com>
Radu Berinde <radu@cockroachlabs.com>
Rafal Jeczalik <rjeczalik@gmail.com>
Rahul Chaudhry <rahulchaudhry@chromium.org>
Raif S. Naffah <go@naffah-raif.name>
Rajat Goel <rajat.goel2010@gmail.com>
Rajath Agasthya <rajathagasthya@gmail.com>
Rajender Reddy Kompally <rajenderreddykompally@gmail.com>
Ralph Corderoy <ralph@inputplus.co.uk>
Ramazan AYYILDIZ <rayyildiz@gmail.com>
Ramesh Dharan <dharan@google.com>
Raph Levien <raph@google.com>
Raphael Geronimi <raphael.geronimi@gmail.com>
Raul Silvera <rsilvera@google.com>
RaviTeja Pothana <ravi.tezu@gmail.com>
Ray Tung <rtung@thoughtworks.com>
Raymond Kazlauskas <raima220@gmail.com>
Rebecca Stambler <rstambler@golang.org>
Reilly Watson <reillywatson@gmail.com>
Reinaldo de Souza Jr <juniorz@gmail.com>
Remi Gillig <remigillig@gmail.com>
Rémy Oudompheng <oudomphe@phare.normalesup.org> <remyoudompheng@gmail.com>
@ -1187,10 +1317,13 @@ Rodrigo Rafael Monti Kochenburger <divoxx@gmail.com>
Roger Pau Monné <royger@gmail.com>
Roger Peppe <rogpeppe@gmail.com>
Roland Shoemaker <rolandshoemaker@gmail.com>
Roman Budnikov <romanyx90@yandex.ru>
Ron Hashimoto <mail@h2so5.net>
Ron Minnich <rminnich@gmail.com>
Ross Chater <rdchater@gmail.com>
Ross Light <light@google.com> <rlight2@gmail.com>
Rowan Worth <sqweek@gmail.com>
Rudi Kramer <rudi.kramer@gmail.com>
Rui Ueyama <ruiu@google.com>
Russ Cox <rsc@golang.org>
Russell Haering <russellhaering@gmail.com>
@ -1202,6 +1335,8 @@ Ryan Hitchman <hitchmanr@gmail.com>
Ryan Lower <rpjlower@gmail.com>
Ryan Seys <ryan@ryanseys.com>
Ryan Slade <ryanslade@gmail.com>
Ryoichi KATO <ryo1kato@gmail.com>
Ryuji Iwata <qt.luigi@gmail.com>
Ryuzo Yamamoto <ryuzo.yamamoto@gmail.com>
S.Çağlar Onur <caglar@10ur.org>
Sai Cheemalapati <saicheems@google.com>
@ -1223,6 +1358,7 @@ Sasha Lionheart <lionhearts@google.com>
Sasha Sobol <sasha@scaledinference.com>
Scott Barron <scott.barron@github.com>
Scott Bell <scott@sctsm.com>
Scott Crunkleton <crunk1@gmail.com>
Scott Ferguson <scottwferg@gmail.com>
Scott Lawrence <bytbox@gmail.com>
Scott Mansfield <smansfield@netflix.com>
@ -1236,11 +1372,15 @@ Sean Harger <sharger@google.com>
Sean Rees <sean@erifax.org>
Sebastien Binet <seb.binet@gmail.com>
Sébastien Paolacci <sebastien.paolacci@gmail.com>
Seiji Takahashi <timaki.st@gmail.com>
Sergei Skorobogatov <skorobo@rambler.ru>
Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
Sergey Arseev <sergey.arseev@intel.com>
Sergey Frolov <sfrolov@google.com>
Sergey Mishin <sergeymishine@gmail.com>
Sergey Semin <gray12511@gmail.com>
Sergio Luis O. B. Correia <sergio@correia.cc>
Sergiusz Bazanski <bazanski@gmail.com>
Seth Hoenig <seth.a.hoenig@gmail.com>
Seth Vargo <sethvargo@gmail.com>
Shahar Kohanim <skohanim@gmail.com>
@ -1270,6 +1410,7 @@ Srdjan Petrovic <spetrovic@google.com>
Sridhar Venkatakrishnan <sridhar@laddoo.net>
StalkR <stalkr@stalkr.net>
Stan Schwertly <stan@schwertly.com>
Stanislav Afanasev <php.progger@gmail.com>
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
Stéphane Travostino <stephane.travostino@gmail.com>
Stephen Ma <stephenm@golang.org>
@ -1277,6 +1418,7 @@ Stephen McQuay <stephen@mcquay.me>
Stephen Searles <stephens2424@gmail.com>
Stephen Weinberg <stephen@q5comm.com>
Steve Francia <spf@golang.org>
Steve Gilbert <stevegilbert23@gmail.com>
Steve McCoy <mccoyst@gmail.com>
Steve Newman <snewman@google.com>
Steve Phillips <elimisteve@gmail.com>
@ -1288,13 +1430,16 @@ Steven Hartland <steven.hartland@multiplay.co.uk>
Steven Wilkin <stevenwilkin@gmail.com>
Sugu Sougoumarane <ssougou@gmail.com>
Suharsh Sivakumar <suharshs@google.com>
Sukrit Handa <sukrit.handa@utoronto.ca>
Sunny <me@darkowlzz.space>
Suyash <dextrous93@gmail.com>
Suzy Mueller <suzmue@golang.org>
Sven Almgren <sven@tras.se>
Sven Blumenstein <svbl@google.com>
Sylvain Zimmer <sylvain@sylvainzimmer.com>
Syohei YOSHIDA <syohex@gmail.com>
Szabolcs Nagy <nsz@port70.net>
Tad Fisher <tadfisher@gmail.com>
Tad Glines <tad.glines@gmail.com>
Taj Khattra <taj.khattra@gmail.com>
Takashi Matsuo <tmatsuo@google.com>
@ -1303,15 +1448,18 @@ Takuto Ikuta <tikuta@google.com>
Takuya Ueda <uedatakuya@gmail.com>
Tal Shprecher <tshprecher@gmail.com>
Tamir Duberstein <tamird@gmail.com>
Tao Wang <twang2218@gmail.com>
Tarmigan Casebolt <tarmigan@gmail.com>
Taro Aoki <aizu.s1230022@gmail.com>
Taru Karttunen <taruti@taruti.net>
Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Ted Kornish <golang@tedkornish.com>
Terin Stock <terinjokes@gmail.com>
Terrel Shumway <gopher@shumway.us>
Tetsuo Kiso <tetsuokiso9@gmail.com>
Than McIntosh <thanm@google.com>
Thanatat Tamtan <acoshift@gmail.com>
Thiago Avelino <t@avelino.xxx>
Thiago Fransosi Farina <thiago.farina@gmail.com> <tfarina@chromium.org>
Thomas Alan Copeland <talan.copeland@gmail.com>
Thomas Bonfort <thomas.bonfort@gmail.com>
@ -1320,19 +1468,23 @@ Thomas de Zeeuw <thomasdezeeuw@gmail.com>
Thomas Desrosiers <thomasdesr@gmail.com>
Thomas Habets <habets@google.com>
Thomas Kappler <tkappler@gmail.com>
Thomas Wanielista <tomwans@gmail.com>
Thorben Krueger <thorben.krueger@gmail.com>
Thordur Bjornsson <thorduri@secnorth.net>
Tilman Dilo <tilman.dilo@gmail.com>
Tim Cooijmans <timcooijmans@gmail.com>
Tim Cooper <tim.cooper@layeh.com>
Tim Ebringer <tim.ebringer@gmail.com>
Tim Heckman <t@heckman.io>
Tim Henderson <tim.tadh@gmail.com>
Tim Hockin <thockin@google.com>
Tim Swast <swast@google.com>
Tim Wright <tenortim@gmail.com>
Timo Savola <timo.savola@gmail.com>
Timo Truyts <alkaloid.btx@gmail.com>
Timothy Studd <tim@timstudd.com>
Tipp Moseley <tipp@google.com>
Tobias Assarsson <tobias.assarsson@gmail.com>
Tobias Columbus <tobias.columbus@gmail.com> <tobias.columbus@googlemail.com>
Tobias Klauser <tklauser@distanz.ch>
Toby Burress <kurin@google.com>
@ -1340,6 +1492,8 @@ Todd Neal <todd@tneal.org>
Todd Wang <toddwang@gmail.com>
Tom Bergan <tombergan@google.com>
Tom Heng <zhm20070928@gmail.com>
Tom Lanyon <tomlanyon@google.com>
Tom Levy <tomlevy93@gmail.com>
Tom Linford <tomlinford@gmail.com>
Tom Szymanski <tgs@google.com>
Tom Wilkie <tom@weave.works>
@ -1358,9 +1512,12 @@ Trey Tacon <ttacon@gmail.com>
Tristan Amini <tamini01@ca.ibm.com>
Tristan Colgate <tcolgate@gmail.com>
Tristan Ooohry <ooohry@gmail.com>
Troels Thomsen <troels@thomsen.io>
Trung Nguyen <trung.n.k@gmail.com>
Tudor Golubenco <tudor.g@gmail.com>
Tugdual Saunier <tugdual.saunier@gmail.com>
Tuo Shan <sturbo89@gmail.com> <shantuo@google.com>
Tyler Bui-Palsulich <tpalsulich@google.com>
Tyler Bunnell <tylerbunnell@gmail.com>
Tyler Treat <ttreat31@gmail.com>
Tzu-Jung Lee <roylee17@currant.com>
@ -1393,10 +1550,13 @@ Wade Simmons <wade@wades.im>
Walter Poupore <wpoupore@google.com>
Wander Lairson Costa <wcosta@mozilla.com>
Wedson Almeida Filho <wedsonaf@google.com>
Wèi Cōngruì <crvv.mail@gmail.com>
Wei Guangjing <vcc.163@gmail.com>
Wei Xiao <wei.xiao@arm.com>
Weichao Tang <tevic.tt@gmail.com>
Wembley G. Leach, Jr <wembley.gl@gmail.com>
Will Chan <willchan@google.com>
Will Faught <will.faught@gmail.com>
Will Norris <willnorris@google.com>
Will Storey <will@summercat.com>
Willem van der Schyff <willemvds@gmail.com>
@ -1405,6 +1565,7 @@ William Josephson <wjosephson@gmail.com>
William Orr <will@worrbase.com> <ay1244@gmail.com>
Wisdom Omuya <deafgoat@gmail.com>
Wu Yunzhou <yunzhouwu@gmail.com>
Xi Ruoyao <xry23333@gmail.com>
Xia Bin <snyh@snyh.org>
Xing Xing <mikespook@gmail.com>
Xu Fei <badgangkiller@gmail.com>
@ -1412,6 +1573,7 @@ Xudong Zhang <felixmelon@gmail.com>
Xuyang Kang <xuyangkang@gmail.com>
Yan Zou <yzou@google.com>
Yann Kerhervé <yann.kerherve@gmail.com>
Yann Salaün <yannsalaun1@gmail.com>
Yao Zhang <lunaria21@gmail.com>
Yasha Bubnov <girokompass@gmail.com>
Yasuharu Goto <matope.ono@gmail.com>
@ -1423,23 +1585,30 @@ Yo-An Lin <yoanlin93@gmail.com>
Yongjian Xu <i3dmaster@gmail.com>
Yorman Arias <cixtords@gmail.com>
Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp>
Yosuke Akatsuka <yosuke.akatsuka@gmail.com>
Yu Heng Zhang <annita.zhang@cn.ibm.com>
Yu Xuan Zhang <zyxsh@cn.ibm.com>
Yuki Yugui Sonoda <yugui@google.com>
Yukihiro Nishinaka <6elpinal@gmail.com>
Yusuke Kagiwada <block.rxckin.beats@gmail.com>
Yuusei Kuwana <kuwana@kumama.org>
Yuval Pavel Zholkover <paulzhol@gmail.com>
Yves Junqueira <yvesj@google.com> <yves.junqueira@gmail.com>
Zac Bergquist <zbergquist99@gmail.com>
Zach Bintliff <zbintliff@gmail.com>
Zach Gershman <zachgersh@gmail.com>
Zak <zrjknill@gmail.com>
Zakatell Kanda <hi@zkanda.io>
Zellyn Hunter <zellyn@squareup.com> <zellyn@gmail.com>
Zev Goldstein <zev.goldstein@gmail.com>
Zhengyu He <hzy@google.com>
Zhongtao Chen <chenzhongtao@126.com>
Zhongwei Yao <zhongwei.yao@arm.com>
Ziad Hatahet <hatahet@gmail.com>
Zorion Arrizabalaga <zorionk@gmail.com>
Максим Федосеев <max.faceless.frei@gmail.com>
Роман Хавроненко <hagen1778@gmail.com>
Тарас Буник <tbunyk@gmail.com>
Фахриддин Балтаев <faxriddinjon@gmail.com>
张嵩 <zs349596@gmail.com>
申习之 <bronze1man@gmail.com>

View file

@ -31,15 +31,14 @@ in your web browser for source installation instructions.
### Contributing
Go is the work of hundreds of contributors. We appreciate your help!
Go is the work of thousands of contributors. We appreciate your help!
To contribute, please read the contribution guidelines:
https://golang.org/doc/contribute.html
Note that the Go project does not use GitHub pull requests, and that
we use the issue tracker for bug reports and proposals only. See
https://golang.org/wiki/Questions for a list of places to ask
questions about the Go language.
Note that the Go project uses the issue tracker for bug reports and
proposals only. See https://golang.org/wiki/Questions for a list of
places to ask questions about the Go language.
[rf]: https://reneefrench.blogspot.com/
[cc3-by]: https://creativecommons.org/licenses/by/3.0/

View file

@ -11,4 +11,3 @@ compatibility.
next.txt is the only file intended to be mutated. It's a list of
features that may be added to the next version. It only affects
warning output from the go api tool.

View file

@ -2,6 +2,7 @@ pkg encoding/json, method (*RawMessage) MarshalJSON() ([]uint8, error)
pkg math/big, const MaxBase = 36
pkg math/big, type Word uintptr
pkg net, func ListenUnixgram(string, *UnixAddr) (*UDPConn, error)
pkg os, const ModeType = 2399141888
pkg os (linux-arm), const O_SYNC = 4096
pkg os (linux-arm-cgo), const O_SYNC = 4096
pkg syscall (darwin-386), const ImplementsGetwd = false
@ -15,25 +16,30 @@ pkg syscall (darwin-amd64-cgo), func Fchflags(string, int) error
pkg syscall (freebsd-386), const AF_MAX = 38
pkg syscall (freebsd-386), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-386), const ELAST = 94
pkg syscall (freebsd-386), const ImplementsGetwd = false
pkg syscall (freebsd-386), const O_CLOEXEC = 0
pkg syscall (freebsd-386), func Fchflags(string, int) error
pkg syscall (freebsd-386-cgo), const AF_MAX = 38
pkg syscall (freebsd-386-cgo), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-386-cgo), const ELAST = 94
pkg syscall (freebsd-386-cgo), const ImplementsGetwd = false
pkg syscall (freebsd-386-cgo), const O_CLOEXEC = 0
pkg syscall (freebsd-amd64), const AF_MAX = 38
pkg syscall (freebsd-amd64), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-amd64), const ELAST = 94
pkg syscall (freebsd-amd64), const ImplementsGetwd = false
pkg syscall (freebsd-amd64), const O_CLOEXEC = 0
pkg syscall (freebsd-amd64), func Fchflags(string, int) error
pkg syscall (freebsd-amd64-cgo), const AF_MAX = 38
pkg syscall (freebsd-amd64-cgo), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-amd64-cgo), const ELAST = 94
pkg syscall (freebsd-amd64-cgo), const ImplementsGetwd = false
pkg syscall (freebsd-amd64-cgo), const O_CLOEXEC = 0
pkg syscall (freebsd-arm), const AF_MAX = 38
pkg syscall (freebsd-arm), const BIOCGRTIMEOUT = 1074545262
pkg syscall (freebsd-arm), const BIOCSRTIMEOUT = 2148287085
pkg syscall (freebsd-arm), const ELAST = 94
pkg syscall (freebsd-arm), const ImplementsGetwd = false
pkg syscall (freebsd-arm), const O_CLOEXEC = 0
pkg syscall (freebsd-arm), const SIOCAIFADDR = 2151967019
pkg syscall (freebsd-arm), const SIOCGIFSTATUS = 3274991931
@ -65,6 +71,7 @@ pkg syscall (freebsd-arm-cgo), const AF_MAX = 38
pkg syscall (freebsd-arm-cgo), const BIOCGRTIMEOUT = 1074545262
pkg syscall (freebsd-arm-cgo), const BIOCSRTIMEOUT = 2148287085
pkg syscall (freebsd-arm-cgo), const ELAST = 94
pkg syscall (freebsd-arm-cgo), const ImplementsGetwd = false
pkg syscall (freebsd-arm-cgo), const O_CLOEXEC = 0
pkg syscall (freebsd-arm-cgo), const SIOCAIFADDR = 2151967019
pkg syscall (freebsd-arm-cgo), const SIOCGIFSTATUS = 3274991931
@ -98,6 +105,12 @@ pkg syscall (linux-amd64), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (linux-amd64-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (linux-arm), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (linux-arm-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (netbsd-386), const ImplementsGetwd = false
pkg syscall (netbsd-386-cgo), const ImplementsGetwd = false
pkg syscall (netbsd-amd64), const ImplementsGetwd = false
pkg syscall (netbsd-amd64-cgo), const ImplementsGetwd = false
pkg syscall (netbsd-arm), const ImplementsGetwd = false
pkg syscall (netbsd-arm-cgo), const ImplementsGetwd = false
pkg syscall (netbsd-arm), const SizeofIfData = 132
pkg syscall (netbsd-arm), func Fchflags(string, int) error
pkg syscall (netbsd-arm), type IfMsghdr struct, Pad_cgo_1 [4]uint8
@ -106,6 +119,7 @@ pkg syscall (netbsd-arm-cgo), func Fchflags(string, int) error
pkg syscall (netbsd-arm-cgo), type IfMsghdr struct, Pad_cgo_1 [4]uint8
pkg syscall (openbsd-386), const BIOCGRTIMEOUT = 1074283118
pkg syscall (openbsd-386), const BIOCSRTIMEOUT = 2148024941
pkg syscall (openbsd-386), const ImplementsGetwd = false
pkg syscall (openbsd-386), const RTF_FMASK = 63496
pkg syscall (openbsd-386), const RTM_VERSION = 4
pkg syscall (openbsd-386), const SIOCBRDGDADDR = 2150132039
@ -158,6 +172,7 @@ pkg syscall (openbsd-386), type Timespec struct, Sec int32
pkg syscall (openbsd-386), type Timeval struct, Sec int32
pkg syscall (openbsd-386-cgo), const BIOCGRTIMEOUT = 1074283118
pkg syscall (openbsd-386-cgo), const BIOCSRTIMEOUT = 2148024941
pkg syscall (openbsd-386-cgo), const ImplementsGetwd = false
pkg syscall (openbsd-386-cgo), const RTF_FMASK = 63496
pkg syscall (openbsd-386-cgo), const RTM_VERSION = 4
pkg syscall (openbsd-386-cgo), const SIOCBRDGDADDR = 2150132039
@ -220,6 +235,7 @@ pkg syscall (openbsd-amd64), const EFER_NXE = 2048
pkg syscall (openbsd-amd64), const EFER_NXE ideal-int
pkg syscall (openbsd-amd64), const EFER_SCE = 1
pkg syscall (openbsd-amd64), const EFER_SCE ideal-int
pkg syscall (openbsd-amd64), const ImplementsGetwd = false
pkg syscall (openbsd-amd64), const PMC5_PIPELINE_FLUSH = 21
pkg syscall (openbsd-amd64), const PMC5_PIPELINE_FLUSH ideal-int
pkg syscall (openbsd-amd64), const RTF_FMASK = 63496
@ -282,6 +298,7 @@ pkg syscall (openbsd-amd64-cgo), const EFER_NXE = 2048
pkg syscall (openbsd-amd64-cgo), const EFER_NXE ideal-int
pkg syscall (openbsd-amd64-cgo), const EFER_SCE = 1
pkg syscall (openbsd-amd64-cgo), const EFER_SCE ideal-int
pkg syscall (openbsd-amd64-cgo), const ImplementsGetwd = false
pkg syscall (openbsd-amd64-cgo), const PMC5_PIPELINE_FLUSH = 21
pkg syscall (openbsd-amd64-cgo), const PMC5_PIPELINE_FLUSH ideal-int
pkg syscall (openbsd-amd64-cgo), const RTF_FMASK = 63496
@ -345,3 +362,24 @@ pkg syscall (openbsd-386-cgo), const SYS_KILL = 37
pkg syscall (openbsd-amd64), const SYS_KILL = 37
pkg syscall (openbsd-amd64-cgo), const SYS_KILL = 37
pkg unicode, const Version = "9.0.0"
pkg text/template/parse, method (*VariableNode) Copy() Node
pkg text/template/parse, method (*VariableNode) String() string
pkg text/template/parse, method (VariableNode) Position() Pos
pkg text/template/parse, method (VariableNode) Type() NodeType
pkg text/template/parse, type PipeNode struct, Decl []*VariableNode
pkg text/template/parse, type VariableNode struct
pkg text/template/parse, type VariableNode struct, Ident []string
pkg text/template/parse, type VariableNode struct, embedded NodeType
pkg text/template/parse, type VariableNode struct, embedded Pos
pkg syscall (windows-386), type CertChainPolicyPara struct, ExtraPolicyPara uintptr
pkg syscall (windows-386), type CertChainPolicyStatus struct, ExtraPolicyStatus uintptr
pkg syscall (windows-386), type CertContext struct, CertInfo uintptr
pkg syscall (windows-386), type CertRevocationInfo struct, CrlInfo uintptr
pkg syscall (windows-386), type CertRevocationInfo struct, OidSpecificInfo uintptr
pkg syscall (windows-386), type CertSimpleChain struct, TrustListInfo uintptr
pkg syscall (windows-amd64), type CertChainPolicyPara struct, ExtraPolicyPara uintptr
pkg syscall (windows-amd64), type CertChainPolicyStatus struct, ExtraPolicyStatus uintptr
pkg syscall (windows-amd64), type CertContext struct, CertInfo uintptr
pkg syscall (windows-amd64), type CertRevocationInfo struct, CrlInfo uintptr
pkg syscall (windows-amd64), type CertRevocationInfo struct, OidSpecificInfo uintptr
pkg syscall (windows-amd64), type CertSimpleChain struct, TrustListInfo uintptr

View file

@ -573,6 +573,7 @@ pkg encoding/xml, type TokenReader interface, Token() (Token, error)
pkg flag, method (*FlagSet) ErrorHandling() ErrorHandling
pkg flag, method (*FlagSet) Name() string
pkg flag, method (*FlagSet) Output() io.Writer
pkg html/template, type Srcset string
pkg math, func Erfcinv(float64) float64
pkg math, func Erfinv(float64) float64
pkg math, func Round(float64) float64
@ -594,7 +595,6 @@ pkg os, method (*SyscallError) Timeout() bool
pkg os, var ErrNoDeadline error
pkg strings, method (*Builder) Grow(int)
pkg strings, method (*Builder) Len() int
pkg strings, method (*Builder) ReadFrom(io.Reader) (int64, error)
pkg strings, method (*Builder) Reset()
pkg strings, method (*Builder) String() string
pkg strings, method (*Builder) Write([]uint8) (int, error)
@ -618,24 +618,6 @@ pkg syscall (windows-386), func CreateProcessAsUser(Token, *uint16, *uint16, *Se
pkg syscall (windows-386), type SysProcAttr struct, Token Token
pkg syscall (windows-amd64), func CreateProcessAsUser(Token, *uint16, *uint16, *SecurityAttributes, *SecurityAttributes, bool, uint32, *uint16, *uint16, *StartupInfo, *ProcessInformation) error
pkg syscall (windows-amd64), type SysProcAttr struct, Token Token
pkg text/template/parse, const NodeBreak = 20
pkg text/template/parse, const NodeBreak NodeType
pkg text/template/parse, const NodeContinue = 21
pkg text/template/parse, const NodeContinue NodeType
pkg text/template/parse, method (*BreakNode) Copy() Node
pkg text/template/parse, method (*BreakNode) Position() Pos
pkg text/template/parse, method (*BreakNode) String() string
pkg text/template/parse, method (*BreakNode) Type() NodeType
pkg text/template/parse, method (*ContinueNode) Copy() Node
pkg text/template/parse, method (*ContinueNode) Position() Pos
pkg text/template/parse, method (*ContinueNode) String() string
pkg text/template/parse, method (*ContinueNode) Type() NodeType
pkg text/template/parse, type BreakNode struct
pkg text/template/parse, type BreakNode struct, embedded NodeType
pkg text/template/parse, type BreakNode struct, embedded Pos
pkg text/template/parse, type ContinueNode struct
pkg text/template/parse, type ContinueNode struct, embedded NodeType
pkg text/template/parse, type ContinueNode struct, embedded Pos
pkg time, func LoadLocationFromTZData(string, []uint8) (*Location, error)
pkg unicode, const Version = "10.0.0"
pkg unicode, var Masaram_Gondi *RangeTable

View file

@ -134,7 +134,7 @@ be able to adapt to changing build environments and conditions. For
example, if we allowed extra configuration such as compiler flags or
command line recipes, then that configuration would need to be updated
each time the build tools changed; it would also be inherently tied
to the use of a specific tool chain.</p>
to the use of a specific toolchain.</p>
<h2>Getting started with the go command</h2>

View file

@ -268,6 +268,12 @@ view a wiki page. It will handle URLs prefixed with "/view/".
{{code "doc/articles/wiki/part2.go" `/^func viewHandler/` `/^}/`}}
<p>
Again, note the use of <code>_</code> to ignore the <code>error</code>
return value from <code>loadPage</code>. This is done here for simplicity
and generally considered bad practice. We will attend to this later.
</p>
<p>
First, this function extracts the page title from <code>r.URL.Path</code>,
the path component of the request URL.
@ -282,12 +288,6 @@ The function then loads the page data, formats the page with a string of simple
HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>.
</p>
<p>
Again, note the use of <code>_</code> to ignore the <code>error</code>
return value from <code>loadPage</code>. This is done here for simplicity
and generally considered bad practice. We will attend to this later.
</p>
<p>
To use this handler, we rewrite our <code>main</code> function to
initialize <code>http</code> using the <code>viewHandler</code> to handle

View file

@ -29,7 +29,7 @@ Instead, the compiler operates on a kind of semi-abstract instruction set,
and instruction selection occurs partly after code generation.
The assembler works on the semi-abstract form, so
when you see an instruction like <code>MOV</code>
what the tool chain actually generates for that operation might
what the toolchain actually generates for that operation might
not be a move instruction at all, perhaps a clear or load.
Or it might correspond exactly to the machine instruction with that name.
In general, machine-specific operations tend to appear as themselves, while more general concepts like
@ -139,7 +139,7 @@ The exact set depends on the architecture.
<p>
There are four predeclared symbols that refer to pseudo-registers.
These are not real registers, but rather virtual registers maintained by
the tool chain, such as a frame pointer.
the toolchain, such as a frame pointer.
The set of pseudo-registers is the same for all architectures:
</p>
@ -738,6 +738,13 @@ The other codes are <code>-&gt;</code> (arithmetic right shift),
The ARM64 port is in an experimental state.
</p>
<p>
<code>R18</code> is the "platform register", reserved on the Apple platform.
<code>R27</code> and <code>R28</code> are reserved by the compiler and linker.
<code>R29</code> is the frame pointer.
<code>R30</code> is the link register.
</p>
<p>
Instruction modifiers are appended to the instruction following a period.
The only modifiers are <code>P</code> (postincrement) and <code>W</code>
@ -752,11 +759,61 @@ Addressing modes:
<ul>
<li>
<code>(R5, R6)</code>: Register pair for <code>LDP</code>/<code>STP</code>.
<code>R0-&gt;16</code>
<br>
<code>R0&gt;&gt;16</code>
<br>
<code>R0&lt;&lt;16</code>
<br>
<code>R0@&gt;16</code>:
These are the same as on the 32-bit ARM.
</li>
<li>
<code>$(8&lt;&lt;12)</code>:
Left shift the immediate value <code>8</code> by <code>12</code> bits.
</li>
<li>
<code>8(R0)</code>:
Add the value of <code>R0</code> and <code>8</code>.
</li>
<li>
<code>(R2)(R0)</code>:
The location at <code>R0</code> plus <code>R2</code>.
</li>
<li>
<code>R0.UXTB</code>
<br>
<code>R0.UXTB&lt;&lt;imm</code>:
<code>UXTB</code>: extract an 8-bit value from the low-order bits of <code>R0</code> and zero-extend it to the size of <code>R0</code>.
<code>R0.UXTB&lt;&lt;imm</code>: left shift the result of <code>R0.UXTB</code> by <code>imm</code> bits.
The <code>imm</code> value can be 0, 1, 2, 3, or 4.
The other extensions include <code>UXTH</code> (16-bit), <code>UXTW</code> (32-bit), and <code>UXTX</code> (64-bit).
</li>
<li>
<code>R0.SXTB</code>
<br>
<code>R0.SXTB&lt;&lt;imm</code>:
<code>SXTB</code>: extract an 8-bit value from the low-order bits of <code>R0</code> and sign-extend it to the size of <code>R0</code>.
<code>R0.SXTB&lt;&lt;imm</code>: left shift the result of <code>R0.SXTB</code> by <code>imm</code> bits.
The <code>imm</code> value can be 0, 1, 2, 3, or 4.
The other extensions include <code>SXTH</code> (16-bit), <code>SXTW</code> (32-bit), and <code>SXTX</code> (64-bit).
</li>
<li>
<code>(R5, R6)</code>: Register pair for <code>LDAXP</code>/<code>LDP</code>/<code>LDXP</code>/<code>STLXP</code>/<code>STP</code>/<code>STP</code>.
</li>
</ul>
<p>
Reference: <a href="/pkg/cmd/internal/obj/arm64">Go ARM64 Assembly Instructions Reference Manual</a>
</p>
<h3 id="ppc64">64-bit PowerPC, a.k.a. ppc64</h3>
<p>
@ -882,6 +939,12 @@ The value of <code>GOMIPS</code> environment variable (<code>hardfloat</code> or
<code>GOMIPS_hardfloat</code> or <code>GOMIPS_softfloat</code>.
</p>
<p>
The value of <code>GOMIPS64</code> environment variable (<code>hardfloat</code> or
<code>softfloat</code>) is made available to assembly code by predefining either
<code>GOMIPS64_hardfloat</code> or <code>GOMIPS64_softfloat</code>.
</p>
<h3 id="unsupported_opcodes">Unsupported opcodes</h3>
<p>

View file

@ -183,7 +183,6 @@ satisfaction of all parties. They are:
<li>Aditya Mukerjee &lt;dev@chimeracoder.net&gt;
<li>Andrew Gerrand &lt;adg@golang.org&gt;
<li>Peggy Li &lt;peggyli.224@gmail.com&gt;
<li>Sarah Adams &lt;sadams.codes@gmail.com&gt;
<li>Steve Francia &lt;steve.francia@gmail.com&gt;
<li>Verónica López &lt;gveronicalg@gmail.com&gt;
</ul>

View file

@ -118,6 +118,6 @@ guidelines</a> for information on design, testing, and our code review process.
<p>
Check <a href="//golang.org/issue">the tracker</a> for
open issues that interest you. Those labeled
<a href="https://github.com/golang/go/issues?q=is%3Aopen+is%3Aissue+label%3Ahelpwanted">helpwanted</a>
<a href="https://github.com/golang/go/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22">help wanted</a>
are particularly in need of outside help.
</p>

File diff suppressed because it is too large Load diff

View file

@ -3,28 +3,54 @@
"Path": "/doc/gdb"
}-->
<p><i>
This applies to the standard toolchain (the <code>gc</code> Go
compiler and tools). Gccgo has native gdb support.
Besides this overview you might want to consult the
<a href="http://sourceware.org/gdb/current/onlinedocs/gdb/">GDB manual</a>.
</i></p>
<!--
NOTE: In this document and others in this directory, the convention is to
set fixed-width phrases with non-fixed-width spaces, as in
<code>hello</code> <code>world</code>.
Do not send CLs removing the interior tags from such phrases.
-->
<i>
<p>
The following instructions apply to the standard toolchain
(the <code>gc</code> Go compiler and tools).
Gccgo has native gdb support.
</p>
<p>
Note that
<a href="https://github.com/derekparker/delve">Delve</a> is a better
alternative to GDB when debugging Go programs built with the standard
toolchain. It understands the Go runtime, data structures, and
expressions better than GDB. Delve currently supports Linux, OSX,
and Windows on <code>amd64</code>.
For the most up-to-date list of supported platforms, please see
<a href="https://github.com/derekparker/delve/tree/master/Documentation/installation">
the Delve documentation</a>.
</p>
</i>
<p>
GDB does not understand Go programs well.
The stack management, threading, and runtime contain aspects that differ
enough from the execution model GDB expects that they can confuse
the debugger, even when the program is compiled with gccgo.
As a consequence, although GDB can be useful in some situations, it is
not a reliable debugger for Go programs, particularly heavily concurrent ones.
Moreover, it is not a priority for the Go project to address these issues, which
are difficult.
In short, the instructions below should be taken only as a guide to how
to use GDB when it works, not as a guarantee of success.
the debugger and cause incorrect results even when the program is
compiled with gccgo.
As a consequence, although GDB can be useful in some situations (e.g.,
debugging Cgo code, or debugging the runtime itself), it is not
a reliable debugger for Go programs, particularly heavily concurrent
ones. Moreover, it is not a priority for the Go project to address
these issues, which are difficult.
</p>
<p>
In short, the instructions below should be taken only as a guide to how
to use GDB when it works, not as a guarantee of success.
Besides this overview you might want to consult the
<a href="http://sourceware.org/gdb/current/onlinedocs/gdb/">GDB manual</a>.
</p>
<p>
In time, a more Go-centric debugging architecture may be required.
</p>
<h2 id="Introduction">Introduction</h2>
@ -38,16 +64,15 @@ use to inspect a live process or a core dump.
<p>
Pass the <code>'-w'</code> flag to the linker to omit the debug information
(for example, <code>go build -ldflags "-w" prog.go</code>).
(for example, <code>go</code> <code>build</code> <code>-ldflags=-w</code> <code>prog.go</code>).
</p>
<p>
The code generated by the <code>gc</code> compiler includes inlining of
function invocations and registerization of variables. These optimizations
can sometimes make debugging with <code>gdb</code> harder. To disable them
when debugging, pass the flags <code>-gcflags "-N -l"</code> to the
<a href="/cmd/go"><code>go</code></a> command used to build the code being
debugged.
can sometimes make debugging with <code>gdb</code> harder.
If you find that you need to disable these optimizations,
build your program using <code>go</code> <code>build</code> <code>-gcflags=all="-N -l"</code>.
</p>
<p>
@ -94,7 +119,7 @@ Show the name, type and location of global variables:
<p>
A recent extension mechanism to GDB allows it to load extension scripts for a
given binary. The tool chain uses this to extend GDB with a handful of
given binary. The toolchain uses this to extend GDB with a handful of
commands to inspect internals of the runtime code (such as goroutines) and to
pretty print the built-in map, slice and channel types.
</p>
@ -139,7 +164,7 @@ the DWARF code.
<p>
If you're interested in what the debugging information looks like, run
'<code>objdump -W a.out</code>' and browse through the <code>.debug_*</code>
<code>objdump</code> <code>-W</code> <code>a.out</code> and browse through the <code>.debug_*</code>
sections.
</p>
@ -162,7 +187,7 @@ the form <code>pkg.(*MyType).Meth</code>.
<p>
In this tutorial we will inspect the binary of the
<a href="/pkg/regexp/">regexp</a> package's unit tests. To build the binary,
change to <code>$GOROOT/src/regexp</code> and run <code>go test -c</code>.
change to <code>$GOROOT/src/regexp</code> and run <code>go</code> <code>test</code> <code>-c</code>.
This should produce an executable file named <code>regexp.test</code>.
</p>
@ -188,7 +213,7 @@ Loading Go Runtime support.
</pre>
<p>
The message <code>"Loading Go Runtime support"</code> means that GDB loaded the
The message "Loading Go Runtime support" means that GDB loaded the
extension from <code>$GOROOT/src/runtime/runtime-gdb.py</code>.
</p>
@ -353,7 +378,7 @@ Stack level 0, frame at 0x7ffff7f9ff88:
</pre>
<p>
The command <code>info locals</code> lists all variables local to the function and their values, but is a bit
The command <code>info</code> <code>locals</code> lists all variables local to the function and their values, but is a bit
dangerous to use, since it will also try to print uninitialized variables. Uninitialized slices may cause gdb to try
to print arbitrary large arrays.
</p>
@ -386,7 +411,7 @@ $3 = struct hchan&lt;*testing.T&gt;
</pre>
<p>
That <code>struct hchan&lt;*testing.T&gt;</code> is the
That <code>struct</code> <code>hchan&lt;*testing.T&gt;</code> is the
runtime-internal representation of a channel. It is currently empty,
or gdb would have pretty-printed its contents.
</p>

View file

@ -16,11 +16,36 @@ git checkout <i>release-branch</i>
<p>
Each major Go release is supported until there are two newer major releases.
For example, Go 1.8 is supported until Go 1.10 is released,
and Go 1.9 is supported until Go 1.11 is released.
For example, Go 1.5 was supported until the Go 1.7 release, and Go 1.6 was
supported until the Go 1.8 release.
We fix critical problems, including <a href="/security">critical security problems</a>,
in supported releases as needed by issuing minor revisions
(for example, Go 1.9.1, Go 1.9.2, and so on).
(for example, Go 1.6.1, Go 1.6.2, and so on).
</p>
<h2 id="go1.10">go1.10 (released 2018/02/16)</h2>
<p>
Go 1.10 is a major release of Go.
Read the <a href="/doc/go1.10">Go 1.10 Release Notes</a> for more information.
</p>
<h3 id="go1.10.minor">Minor revisions</h3>
<p>
go1.10.1 (released 2018/03/28) includes fixes to the compiler, runtime, and the
<code>archive/zip</code>, <code>crypto/tls</code>, <code>crypto/x509</code>,
<code>encoding/json</code>, <code>net</code>, <code>net/http</code>, and
<code>net/http/pprof</code> packages.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.10.1">Go
1.10.1 milestone</a> on our issue tracker for details.
</p>
<p>
go1.10.2 (released 2018/05/01) includes fixes to the compiler, linker, and go
command.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.10.2">Go
1.10.2 milestone</a> on our issue tracker for details.
</p>
<h2 id="go1.9">go1.9 (released 2017/08/24)</h2>
@ -49,6 +74,34 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.2">Go
1.9.2 milestone</a> on our issue tracker for details.
</p>
<p>
go1.9.3 (released 2018/01/22) includes fixes to the compiler, runtime,
and the <code>database/sql</code>, <code>math/big</code>, <code>net/http</code>,
and <code>net/url</code> packages.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.3">Go
1.9.3 milestone</a> on our issue tracker for details.
</p>
<p>
go1.9.4 (released 2018/02/07) includes a security fix to “go get”.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.4">Go
1.9.4</a> milestone on our issue tracker for details.
</p>
<p>
go1.9.5 (released 2018/03/28) includes fixes to the compiler, go command, and
<code>net/http/pprof</code> package.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.5">Go
1.9.5 milestone</a> on our issue tracker for details.
</p>
<p>
go1.9.6 (released 2018/05/01) includes fixes to the compiler and go command.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.6">Go
1.9.6 milestone</a> on our issue tracker for details.
</p>
<h2 id="go1.8">go1.8 (released 2017/02/16)</h2>
<p>
@ -99,6 +152,20 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.5">Go
1.8.5 milestone</a> on our issue tracker for details.
</p>
<p>
go1.8.6 (released 2018/01/22) includes the same fix in <code>math/big</code>
as Go 1.9.3 and was released at the same time.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.6">Go
1.8.6 milestone</a> on our issue tracker for details.
</p>
<p>
go1.8.7 (released 2018/02/07) includes a security fix to “go get”.
It contains the same fix as Go 1.9.4 and was released at the same time.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.7">Go
1.8.7</a> milestone on our issue tracker for details.
</p>
<h2 id="go1.7">go1.7 (released 2016/08/15)</h2>
<p>
@ -272,7 +339,7 @@ See the <a href="https://github.com/golang/go/commits/go1.3.2">change history</a
</p>
<p>
go1.3.3 (released 2014/09/30) includes further bug fixes to cgo, the runtime package, and the nacl port.
go1.3.3 (released 2014/09/30) includes further bug fixes to cgo, the runtime package, and the nacl port.
See the <a href="https://github.com/golang/go/commits/go1.3.3">change history</a> for details.
</p>
@ -336,7 +403,7 @@ about the future of Go 1.
</p>
<p>
The go1 release corresponds to
The go1 release corresponds to
<code><a href="weekly.html#2012-03-27">weekly.2012-03-27</a></code>.
</p>
@ -352,7 +419,7 @@ It also includes several minor code and documentation fixes.
<p>
go1.0.2 (released 2012/06/13) was issued to fix two bugs in the implementation
of maps using struct or array keys:
of maps using struct or array keys:
<a href="//golang.org/issue/3695">issue 3695</a> and
<a href="//golang.org/issue/3573">issue 3573</a>.
It also includes many minor code and documentation fixes.

View file

@ -3,6 +3,13 @@
"Template": true
}-->
<!--
NOTE: In this document and others in this directory, the convention is to
set fixed-width phrases with non-fixed-width spaces, as in
<code>hello</code> <code>world</code>.
Do not send CLs removing the interior tags from such phrases.
-->
<h2 id="introduction">Introduction</h2>
<p>
@ -45,7 +52,7 @@ of code. The Go runtime provides <a href="https://golang.org/pkg/runtime/pprof/"
profiling data</a> in the format expected by the
<a href="https://github.com/google/pprof/blob/master/doc/pprof.md">pprof visualization tool</a>.
The profiling data can be collected during testing
via <code>go test</code> or endpoints made available from the <a href="/pkg/net/http/pprof/">
via <code>go</code> <code>test</code> or endpoints made available from the <a href="/pkg/net/http/pprof/">
net/http/pprof</a> package. Users need to collect the profiling data and use pprof tools to filter
and visualize the top code paths.
</p>
@ -119,7 +126,7 @@ so it is recommended to collect only a single profile at a time.
<p>
The Go tools provide text, graph, and <a href="http://valgrind.org/docs/manual/cl-manual.html">callgrind</a>
visualization of the profile data via
visualization of the profile data using
<code><a href="https://github.com/google/pprof/blob/master/doc/pprof.md">go tool pprof</a></code>.
Read <a href="https://blog.golang.org/profiling-go-programs">Profiling Go programs</a>
to see them in action.
@ -149,9 +156,11 @@ in the listing.</p>
</p>
<p>
Another way to visualize profile data is a <a href="https://github.com/uber/go-torch">flame graph</a>.
Another way to visualize profile data is a <a href="http://www.brendangregg.com/flamegraphs.html">flame graph</a>.
Flame graphs allow you to move in a specific ancestry path, so you can zoom
in/out specific sections of code more easily.
in/out of specific sections of code.
The <a href="https://github.com/google/pprof">upstream pprof</a>
has support for flame graphs.
</p>
<p>
@ -183,9 +192,19 @@ handler on :7777 at /custom_debug_path/profile:
<p>
<pre>
mux := http.NewServeMux()
mux.HandleFunc("/custom_debug_path/profile", pprof.Profile)
http.ListenAndServe(":7777", mux)
package main
import (
"log"
"net/http"
"net/http/pprof"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/custom_debug_path/profile", pprof.Profile)
log.Fatal(http.ListenAndServe(":7777", mux))
}
</pre>
</p>
@ -203,7 +222,7 @@ an execution tracer to trace the runtime events within an interval.
<p>Tracing enables us to:</p>
<ul>
<li>Instrument and profile application latency in a Go process.</li>
<li>Instrument and analyze application latency in a Go process.</li>
<li>Measure the cost of specific calls in a long chain of calls.</li>
<li>Figure out the utilization and performance improvements.
Bottlenecks are not always obvious without tracing data.</li>
@ -252,7 +271,8 @@ trace spans. You need to manually instrument your code to create, end, and annot
<p><strong>How should I propagate trace headers in Go libraries?</strong></p>
<p>
You can propagate trace identifiers and tags in the <code>context.Context</code>.
You can propagate trace identifiers and tags in the
<a href="/pkg/context#Context"><code>context.Context</code></a>.
There is no canonical trace key or common representation of trace headers
in the industry yet. Each tracing provider is responsible for providing propagation
utilities in their Go libraries.
@ -265,7 +285,8 @@ runtime can be included in a trace?</strong>
<p>
The standard library and runtime are trying to expose several additional APIs
to notify on low level internal events. For example, httptrace.ClientTrace
to notify on low level internal events. For example,
<a href="/pkg/net/http/httptrace#ClientTrace"><code>httptrace.ClientTrace</code></a>
provides APIs to follow low-level events in the life cycle of an outgoing request.
There is an ongoing effort to retrieve low-level runtime events from
the runtime execution tracer and allow users to define and record their user events.
@ -303,25 +324,25 @@ create confusion.
<p><strong>How well do debuggers work with Go programs?</strong></p>
<p>
As of Go 1.9, the DWARF info generated by the gc compiler is not complete
and sometimes makes debugging harder. There is an ongoing effort to improve the
DWARF information to help the debuggers display more accurate information.
Until those improvements are in you may prefer to disable compiler
optimizations during development for more accuracy. To disable optimizations,
use the "-N -l" compiler flags. For example, the following command builds
a package with no compiler optimizations:
The <code>gc</code> compiler performs optimizations such as
function inlining and variable registerization. These optimizations
sometimes make debugging with debuggers harder. There is an ongoing
effort to improve the quality of the DWARF information generated for
optimized binaries. Until those improvements are available, we recommend
disabling optimizations when building the code being debugged. The following
command builds a package with no compiler optimizations:
<p>
<pre>
$ go build -gcflags="-N -l"
$ go build -gcflags=all="-N -l"
</pre>
</p>
<p>
As of Go 1.10, the Go binaries will have the required DWARF information
for accurate debugging. To enable the DWARF improvements, use the following
compiler flags and use GDB until Delve supports location lists:
</p>
As part of the improvement effort, Go 1.10 introduced a new compiler
flag <code>-dwarflocationlists</code>. The flag causes the compiler to
add location lists that helps debuggers work with optimized binaries.
The following command builds a package with optimizations but with
the DWARF location lists:
<p>
<pre>
@ -333,9 +354,7 @@ $ go build -gcflags="-dwarflocationlists=true"
<p>
Even though both delve and gdb provides CLIs, most editor integrations
and IDEs provides debugging-specific user interfaces. Please refer to
the <a href="/doc/editors.html">editors guide</a> to see the options
with debugger UI support.
and IDEs provides debugging-specific user interfaces.
</p>
<p><strong>Is it possible to do postmortem debugging with Go programs?</strong></p>
@ -421,7 +440,7 @@ Use profiling tools instead first to address them.</p>
fine, and then it became serialized. It suggests that there might
be lock contention for a shared resource that creates a bottleneck.</p>
<p>See <a href="https://golang.org/cmd/trace/"><code>go tool trace</code></a>
<p>See <a href="https://golang.org/cmd/trace/"><code>go</code> <code>tool</code> <code>trace</code></a>
to collect and analyze runtime traces.
</p>

View file

@ -33,199 +33,3 @@ community-maintained list of
<a href="https://github.com/golang/go/wiki/IDEsAndTextEditorPlugins">IDEs and text editor plugins</a>
is available at the Wiki.
</p>
<p>
Each development environment integrates a number of Go-specific tools.
The following feature matrix lists and compares the most significant features.
</p>
<table class="features-matrix">
<tr>
<th></th>
<th><img title="Vim Go" src="/doc/editors/vimgo.png"><br>vim</th>
<th><img title="Visual Studio Code" src="/doc/editors/vscodego.png"><br>Visual Studio Code</th>
<th><img title="GoLand" src="/doc/editors/goland.png"><br>GoLand</th>
<th><img title="Go-Plus" src="/doc/editors/go-plus.png"><br>Atom</th>
</tr>
<tr>
<td class="feature-row" colspan="5">Editing features</td>
</tr>
<tr>
<td>Build and run from the editor/IDE</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Autocompletion of identifiers (variable, method, and function names)</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Type-aware autocompletion</td>
<td class="no">No</td>
<td class="no">No</td>
<td class="yes">Yes</td>
<td class="no">No</td>
</tr>
<tr>
<td>Rename identifiers</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Auto format, build, vet, and lint on save</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes<sup>1</sup></td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Auto insert import paths and remove unused on save</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes<sup>2</sup></td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Auto generate JSON, XML tags for struct fields</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td class="feature-row" colspan="5">Navigation features</td>
</tr>
<tr>
<td>Display documentation inline, or open godoc in browser</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Switch between <code>*.go</code> and <code>*_test.go</code> file</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">No</td>
</tr>
<tr>
<td>Jump to definition and referees</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Look up for interface implementations</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Search for callers and callees</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td class="feature-row" colspan="5">Testing and debugging features</td>
</tr>
<tr>
<td>Debugger support</td>
<td class="no">No</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes<sup>3</sup></td>
</tr>
<tr>
<td>Run a single test case, all tests from file, or all tests from a package</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="no">No</td>
</tr>
<tr>
<td>Auto generate tests for packages, files and identifiers</td>
<td class="no">No</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="no">No</td>
</tr>
<tr>
<td>Debug tests</td>
<td class="no">No</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes<sup>3</sup></td>
</tr>
<tr>
<td>Display test coverage</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr class="download">
<td></td>
<td><a href="https://github.com/fatih/vim-go">Install</a></td>
<td><a href="https://marketplace.visualstudio.com/items?itemName=lukehoban.Go">Install</a></td>
<td><a href="https://www.jetbrains.com/go">Install</a></td>
<td><a href="https://atom.io/packages/go-plus">Install</a></td>
</tr>
</table>
<p>
<sup>1</sup>Possible when enabled via Settings &gt; Go &gt; On Save, <code>go</code> <code>vet</code> and <code>golint</code> are available via plugins. Also runs tests on save if configured.
<br>
<sup>2</sup>Additionally, user input can disambiguate when two or more options are available.
<br>
<sup>3</sup>Available if the <a href="https://atom.io/packages/go-debug">go-debug</a> package is installed.
</p>
</div>
<style>
.features-matrix {
min-width: 800px;
border-collapse: collapse;
}
.features-matrix th {
width: 60px;
text-align: center;
font-size: 14px;
color: #666;
}
.features-matrix th img {
width: 48px;
}
.features-matrix .yes {
text-align: center;
}
.features-matrix .no {
text-align: center;
background-color: #ffe9e9;
}
.features-matrix .download {
font-weight: bold;
text-align: center;
}
.features-matrix td {
padding: 11px 5px 11px 5px;
border-bottom: solid 1px #ebebeb;
}
.features-matrix .feature-row {
background-color: #ebebeb;
font-weight: bold;
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -3588,8 +3588,7 @@ That's left as an exercise for the reader.
<p>
Let's finish with a complete Go program, a web server.
This one is actually a kind of web re-server.
Google provides a service at
<a href="http://chart.apis.google.com">http://chart.apis.google.com</a>
Google provides a service at <code>chart.apis.google.com</code>
that does automatic formatting of data into charts and graphs.
It's hard to use interactively, though,
because you need to put the data into the URL as a query.

View file

@ -166,7 +166,7 @@ providing a complete Go 1.1 implementation.
<h3 id="gc_flag">Command-line flag parsing</h3>
<p>
In the gc tool chain, the compilers and linkers now use the
In the gc toolchain, the compilers and linkers now use the
same command-line flag parsing rules as the Go flag package, a departure
from the traditional Unix flag parsing. This may affect scripts that invoke
the tool directly.
@ -305,7 +305,7 @@ The race detector is documented in <a href="/doc/articles/race_detector.html">a
<p>
Due to the change of the <a href="#int"><code>int</code></a> to 64 bits and
a new internal <a href="//golang.org/s/go11func">representation of functions</a>,
the arrangement of function arguments on the stack has changed in the gc tool chain.
the arrangement of function arguments on the stack has changed in the gc toolchain.
Functions written in assembly will need to be revised at least
to adjust frame pointer offsets.
</p>
@ -395,7 +395,7 @@ Run <code>go help test</code> for more information.
The <a href="/cmd/fix/"><code>fix</code></a> command, usually run as
<code>go fix</code>, no longer applies fixes to update code from
before Go 1 to use Go 1 APIs.
To update pre-Go 1 code to Go 1.1, use a Go 1.0 tool chain
To update pre-Go 1 code to Go 1.1, use a Go 1.0 toolchain
to convert the code to Go 1.0 first.
</p>
@ -427,7 +427,7 @@ To build a file only with Go 1.0.x, use the converse constraint:
<h3 id="platforms">Additional platforms</h3>
<p>
The Go 1.1 tool chain adds experimental support for <code>freebsd/arm</code>,
The Go 1.1 toolchain adds experimental support for <code>freebsd/arm</code>,
<code>netbsd/386</code>, <code>netbsd/amd64</code>, <code>netbsd/arm</code>,
<code>openbsd/386</code> and <code>openbsd/amd64</code> platforms.
</p>

View file

@ -15,34 +15,37 @@ Do not send CLs removing the interior tags from such phrases.
ul li { margin: 0.5em 0; }
</style>
<h2 id="introduction">DRAFT RELEASE NOTES - Introduction to Go 1.10</h2>
<p><strong>
Go 1.10 is not yet released. These are work-in-progress
release notes. Go 1.10 is expected to be released in February 2018.
</strong></p>
<h2 id="introduction">Introduction to Go 1.10</h2>
<p>
The latest Go release, version 1.10, arrives six months after <a href="go1.9">go1.9</a>.
The latest Go release, version 1.10, arrives six months after <a href="go1.9">Go 1.9</a>.
Most of its changes are in the implementation of the toolchain, runtime, and libraries.
As always, the release maintains the Go 1 <a href="/doc/go1compat.html">promise of compatibility</a>.
We expect almost all Go programs to continue to compile and run as before.
</p>
<p>
OVERVIEW HERE
This release improves <a href="#build">caching of built packages</a>,
adds <a href="#test">caching of successful test results</a>,
runs <a href="#test-vet">vet automatically during tests</a>,
and
permits <a href="#cgo">passing string values directly between Go and C using cgo</a>.
A new <a href="#cgo">compiler option whitelist</a> may cause
unexpected <a href="https://golang.org/s/invalidflag"><code>invalid
flag</code></a> errors in code that built successfully with older
releases.
</p>
<h2 id="language">Changes to the language</h2>
<p>
There are no substantive changes to the language.
There are no significant changes to the language specification.
</p>
<p><!-- CL 60230 -->
A corner case involving shifts by untyped constants has been clarified,
A corner case involving shifts of untyped constants has been clarified,
and as a result the compilers have been updated to allow the index expression
<code>x[1.0</code>&nbsp;<code>&lt;&lt;</code>&nbsp;<code>s]</code> where <code>s</code> is an untyped constant;
<code>x[1.0</code>&nbsp;<code>&lt;&lt;</code>&nbsp;<code>s]</code> where <code>s</code> is an unsigned integer;
the <a href="/pkg/go/types/">go/types</a> package already did.
</p>
@ -64,11 +67,6 @@ in particular <a href="#asm">new instructions in the assembler</a>
and improvements to the code generated by the compilers.
</p>
<p id="darwin">
Go 1.10 is the last release that will run on OS X 10.8 Mountain Lion.
Go 1.11 will require OS X 10.9 Mavericks or later.
</p>
<p id="freebsd">
As <a href="go1.9#freebsd">announced in the Go 1.9 release notes</a>,
Go 1.10 now requires FreeBSD 10.3 or later;
@ -76,15 +74,9 @@ support for FreeBSD 9.3 has been removed.
</p>
<p id="netbsd">
Go now runs on NetBSD again, but requires the unreleased NetBSD 8.
Only <code>GOARCH=amd64</code> running on NetBSD amd64 and <code>GOARCH=386</code>
running on NetBSD i386 are known to work. 64-bit Go binaries are known to
fail on 32-bit NetBSD kernels. <code>GOARCH=arm</code> is untested.
</p>
<p id="openbsd">
Go 1.10 is the last release that will run on OpenBSD 6.0.
Go 1.11 will require OpenBSD 6.2.
Go now runs on NetBSD again but requires the unreleased NetBSD 8.
Only <code>GOARCH</code> <code>amd64</code> and <code>386</code> have
been fixed. The <code>arm</code> port is still broken.
</p>
<p id="mips">
@ -94,13 +86,34 @@ On 32-bit MIPS systems, the new environment variable settings
hardware instructions or software emulation for floating-point computations.
</p>
<p id="openbsd">
Go 1.10 is the last release that will run on OpenBSD 6.0.
Go 1.11 will require OpenBSD 6.2.
</p>
<p id="darwin">
Go 1.10 is the last release that will run on OS X 10.8 Mountain Lion or OS X 10.9 Mavericks.
Go 1.11 will require OS X 10.10 Yosemite or later.
</p>
<p id="windows">
Go 1.10 is the last release that will run on Windows XP or Windows Vista.
Go 1.11 will require Windows 7 or later.
</p>
<h2 id="tools">Tools</h2>
<h3 id="goroot">Default GOROOT &amp; GOTMPDIR</h3>
<p>
TODO: default GOROOT changes in cmd/go
TODO: computed GOROOT change
If the environment variable <code>$GOROOT</code> is unset,
the go tool previously used the default <code>GOROOT</code>
set during toolchain compilation.
Now, before falling back to that default, the go tool attempts to
deduce <code>GOROOT</code> from its own executable path.
This allows binary distributions to be unpacked anywhere in the
file system and then be used without setting <code>GOROOT</code>
explicitly.
</p>
<p>
@ -117,7 +130,7 @@ The <code>go</code>&nbsp;<code>build</code> command now detects out-of-date pack
purely based on the content of source files, specified build flags, and metadata stored in the compiled packages.
Modification times are no longer consulted or relevant.
The old advice to add <code>-a</code> to force a rebuild in cases where
the modification times were misleading for one reason or another
the modification times were misleading for one reason or another
(for example, changes in build flags) is no longer necessary:
builds now always detect when packages must be rebuilt.
(If you observe otherwise, please file a bug.)
@ -146,17 +159,17 @@ back and forth between different branches in a version control system).
The old advice to add the <code>-i</code> flag for speed, as in <code>go</code> <code>build</code> <code>-i</code>
or <code>go</code> <code>test</code> <code>-i</code>,
is no longer necessary: builds run just as fast without <code>-i</code>.
For more details, see <a href="TODO"><code>go</code> <code>help</code> <code>cache</code></a>.
For more details, see <a href="/cmd/go/#hdr-Build_and_test_caching"><code>go</code> <code>help</code> <code>cache</code></a>.
</p>
<p>
The <code>go</code>&nbsp;</code>install</code> command now installs only the
The <code>go</code>&nbsp;<code>install</code> command now installs only the
packages and commands listed directly on the command line.
For example, <code>go</code> <code>install</code> <code>cmd/gofmt</code>
installs the gofmt program but not any of the packages on which it depends.
The new build cache makes future commands still run as quickly as if the
dependencies had been installed.
To force the installation of dependencies, use the new
To force the installation of dependencies, use the new
<code>go</code> <code>install</code> <code>-i</code> flag.
Installing dependency packages should not be necessary in general,
and the very concept of installed packages may disappear in a future release.
@ -188,7 +201,7 @@ only to command lines using a subset of the
The idiomatic way to bypass test caching is to use <code>-count=1</code>.
</p>
<p>
<p id="test-vet">
The <code>go</code>&nbsp;<code>test</code> command now automatically runs
<code>go</code> <code>vet</code> on the package being tested,
to identify significant problems before running the test.
@ -253,7 +266,19 @@ and the <a href="/cmd/test2json/">test2json documentation</a>.
<h3 id="cgo">Cgo</h3>
<p>
Cgo now implements a C typedef like “<code>typedef</code> <code>X</code> <code>Y</code>;” using a Go type alias,
Options specified by cgo using <code>#cgo CFLAGS</code> and the like
are now checked against a whitelist of permitted options.
This closes a security hole in which a downloaded package uses
compiler options like
<span style="white-space: nowrap"><code>-fplugin</code></span>
to run arbitrary code on the machine where it is being built.
This can cause a build error such as <code>invalid flag in #cgo CFLAGS</code>.
For more background, and how to handle this error, see
<a href="https://golang.org/s/invalidflag">https://golang.org/s/invalidflag</a>.
</p>
<p>
Cgo now implements a C typedef like “<code>typedef</code> <code>X</code> <code>Y</code>” using a Go type alias,
so that Go code may use the types <code>C.X</code> and <code>C.Y</code> interchangeably.
It also now supports the use of niladic function-like macros.
Also, the documentation has been updated to clarify that
@ -261,9 +286,13 @@ Go structs and Go arrays are not supported in the type signatures of cgo-exporte
</p>
<p>
TODO: CL 70890 "permit passing string values directly between Go and C."
<br>
TODO: CL 66332 "special case C ptr types to use uintptr."
Cgo now supports direct access to Go string values from C.
Functions in the C preamble may use the type <code>_GoString_</code>
to accept a Go string as an argument.
C code may call <code>_GoStringLen</code> and <code>_GoStringPtr</code>
for direct access to the contents of the string.
A value of type <code>_GoString_</code>
may be passed in a call to an exported Go function that takes an argument of Go type <code>string</code>.
</p>
<p>
@ -275,10 +304,37 @@ The new set of environment variables <code>CC_FOR_<i>goos</i>_<i>goarch</i></cod
allows specifying a different default C compiler for each target.
Note that these variables only apply during toolchain bootstrap,
to set the defaults used by the resulting toolchain.
Later <code>go</code> <code>build</code> commands refer to the <code>CC</code> environment
Later <code>go</code> <code>build</code> commands use the <code>CC</code> environment
variable or else the built-in default.
</p>
<p>
Cgo now translates some C types that would normally map to a pointer
type in Go, to a <code>uintptr</code> instead. These types include
the <code>CFTypeRef</code> hierarchy in Darwin's CoreFoundation
framework and the <code>jobject</code> hierarchy in Java's JNI
interface.
</p>
<p>
These types must be <code>uintptr</code> on the Go side because they
would otherwise confuse the Go garbage collector; they are sometimes
not really pointers but data structures encoded in a pointer-sized integer.
Pointers to Go memory must not be stored in these <code>uintptr</code> values.
</p>
<p>
Because of this change, values of the affected types need to be
zero-initialized with the constant <code>0</code> instead of the
constant <code>nil</code>. Go 1.10 provides <code>gofix</code>
modules to help with that rewrite:
</p>
<pre>
go tool fix -r cftype &lt;pkg&gt;
go tool fix -r jni &lt;pkg&gt;
</pre>
<p>
For more details, see the <a href="/cmd/cgo/">cgo documentation</a>.
</p>
@ -296,7 +352,7 @@ $ go doc mail.Address
package mail // import "net/mail"
type Address struct {
Name string
Name string
Address string
}
Address represents a single mail address.
@ -336,8 +392,9 @@ without the binary that produced the profile.
</p>
<p>
The <a href="/cmd/pprof/"><code>go</code>&nbsp;<code>tool</code>&nbsp;<code>pprof</code></a> profile visualizer has been updated to
the latest version from <a href="https://github.com/google/pprof">github.com/google/pprof</a>,
The <a href="/cmd/pprof/"><code>go</code>&nbsp;<code>tool</code>&nbsp;<code>pprof</code></a>
profile visualizer has been updated to git version 9e20b5b (2017-11-08)
from <a href="https://github.com/google/pprof">github.com/google/pprof</a>,
which includes an updated web interface.
</p>
@ -368,7 +425,7 @@ First, certain complex three-index slice expressions previously formatted like
<code>x[i+1</code>&nbsp;<code>:</code>&nbsp;<code>j:k]</code> and now
format with more consistent spacing: <code>x[i+1</code>&nbsp;<code>:</code>&nbsp;<code>j</code>&nbsp;<code>:</code>&nbsp;<code>k]</code>.
Second, single-method interface literals written on a single line,
which are sometimes used in type assertions,
which are sometimes used in type assertions,
are no longer split onto multiple lines.
</p>
@ -383,17 +440,10 @@ a repository is not “properly formatted” is inherently fragile and not recom
<p>
If multiple programs must agree about which version of gofmt is used to format a source file,
we recommend that they do this by arranging to invoke the same gofmt binary.
For example, in the Go open source repository, we arrange for goimports and
our Git pre-commit hook to agree about source code formatting by having both
invoke the gofmt binary found in the current path.
TODO: Make goimports actually do that. #22695.
As another example, inside Google we arrange that source code presubmit
checks run a gofmt binary maintained at a fixed path in a shared, distributed file system;
that on engineering workstations <code>/usr/bin/gofmt</code>
is a symbolic link to that same path;
and that all editor integrations used for Google development
explicitly invoke /usr/bin/gofmt.
TODO: TMI?
For example, in the Go open source repository, our Git pre-commit hook is written in Go
and could import <code>go/format</code> directly, but instead it invokes the <code>gofmt</code>
binary found in the current path, so that the pre-commit hook need not be recompiled
each time <code>gofmt</code> changes.
</p>
<h3 id="compiler">Compiler Toolchain</h3>
@ -412,10 +462,10 @@ and each package is now presented as its own DWARF compilation unit.
<p>
The various <a href="https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit">build modes</a>
has been ported to more systems.
have been ported to more systems.
Specifically, <code>c-shared</code> now works on <code>linux/ppc64le</code>, <code>windows/386</code>, and <code>windows/amd64</code>;
<code>pie</code> now works on <code>darwin/amd64</code> and also forces the use of external linking on all systems;
and <code>plugin</code> now works on <code>linux/ppc64le</code>.
and <code>plugin</code> now works on <code>linux/ppc64le</code> and <code>darwin/amd64</code>.
</p>
<p>
@ -477,7 +527,7 @@ instructions.
</p>
<p>
For the PowerPC 64-bit port, the assembler now supports the POWER9 instructions
For the PowerPC 64-bit port, the assembler now supports the POWER9 instructions
<code><small>ADDEX</small></code>,
<code><small>CMPEQB</small></code>,
<code><small>COPY</small></code>,
@ -497,7 +547,7 @@ and
</p>
<p>
For the S390X port, the assembler now supports the
For the S390X port, the assembler now supports the
<code><small>TMHH</small></code>,
<code><small>TMHL</small></code>,
<code><small>TMLH</small></code>,
@ -517,7 +567,11 @@ to avoid clearing the condition flags unexpectedly.
<h3 id="gccgo">Gccgo</h3>
<p>
TODO: Words about GCC 8 and Go 1.10.
Due to the alignment of Go's semiannual release schedule with GCC's
annual release schedule,
GCC release 7 contains the Go 1.8.3 version of gccgo.
We expect that the next release, GCC 8, will contain the Go 1.10
version of gccgo.
</p>
<h2 id="runtime">Runtime</h2>
@ -537,7 +591,7 @@ Now, the calls nest: if <code>LockOSThread</code> is called multiple times,
in order to unlock the thread.
Existing code that was careful not to nest these calls will remain correct.
Existing code that incorrectly assumed the calls nested will become correct.
Most uses of these functions in public Go source falls into the second category.
Most uses of these functions in public Go source code falls into the second category.
</p>
<p>
@ -555,12 +609,23 @@ optimization decisions and implementation details.
</p>
<p>
There is no longer a limit on the <a href="/pkg/runtime/#GOMAXPROCS"><code>GOMAXPROCS</code></a> setting.
(In Go 1.9 the limit was 1024.)
The garbage collector has been modified to reduce its impact on allocation latency.
It now uses a smaller fraction of the overall CPU when running, but it may run more of the time.
The total CPU consumed by the garbage collector has not changed significantly.
</p>
<p>
TODO: Anything about CL 59970: "runtime: separate soft and hard heap limits"?
The <a href="/pkg/runtime/#GOROOT"><code>GOROOT</code></a> function
now defaults (when the <code>$GOROOT</code> environment variable is not set)
to the <code>GOROOT</code> or <code>GOROOT_FINAL</code> in effect
at the time the calling program was compiled.
Previously it used the <code>GOROOT</code> or <code>GOROOT_FINAL</code> in effect
at the time the toolchain that compiled the calling program was compiled.
</p>
<p>
There is no longer a limit on the <a href="/pkg/runtime/#GOMAXPROCS"><code>GOMAXPROCS</code></a> setting.
(In Go 1.9 the limit was 1024.)
</p>
<h2 id="performance">Performance</h2>
@ -689,9 +754,9 @@ The
<a href="/pkg/bytes/#Split"><code>Split</code></a>,
and
<a href="/pkg/bytes/#SplitAfter"><code>SplitAfter</code></a>
each already returned slices pointing into the same underlying array as its input.
Go 1.10 changes each of the returned subslices to have capacity equal to its length,
so that appending to a subslice will not overwrite adjacent data in the original input.
functions have always returned subslices of their inputs.
Go 1.10 changes each returned subslice to have capacity equal to its length,
so that appending to one cannot overwrite adjacent data in the original input.
</p>
</dl>
@ -717,13 +782,13 @@ them unless explicitly advertised.
<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
<dd>
<p>
Leaf certificate validation now enforces the name constraints for all
<a href="/pkg/crypto/x509/#Certificate.Verify"><code>Certificate.Verify</code></a>
now enforces the name constraints for all
names contained in the certificate, not just the one name that a client has asked about.
Extended key usage restrictions are similarly now checked all at once.
As a result, after a certificate has been validated, now it can be trusted in its entirety.
It is no longer necessary to revalidate the certificate for each additional name
or key usage.
TODO: Link to docs that may not exist yet.
</p>
<p>
@ -731,7 +796,8 @@ Parsed certificates also now report URI names and IP, email, and URI constraints
<a href="/pkg/crypto/x509/#Certificate"><code>Certificate</code></a> fields
<code>URIs</code>, <code>PermittedIPRanges</code>, <code>ExcludedIPRanges</code>,
<code>PermittedEmailAddresses</code>, <code>ExcludedEmailAddresses</code>,
<code>PermittedURIDomains</code>, and <code>ExcludedURIDomains</code>.
<code>PermittedURIDomains</code>, and <code>ExcludedURIDomains</code>. Certificates with
invalid values for those fields are now rejected.
</p>
<p>
@ -760,6 +826,13 @@ formats the X.509 distinguished name in the standard RFC 2253 format.
<dl id="database/sql/driver"><dt><a href="/pkg/database/sql/driver/">database/sql/driver</a></dt>
<dd>
<p>
Drivers that currently hold on to the destination buffer provided by
<a href="/pkg/database/sql/driver/#Rows.Next"><code>driver.Rows.Next</code></a> should ensure they no longer
write to a buffer assigned to the destination array outside of that call.
Drivers must be careful that underlying buffers are not modified when closing
<a href="/pkg/database/sql/driver/#Rows"><code>driver.Rows</code></a>.
</p>
<p>
Drivers that want to construct a <a href="/pkg/database/sql/#DB"><code>sql.DB</code></a> for
their clients can now implement the <a href="/pkg/database/sql/driver/#Connector"><code>Connector</code></a> interface
and call the new <a href="/pkg/database/sql/#OpenDB"><code>sql.OpenDB</code></a> function,
@ -819,8 +892,8 @@ types and associated constants.
</p>
<p>
Go 1.10 also adds support for the <code>LC_RPATH</code> load command,
represented by the types
<a href="/pkg/debug/macho/#RpathCmd"><code>RpathCmd</code></a> and
represented by the types
<a href="/pkg/debug/macho/#RpathCmd"><code>RpathCmd</code></a> and
<a href="/pkg/debug/macho/#Rpath"><code>Rpath</code></a>,
and new <a href="/pkg/debug/macho/#pkg-constants">named constants</a>
for the various flag bits found in headers.
@ -860,7 +933,7 @@ such as NUL, carriage return, newline, invalid runes, and the Unicode replacemen
or setting <code>Comma</code> and <code>Comment</code> equal to each other.
</p>
<p>
In the case of a syntax error in a CSV record that spans multiple input lines, <code>Reader</code>
In the case of a syntax error in a CSV record that spans multiple input lines, <code>Reader</code>
now reports the line on which the record started in the <a href="/pkg/encoding/csv/#ParseError"><code>ParseError</code></a>'s new <code>StartLine</code> field.
</p>
</dl>
@ -870,17 +943,17 @@ now reports the line on which the record started in the <a href="/pkg/encoding/c
<p>
The new functions
<a href="/pkg/encoding/hex/#NewEncoder"><code>NewEncoder</code></a>
and
and
<a href="/pkg/encoding/hex/#NewDecoder"><code>NewDecoder</code></a>
provide streaming conversions to and from hexadecimal,
analogous to equivalent functions already in
analogous to equivalent functions already in
<a href="/pkg/encoding/base32/">encoding/base32</a>
and
<a href="/pkg/encoding/base64/">encoding/base64</a>.
</p>
<p>
When the functions
When the functions
<a href="/pkg/encoding/hex/#Decode"><code>Decode</code></a>
and
<a href="/pkg/encoding/hex/#DecodeString"><code>DecodeString</code></a>
@ -928,7 +1001,7 @@ block that is impossible to encode as PEM data.
<p>
The new function
<a href="/pkg/encoding/xml/#NewTokenDecoder"><code>NewTokenDecoder</code></a>
is like
is like
<a href="/pkg/encoding/xml/#NewDecoder"><code>NewDecoder</code></a>
but creates a decoder reading from a <a href="/pkg/encoding/xml/#TokenReader"><code>TokenReader</code></a>
instead of an XML-formatted byte stream.
@ -941,7 +1014,7 @@ This is meant to enable the construction of XML stream transformers in client li
<p>
The default
<a href="/pkg/flag/#Usage"><code>Usage</code></a> function now prints
its first line of output to
its first line of output to
<code>CommandLine.Output()</code>
instead of assuming <code>os.Stderr</code>,
so that the usage message is properly redirected for
@ -1008,12 +1081,10 @@ now implement those interfaces.
<dl id="html/template"><dt><a href="/pkg/html/template/">html/template</a></dt>
<dd>
<p>
The new actions <code>{{"{{break}}"}}</code> and <code>{{"{{continue}}"}}</code>
break out of the innermost <code>{{"{{range"}}</code>&nbsp;...<code>}}</code> loop,
like the corresponding Go statements.
</p>
<p>
TODO: something about the AddParseTree problem (#21844).
The new <a href="/pkg/html/template#Srcset"><code>Srcset</code></a> content
type allows for proper handling of values within the
<a href="https://w3c.github.io/html/semantics-embedded-content.html#element-attrdef-img-srcset"><code>srcset</code></a>
attribute of <code>img</code> tags.
</p>
</dl>
@ -1026,9 +1097,9 @@ in its <a href="/pkg/math/big/#Int.SetString"><code>SetString</code></a> and <a
The value of the constant <code>MaxBase</code> has been updated.
</p>
<p>
<a href="/pkg/math/big/#Int"><code>Int</code></a> adds a new
<a href="/pkg/math/big/#Int"><code>Int</code></a> adds a new
<a href="/pkg/math/big/#CmpAbs"><code>CmpAbs</code></a> method
that is like <a href="/pkg/math/big/#Cmp"><code>Cmp</code></a> but
that is like <a href="/pkg/math/big/#Cmp"><code>Cmp</code></a> but
compares only the absolute values (not the signs) of its arguments.
</p>
<p>
@ -1042,11 +1113,11 @@ compute square roots.
<dd>
<p>
Branch cuts and other boundary cases in
<a href="/pkg/math/cmplx/#Asin"><code>Asin<code></a>,
<a href="/pkg/math/cmplx/#Asinh"><code>Asinh<code></a>,
<a href="/pkg/math/cmplx/#Atan"><code>Atan<code></a>,
<a href="/pkg/math/cmplx/#Asin"><code>Asin</code></a>,
<a href="/pkg/math/cmplx/#Asinh"><code>Asinh</code></a>,
<a href="/pkg/math/cmplx/#Atan"><code>Atan</code></a>,
and
<a href="/pkg/math/cmplx/#Sqrt"><code>Sqrt<code></a>
<a href="/pkg/math/cmplx/#Sqrt"><code>Sqrt</code></a>
have been corrected to match the definitions used in the C99 standard.
</p>
</dl>
@ -1113,7 +1184,7 @@ goroutines shortly after <code>Close</code> returned.)
<p>
<a href="/pkg/net/#TCPListener"><code>TCPListener</code></a> and
<a href="/pkg/net/#UnixListener"><code>UnixListener</code></a>
now implement
now implement
<a href="/pkg/syscall/#Conn"><code>syscall.Conn</code></a>,
to allow setting options on the underlying file descriptor
using <a href="/pkg/syscall/#RawConn"><code>syscall.RawConn.Control</code></a>.
@ -1154,14 +1225,11 @@ The content-serving handlers also now omit the <code>Content-Type</code> header
if passed an invalid (non-3-digit) status code.
</p>
<p>
<a href="/pkg/net/http/#Redirect"><code>Redirect</code></a> now sets the <code>Content-Type</code> header before writing its HTTP response.
<!-- CL 46631 -->
The <code>Server</code> will no longer add an implicit Content-Type when a <code>Handler</code> does not write any output.
</p>
</dl>
<dl id="net/http/httputil"><dt><a href="/pkg/net/http/httputil/">net/http/httputil</a></dt>
<dd>
<p>
TODO: ReverseProxy and back end errors and ModifyResponse.
<a href="/pkg/net/http/#Redirect"><code>Redirect</code></a> now sets the <code>Content-Type</code> header before writing its HTTP response.
</p>
</dl>
@ -1200,7 +1268,7 @@ were not indented.
<dd>
<p>
<a href="/pkg/net/url/#ResolveReference"><code>ResolveReference</code></a>
now preseves multiple leading slashes in the target URL.
now preserves multiple leading slashes in the target URL.
Previously it rewrote multiple leading slashes to a single slash,
which resulted in the <a href="/pkg/net/http/#Client"><code>http.Client</code></a>
following certain redirects incorrectly.
@ -1249,22 +1317,26 @@ and
that allow setting I/O deadlines when the
underlying file descriptor supports non-blocking I/O operations.
The definition of these methods matches those in <a href="/pkg/net/#Conn"><code>net.Conn</code></a>.
If an I/O method fails due to missing a deadline, it will return a
timeout error; the
new <a href="/pkg/os/#IsTimeout"><code>IsTimeout</code></a> function
reports whether an error represents a timeout.
</p>
<p>
Also matching <code>net.Conn</code>,
<code>File</code>'s
<code>File</code>'s
<a href="/pkg/os/#File.Close"><code>Close</code></a> method
now guarantee that when <code>Close</code> returns,
the underlying file descriptor has been closed.
(In earlier releases, like for <code>net.Conn</code>'s,
(In earlier releases,
if the <code>Close</code> stopped pending I/O
in other goroutines, the closing of the file descriptor could happen in one of those
goroutines shortly after <code>Close</code> returned.)
</p>
<p>
On BSD, macOS, and Solaris systems,
On BSD, macOS, and Solaris systems,
<a href="/pkg/os/#Chtimes"><code>Chtimes</code></a>
now supports setting file times with nanosecond precision
(assuming the underlying file system can represent them).
@ -1286,7 +1358,7 @@ in the corresponding <a href="/pkg/reflect/#StructField">StructField</a>,
with the result that for those fields,
and <a href="/pkg/reflect/#Value.CanSet"><code>Value.CanSet</code></a>
incorrectly returned true and
and <a href="/pkg/reflect/#Value.Set"><code>Value.Set</code></a>
<a href="/pkg/reflect/#Value.Set"><code>Value.Set</code></a>
incorrectly succeeded.
The underlying metadata has been corrected;
for those fields,
@ -1297,7 +1369,6 @@ that could previously unmarshal into such fields
but no longer can.
For example, see the <a href="#encoding/json"><code>encoding/json</code> notes</a>.
</p>
</p>
</dl>
<dl id="runtime/pprof"><dt><a href="/pkg/runtime/pprof/">runtime/pprof</a></dt>
@ -1312,7 +1383,7 @@ the binary that generated them.
<dl id="strconv"><dt><a href="/pkg/strconv/">strconv</a></dt>
<dd>
<p>
<a href="/pkg/strconv/#ParseUint"><code>ParseUint</code></a> now returns
<a href="/pkg/strconv/#ParseUint"><code>ParseUint</code></a> now returns
the maximum magnitude integer of the appropriate size
with any <code>ErrRange</code> error, as it was already documented to do.
Previously it returned 0 with <code>ErrRange</code> errors.
@ -1351,15 +1422,6 @@ is now implemented.
</p>
</dl>
<dl id="text/template"><dt><a href="/pkg/text/template/">text/template</a></dt>
<dd>
<p>
The new actions <code>{{"{{break}}"}}</code> and <code>{{"{{continue}}"}}</code>
break out of the innermost <code>{{"{{range"}}</code>&nbsp;...<code>}}</code> loop,
like the corresponding Go statements.
</p>
</dl>
<dl id="time"><dt><a href="/pkg/time/">time</a></dt>
<dd>
<p>
@ -1378,7 +1440,7 @@ allows conversion of IANA time zone file data to a <a href="/pkg/time/#Location"
<dd>
<p>
The <a href="/pkg/unicode/"><code>unicode</code></a> package and associated
support throughout the system has been upgraded from version 9.0 to
support throughout the system has been upgraded from Unicode 9.0 to
<a href="http://www.unicode.org/versions/Unicode10.0.0/">Unicode 10.0</a>,
which adds 8,518 new characters, including four new scripts, one new property,
a Bitcoin currency symbol, and 56 new emoji.

View file

@ -266,7 +266,7 @@ is now an error.
<p>
On the ARM, the toolchain supports "external linking", which
is a step towards being able to build shared libraries with the gc
tool chain and to provide dynamic linking support for environments
toolchain and to provide dynamic linking support for environments
in which that is necessary.
</p>

View file

@ -11,7 +11,7 @@ The latest Go release, version 1.3, arrives six months after 1.2,
and contains no language changes.
It focuses primarily on implementation work, providing
precise garbage collection,
a major refactoring of the compiler tool chain that results in
a major refactoring of the compiler toolchain that results in
faster builds, especially for large projects,
significant performance improvements across the board,
and support for DragonFly BSD, Solaris, Plan 9 and Google's Native Client architecture (NaCl).
@ -285,7 +285,7 @@ building and linking with a shared library.
<h3 id="gc_flag">Command-line flag parsing</h3>
<p>
In the gc tool chain, the assemblers now use the
In the gc toolchain, the assemblers now use the
same command-line flag parsing rules as the Go flag package, a departure
from the traditional Unix flag parsing.
This may affect scripts that invoke the tool directly.

View file

@ -775,7 +775,7 @@ to turn a string into an error. It replaces the old <code>os.NewError</code>.
</p>
{{code "/doc/progs/go1.go" `/ErrSyntax/`}}
<p>
<em>Updating</em>:
Running <code>go</code> <code>fix</code> will update almost all code affected by the change.
@ -1827,7 +1827,7 @@ for full details.
<tr><td>Uitob(x, b)</td> <td>FormatUint(uint64(x), b)</td></tr>
<tr><td>Uitob64(x, b)</td> <td>FormatUint(x, b)</td></tr>
</table>
<p>
<em>Updating</em>:
Running <code>go</code> <code>fix</code> will update almost all code affected by the change.
@ -1841,7 +1841,7 @@ a cast that must be added by hand; the <code>go</code> <code>fix</code> tool wil
<h3 id="templates">The template packages</h3>
<p>
The <code>template</code> and <code>exp/template/html</code> packages have moved to
The <code>template</code> and <code>exp/template/html</code> packages have moved to
<a href="/pkg/text/template/"><code>text/template</code></a> and
<a href="/pkg/html/template/"><code>html/template</code></a>.
More significant, the interface to these packages has been simplified.
@ -2035,4 +2035,4 @@ They are available for many combinations of architecture and operating system
Installation details are described on the
<a href="/doc/install">Getting Started</a> page, while
the distributions themselves are listed on the
<a href="https://golang.org/dl/">downloads page</a>.
<a href="/dl/">downloads page</a>.

View file

@ -190,8 +190,8 @@ For details and background, see
<h2 id="tools">Tools</h2>
<p>
Finally, the Go tool chain (compilers, linkers, build tools, and so
on) are under active development and may change behavior. This
Finally, the Go toolchain (compilers, linkers, build tools, and so
on) is under active development and may change behavior. This
means, for instance, that scripts that depend on the location and
properties of the tools may be broken by a point release.
</p>

View file

@ -479,6 +479,15 @@ as when hosting an untrusted program, the implementation could interlock
map access.
</p>
<p>
Map access is unsafe only when updates are occurring.
As long as all goroutines are only reading—looking up elements in the map,
including iterating through it using a
<code>for</code> <code>range</code> loop—and not changing the map
by assigning to elements or doing deletions,
it is safe for them to access the map concurrently without synchronization.
</p>
<h3 id="language_changes">
Will you accept my language change?</h3>
@ -1088,24 +1097,27 @@ The <code>go get</code> command therefore uses HTTPS for safety.
</p>
<p>
If you use <code>git</code> and prefer to push changes through SSH using your existing key
it's easy to work around this. For GitHub, try one of these solutions:
<code>Git</code> can be configured to authenticate over HTTPS or to use SSH in place of HTTPS.
To authenticate over HTTPS, you can add a line
to the <code>$HOME/.netrc</code> file that git consults:
</p>
<ul>
<li>Manually clone the repository in the expected package directory:
<pre>
$ cd src/github.com/username
$ git clone git@github.com:username/package.git
machine github.com login <i>USERNAME</i> password <i>APIKEY</i>
</pre>
</li>
<li>Force <code>git push</code> to use the <code>SSH</code> protocol by appending
these two lines to <code>~/.gitconfig</code>:
<p>
For GitHub accounts, the password can be a
<a href="https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/">personal access token</a>.
</p>
<p>
<code>Git</code> can also be configured to use SSH in place of HTTPS for URLs matching a given prefix.
For example, to use SSH for all GitHub access,
add these lines to your <code>~/.gitconfig</code>:
</p>
<pre>
[url "git@github.com:"]
pushInsteadOf = https://github.com/
[url "ssh://git@github.com/"]
insteadOf = https://github.com/
</pre>
</li>
</ul>
<h3 id="get_version">
How should I manage package versions using "go get"?</h3>
@ -1842,19 +1854,20 @@ supported by recent modifications to the gold linker.
Why is my trivial program such a large binary?</h3>
<p>
The linker in the <code>gc</code> tool chain
creates statically-linked binaries by default. All Go binaries therefore include the Go
The linker in the <code>gc</code> toolchain
creates statically-linked binaries by default.
All Go binaries therefore include the Go
run-time, along with the run-time type information necessary to support dynamic
type checks, reflection, and even panic-time stack traces.
</p>
<p>
A simple C "hello, world" program compiled and linked statically using gcc
on Linux is around 750 kB,
including an implementation of <code>printf</code>.
An equivalent Go program using <code>fmt.Printf</code>
is around 1.5 MB, but
that includes more powerful run-time support and type information.
A simple C "hello, world" program compiled and linked statically using
gcc on Linux is around 750 kB, including an implementation of
<code>printf</code>.
An equivalent Go program using
<code>fmt.Printf</code> weighs a couple of megabytes, but that includes
more powerful run-time support and type and debugging information.
</p>
<h3 id="unused_variables_and_imports">
@ -1922,6 +1935,26 @@ eliminating the unused imports issue in practice.
This program is easily connected to most editors to run automatically when a Go source file is written.
</p>
<h3 id="virus">
Why does my virus-scanning software think my Go distribution or compiled binary is infected?</h3>
<p>
This is a common occurrence, especially on Windows machines, and is almost always a false positive.
Commercial virus scanning programs are often confused by the structure of Go binaries, which
they don't see as often as those compiled from other languages.
</p>
<p>
If you've just installed the Go distribution and the system reports it is infected, that's certainly a mistake.
To be really thorough, you can verify the download by comparing the checksum with those on the
<a href="https://golang.org/dl/">downloads page</a>.
</p>
<p>
In any case, if you believe the report is in error, please report a bug to the supplier of your virus scanner.
Maybe in time virus scanners can learn to understand Go programs.
</p>
<h2 id="Performance">Performance</h2>
<h3 id="Why_does_Go_perform_badly_on_benchmark_x">

View file

@ -1,6 +1,6 @@
<!--{
"Title": "The Go Programming Language Specification",
"Subtitle": "Version of October 25, 2017",
"Subtitle": "Version of May 9, 2018",
"Path": "/ref/spec"
}-->
@ -694,9 +694,8 @@ TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType
</pre>
<p>
Named instances of the boolean, numeric, and string types are
<a href="#Predeclared_identifiers">predeclared</a>.
Other named types are introduced with <a href="#Type_declarations">type declarations</a>.
The language <a href="#Predeclared_identifiers">predeclares</a> certain type names.
Others are introduced with <a href="#Type_declarations">type declarations</a>.
<i>Composite types</i>&mdash;array, struct, pointer, function,
interface, slice, map, and channel types&mdash;may be constructed using
type literals.
@ -1025,8 +1024,8 @@ of a struct except that they cannot be used as field names in
</p>
<p>
Given a struct type <code>S</code> and a type named <code>T</code>,
promoted methods are included in the method set of the struct as follows:
Given a struct type <code>S</code> and a <a href="#Type_definitions">defined type</a>
<code>T</code>, promoted methods are included in the method set of the struct as follows:
</p>
<ul>
<li>
@ -1453,9 +1452,9 @@ components have identical types. In detail:
<a href="#Exported_identifiers">Non-exported</a> method names from different
packages are always different. The order of the methods is irrelevant.</li>
<li>Two map types are identical if they have identical key and value types.</li>
<li>Two map types are identical if they have identical key and element types.</li>
<li>Two channel types are identical if they have identical value types and
<li>Two channel types are identical if they have identical element types and
the same direction.</li>
</ul>
@ -1495,7 +1494,7 @@ A2 and struct{ a, b int }
A3 and int
A4, func(int, float64) *[]string, and A5
B0, B0, and C0
B0 and C0
[]int and []int
struct{ a, b *T5 } and struct{ a, b *T5 }
func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5
@ -2149,9 +2148,8 @@ to a function.
</p>
<pre class="ebnf">
FunctionDecl = "func" FunctionName ( Function | Signature ) .
FunctionDecl = "func" FunctionName Signature [ FunctionBody ] .
FunctionName = identifier .
Function = Signature FunctionBody .
FunctionBody = Block .
</pre>
@ -2197,7 +2195,7 @@ and associates the method with the receiver's <i>base type</i>.
</p>
<pre class="ebnf">
MethodDecl = "func" Receiver MethodName ( Function | Signature ) .
MethodDecl = "func" Receiver MethodName Signature [ FunctionBody ] .
Receiver = Parameters .
</pre>
@ -2519,7 +2517,7 @@ A function literal represents an anonymous <a href="#Function_declarations">func
</p>
<pre class="ebnf">
FunctionLit = "func" Function .
FunctionLit = "func" Signature FunctionBody .
</pre>
<pre>
@ -2643,8 +2641,8 @@ expression is illegal.
</li>
<li>
As an exception, if the type of <code>x</code> is a named pointer type
and <code>(*x).f</code> is a valid selector expression denoting a field
As an exception, if the type of <code>x</code> is a <a href="#Type_definitions">defined</a>
pointer type and <code>(*x).f</code> is a valid selector expression denoting a field
(but not a method), <code>x.f</code> is shorthand for <code>(*x).f</code>.
</li>
@ -3033,11 +3031,11 @@ For <code>a</code> of <a href="#Map_types">map type</a> <code>M</code>:
<a href="#Assignability">assignable</a>
to the key type of <code>M</code></li>
<li>if the map contains an entry with key <code>x</code>,
<code>a[x]</code> is the map value with key <code>x</code>
and the type of <code>a[x]</code> is the value type of <code>M</code></li>
<code>a[x]</code> is the map element with key <code>x</code>
and the type of <code>a[x]</code> is the element type of <code>M</code></li>
<li>if the map is <code>nil</code> or does not contain such an entry,
<code>a[x]</code> is the <a href="#The_zero_value">zero value</a>
for the value type of <code>M</code></li>
for the element type of <code>M</code></li>
</ul>
<p>
@ -3053,7 +3051,6 @@ used in an <a href="#Assignments">assignment</a> or initialization of the specia
v, ok = a[x]
v, ok := a[x]
var v, ok = a[x]
var v, ok T = a[x]
</pre>
<p>
@ -3558,9 +3555,10 @@ with <code>x / y</code> truncated towards zero
</pre>
<p>
As an exception to this rule, if the dividend <code>x</code> is the most
negative value for the int type of <code>x</code>, the quotient
<code>q = x / -1</code> is equal to <code>x</code> (and <code>r = 0</code>).
The one exception to this rule is that if the dividend <code>x</code> is
the most negative value for the int type of <code>x</code>, the quotient
<code>q = x / -1</code> is equal to <code>x</code> (and <code>r = 0</code>)
due to two's-complement <a href="#Integer_overflow">integer overflow</a>:
</p>
<pre>
@ -3619,15 +3617,15 @@ For unsigned integer values, the operations <code>+</code>,
computed modulo 2<sup><i>n</i></sup>, where <i>n</i> is the bit width of
the <a href="#Numeric_types">unsigned integer</a>'s type.
Loosely speaking, these unsigned integer operations
discard high bits upon overflow, and programs may rely on ``wrap around''.
discard high bits upon overflow, and programs may rely on "wrap around".
</p>
<p>
For signed integers, the operations <code>+</code>,
<code>-</code>, <code>*</code>, and <code>&lt;&lt;</code> may legally
<code>-</code>, <code>*</code>, <code>/</code>, and <code>&lt;&lt;</code> may legally
overflow and the resulting value exists and is deterministically defined
by the signed integer representation, the operation, and its operands.
No exception is raised as a result of overflow. A
compiler may not optimize code under the assumption that overflow does
No exception is raised as a result of overflow.
A compiler may not optimize code under the assumption that overflow does
not occur. For instance, it may not assume that <code>x &lt; x + 1</code> is always true.
</p>
@ -4162,11 +4160,6 @@ operands and are evaluated at compile time.
Untyped boolean, numeric, and string constants may be used as operands
wherever it is legal to use an operand of boolean, numeric, or string type,
respectively.
Except for shift operations, if the operands of a binary operation are
different kinds of untyped constants, the operation and, for non-boolean operations, the result use
the kind that appears later in this list: integer, rune, floating-point, complex.
For example, an untyped integer constant divided by an
untyped complex constant yields an untyped complex constant.
</p>
<p>
@ -4176,9 +4169,17 @@ an untyped boolean constant. If the left operand of a constant
result is an integer constant; otherwise it is a constant of the same
type as the left operand, which must be of
<a href="#Numeric_types">integer type</a>.
Applying all other operators to untyped constants results in an untyped
constant of the same kind (that is, a boolean, integer, floating-point,
complex, or string constant).
</p>
<p>
Any other operation on untyped constants results in an untyped constant of the
same kind; that is, a boolean, integer, floating-point, complex, or string
constant.
If the untyped operands of a binary operation (other than a shift) are of
different kinds, the result is of the operand's kind that appears later in this
list: integer, rune, floating-point, complex.
For example, an untyped integer constant divided by an
untyped complex constant yields an untyped complex constant.
</p>
<pre>
@ -4356,7 +4357,9 @@ SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | S
<h3 id="Terminating_statements">Terminating statements</h3>
<p>
A terminating statement is one of the following:
A <i>terminating statement</i> prevents execution of all statements that lexically
appear after it in the same <a href="#Blocks">block</a>. The following statements
are terminating:
</p>
<ol>
@ -5120,7 +5123,7 @@ for i, s := range a {
}
var key string
var val interface {} // value type of m is assignable to val
var val interface {} // element type of m is assignable to val
m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
for key, val = range m {
h(key, val)

View file

@ -24,7 +24,7 @@ packages, though, read on.
<div class="detail">
<p>
There are two official Go compiler tool chains.
There are two official Go compiler toolchains.
This document focuses on the <code>gc</code> Go
compiler and tools.
For information on how to work on <code>gccgo</code>, a more traditional
@ -119,7 +119,7 @@ Go does not support CentOS 6 on these systems.
<h2 id="go14">Install Go compiler binaries</h2>
<p>
The Go tool chain is written in Go. To build it, you need a Go compiler installed.
The Go toolchain is written in Go. To build it, you need a Go compiler installed.
The scripts that do the initial build of the tools look for an existing Go tool
chain in <code>$GOROOT_BOOTSTRAP</code>.
If unset, the default value of <code>GOROOT_BOOTSTRAP</code>
@ -127,26 +127,26 @@ is <code>$HOME/go1.4</code>.
</p>
<p>
There are many options for the bootstrap tool chain.
There are many options for the bootstrap toolchain.
After obtaining one, set <code>GOROOT_BOOTSTRAP</code> to the
directory containing the unpacked tree.
For example, <code>$GOROOT_BOOTSTRAP/bin/go</code> should be
the <code>go</code> command binary for the bootstrap tool chain.
the <code>go</code> command binary for the bootstrap toolchain.
</p>
<p>
To use a binary release as a bootstrap tool chain, see
To use a binary release as a bootstrap toolchain, see
<a href="/dl/">the downloads page</a> or use any other
packaged Go distribution.
</p>
<p>
To build a bootstrap tool chain from source, use
To build a bootstrap toolchain from source, use
either the git branch <code>release-branch.go1.4</code> or
<a href="https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz">go1.4-bootstrap-20171003.tar.gz</a>,
which contains the Go 1.4 source code plus accumulated fixes
to keep the tools running on newer operating systems.
(Go 1.4 was the last distribution in which the tool chain was written in C.)
(Go 1.4 was the last distribution in which the toolchain was written in C.)
After unpacking the Go 1.4 source, <code>cd</code> to
the <code>src</code> subdirectory, set <code>CGO_ENABLED=0</code> in
the environment, and run <code>make.bash</code> (or,
@ -154,7 +154,7 @@ on Windows, <code>make.bat</code>).
</p>
<p>
To cross-compile a bootstrap tool chain from source, which is
To cross-compile a bootstrap toolchain from source, which is
necessary on systems Go 1.4 did not target (for
example, <code>linux/ppc64le</code>), install Go on a different system
and run <a href="/src/bootstrap.bash">bootstrap.bash</a>.
@ -307,7 +307,7 @@ package main
import "fmt"
func main() {
fmt.Printf("hello, world\n")
fmt.Printf("hello, world\n")
}
</pre>
@ -446,6 +446,7 @@ defaults to the parent of the directory where <code>all.bash</code> was run.
There is no need to set this unless you want to switch between multiple
local copies of the repository.
</p>
</li>
<li><code>$GOROOT_FINAL</code>
<p>
@ -456,12 +457,14 @@ If you want to build the Go tree in one location
but move it elsewhere after the build, set
<code>$GOROOT_FINAL</code> to the eventual location.
</p>
</li>
<li><code>$GOOS</code> and <code>$GOARCH</code>
<p>
The name of the target operating system and compilation architecture.
These default to the values of <code>$GOHOSTOS</code> and
<code>$GOHOSTARCH</code> respectively (described below).
</li>
<p>
Choices for <code>$GOOS</code> are
@ -582,6 +585,7 @@ The name of the host operating system and compilation architecture.
These default to the local system's operating system and
architecture.
</p>
</li>
<p>
Valid choices are the same as for <code>$GOOS</code> and
@ -600,6 +604,7 @@ directory to your <code>$PATH</code>, so you can use the tools.
If <code>$GOBIN</code> is set, the <a href="/cmd/go">go command</a>
installs all commands there.
</p>
</li>
<li><code>$GO386</code> (for <code>386</code> only, default is auto-detected
if built on either <code>386</code> or <code>amd64</code>, <code>387</code> otherwise)
@ -609,9 +614,10 @@ This controls the code generated by gc to use either the 387 floating-point unit
floating point computations.
</p>
<ul>
<li><code>GO386=387</code>: use x87 for floating point operations; should support all x86 chips (Pentium MMX or later).
<li><code>GO386=sse2</code>: use SSE2 for floating point operations; has better performance than 387, but only available on Pentium 4/Opteron/Athlon 64 or later.
<li><code>GO386=387</code>: use x87 for floating point operations; should support all x86 chips (Pentium MMX or later).</li>
<li><code>GO386=sse2</code>: use SSE2 for floating point operations; has better performance than 387, but only available on Pentium 4/Opteron/Athlon 64 or later.</li>
</ul>
</li>
<li><code>$GOARM</code> (for <code>arm</code> only; default is auto-detected if building
on the target processor, 6 if not)
@ -620,9 +626,9 @@ This sets the ARM floating point co-processor architecture version the run-time
should target. If you are compiling on the target system, its value will be auto-detected.
</p>
<ul>
<li><code>GOARM=5</code>: use software floating point; when CPU doesn't have VFP co-processor
<li><code>GOARM=6</code>: use VFPv1 only; default if cross compiling; usually ARM11 or better cores (VFPv2 or better is also supported)
<li><code>GOARM=7</code>: use VFPv3; usually Cortex-A cores
<li><code>GOARM=5</code>: use software floating point; when CPU doesn't have VFP co-processor</li>
<li><code>GOARM=6</code>: use VFPv1 only; default if cross compiling; usually ARM11 or better cores (VFPv2 or better is also supported)</li>
<li><code>GOARM=7</code>: use VFPv3; usually Cortex-A cores</li>
</ul>
<p>
If in doubt, leave this variable unset, and adjust it if required
@ -631,6 +637,17 @@ The <a href="//golang.org/wiki/GoArm">GoARM</a> page
on the <a href="//golang.org/wiki">Go community wiki</a>
contains further details regarding Go's ARM support.
</p>
</li>
<li><code>$GOMIPS</code> (for <code>mips</code> and <code>mipsle</code> only)
<p>
This sets whether to use floating point instructions.
</p>
<ul>
<li><code>GOMIPS=hardfloat</code>: use floating point instructions (the default)</li>
<li><code>GOMIPS=softfloat</code>: use soft floating point</li>
</ul>
</li>
</ul>

View file

@ -8,14 +8,14 @@
<h2 id="download">Download the Go distribution</h2>
<p>
<a href="https://golang.org/dl/" id="start" class="download">
<a href="/dl/" id="start" class="download">
<span class="big">Download Go</span>
<span class="desc">Click here to visit the downloads page</span>
</a>
</p>
<p>
<a href="https://golang.org/dl/" target="_blank">Official binary
<a href="/dl/" target="_blank">Official binary
distributions</a> are available for the FreeBSD (release 10-STABLE and above),
Linux, Mac OS X (10.8 and above), and Windows operating systems and
the 32-bit (<code>386</code>) and 64-bit (<code>amd64</code>) x86 processor
@ -33,7 +33,7 @@ system and architecture, try
<h2 id="requirements">System requirements</h2>
<p>
Go <a href="https://golang.org/dl/">binary distributions</a> are available for these supported operating systems and architectures.
Go <a href="/dl/">binary distributions</a> are available for these supported operating systems and architectures.
Please ensure your system meets these requirements before proceeding.
If your OS or architecture is not on the list, you may be able to
<a href="/doc/install/source">install from source</a> or
@ -77,7 +77,7 @@ first <a href="#uninstall">remove the existing version</a>.
<h3 id="tarball">Linux, Mac OS X, and FreeBSD tarballs</h3>
<p>
<a href="https://golang.org/dl/">Download the archive</a>
<a href="/dl/">Download the archive</a>
and extract it into <code>/usr/local</code>, creating a Go tree in
<code>/usr/local/go</code>. For example:
</p>
@ -106,6 +106,14 @@ variable. You can do this by adding this line to your <code>/etc/profile</code>
export PATH=$PATH:/usr/local/go/bin
</pre>
<p>
<b>Note</b>: changes made to a <code>profile</code> file may not apply until the
next time you log into your computer.
To apply the changes immediately, just run the shell commands directly
or execute them from the profile using a command such as
<code>source $HOME/.profile</code>.
</p>
<h4 id="tarball_non_standard">Installing to a custom location</h4>
<p>
@ -138,7 +146,7 @@ location.
<h3 id="osx">Mac OS X package installer</h3>
<p>
<a href="https://golang.org/dl/">Download the package file</a>,
<a href="/dl/">Download the package file</a>,
open it, and follow the prompts to install the Go tools.
The package installs the Go distribution to <code>/usr/local/go</code>.
</p>
@ -167,7 +175,7 @@ MSI installer that configures your installation automatically.
<h4 id="windows_msi">MSI installer</h4>
<p>
Open the <a href="https://golang.org/dl/">MSI file</a>
Open the <a href="/dl/">MSI file</a>
and follow the prompts to install the Go tools.
By default, the installer puts the Go distribution in <code>c:\Go</code>.
</p>
@ -185,7 +193,7 @@ command prompts for the change to take effect.
<h4 id="windows_zip">Zip archive</h4>
<p>
<a href="https://golang.org/dl/">Download the zip file</a> and extract it into the directory of your choice (we suggest <code>c:\Go</code>).
<a href="/dl/">Download the zip file</a> and extract it into the directory of your choice (we suggest <code>c:\Go</code>).
</p>
<p>
@ -236,7 +244,7 @@ package main
import "fmt"
func main() {
fmt.Printf("hello, world\n")
fmt.Printf("hello, world\n")
}
</pre>
@ -278,7 +286,7 @@ If you see the "hello, world" message then your Go installation is working.
<p>
You can run <code>go</code> <code>install</code> to install the binary into
your workspace's <code>bin</code> directory
or <code>go</code> <code>clean</code> to remove it.
or <code>go</code> <code>clean</code> <code>-i</code> to remove it.
</p>
<p>

View file

@ -20,11 +20,11 @@ func viewRecord(w http.ResponseWriter, r *http.Request) {
key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil)
record := new(Record)
if err := datastore.Get(c, key, record); err != nil {
http.Error(w, err.Error(), 500)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if err := viewTemplate.Execute(w, record); err != nil {
http.Error(w, err.Error(), 500)
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

View file

@ -33,7 +33,7 @@ type appHandler func(http.ResponseWriter, *http.Request) error
func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := fn(w, r); err != nil {
http.Error(w, err.Error(), 500)
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

View file

@ -58,7 +58,7 @@ simple, reliable, and efficient software.
<div id="gopher"></div>
<a href="https://golang.org/dl/" id="start">
<a href="/dl/" id="start">
<span class="big">Download Go</span>
<span class="desc">
Binary distributions available for<br>
@ -74,7 +74,7 @@ Linux, Mac OS X, Windows, and more.
<div class="left">
<div id="video">
<div class="rootHeading">Featured video</div>
<iframe width="415" height="241" src="//www.youtube.com/embed/ytEkHepK08c" frameborder="0" allowfullscreen></iframe>
<div class="js-frontpage-video" style="--aspect-ratio-padding: 58.07%;"><iframe width="415" height="241" src="//www.youtube.com/embed/ytEkHepK08c" frameborder="0" allowfullscreen></iframe></div>
</div>
</div>
@ -153,6 +153,10 @@ Linux, Mac OS X, Windows, and more.
];
var v = videos[Math.floor(Math.random()*videos.length)];
$('#video iframe').attr('height', v.h).attr('src', v.s);
// Compute the aspect ratio (as a percentage) of the video
// using the fixed width 415 and the height of the current video, v.h.
var ar = 100*v.h/415;
$('.js-frontpage-video').attr('style', '--aspect-ratio-padding: ' + ar + '%;');
});
{{end}}

View file

@ -3,7 +3,7 @@ the code and data maintained as part of the IANA Time Zone Database.
The IANA asserts that the database is in the public domain.
For more information, see
http://www.iana.org/time-zones
https://www.iana.org/time-zones
ftp://ftp.iana.org/tz/code/tz-link.htm
http://tools.ietf.org/html/rfc6557

View file

@ -5,7 +5,7 @@
# This script rebuilds the time zone files using files
# downloaded from the ICANN/IANA distribution.
# Consult http://www.iana.org/time-zones for the latest versions.
# Consult https://www.iana.org/time-zones for the latest versions.
# Versions to use.
CODE=2017c
@ -16,8 +16,8 @@ rm -rf work
mkdir work
cd work
mkdir zoneinfo
curl -O http://www.iana.org/time-zones/repository/releases/tzcode$CODE.tar.gz
curl -O http://www.iana.org/time-zones/repository/releases/tzdata$DATA.tar.gz
curl -L -O https://www.iana.org/time-zones/repository/releases/tzcode$CODE.tar.gz
curl -L -O https://www.iana.org/time-zones/repository/releases/tzdata$DATA.tar.gz
tar xzf tzcode$CODE.tar.gz
tar xzf tzdata$DATA.tar.gz
@ -42,10 +42,9 @@ zip -0 -r ../../zoneinfo.zip *
cd ../..
echo
if [ "$1" = "-work" ]; then
if [ "$1" = "-work" ]; then
echo Left workspace behind in work/.
else
rm -rf work
fi
echo New time zone files in zoneinfo.zip.

View file

@ -8,4 +8,17 @@ mobile subrepository:
To run the standard library tests, see androidtest.bash. Run it as
CC_FOR_TARGET=.../ndk-gcc GOARCH=arm GOARM=7 ./androidtest.bash
CC_FOR_TARGET=$STANDALONE_NDK_PATH/bin/clang GOARCH=arm64 ./androidtest.bash
To create a standalone android NDK tool chain, follow the instructions on
https://developer.android.com/ndk/guides/standalone_toolchain
To run tests on the Android device, add the bin directory to PATH so the
go tool can find the go_android_$GOARCH_exec wrapper generated by
androidtest.bash. Then, use the same GOARCH as when androidtest.bash ran
and set GOOS to android. For example, to run the go1 benchmarks
export PATH=$GOROOT/bin:$PATH
cd $GOROOT/test/bench/go1/
GOOS=android GOARCH=arm64 go test -bench=. -count=N -timeout=T

View file

@ -21,6 +21,9 @@ import (
)
func run(args ...string) string {
if flags := os.Getenv("GOANDROID_ADB_FLAGS"); flags != "" {
args = append(strings.Split(flags, " "), args...)
}
buf := new(bytes.Buffer)
cmd := exec.Command("adb", args...)
cmd.Stdout = io.MultiWriter(os.Stdout, buf)

View file

@ -349,6 +349,14 @@ var ptrTests = []ptrTest{
body: `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`,
fail: false,
},
{
// Test poller deadline with cgocheck=2. Issue #23435.
name: "deadline",
c: `#define US 10`,
imports: []string{"os", "time"},
body: `r, _, _ := os.Pipe(); r.SetDeadline(time.Now().Add(C.US * time.Microsecond))`,
fail: false,
},
}
func TestPointerChecks(t *testing.T) {

View file

@ -5,7 +5,7 @@
package main
/*
#cgo LDFLAGS: -c
#cgo LDFLAGS: -L/nonexist
void test() {
xxx; // ERROR HERE

View file

@ -31,6 +31,8 @@ struct S {
int x;
};
const char *cstr = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890";
extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter);
enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; }
@ -149,6 +151,18 @@ func benchCgoCall(b *testing.B) {
}
}
var sinkString string
func benchGoString(b *testing.B) {
for i := 0; i < b.N; i++ {
sinkString = C.GoString(C.cstr)
}
const want = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890"
if sinkString != want {
b.Fatalf("%q != %q", sinkString, want)
}
}
// Issue 2470.
func testUnsignedInt(t *testing.T) {
a := (int64)(C.UINT32VAL)

View file

@ -27,6 +27,7 @@ func testBuildID(t *testing.T) {
defer f.Close()
c := 0
sections:
for i, s := range f.Sections {
if s.Type != elf.SHT_NOTE {
continue
@ -47,7 +48,7 @@ func testBuildID(t *testing.T) {
if len(d) < 12 {
t.Logf("note section %d too short (%d < 12)", i, len(d))
continue
continue sections
}
namesz := f.ByteOrder.Uint32(d)
@ -59,7 +60,7 @@ func testBuildID(t *testing.T) {
if int(12+an+ad) > len(d) {
t.Logf("note section %d too short for header (%d < 12 + align(%d,4) + align(%d,4))", i, len(d), namesz, descsz)
continue
continue sections
}
// 3 == NT_GNU_BUILD_ID

View file

@ -86,5 +86,9 @@ func Test21809(t *testing.T) { test21809(t) }
func Test6907(t *testing.T) { test6907(t) }
func Test6907Go(t *testing.T) { test6907Go(t) }
func Test21897(t *testing.T) { test21897(t) }
func Test22906(t *testing.T) { test22906(t) }
func Test24206(t *testing.T) { test24206(t) }
func Test25143(t *testing.T) { test25143(t) }
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
func BenchmarkGoString(b *testing.B) { benchGoString(b) }

View file

@ -1,16 +0,0 @@
// 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.
// Issue 19832. Functions taking a pointer typedef were being expanded and triggering a compiler error.
package cgotest
// typedef struct { int i; } *PS;
// void T19832(PS p) {}
import "C"
import "testing"
func test19832(t *testing.T) {
C.T19832(nil)
}

View file

@ -0,0 +1,54 @@
// +build amd64,linux
// 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.
package cgotest
// Test that C.GoString uses IndexByte in safe manner.
/*
#include <sys/mman.h>
// Returns string with null byte at the last valid address
char* dangerousString1() {
int pageSize = 4096;
char *data = mmap(0, 2 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
mprotect(data + pageSize,pageSize,PROT_NONE);
int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte
int i = start;
for (; i < pageSize; i++) {
data[i] = 'x';
}
data[pageSize -1 ] = 0;
return data+start;
}
char* dangerousString2() {
int pageSize = 4096;
char *data = mmap(0, 3 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
mprotect(data + 2 * pageSize,pageSize,PROT_NONE);
int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte
int i = start;
for (; i < 2 * pageSize; i++) {
data[i] = 'x';
}
data[2*pageSize -1 ] = 0;
return data+start;
}
*/
import "C"
import (
"testing"
)
func test24206(t *testing.T) {
if l := len(C.GoString(C.dangerousString1())); l != 123 {
t.Errorf("Incorrect string length - got %d, want 123", l)
}
if l := len(C.GoString(C.dangerousString2())); l != 4096+123 {
t.Errorf("Incorrect string length - got %d, want %d", l, 4096+123)
}
}

View file

@ -0,0 +1,13 @@
// +build !amd64 !linux
// 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.
package cgotest
import "testing"
func test24206(t *testing.T) {
t.Skip("Skipping on non-amd64 or non-linux system")
}

View file

@ -0,0 +1,22 @@
// 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.
package cgotest
import "C"
import "testing"
func issue25143sum(ns ...C.int) C.int {
total := C.int(0)
for _, n := range ns {
total += n
}
return total
}
func test25143(t *testing.T) {
if got, want := issue25143sum(1, 2, 3), C.int(6); got != want {
t.Errorf("issue25143sum(1, 2, 3) == %v, expected %v", got, want)
}
}

View file

@ -4,6 +4,25 @@
// +build !windows
#include <stdint.h>
#include <dlfcn.h>
// Write our own versions of dlopen/dlsym/dlclose so that we represent
// the opaque handle as a Go uintptr rather than a Go pointer to avoid
// garbage collector confusion. See issue 23663.
uintptr_t dlopen4029(char* name, int flags) {
return (uintptr_t)(dlopen(name, flags));
}
uintptr_t dlsym4029(uintptr_t handle, char* name) {
return (uintptr_t)(dlsym((void*)(handle), name));
}
int dlclose4029(uintptr_t handle) {
return dlclose((void*)(handle));
}
void call4029(void *arg) {
void (*fn)(void) = arg;
fn();

View file

@ -7,10 +7,15 @@
package cgotest
/*
#include <stdint.h>
#include <dlfcn.h>
#cgo linux LDFLAGS: -ldl
extern void call4029(void *arg);
extern uintptr_t dlopen4029(char*, int);
extern uintptr_t dlsym4029(uintptr_t, char*);
extern int dlclose4029(uintptr_t);
extern void call4029(uintptr_t arg);
*/
import "C"
@ -51,15 +56,15 @@ func test4029(t *testing.T) {
}
func loadThySelf(t *testing.T, symbol string) {
this_process := C.dlopen(nil, C.RTLD_NOW)
if this_process == nil {
this_process := C.dlopen4029(nil, C.RTLD_NOW)
if this_process == 0 {
t.Error("dlopen:", C.GoString(C.dlerror()))
return
}
defer C.dlclose(this_process)
defer C.dlclose4029(this_process)
symbol_address := C.dlsym(this_process, C.CString(symbol))
if symbol_address == nil {
symbol_address := C.dlsym4029(this_process, C.CString(symbol))
if symbol_address == 0 {
t.Error("dlsym:", C.GoString(C.dlerror()))
return
}

View file

@ -9,7 +9,7 @@
TEXT cas<>(SB),NOSPLIT,$0
MOVW $0xffff0fc0, R15 // R15 is PC
TEXT ·RewindAndSetgid(SB),NOSPLIT,$-4-0
TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0
// Save link register
MOVW R14, R4

View file

@ -6,7 +6,7 @@
#include "textflag.h"
TEXT ·RewindAndSetgid(SB),NOSPLIT,$-8-0
TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0
// Save link register
MOVD R30, R9

View file

@ -7,7 +7,7 @@
#include "textflag.h"
TEXT ·RewindAndSetgid(SB),NOSPLIT,$-4-0
TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0
// Rewind stack pointer so anything that happens on the stack
// will clobber the test pattern created by the caller
ADDU $(1024*8), R29

View file

@ -32,7 +32,7 @@ func IntoGoAndBack() {
func testSigprocmask(t *testing.T) {
if r := C.RunSigThread(); r != 0 {
t.Error("pthread_create/pthread_join failed")
t.Errorf("pthread_create/pthread_join failed: %d", r)
}
if !blocked {
t.Error("Go runtime unblocked SIGIO")

View file

@ -0,0 +1,74 @@
// 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 cgo
package cgotest
/*
// It's going to be hard to include a whole real JVM to test this.
// So we'll simulate a really easy JVM using just the parts we need.
// This is the relevant part of jni.h.
struct _jobject;
typedef struct _jobject *jobject;
typedef jobject jclass;
typedef jobject jthrowable;
typedef jobject jstring;
typedef jobject jarray;
typedef jarray jbooleanArray;
typedef jarray jbyteArray;
typedef jarray jcharArray;
typedef jarray jshortArray;
typedef jarray jintArray;
typedef jarray jlongArray;
typedef jarray jfloatArray;
typedef jarray jdoubleArray;
typedef jarray jobjectArray;
typedef jobject jweak;
// Note: jvalue is already a non-pointer type due to it being a C union.
*/
import "C"
import (
"testing"
)
func test22906(t *testing.T) {
var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types.
_ = x1
var x2 C.jclass = 0
_ = x2
var x3 C.jthrowable = 0
_ = x3
var x4 C.jstring = 0
_ = x4
var x5 C.jarray = 0
_ = x5
var x6 C.jbooleanArray = 0
_ = x6
var x7 C.jbyteArray = 0
_ = x7
var x8 C.jcharArray = 0
_ = x8
var x9 C.jshortArray = 0
_ = x9
var x10 C.jintArray = 0
_ = x10
var x11 C.jlongArray = 0
_ = x11
var x12 C.jfloatArray = 0
_ = x12
var x13 C.jdoubleArray = 0
_ = x13
var x14 C.jobjectArray = 0
_ = x14
var x15 C.jweak = 0
_ = x15
}

View file

@ -13,6 +13,7 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"syscall"
"testing"
@ -166,6 +167,28 @@ func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) {
t.Logf("%s", out)
t.Fatal(err)
}
checkLineComments(t, libgoh)
}
var badLineRegexp = regexp.MustCompile(`(?m)^#line [0-9]+ "/.*$`)
// checkLineComments checks that the export header generated by
// -buildmode=c-archive doesn't have any absolute paths in the #line
// comments. We don't want those paths because they are unhelpful for
// the user and make the files change based on details of the location
// of GOPATH.
func checkLineComments(t *testing.T, hdrname string) {
hdr, err := ioutil.ReadFile(hdrname)
if err != nil {
if !os.IsNotExist(err) {
t.Error(err)
}
return
}
if line := badLineRegexp.Find(hdr); line != nil {
t.Errorf("bad #line directive with absolute path in %s: %q", hdrname, line)
}
}
func TestInstall(t *testing.T) {
@ -209,6 +232,7 @@ func TestEarlySignalHandler(t *testing.T) {
t.Logf("%s", out)
t.Fatal(err)
}
checkLineComments(t, "libgo2.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main2.c", "libgo2.a")
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
@ -238,6 +262,7 @@ func TestSignalForwarding(t *testing.T) {
t.Logf("%s", out)
t.Fatal(err)
}
checkLineComments(t, "libgo2.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
@ -260,6 +285,9 @@ func TestSignalForwarding(t *testing.T) {
}
func TestSignalForwardingExternal(t *testing.T) {
if GOOS == "freebsd" {
t.Skipf("skipping on %s/%s; signal always goes to the Go runtime", GOOS, GOARCH)
}
checkSignalForwardingTest(t)
defer func() {
@ -275,6 +303,7 @@ func TestSignalForwardingExternal(t *testing.T) {
t.Logf("%s", out)
t.Fatal(err)
}
checkLineComments(t, "libgo2.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
@ -387,6 +416,7 @@ func TestOsSignal(t *testing.T) {
t.Logf("%s", out)
t.Fatal(err)
}
checkLineComments(t, "libgo3.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main3.c", "libgo3.a")
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
@ -419,6 +449,7 @@ func TestSigaltstack(t *testing.T) {
t.Logf("%s", out)
t.Fatal(err)
}
checkLineComments(t, "libgo4.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main4.c", "libgo4.a")
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
@ -433,7 +464,7 @@ func TestSigaltstack(t *testing.T) {
}
const testar = `#!/usr/bin/env bash
while expr $1 : '[-]' >/dev/null; do
while [[ $1 == -* ]] >/dev/null; do
shift
done
echo "testar" > $1
@ -470,6 +501,7 @@ func TestExtar(t *testing.T) {
t.Logf("%s", out)
t.Fatal(err)
}
checkLineComments(t, "libgo4.h")
if _, err := os.Stat("testar.ran"); err != nil {
if os.IsNotExist(err) {
@ -570,6 +602,7 @@ func TestSIGPROF(t *testing.T) {
t.Logf("%s", out)
t.Fatal(err)
}
checkLineComments(t, "libgo6.h")
ccArgs := append(cc, "-o", "testp6"+exeSuffix, "main6.c", "libgo6.a")
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
@ -608,6 +641,7 @@ func TestCompileWithoutShared(t *testing.T) {
if err != nil {
t.Fatal(err)
}
checkLineComments(t, "libgo2.h")
exe := "./testnoshared" + exeSuffix
@ -642,3 +676,50 @@ func TestCompileWithoutShared(t *testing.T) {
t.Logf("%s", out)
expectSignal(t, err, syscall.SIGPIPE)
}
// Test that installing a second time recreates the header files.
func TestCachedInstall(t *testing.T) {
defer os.RemoveAll("pkg")
h1 := filepath.Join("pkg", libgodir, "libgo.h")
h2 := filepath.Join("pkg", libgodir, "p.h")
buildcmd := []string{"go", "install", "-i", "-buildmode=c-archive", "libgo"}
cmd := exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = gopathEnv
t.Log(buildcmd)
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
}
if _, err := os.Stat(h1); err != nil {
t.Errorf("libgo.h not installed: %v", err)
}
if _, err := os.Stat(h2); err != nil {
t.Errorf("p.h not installed: %v", err)
}
if err := os.Remove(h1); err != nil {
t.Fatal(err)
}
if err := os.Remove(h2); err != nil {
t.Fatal(err)
}
cmd = exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = gopathEnv
t.Log(buildcmd)
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
}
if _, err := os.Stat(h1); err != nil {
t.Errorf("libgo.h not installed in second run: %v", err)
}
if _, err := os.Stat(h2); err != nil {
t.Errorf("p.h not installed in second run: %v", err)
}
}

View file

@ -85,6 +85,8 @@ int main(int argc, char** argv) {
printf("write(2) unexpectedly succeeded\n");
return 0;
}
printf("did not receieve SIGPIPE\n");
return 0;
}
default:
printf("Unknown test: %d\n", test);

View file

@ -7,6 +7,7 @@ package cshared_test
import (
"debug/elf"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
@ -55,7 +56,8 @@ func TestMain(m *testing.M) {
androiddir = fmt.Sprintf("/data/local/tmp/testcshared-%d", os.Getpid())
if GOOS == "android" {
cmd := exec.Command("adb", "shell", "mkdir", "-p", androiddir)
args := append(adbCmd(), "shell", "mkdir", "-p", androiddir)
cmd := exec.Command(args[0], args[1:]...)
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("setupAndroid failed: %v\n%s\n", err, out)
@ -154,11 +156,19 @@ func cmdToRun(name string) string {
return "./" + name + exeSuffix
}
func adbCmd() []string {
cmd := []string{"adb"}
if flags := os.Getenv("GOANDROID_ADB_FLAGS"); flags != "" {
cmd = append(cmd, strings.Split(flags, " ")...)
}
return cmd
}
func adbPush(t *testing.T, filename string) {
if GOOS != "android" {
return
}
args := []string{"adb", "push", filename, fmt.Sprintf("%s/%s", androiddir, filename)}
args := append(adbCmd(), "push", filename, fmt.Sprintf("%s/%s", androiddir, filename))
cmd := exec.Command(args[0], args[1:]...)
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("adb command failed: %v\n%s\n", err, out)
@ -169,7 +179,7 @@ func adbRun(t *testing.T, env []string, adbargs ...string) string {
if GOOS != "android" {
t.Fatalf("trying to run adb command when operating system is not android.")
}
args := []string{"adb", "shell"}
args := append(adbCmd(), "shell")
// Propagate LD_LIBRARY_PATH to the adb shell invocation.
for _, e := range env {
if strings.Index(e, "LD_LIBRARY_PATH=") != -1 {
@ -237,7 +247,7 @@ func createHeaders() error {
}
if GOOS == "android" {
args = []string{"adb", "push", libgoname, fmt.Sprintf("%s/%s", androiddir, libgoname)}
args = append(adbCmd(), "push", libgoname, fmt.Sprintf("%s/%s", androiddir, libgoname))
cmd = exec.Command(args[0], args[1:]...)
out, err = cmd.CombinedOutput()
if err != nil {
@ -270,7 +280,8 @@ func cleanupAndroid() {
if GOOS != "android" {
return
}
cmd := exec.Command("adb", "shell", "rm", "-rf", androiddir)
args := append(adbCmd(), "shell", "rm", "-rf", androiddir)
cmd := exec.Command(args[0], args[1:]...)
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("cleanupAndroid failed: %v\n%s\n", err, out)
@ -311,7 +322,11 @@ func TestExportedSymbolsWithDynamicLoad(t *testing.T) {
createHeadersOnce(t)
runCC(t, "-o", cmd, "main1.c", "-ldl")
if GOOS != "freebsd" {
runCC(t, "-o", cmd, "main1.c", "-ldl")
} else {
runCC(t, "-o", cmd, "main1.c")
}
adbPush(t, cmd)
defer os.Remove(bin)
@ -400,7 +415,11 @@ func testSignalHandlers(t *testing.T, pkgname, cfile, cmd string) {
"-o", libname, pkgname,
)
adbPush(t, libname)
runCC(t, "-pthread", "-o", cmd, cfile, "-ldl")
if GOOS != "freebsd" {
runCC(t, "-pthread", "-o", cmd, cfile, "-ldl")
} else {
runCC(t, "-pthread", "-o", cmd, cfile)
}
adbPush(t, cmd)
bin := cmdToRun(cmd)
@ -477,3 +496,99 @@ func TestPIE(t *testing.T) {
}
}
}
// Test that installing a second time recreates the header files.
func TestCachedInstall(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "cshared")
if err != nil {
t.Fatal(err)
}
// defer os.RemoveAll(tmpdir)
copyFile(t, filepath.Join(tmpdir, "src", "libgo", "libgo.go"), filepath.Join("src", "libgo", "libgo.go"))
copyFile(t, filepath.Join(tmpdir, "src", "p", "p.go"), filepath.Join("src", "p", "p.go"))
env := append(os.Environ(), "GOPATH="+tmpdir)
buildcmd := []string{"go", "install", "-x", "-i", "-buildmode=c-shared", "-installsuffix", "testcshared", "libgo"}
cmd := exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = env
t.Log(buildcmd)
out, err := cmd.CombinedOutput()
t.Logf("%s", out)
if err != nil {
t.Fatal(err)
}
var libgoh, ph string
walker := func(path string, info os.FileInfo, err error) error {
if err != nil {
t.Fatal(err)
}
var ps *string
switch filepath.Base(path) {
case "libgo.h":
ps = &libgoh
case "p.h":
ps = &ph
}
if ps != nil {
if *ps != "" {
t.Fatalf("%s found again", *ps)
}
*ps = path
}
return nil
}
if err := filepath.Walk(tmpdir, walker); err != nil {
t.Fatal(err)
}
if libgoh == "" {
t.Fatal("libgo.h not installed")
}
if ph == "" {
t.Fatal("p.h not installed")
}
if err := os.Remove(libgoh); err != nil {
t.Fatal(err)
}
if err := os.Remove(ph); err != nil {
t.Fatal(err)
}
cmd = exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = env
t.Log(buildcmd)
out, err = cmd.CombinedOutput()
t.Logf("%s", out)
if err != nil {
t.Fatal(err)
}
if _, err := os.Stat(libgoh); err != nil {
t.Errorf("libgo.h not installed in second run: %v", err)
}
if _, err := os.Stat(ph); err != nil {
t.Errorf("p.h not installed in second run: %v", err)
}
}
// copyFile copies src to dst.
func copyFile(t *testing.T, dst, src string) {
t.Helper()
data, err := ioutil.ReadFile(src)
if err != nil {
t.Fatal(err)
}
if err := os.MkdirAll(filepath.Dir(dst), 0777); err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(dst, data, 0666); err != nil {
t.Fatal(err)
}
}

View file

@ -9,7 +9,7 @@
#include <time.h>
#include <unistd.h>
#define fd (100)
#define fd (30)
// Tests libgo2.so, which does not export any functions.
// Read a string from the file descriptor and print it.
@ -21,7 +21,7 @@ int main(void) {
// The descriptor will be initialized in a thread, so we have to
// give a chance to get opened.
for (i = 0; i < 1000; i++) {
for (i = 0; i < 200; i++) {
n = read(fd, buf, sizeof buf);
if (n >= 0)
break;
@ -33,7 +33,7 @@ int main(void) {
// An EBADF error means that the shared library has not opened the
// descriptor yet.
ts.tv_sec = 0;
ts.tv_nsec = 1000000;
ts.tv_nsec = 10000000;
nanosleep(&ts, NULL);
}

View file

@ -21,7 +21,7 @@ import (
// that the C code can also use.
const (
fd = 100
fd = 30
)
func init() {

View file

@ -0,0 +1,21 @@
// 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.
package main
import "plugin"
func main() {
p, err := plugin.Open("issue24351.so")
if err != nil {
panic(err)
}
f, err := p.Lookup("B")
if err != nil {
panic(err)
}
c := make(chan bool)
f.(func(chan bool))(c)
<-c
}

View file

@ -0,0 +1,14 @@
// 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.
package main
import "fmt"
func B(c chan bool) {
go func() {
fmt.Println(1.5)
c <- true
}()
}

View file

@ -85,3 +85,8 @@ GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22175 src/issue22175/main.
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue.22295.so issue22295.pkg
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22295 src/issue22295.pkg/main.go
./issue22295
# Test for issue 24351
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue24351.so src/issue24351/plugin.go
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue24351 src/issue24351/main.go
./issue24351

View file

@ -407,7 +407,7 @@ func (d *tempDir) RemoveAll(t *testing.T) {
return
}
if err := os.RemoveAll(d.base); err != nil {
t.Fatal("Failed to remove temp dir: %v", err)
t.Fatalf("Failed to remove temp dir: %v", err)
}
}

View file

@ -351,10 +351,10 @@ func readNotes(f *elf.File) ([]*note, error) {
func dynStrings(t *testing.T, path string, flag elf.DynTag) []string {
f, err := elf.Open(path)
defer f.Close()
if err != nil {
t.Fatalf("elf.Open(%q) failed: %v", path, err)
}
defer f.Close()
dynstrings, err := f.DynString(flag)
if err != nil {
t.Fatalf("DynString(%s) failed on %s: %v", flag, path, err)
@ -598,7 +598,6 @@ func TestThreeGopathShlibs(t *testing.T) {
// If gccgo is not available or not new enough call t.Skip. Otherwise,
// return a build.Context that is set up for gccgo.
func prepGccgo(t *testing.T) build.Context {
t.Skip("golang.org/issue/22472")
gccgoName := os.Getenv("GCCGO")
if gccgoName == "" {
gccgoName = "gccgo"
@ -648,8 +647,6 @@ func TestGoPathShlibGccgo(t *testing.T) {
// library with gccgo, another GOPATH package that depends on the first and an
// executable that links the second library.
func TestTwoGopathShlibsGccgo(t *testing.T) {
t.Skip("golang.org/issue/22224")
gccgoContext := prepGccgo(t)
libgoRE := regexp.MustCompile("libgo.so.[0-9]+")
@ -793,6 +790,7 @@ func TestRebuilding(t *testing.T) {
// If the .a file is newer than the .so, the .so is rebuilt (but not the .a)
t.Run("newarchive", func(t *testing.T) {
resetFileStamps()
AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a"))
goCmd(t, "list", "-linkshared", "-f={{.ImportPath}} {{.Stale}} {{.StaleReason}} {{.Target}}", "depBase")
AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a"))
cleanup := touch(t, filepath.Join(gopathInstallDir, "depBase.a"))

View file

@ -1,44 +1,50 @@
Go on iOS
=========
To build a cross compiling toolchain for iOS on OS X, first modify clangwrap.sh
in misc/ios to match your setup. And then run:
For details on developing Go for iOS on macOS, see the documentation in the mobile
subrepository:
GOARM=7 CGO_ENABLED=1 GOARCH=arm CC_FOR_TARGET=`pwd`/../misc/ios/clangwrap.sh \
CXX_FOR_TARGET=`pwd`/../misc/ios/clangwrap.sh ./make.bash
https://github.com/golang/mobile
To build a program, use the normal go build command:
It is necessary to set up the environment before running tests or programs directly on a
device.
CGO_ENABLED=1 GOARCH=arm go build import/path
First make sure you have a valid developer certificate and have setup your device properly
to run apps signed by your developer certificate. Then install the libimobiledevice and
ideviceinstaller tools from https://www.libimobiledevice.org/. Use the HEAD versions from
source; the stable versions have bugs that prevents the Go exec wrapper to install and run
apps.
To run a program on an iDevice, first make sure you have a valid developer
certificate and have setup your iDevice properly to run apps signed by your
developer certificate. Then install https://github.com/phonegap/ios-deploy.
At a first step, you can try building the famous hello world program to run
on your test device.
(The needed files are provided at https://github.com/minux/go-ios-examples.)
Second, the Go exec wrapper must be told the developer account signing identity, the team
id and a provisioned bundle id to use. They're specified with the environment variables
GOIOS_DEV_ID, GOIOS_TEAM_ID and GOIOS_APP_ID. The detect.go program in this directory will
attempt to auto-detect suitable values. Run it as
# assume your program binary is helloworld.go, build it into the
# example hello.app bundle.
CGO_ENABLED=1 GOARCH=arm go build -o hello.app/hello helloworld.go
# sign the executable using your developer certificate
codesign -f -s "iPhone Developer" --entitlements hello.app/Entitlements.plist hello.app/hello
# run the program inside lldb on iDevice, run `ios-deploy` for more
# command options
ios-deploy --debug --uninstall --bundle hello.app
# Depending on your ios-deploy version, you might need to enter "run"
# into lldb to run your program, and its output will be shown by lldb.
go run detect.go
Notes:
- A dummy hello.app bundle is provided in this directory to help you get started.
- Running the program on an iDevice requires code sign and thus external linking,
if your program uses cgo, then it will automatically use external linking.
However, if your program does not use cgo, please make sure to add
import _ "runtime/cgo"
so that external linking will be used.
which will output something similar to
Known issues
============
- crypto/x509 won't build, I don't yet know how to get system root on iOS.
- Because I still want to be able to do native build, CGO_ENABLED=1 is not the
default, yet.
export GOIOS_DEV_ID="iPhone Developer: xxx@yyy.zzz (XXXXXXXX)"
export GOIOS_APP_ID=YYYYYYYY.some.bundle.id
export GOIOS_TEAM_ID=ZZZZZZZZ
If you have multiple devices connected, specify the device UDID with the GOIOS_DEVICE_ID
variable. Use `idevice_id -l` to list all available UDIDs.
Finally, to run the standard library tests, run iostest.bash with GOARCH set. For example,
GOARCH=arm64 ./iostest.bash
To use the go tool directly to run programs and tests, put $GOROOT/bin into PATH to ensure
the go_darwin_$GOARCH_exec wrapper is found. For example, to run the archive/tar tests
export PATH=$GOROOT/bin:$PATH
GOARCH=arm64 go test archive/tar
Note that the go_darwin_$GOARCH_exec wrapper uninstalls any existing app identified by
the bundle id before installing a new app. If the uninstalled app is the last app by
the developer identity, the device might also remove the permission to run apps from
that developer, and the exec wrapper will fail to install the new app. To avoid that,
install another app with the same developer identity but with a different bundle id.
That way, the permission to install apps is held on to while the primary app is
uninstalled.

View file

@ -14,6 +14,7 @@ package main
import (
"bytes"
"crypto/x509"
"fmt"
"io/ioutil"
"os"
@ -22,12 +23,14 @@ import (
)
func main() {
devID := detectDevID()
udids := getLines(exec.Command("idevice_id", "-l"))
if len(udids) == 0 {
fail("no udid found; is a device connected?")
}
udid := detectUDID()
mps := detectMobileProvisionFiles(udid)
mps := detectMobileProvisionFiles(udids)
if len(mps) == 0 {
fail("did not find mobile provision matching device udid %s", udid)
fail("did not find mobile provision matching device udids %q", udids)
}
fmt.Println("Available provisioning profiles below.")
@ -35,7 +38,6 @@ func main() {
fmt.Println("will be overwritten when running Go programs.")
for _, mp := range mps {
fmt.Println()
fmt.Printf("export GOIOS_DEV_ID=%s\n", devID)
f, err := ioutil.TempFile("", "go_ios_detect_")
check(err)
fname := f.Name()
@ -46,6 +48,12 @@ func main() {
check(err)
check(f.Close())
cert, err := plistExtract(fname, "DeveloperCertificates:0")
check(err)
pcert, err := x509.ParseCertificate(cert)
check(err)
fmt.Printf("export GOIOS_DEV_ID=\"%s\"\n", pcert.Subject.CommonName)
appID, err := plistExtract(fname, "Entitlements:application-identifier")
check(err)
fmt.Printf("export GOIOS_APP_ID=%s\n", appID)
@ -56,39 +64,7 @@ func main() {
}
}
func detectDevID() string {
cmd := exec.Command("security", "find-identity", "-p", "codesigning", "-v")
lines := getLines(cmd)
for _, line := range lines {
if !bytes.Contains(line, []byte("iPhone Developer")) {
continue
}
if bytes.Contains(line, []byte("REVOKED")) {
continue
}
fields := bytes.Fields(line)
return string(fields[1])
}
fail("no code signing identity found")
panic("unreachable")
}
var udidPrefix = []byte("UniqueDeviceID: ")
func detectUDID() []byte {
cmd := exec.Command("ideviceinfo")
lines := getLines(cmd)
for _, line := range lines {
if bytes.HasPrefix(line, udidPrefix) {
return bytes.TrimPrefix(line, udidPrefix)
}
}
fail("udid not found; is the device connected?")
panic("unreachable")
}
func detectMobileProvisionFiles(udid []byte) []string {
func detectMobileProvisionFiles(udids [][]byte) []string {
cmd := exec.Command("mdfind", "-name", ".mobileprovision")
lines := getLines(cmd)
@ -98,11 +74,17 @@ func detectMobileProvisionFiles(udid []byte) []string {
continue
}
xmlLines := getLines(parseMobileProvision(string(line)))
for _, xmlLine := range xmlLines {
if bytes.Contains(xmlLine, udid) {
files = append(files, string(line))
matches := 0
for _, udid := range udids {
for _, xmlLine := range xmlLines {
if bytes.Contains(xmlLine, udid) {
matches++
}
}
}
if matches == len(udids) {
files = append(files, string(line))
}
}
return files
}
@ -121,7 +103,12 @@ func plistExtract(fname string, path string) ([]byte, error) {
func getLines(cmd *exec.Cmd) [][]byte {
out := output(cmd)
return bytes.Split(out, []byte("\n"))
lines := bytes.Split(out, []byte("\n"))
// Skip the empty line at the end.
if len(lines[len(lines)-1]) == 0 {
lines = lines[:len(lines)-1]
}
return lines
}
func output(cmd *exec.Cmd) []byte {

View file

@ -21,27 +21,26 @@ package main
import (
"bytes"
"encoding/xml"
"errors"
"flag"
"fmt"
"go/build"
"io"
"io/ioutil"
"log"
"net"
"os"
"os/exec"
"os/signal"
"path/filepath"
"runtime"
"strings"
"sync"
"syscall"
"time"
)
const debug = false
var errRetry = errors.New("failed to start test harness (retry attempted)")
var tmpdir string
var (
@ -88,10 +87,28 @@ func main() {
bundleID = parts[1]
}
exitCode, err := runMain()
if err != nil {
log.Fatalf("%v\n", err)
}
os.Exit(exitCode)
}
func runMain() (int, error) {
var err error
tmpdir, err = ioutil.TempDir("", "go_darwin_arm_exec_")
if err != nil {
log.Fatal(err)
return 1, err
}
if !debug {
defer os.RemoveAll(tmpdir)
}
appdir := filepath.Join(tmpdir, "gotest.app")
os.RemoveAll(appdir)
if err := assembleApp(appdir, os.Args[1]); err != nil {
return 1, err
}
// This wrapper uses complicated machinery to run iOS binaries. It
@ -103,33 +120,43 @@ func main() {
lockName := filepath.Join(os.TempDir(), "go_darwin_arm_exec-"+deviceID+".lock")
lock, err = os.OpenFile(lockName, os.O_CREATE|os.O_RDONLY, 0666)
if err != nil {
log.Fatal(err)
return 1, err
}
if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX); err != nil {
log.Fatal(err)
return 1, err
}
// Approximately 1 in a 100 binaries fail to start. If it happens,
// try again. These failures happen for several reasons beyond
// our control, but all of them are safe to retry as they happen
// before lldb encounters the initial getwd breakpoint. As we
// know the tests haven't started, we are not hiding flaky tests
// with this retry.
for i := 0; i < 5; i++ {
if i > 0 {
fmt.Fprintln(os.Stderr, "start timeout, trying again")
}
err = run(os.Args[1], os.Args[2:])
if err == nil || err != errRetry {
break
}
if err := uninstall(bundleID); err != nil {
return 1, err
}
if !debug {
os.RemoveAll(tmpdir)
if err := install(appdir); err != nil {
return 1, err
}
if err := mountDevImage(); err != nil {
return 1, err
}
// Kill any hanging debug bridges that might take up port 3222.
exec.Command("killall", "idevicedebugserverproxy").Run()
closer, err := startDebugBridge()
if err != nil {
fmt.Fprintf(os.Stderr, "go_darwin_arm_exec: %v\n", err)
os.Exit(1)
return 1, err
}
defer closer()
if err := run(appdir, bundleID, os.Args[2:]); err != nil {
// If the lldb driver completed with an exit code, use that.
if err, ok := err.(*exec.ExitError); ok {
if ws, ok := err.Sys().(interface{ ExitStatus() int }); ok {
return ws.ExitStatus(), nil
}
}
return 1, err
}
return 0, nil
}
func getenv(envvar string) string {
@ -140,9 +167,7 @@ func getenv(envvar string) string {
return s
}
func run(bin string, args []string) (err error) {
appdir := filepath.Join(tmpdir, "gotest.app")
os.RemoveAll(appdir)
func assembleApp(appdir, bin string) error {
if err := os.MkdirAll(appdir, 0755); err != nil {
return err
}
@ -182,285 +207,325 @@ func run(bin string, args []string) (err error) {
if err := cmd.Run(); err != nil {
return fmt.Errorf("codesign: %v", err)
}
return nil
}
oldwd, err := os.Getwd()
// mountDevImage ensures a developer image is mounted on the device.
// The image contains the device lldb server for idevicedebugserverproxy
// to connect to.
func mountDevImage() error {
// Check for existing mount.
cmd := idevCmd(exec.Command("ideviceimagemounter", "-l", "-x"))
out, err := cmd.CombinedOutput()
if err != nil {
return err
os.Stderr.Write(out)
return fmt.Errorf("ideviceimagemounter: %v", err)
}
if err := os.Chdir(filepath.Join(appdir, "..")); err != nil {
return err
var info struct {
Dict struct {
Data []byte `xml:",innerxml"`
} `xml:"dict"`
}
defer os.Chdir(oldwd)
// Setting up lldb is flaky. The test binary itself runs when
// started is set to true. Everything before that is considered
// part of the setup and is retried.
started := false
defer func() {
if r := recover(); r != nil {
if w, ok := r.(waitPanic); ok {
err = w.err
if !started {
fmt.Printf("lldb setup error: %v\n", err)
err = errRetry
}
return
}
panic(r)
}
}()
defer exec.Command("killall", "ios-deploy").Run() // cleanup
exec.Command("killall", "ios-deploy").Run()
var opts options
opts, args = parseArgs(args)
// ios-deploy invokes lldb to give us a shell session with the app.
s, err := newSession(appdir, args, opts)
if err := xml.Unmarshal(out, &info); err != nil {
return fmt.Errorf("mountDevImage: failed to decode mount information: %v", err)
}
dict, err := parsePlistDict(info.Dict.Data)
if err != nil {
return err
return fmt.Errorf("mountDevImage: failed to parse mount information: %v", err)
}
defer func() {
b := s.out.Bytes()
if err == nil && !debug {
i := bytes.Index(b, []byte("(lldb) process continue"))
if i > 0 {
b = b[i:]
}
}
os.Stdout.Write(b)
}()
cond := func(out *buf) bool {
i0 := s.out.LastIndex([]byte("(lldb)"))
i1 := s.out.LastIndex([]byte("fruitstrap"))
i2 := s.out.LastIndex([]byte(" connect"))
return i0 > 0 && i1 > 0 && i2 > 0
}
if err := s.wait("lldb start", cond, 15*time.Second); err != nil {
panic(waitPanic{err})
}
// Script LLDB. Oh dear.
s.do(`process handle SIGHUP --stop false --pass true --notify false`)
s.do(`process handle SIGPIPE --stop false --pass true --notify false`)
s.do(`process handle SIGUSR1 --stop false --pass true --notify false`)
s.do(`process handle SIGCONT --stop false --pass true --notify false`)
s.do(`process handle SIGSEGV --stop false --pass true --notify false`) // does not work
s.do(`process handle SIGBUS --stop false --pass true --notify false`) // does not work
if opts.lldb {
_, err := io.Copy(s.in, os.Stdin)
if err != io.EOF {
return err
}
if dict["ImagePresent"] == "true" && dict["Status"] == "Complete" {
return nil
}
started = true
s.doCmd("run", "stop reason = signal SIGINT", 20*time.Second)
startTestsLen := s.out.Len()
fmt.Fprintln(s.in, `process continue`)
passed := func(out *buf) bool {
// Just to make things fun, lldb sometimes translates \n into \r\n.
return s.out.LastIndex([]byte("\nPASS\n")) > startTestsLen ||
s.out.LastIndex([]byte("\nPASS\r")) > startTestsLen ||
s.out.LastIndex([]byte("\n(lldb) PASS\n")) > startTestsLen ||
s.out.LastIndex([]byte("\n(lldb) PASS\r")) > startTestsLen ||
s.out.LastIndex([]byte("exited with status = 0 (0x00000000) \n")) > startTestsLen ||
s.out.LastIndex([]byte("exited with status = 0 (0x00000000) \r")) > startTestsLen
}
err = s.wait("test completion", passed, opts.timeout)
if passed(s.out) {
// The returned lldb error code is usually non-zero.
// We check for test success by scanning for the final
// PASS returned by the test harness, assuming the worst
// in its absence.
// Some devices only give us an ImageSignature key.
if _, exists := dict["ImageSignature"]; exists {
return nil
}
return err
}
type lldbSession struct {
cmd *exec.Cmd
in *os.File
out *buf
timedout chan struct{}
exited chan error
}
func newSession(appdir string, args []string, opts options) (*lldbSession, error) {
lldbr, in, err := os.Pipe()
// No image is mounted. Find a suitable image.
imgPath, err := findDevImage()
if err != nil {
return nil, err
return err
}
s := &lldbSession{
in: in,
out: new(buf),
exited: make(chan error),
sigPath := imgPath + ".signature"
cmd = idevCmd(exec.Command("ideviceimagemounter", imgPath, sigPath))
if out, err := cmd.CombinedOutput(); err != nil {
os.Stderr.Write(out)
return fmt.Errorf("ideviceimagemounter: %v", err)
}
return nil
}
iosdPath, err := exec.LookPath("ios-deploy")
// findDevImage use the device iOS version and build to locate a suitable
// developer image.
func findDevImage() (string, error) {
cmd := idevCmd(exec.Command("ideviceinfo"))
out, err := cmd.Output()
if err != nil {
return nil, err
return "", fmt.Errorf("ideviceinfo: %v", err)
}
cmdArgs := []string{
// lldb tries to be clever with terminals.
// So we wrap it in script(1) and be clever
// right back at it.
"script",
"-q", "-t", "0",
"/dev/null",
iosdPath,
"--debug",
"-u",
"-r",
"-n",
`--args=` + strings.Join(args, " ") + ``,
"--bundle", appdir,
}
if deviceID != "" {
cmdArgs = append(cmdArgs, "--id", deviceID)
}
s.cmd = exec.Command(cmdArgs[0], cmdArgs[1:]...)
if debug {
log.Println(strings.Join(s.cmd.Args, " "))
}
var out io.Writer = s.out
if opts.lldb {
out = io.MultiWriter(out, os.Stderr)
}
s.cmd.Stdout = out
s.cmd.Stderr = out // everything of interest is on stderr
s.cmd.Stdin = lldbr
if err := s.cmd.Start(); err != nil {
return nil, fmt.Errorf("ios-deploy failed to start: %v", err)
}
// Manage the -test.timeout here, outside of the test. There is a lot
// of moving parts in an iOS test harness (notably lldb) that can
// swallow useful stdio or cause its own ruckus.
if opts.timeout > 1*time.Second {
s.timedout = make(chan struct{})
time.AfterFunc(opts.timeout-1*time.Second, func() {
close(s.timedout)
})
}
go func() {
s.exited <- s.cmd.Wait()
}()
return s, nil
}
func (s *lldbSession) do(cmd string) { s.doCmd(cmd, "(lldb)", 0) }
func (s *lldbSession) doCmd(cmd string, waitFor string, extraTimeout time.Duration) {
startLen := s.out.Len()
fmt.Fprintln(s.in, cmd)
cond := func(out *buf) bool {
i := s.out.LastIndex([]byte(waitFor))
return i > startLen
}
if err := s.wait(fmt.Sprintf("running cmd %q", cmd), cond, extraTimeout); err != nil {
panic(waitPanic{err})
}
}
func (s *lldbSession) wait(reason string, cond func(out *buf) bool, extraTimeout time.Duration) error {
doTimeout := 2*time.Second + extraTimeout
doTimedout := time.After(doTimeout)
for {
select {
case <-s.timedout:
if p := s.cmd.Process; p != nil {
p.Kill()
}
return fmt.Errorf("test timeout (%s)", reason)
case <-doTimedout:
if p := s.cmd.Process; p != nil {
p.Kill()
}
return fmt.Errorf("command timeout (%s for %v)", reason, doTimeout)
case err := <-s.exited:
return fmt.Errorf("exited (%s: %v)", reason, err)
default:
if cond(s.out) {
return nil
}
time.Sleep(20 * time.Millisecond)
}
}
}
type buf struct {
mu sync.Mutex
buf []byte
}
func (w *buf) Write(in []byte) (n int, err error) {
w.mu.Lock()
defer w.mu.Unlock()
w.buf = append(w.buf, in...)
return len(in), nil
}
func (w *buf) LastIndex(sep []byte) int {
w.mu.Lock()
defer w.mu.Unlock()
return bytes.LastIndex(w.buf, sep)
}
func (w *buf) Bytes() []byte {
w.mu.Lock()
defer w.mu.Unlock()
b := make([]byte, len(w.buf))
copy(b, w.buf)
return b
}
func (w *buf) Len() int {
w.mu.Lock()
defer w.mu.Unlock()
return len(w.buf)
}
type waitPanic struct {
err error
}
type options struct {
timeout time.Duration
lldb bool
}
func parseArgs(binArgs []string) (opts options, remainingArgs []string) {
var flagArgs []string
for _, arg := range binArgs {
if strings.Contains(arg, "-test.timeout") {
flagArgs = append(flagArgs, arg)
}
if strings.Contains(arg, "-lldb") {
flagArgs = append(flagArgs, arg)
var iosVer, buildVer string
lines := bytes.Split(out, []byte("\n"))
for _, line := range lines {
spl := bytes.SplitN(line, []byte(": "), 2)
if len(spl) != 2 {
continue
}
remainingArgs = append(remainingArgs, arg)
key, val := string(spl[0]), string(spl[1])
switch key {
case "ProductVersion":
iosVer = val
case "BuildVersion":
buildVer = val
}
}
f := flag.NewFlagSet("", flag.ContinueOnError)
f.DurationVar(&opts.timeout, "test.timeout", 10*time.Minute, "")
f.BoolVar(&opts.lldb, "lldb", false, "")
f.Parse(flagArgs)
return opts, remainingArgs
if iosVer == "" || buildVer == "" {
return "", errors.New("failed to parse ideviceinfo output")
}
verSplit := strings.Split(iosVer, ".")
if len(verSplit) > 2 {
// Developer images are specific to major.minor ios version.
// Cut off the patch version.
iosVer = strings.Join(verSplit[:2], ".")
}
sdkBase := "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport"
patterns := []string{fmt.Sprintf("%s (%s)", iosVer, buildVer), fmt.Sprintf("%s (*)", iosVer), fmt.Sprintf("%s*", iosVer)}
for _, pattern := range patterns {
matches, err := filepath.Glob(filepath.Join(sdkBase, pattern, "DeveloperDiskImage.dmg"))
if err != nil {
return "", fmt.Errorf("findDevImage: %v", err)
}
if len(matches) > 0 {
return matches[0], nil
}
}
return "", fmt.Errorf("failed to find matching developer image for iOS version %s build %s", iosVer, buildVer)
}
// startDebugBridge ensures that the idevicedebugserverproxy runs on
// port 3222.
func startDebugBridge() (func(), error) {
errChan := make(chan error, 1)
cmd := idevCmd(exec.Command("idevicedebugserverproxy", "3222"))
var stderr bytes.Buffer
cmd.Stderr = &stderr
if err := cmd.Start(); err != nil {
return nil, fmt.Errorf("idevicedebugserverproxy: %v", err)
}
go func() {
if err := cmd.Wait(); err != nil {
if _, ok := err.(*exec.ExitError); ok {
errChan <- fmt.Errorf("idevicedebugserverproxy: %s", stderr.Bytes())
} else {
errChan <- fmt.Errorf("idevicedebugserverproxy: %v", err)
}
}
errChan <- nil
}()
closer := func() {
cmd.Process.Kill()
<-errChan
}
// Dial localhost:3222 to ensure the proxy is ready.
delay := time.Second / 4
for attempt := 0; attempt < 5; attempt++ {
conn, err := net.DialTimeout("tcp", "localhost:3222", 5*time.Second)
if err == nil {
conn.Close()
return closer, nil
}
select {
case <-time.After(delay):
delay *= 2
case err := <-errChan:
return nil, err
}
}
closer()
return nil, errors.New("failed to set up idevicedebugserverproxy")
}
// findDeviceAppPath returns the device path to the app with the
// given bundle ID. It parses the output of ideviceinstaller -l -o xml,
// looking for the bundle ID and the corresponding Path value.
func findDeviceAppPath(bundleID string) (string, error) {
cmd := idevCmd(exec.Command("ideviceinstaller", "-l", "-o", "xml"))
out, err := cmd.CombinedOutput()
if err != nil {
os.Stderr.Write(out)
return "", fmt.Errorf("ideviceinstaller: -l -o xml %v", err)
}
var list struct {
Apps []struct {
Data []byte `xml:",innerxml"`
} `xml:"array>dict"`
}
if err := xml.Unmarshal(out, &list); err != nil {
return "", fmt.Errorf("failed to parse ideviceinstaller output: %v", err)
}
for _, app := range list.Apps {
values, err := parsePlistDict(app.Data)
if err != nil {
return "", fmt.Errorf("findDeviceAppPath: failed to parse app dict: %v", err)
}
if values["CFBundleIdentifier"] == bundleID {
if path, ok := values["Path"]; ok {
return path, nil
}
}
}
return "", fmt.Errorf("failed to find device path for bundle: %s", bundleID)
}
// Parse an xml encoded plist. Plist values are mapped to string.
func parsePlistDict(dict []byte) (map[string]string, error) {
d := xml.NewDecoder(bytes.NewReader(dict))
values := make(map[string]string)
var key string
var hasKey bool
for {
tok, err := d.Token()
if err == io.EOF {
break
}
if err != nil {
return nil, err
}
if tok, ok := tok.(xml.StartElement); ok {
if tok.Name.Local == "key" {
if err := d.DecodeElement(&key, &tok); err != nil {
return nil, err
}
hasKey = true
} else if hasKey {
var val string
var err error
switch n := tok.Name.Local; n {
case "true", "false":
// Bools are represented as <true/> and <false/>.
val = n
err = d.Skip()
default:
err = d.DecodeElement(&val, &tok)
}
if err != nil {
return nil, err
}
values[key] = val
hasKey = false
} else {
if err := d.Skip(); err != nil {
return nil, err
}
}
}
}
return values, nil
}
func uninstall(bundleID string) error {
cmd := idevCmd(exec.Command(
"ideviceinstaller",
"-U", bundleID,
))
if out, err := cmd.CombinedOutput(); err != nil {
os.Stderr.Write(out)
return fmt.Errorf("ideviceinstaller -U %q: %s", bundleID, err)
}
return nil
}
func install(appdir string) error {
attempt := 0
for {
cmd := idevCmd(exec.Command(
"ideviceinstaller",
"-i", appdir,
))
if out, err := cmd.CombinedOutput(); err != nil {
// Sometimes, installing the app fails for some reason.
// Give the device a few seconds and try again.
if attempt < 5 {
time.Sleep(5 * time.Second)
attempt++
continue
}
os.Stderr.Write(out)
return fmt.Errorf("ideviceinstaller -i %q: %v (%d attempts)", appdir, err, attempt)
}
return nil
}
}
func idevCmd(cmd *exec.Cmd) *exec.Cmd {
if deviceID != "" {
// Inject -u device_id after the executable, but before the arguments.
args := []string{cmd.Args[0], "-u", deviceID}
cmd.Args = append(args, cmd.Args[1:]...)
}
return cmd
}
func run(appdir, bundleID string, args []string) error {
var env []string
for _, e := range os.Environ() {
// Don't override TMPDIR on the device.
if strings.HasPrefix(e, "TMPDIR=") {
continue
}
env = append(env, e)
}
attempt := 0
for {
// The device app path reported by the device might be stale, so retry
// the lookup of the device path along with the lldb launching below.
deviceapp, err := findDeviceAppPath(bundleID)
if err != nil {
// The device app path might not yet exist for a newly installed app.
if attempt == 5 {
return err
}
attempt++
time.Sleep(5 * time.Second)
continue
}
lldb := exec.Command(
"python",
"-", // Read script from stdin.
appdir,
deviceapp,
)
lldb.Args = append(lldb.Args, args...)
lldb.Env = env
lldb.Stdin = strings.NewReader(lldbDriver)
lldb.Stdout = os.Stdout
var out bytes.Buffer
lldb.Stderr = io.MultiWriter(&out, os.Stderr)
err = lldb.Start()
if err == nil {
// Forward SIGQUIT to the lldb driver which in turn will forward
// to the running program.
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGQUIT)
proc := lldb.Process
go func() {
for sig := range sigs {
proc.Signal(sig)
}
}()
err = lldb.Wait()
signal.Stop(sigs)
close(sigs)
}
// If the program was not started it can be retried without papering over
// real test failures.
started := bytes.HasPrefix(out.Bytes(), []byte("lldb: running program"))
if started || err == nil || attempt == 5 {
return err
}
// Sometimes, the app was not yet ready to launch or the device path was
// stale. Retry.
attempt++
time.Sleep(5 * time.Second)
}
}
func copyLocalDir(dst, src string) error {
@ -656,3 +721,91 @@ const resourceRules = `<?xml version="1.0" encoding="UTF-8"?>
</dict>
</plist>
`
const lldbDriver = `
import sys
import os
import signal
exe, device_exe, args = sys.argv[1], sys.argv[2], sys.argv[3:]
env = []
for k, v in os.environ.items():
env.append(k + "=" + v)
sys.path.append('/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python')
import lldb
debugger = lldb.SBDebugger.Create()
debugger.SetAsync(True)
debugger.SkipLLDBInitFiles(True)
err = lldb.SBError()
target = debugger.CreateTarget(exe, None, 'remote-ios', True, err)
if not target.IsValid() or not err.Success():
sys.stderr.write("lldb: failed to setup up target: %s\n" % (err))
sys.exit(1)
target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_exe))
listener = debugger.GetListener()
process = target.ConnectRemote(listener, 'connect://localhost:3222', None, err)
if not err.Success():
sys.stderr.write("lldb: failed to connect to remote target: %s\n" % (err))
sys.exit(1)
# Don't stop on signals.
sigs = process.GetUnixSignals()
for i in range(0, sigs.GetNumSignals()):
sig = sigs.GetSignalAtIndex(i)
sigs.SetShouldStop(sig, False)
sigs.SetShouldNotify(sig, False)
event = lldb.SBEvent()
running = False
prev_handler = None
while True:
if not listener.WaitForEvent(1, event):
continue
if not lldb.SBProcess.EventIsProcessEvent(event):
continue
if running:
# Pass through stdout and stderr.
while True:
out = process.GetSTDOUT(8192)
if not out:
break
sys.stdout.write(out)
while True:
out = process.GetSTDERR(8192)
if not out:
break
sys.stderr.write(out)
state = process.GetStateFromEvent(event)
if state in [lldb.eStateCrashed, lldb.eStateDetached, lldb.eStateUnloaded, lldb.eStateExited]:
if running:
signal.signal(signal.SIGQUIT, prev_handler)
break
elif state == lldb.eStateConnected:
process.RemoteLaunch(args, env, None, None, None, None, 0, False, err)
if not err.Success():
sys.stderr.write("lldb: failed to launch remote process: %s\n" % (err))
process.Kill()
debugger.Terminate()
sys.exit(1)
# Forward SIGQUIT to the program.
def signal_handler(signal, frame):
process.Signal(signal)
prev_handler = signal.signal(signal.SIGQUIT, signal_handler)
# Tell the Go driver that the program is running and should not be retried.
sys.stderr.write("lldb: running program\n")
running = True
# Process stops once at the beginning. Continue.
process.Continue()
exitStatus = process.GetExitStatus()
process.Kill()
debugger.Terminate()
sys.exit(exitStatus)
`

View file

@ -9,7 +9,7 @@
# content languages and encodings, so choose them carefully.
#
# Internet media types should be registered as described in RFC 4288.
# The registry is at <http://www.iana.org/assignments/media-types/>.
# The registry is at <https://www.iana.org/assignments/media-types/>.
#
# MIME type (lowercased) Extensions
# ============================================ ==========

View file

@ -1,8 +1,8 @@
This directory contains helper file for trace viewer (`go tool trace`).
`trace_viewer_lean.html` was generated by following
`trace_viewer_full.html` was generated by following
[instructions](https://github.com/catapult-project/catapult/blob/master/tracing/docs/embedding-trace-viewer.md)
on revision `623a005a3ffa9de13c4b92bc72290e7bcd1ca591`
on revision `dc970d3e1f7b3da5a2849de70ff253acdb70148f`
of [catapult](https://github.com/catapult-project/catapult) using:
```
catapult$ ./tracing/bin/vulcanize_trace_viewer --config=full

File diff suppressed because one or more lines are too long

14
misc/wasm/go_js_wasm_exec Executable file
View file

@ -0,0 +1,14 @@
#!/bin/bash
# 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.
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
exec node "$DIR/wasm_exec.js" "$@"

30
misc/wasm/wasm_exec.html Normal file
View file

@ -0,0 +1,30 @@
<!doctype html>
<!--
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.
-->
<html>
<head>
<meta charset="utf-8">
<title>Go wasm</title>
</head>
<body>
<script src="wasm_exec.js"></script>
<script>
async function loadAndCompile() {
let resp = await fetch("test.wasm");
let bytes = await resp.arrayBuffer();
await go.compile(bytes);
document.getElementById("runButton").disabled = false;
}
loadAndCompile();
</script>
<button onClick="console.clear(); go.run();" id="runButton" disabled>Run</button>
</body>
</html>

335
misc/wasm/wasm_exec.js Executable file
View file

@ -0,0 +1,335 @@
// 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.
(() => {
let args = ["js"];
// Map web browser API and Node.js API to a single common API (preferring web standards over Node.js API).
const isNodeJS = typeof process !== "undefined";
if (isNodeJS) {
if (process.argv.length < 3) {
process.stderr.write("usage: go_js_wasm_exec [wasm binary]\n");
process.exit(1);
}
args = args.concat(process.argv.slice(3));
global.require = require;
global.fs = require("fs");
const nodeCrypto = require("crypto");
global.crypto = {
getRandomValues(b) {
nodeCrypto.randomFillSync(b);
},
};
const now = () => {
const [sec, nsec] = process.hrtime();
return sec * 1000 + nsec / 1000000;
};
global.performance = {
timeOrigin: Date.now() - now(),
now: now,
};
const util = require("util");
global.TextEncoder = util.TextEncoder;
global.TextDecoder = util.TextDecoder;
} else {
window.global = window;
global.process = {
env: {},
exit(code) {
if (code !== 0) {
console.warn("exit code:", code);
}
},
};
let outputBuf = "";
global.fs = {
constants: {},
writeSync(fd, buf) {
outputBuf += decoder.decode(buf);
const nl = outputBuf.lastIndexOf("\n");
if (nl != -1) {
console.log(outputBuf.substr(0, nl));
outputBuf = outputBuf.substr(nl + 1);
}
return buf.length;
},
};
}
const encoder = new TextEncoder("utf-8");
const decoder = new TextDecoder("utf-8");
let mod, inst;
let values = []; // TODO: garbage collection
const mem = () => {
// The buffer may change when requesting more memory.
return new DataView(inst.exports.mem.buffer);
}
const setInt64 = (addr, v) => {
mem().setUint32(addr + 0, v, true);
mem().setUint32(addr + 4, Math.floor(v / 4294967296), true);
}
const getInt64 = (addr) => {
const low = mem().getUint32(addr + 0, true);
const high = mem().getInt32(addr + 4, true);
return low + high * 4294967296;
}
const loadValue = (addr) => {
const id = mem().getUint32(addr, true);
return values[id];
}
const storeValue = (addr, v) => {
if (v === undefined) {
mem().setUint32(addr, 0, true);
return;
}
if (v === null) {
mem().setUint32(addr, 1, true);
return;
}
values.push(v);
mem().setUint32(addr, values.length - 1, true);
}
const loadSlice = (addr) => {
const array = getInt64(addr + 0);
const len = getInt64(addr + 8);
return new Uint8Array(inst.exports.mem.buffer, array, len);
}
const loadSliceOfValues = (addr) => {
const array = getInt64(addr + 0);
const len = getInt64(addr + 8);
const a = new Array(len);
for (let i = 0; i < len; i++) {
const id = mem().getUint32(array + i * 4, true);
a[i] = values[id];
}
return a;
}
const loadString = (addr) => {
const saddr = getInt64(addr + 0);
const len = getInt64(addr + 8);
return decoder.decode(new DataView(inst.exports.mem.buffer, saddr, len));
}
global.go = {
async compileAndRun(source) {
await go.compile(source);
await go.run();
},
async compile(source) {
mod = await WebAssembly.compile(source);
},
async run() {
let importObject = {
go: {
// func wasmExit(code int32)
"runtime.wasmExit": (sp) => {
process.exit(mem().getInt32(sp + 8, true));
},
// func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
"runtime.wasmWrite": (sp) => {
const fd = getInt64(sp + 8);
const p = getInt64(sp + 16);
const n = mem().getInt32(sp + 24, true);
fs.writeSync(fd, new Uint8Array(inst.exports.mem.buffer, p, n));
},
// func nanotime() int64
"runtime.nanotime": (sp) => {
setInt64(sp + 8, (performance.timeOrigin + performance.now()) * 1000000);
},
// func walltime() (sec int64, nsec int32)
"runtime.walltime": (sp) => {
const msec = (new Date).getTime();
setInt64(sp + 8, msec / 1000);
mem().setInt32(sp + 16, (msec % 1000) * 1000000, true);
},
// func boolVal(value bool) Value
"syscall/js.boolVal": (sp) => {
storeValue(sp + 16, mem().getUint8(sp + 8) !== 0);
},
// func intVal(value int) Value
"syscall/js.intVal": (sp) => {
storeValue(sp + 16, getInt64(sp + 8));
},
// func floatVal(value float64) Value
"syscall/js.floatVal": (sp) => {
storeValue(sp + 16, mem().getFloat64(sp + 8, true));
},
// func stringVal(value string) Value
"syscall/js.stringVal": (sp) => {
storeValue(sp + 24, loadString(sp + 8));
},
// func (v Value) Get(key string) Value
"syscall/js.Value.Get": (sp) => {
storeValue(sp + 32, Reflect.get(loadValue(sp + 8), loadString(sp + 16)));
},
// func (v Value) set(key string, value Value)
"syscall/js.Value.set": (sp) => {
Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
},
// func (v Value) Index(i int) Value
"syscall/js.Value.Index": (sp) => {
storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
},
// func (v Value) setIndex(i int, value Value)
"syscall/js.Value.setIndex": (sp) => {
Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));
},
// func (v Value) call(name string, args []Value) (Value, bool)
"syscall/js.Value.call": (sp) => {
try {
const v = loadValue(sp + 8);
const m = Reflect.get(v, loadString(sp + 16));
const args = loadSliceOfValues(sp + 32);
storeValue(sp + 56, Reflect.apply(m, v, args));
mem().setUint8(sp + 60, 1);
} catch (err) {
storeValue(sp + 56, err);
mem().setUint8(sp + 60, 0);
}
},
// func (v Value) invoke(args []Value) (Value, bool)
"syscall/js.Value.invoke": (sp) => {
try {
const v = loadValue(sp + 8);
const args = loadSliceOfValues(sp + 16);
storeValue(sp + 40, Reflect.apply(v, undefined, args));
mem().setUint8(sp + 44, 1);
} catch (err) {
storeValue(sp + 40, err);
mem().setUint8(sp + 44, 0);
}
},
// func (v Value) new(args []Value) (Value, bool)
"syscall/js.Value.new": (sp) => {
try {
const v = loadValue(sp + 8);
const args = loadSliceOfValues(sp + 16);
storeValue(sp + 40, Reflect.construct(v, args));
mem().setUint8(sp + 44, 1);
} catch (err) {
storeValue(sp + 40, err);
mem().setUint8(sp + 44, 0);
}
},
// func (v Value) Float() float64
"syscall/js.Value.Float": (sp) => {
mem().setFloat64(sp + 16, parseFloat(loadValue(sp + 8)), true);
},
// func (v Value) Int() int
"syscall/js.Value.Int": (sp) => {
setInt64(sp + 16, parseInt(loadValue(sp + 8)));
},
// func (v Value) Bool() bool
"syscall/js.Value.Bool": (sp) => {
mem().setUint8(sp + 16, !!loadValue(sp + 8));
},
// func (v Value) Length() int
"syscall/js.Value.Length": (sp) => {
setInt64(sp + 16, parseInt(loadValue(sp + 8).length));
},
// func (v Value) prepareString() (Value, int)
"syscall/js.Value.prepareString": (sp) => {
const str = encoder.encode(String(loadValue(sp + 8)));
storeValue(sp + 16, str);
setInt64(sp + 24, str.length);
},
// func (v Value) loadString(b []byte)
"syscall/js.Value.loadString": (sp) => {
const str = loadValue(sp + 8);
loadSlice(sp + 16).set(str);
},
"debug": (value) => {
console.log(value);
},
}
};
inst = await WebAssembly.instantiate(mod, importObject);
values = [undefined, null, global, inst.exports.mem];
// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
let offset = 4096;
const strPtr = (str) => {
let ptr = offset;
new Uint8Array(inst.exports.mem.buffer, offset, str.length + 1).set(encoder.encode(str + "\0"));
offset += str.length + (8 - (str.length % 8));
return ptr;
};
const argc = args.length;
const argvPtrs = [];
args.forEach((arg) => {
argvPtrs.push(strPtr(arg));
});
const keys = Object.keys(process.env).sort();
argvPtrs.push(keys.length);
keys.forEach((key) => {
argvPtrs.push(strPtr(`${key}=${process.env[key]}`));
});
const argv = offset;
argvPtrs.forEach((ptr) => {
mem().setUint32(offset, ptr, true);
mem().setUint32(offset + 4, 0, true);
offset += 8;
});
try {
inst.exports.run(argc, argv);
} catch (err) {
console.error(err);
process.exit(1);
}
}
}
if (isNodeJS) {
go.compileAndRun(fs.readFileSync(process.argv[2])).catch((err) => {
console.error(err);
process.exit(1);
});
}
})();

View file

@ -23,17 +23,10 @@ if [ "$GOOS" != "android" ]; then
exit 1
fi
if [ -z $GOARM ]; then
export GOARM=7
fi
if [ "$GOARM" != "7" ]; then
if [ -n "$GOARM" ] && [ "$GOARM" != "7" ]; then
echo "android only supports GOARM=7, got GOARM=$GOARM" 1>&2
exit 1
fi
if [ "$GOARCH" = "" ]; then
echo "GOARCH must be set" 1>&2
exit 1
fi
export CGO_ENABLED=1
unset GOBIN
@ -77,8 +70,8 @@ cp -a "${GOROOT}/lib" "${FAKE_GOROOT}/"
cp -a "${pkgdir}" "${FAKE_GOROOT}/pkg/"
echo '# Syncing test files to android device'
adb shell mkdir -p /data/local/tmp/goroot
time adb sync data &> /dev/null
adb $GOANDROID_ADB_FLAGS shell mkdir -p /data/local/tmp/goroot
time adb $GOANDROID_ADB_FLAGS sync data &> /dev/null
export CLEANER=${ANDROID_TEST_DIR}/androidcleaner-$$
cp ../misc/android/cleaner.go $CLEANER.go
@ -86,8 +79,8 @@ echo 'var files = `' >> $CLEANER.go
(cd $ANDROID_PRODUCT_OUT/data/local/tmp/goroot; find . >> $CLEANER.go)
echo '`' >> $CLEANER.go
go build -o $CLEANER $CLEANER.go
adb push $CLEANER /data/local/tmp/cleaner
adb shell /data/local/tmp/cleaner
adb $GOANDROID_ADB_FLAGS push $CLEANER /data/local/tmp/cleaner
adb $GOANDROID_ADB_FLAGS shell /data/local/tmp/cleaner
echo ''

View file

@ -56,7 +56,7 @@ func (he headerError) Error() string {
const (
// Type '0' indicates a regular file.
TypeReg = '0'
TypeRegA = '\x00' // For legacy support; use TypeReg instead
TypeRegA = '\x00' // Deprecated: Use TypeReg instead.
// Type '1' to '6' are header-only flags and may not have a data body.
TypeLink = '1' // Hard link
@ -138,7 +138,10 @@ var basicKeys = map[string]bool{
// should do so by creating a new Header and copying the fields
// that they are interested in preserving.
type Header struct {
Typeflag byte // Type of header entry (should be TypeReg for most files)
// Typeflag is the type of header entry.
// The zero value is automatically promoted to either TypeReg or TypeDir
// depending on the presence of a trailing slash in Name.
Typeflag byte
Name string // Name of file entry
Linkname string // Target name of link (valid for TypeLink or TypeSymlink)
@ -184,7 +187,7 @@ type Header struct {
// The key and value should be non-empty UTF-8 strings.
//
// When Writer.WriteHeader is called, PAX records derived from the
// the other fields in Header take precedence over PAXRecords.
// other fields in Header take precedence over PAXRecords.
PAXRecords map[string]string
// Format specifies the format of the tar header.

View file

@ -64,7 +64,6 @@ func (tr *Reader) next() (*Header, error) {
// normally be visible to the outside. As such, this loop iterates through
// one or more "header files" until it finds a "normal file".
format := FormatUSTAR | FormatPAX | FormatGNU
loop:
for {
// Discard the remainder of the file and any padding.
if err := discard(tr.r, tr.curr.PhysicalRemaining()); err != nil {
@ -102,7 +101,7 @@ loop:
Format: format,
}, nil
}
continue loop // This is a meta header affecting the next header
continue // This is a meta header affecting the next header
case TypeGNULongName, TypeGNULongLink:
format.mayOnlyBe(FormatGNU)
realname, err := ioutil.ReadAll(tr)
@ -117,7 +116,7 @@ loop:
case TypeGNULongLink:
gnuLongLink = p.parseString(realname)
}
continue loop // This is a meta header affecting the next header
continue // This is a meta header affecting the next header
default:
// The old GNU sparse format is handled here since it is technically
// just a regular file with additional attributes.
@ -131,8 +130,12 @@ loop:
if gnuLongLink != "" {
hdr.Linkname = gnuLongLink
}
if hdr.Typeflag == TypeRegA && strings.HasSuffix(hdr.Name, "/") {
hdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories
if hdr.Typeflag == TypeRegA {
if strings.HasSuffix(hdr.Name, "/") {
hdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories
} else {
hdr.Typeflag = TypeReg
}
}
// The extended headers may have updated the size.
@ -200,7 +203,7 @@ func (tr *Reader) handleSparseFile(hdr *Header, rawHdr *block) error {
// readGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers.
// If they are found, then this function reads the sparse map and returns it.
// This assumes that 0.0 headers have already been converted to 0.1 headers
// by the the PAX header parsing logic.
// by the PAX header parsing logic.
func (tr *Reader) readGNUSparsePAXHeaders(hdr *Header) (sparseDatas, error) {
// Identify the version of GNU headers.
var is1x0 bool

View file

@ -189,7 +189,7 @@ func TestReader(t *testing.T) {
Gid: 5000,
Size: 5,
ModTime: time.Unix(1244593104, 0),
Typeflag: '\x00',
Typeflag: '0',
}, {
Name: "small2.txt",
Mode: 0444,
@ -197,7 +197,7 @@ func TestReader(t *testing.T) {
Gid: 5000,
Size: 11,
ModTime: time.Unix(1244593104, 0),
Typeflag: '\x00',
Typeflag: '0',
}},
}, {
file: "testdata/pax.tar",
@ -378,9 +378,9 @@ func TestReader(t *testing.T) {
"security.selinux": "unconfined_u:object_r:default_t:s0\x00",
},
PAXRecords: map[string]string{
"mtime": "1386065770.449252304",
"atime": "1389782991.41987522",
"ctime": "1386065770.449252304",
"mtime": "1386065770.449252304",
"atime": "1389782991.41987522",
"ctime": "1386065770.449252304",
"SCHILY.xattr.security.selinux": "unconfined_u:object_r:default_t:s0\x00",
},
Format: FormatPAX,
@ -534,9 +534,10 @@ func TestReader(t *testing.T) {
// a buggy pre-Go1.8 tar.Writer.
file: "testdata/invalid-go17.tar",
headers: []*Header{{
Name: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/foo",
Uid: 010000000,
ModTime: time.Unix(0, 0),
Name: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/foo",
Uid: 010000000,
ModTime: time.Unix(0, 0),
Typeflag: '0',
}},
}, {
// USTAR archive with a regular entry with non-zero device numbers.

View file

@ -306,6 +306,7 @@ func TestRoundTrip(t *testing.T) {
ModTime: time.Now().Round(time.Second),
PAXRecords: map[string]string{"uid": "2097152"},
Format: FormatPAX,
Typeflag: TypeReg,
}
if err := tw.WriteHeader(hdr); err != nil {
t.Fatalf("tw.WriteHeader: %v", err)

Binary file not shown.

Binary file not shown.

View file

@ -5,7 +5,6 @@
package tar
import (
"bytes"
"fmt"
"io"
"path"
@ -71,6 +70,16 @@ func (tw *Writer) WriteHeader(hdr *Header) error {
}
tw.hdr = *hdr // Shallow copy of Header
// Avoid usage of the legacy TypeRegA flag, and automatically promote
// it to use TypeReg or TypeDir.
if tw.hdr.Typeflag == TypeRegA {
if strings.HasSuffix(tw.hdr.Name, "/") {
tw.hdr.Typeflag = TypeDir
} else {
tw.hdr.Typeflag = TypeReg
}
}
// Round ModTime and ignore AccessTime and ChangeTime unless
// the format is explicitly chosen.
// This ensures nominal usage of WriteHeader (without specifying the format)
@ -166,7 +175,7 @@ func (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error {
sort.Strings(keys)
// Write each record to a buffer.
var buf bytes.Buffer
var buf strings.Builder
for _, k := range keys {
rec, err := formatPAXRecord(k, paxHdrs[k])
if err != nil {

View file

@ -461,6 +461,15 @@ func TestWriter(t *testing.T) {
testHeader{Header{Name: strings.Repeat("123456789/", 30)}, nil},
testClose{nil},
},
}, {
// Automatically promote zero value of Typeflag depending on the name.
file: "testdata/file-and-dir.tar",
tests: []testFnc{
testHeader{Header{Name: "small.txt", Size: 5}, nil},
testWrite{"Kilts", 5, nil},
testHeader{Header{Name: "dir/"}, nil},
testClose{nil},
},
}}
equalError := func(x, y error) bool {
@ -809,8 +818,8 @@ func TestValidTypeflagWithPAXHeader(t *testing.T) {
if err != nil {
t.Fatalf("Failed to read header: %s", err)
}
if header.Typeflag != 0 {
t.Fatalf("Typeflag should've been 0, found %d", header.Typeflag)
if header.Typeflag != TypeReg {
t.Fatalf("Typeflag should've been %d, found %d", TypeReg, header.Typeflag)
}
}
}

View file

@ -366,7 +366,7 @@ parseExtras:
epoch := time.Date(1601, time.January, 1, 0, 0, 0, 0, time.UTC)
modified = time.Unix(epoch.Unix()+secs, nsecs)
}
case unixExtraID:
case unixExtraID, infoZipUnixExtraID:
if len(fieldBuf) < 8 {
continue parseExtras
}
@ -379,12 +379,6 @@ parseExtras:
}
ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
modified = time.Unix(ts, 0)
case infoZipUnixExtraID:
if len(fieldBuf) < 4 {
continue parseExtras
}
ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
modified = time.Unix(ts, 0)
}
}

View file

@ -414,7 +414,7 @@ var tests = []ZipTest{
Name: "test.txt",
Content: []byte{},
Size: 1<<32 - 1,
Modified: time.Date(2017, 10, 31, 21, 17, 27, 0, timeZone(-7*time.Hour)),
Modified: time.Date(2017, 10, 31, 21, 11, 57, 0, timeZone(-7*time.Hour)),
Mode: 0644,
},
},

View file

@ -82,7 +82,8 @@ const (
type FileHeader struct {
// Name is the name of the file.
// It must be a relative path, not start with a drive letter (e.g. C:),
// and must use forward slashes instead of back slashes.
// and must use forward slashes instead of back slashes. A trailing slash
// indicates that this file is a directory and should have no data.
Name string
// Comment is any arbitrary user-defined string shorter than 64KiB.

View file

@ -11,6 +11,7 @@ import (
"hash"
"hash/crc32"
"io"
"strings"
"unicode/utf8"
)
@ -209,7 +210,8 @@ func (w *Writer) Close() error {
// The file contents will be compressed using the Deflate method.
// The name must be a relative path: it must not start with a drive
// letter (e.g. C:) or leading slash, and only forward slashes are
// allowed.
// allowed. To create a directory instead of a file, add a trailing
// slash to the name.
// The file's contents must be written to the io.Writer before the next
// call to Create, CreateHeader, or Close.
func (w *Writer) Create(name string) (io.Writer, error) {
@ -261,8 +263,6 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
return nil, errors.New("archive/zip: invalid duplicate FileHeader")
}
fh.Flags |= 0x8 // we will write a data descriptor
// The ZIP format has a sad state of affairs regarding character encoding.
// Officially, the name and comment fields are supposed to be encoded
// in CP-437 (which is mostly compatible with ASCII), unless the UTF-8
@ -319,35 +319,52 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
fh.Extra = append(fh.Extra, mbuf[:]...)
}
fw := &fileWriter{
zipw: w.cw,
compCount: &countWriter{w: w.cw},
crc32: crc32.NewIEEE(),
}
comp := w.compressor(fh.Method)
if comp == nil {
return nil, ErrAlgorithm
}
var err error
fw.comp, err = comp(fw.compCount)
if err != nil {
return nil, err
}
fw.rawCount = &countWriter{w: fw.comp}
var (
ow io.Writer
fw *fileWriter
)
h := &header{
FileHeader: fh,
offset: uint64(w.cw.count),
}
w.dir = append(w.dir, h)
fw.header = h
if strings.HasSuffix(fh.Name, "/") {
// Set the compression method to Store to ensure data length is truly zero,
// which the writeHeader method always encodes for the size fields.
// This is necessary as most compression formats have non-zero lengths
// even when compressing an empty string.
fh.Method = Store
fh.Flags &^= 0x8 // we will not write a data descriptor
ow = dirWriter{}
} else {
fh.Flags |= 0x8 // we will write a data descriptor
fw = &fileWriter{
zipw: w.cw,
compCount: &countWriter{w: w.cw},
crc32: crc32.NewIEEE(),
}
comp := w.compressor(fh.Method)
if comp == nil {
return nil, ErrAlgorithm
}
var err error
fw.comp, err = comp(fw.compCount)
if err != nil {
return nil, err
}
fw.rawCount = &countWriter{w: fw.comp}
fw.header = h
ow = fw
}
w.dir = append(w.dir, h)
if err := writeHeader(w.cw, fh); err != nil {
return nil, err
}
// If we're creating a directory, fw is nil.
w.last = fw
return fw, nil
return ow, nil
}
func writeHeader(w io.Writer, h *FileHeader) error {
@ -400,6 +417,12 @@ func (w *Writer) compressor(method uint16) Compressor {
return comp
}
type dirWriter struct{}
func (dirWriter) Write([]byte) (int, error) {
return 0, errors.New("zip: write to directory")
}
type fileWriter struct {
*header
zipw io.Writer

View file

@ -6,6 +6,7 @@ package zip
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"io/ioutil"
@ -299,6 +300,52 @@ func TestWriterFlush(t *testing.T) {
}
}
func TestWriterDir(t *testing.T) {
w := NewWriter(ioutil.Discard)
dw, err := w.Create("dir/")
if err != nil {
t.Fatal(err)
}
if _, err := dw.Write([]byte("hello")); err == nil {
t.Error("Write to directory: got nil error, want non-nil")
}
}
func TestWriterDirAttributes(t *testing.T) {
var buf bytes.Buffer
w := NewWriter(&buf)
if _, err := w.Create("dir/"); err != nil {
t.Fatal(err)
}
if err := w.Close(); err != nil {
t.Fatal(err)
}
b := buf.Bytes()
var sig [4]byte
binary.LittleEndian.PutUint32(sig[:], uint32(fileHeaderSignature))
idx := bytes.Index(b, sig[:])
if idx == -1 {
t.Fatal("file header not found")
}
b = b[idx:]
if !bytes.Equal(b[6:10], []byte{0, 0, 0, 0}) { // FileHeader.Flags: 0, FileHeader.Method: 0
t.Errorf("unexpected method and flags: %v", b[6:10])
}
if !bytes.Equal(b[14:26], make([]byte, 12)) { // FileHeader.{CRC32,CompressSize,UncompressedSize} all zero.
t.Errorf("unexpected crc, compress and uncompressed size to be 0 was: %v", b[14:26])
}
binary.LittleEndian.PutUint32(sig[:], uint32(dataDescriptorSignature))
if bytes.Index(b, sig[:]) != -1 {
t.Error("there should be no data descriptor")
}
}
func testCreate(t *testing.T, w *Writer, wt *WriteTest) {
header := &FileHeader{
Name: wt.Name,

View file

@ -15,6 +15,7 @@ import (
"internal/testenv"
"io"
"io/ioutil"
"runtime"
"sort"
"strings"
"testing"
@ -140,14 +141,7 @@ func (r *rleBuffer) Write(p []byte) (n int, err error) {
rp = &r.buf[len(r.buf)-1]
// Fast path, if p is entirely the same byte repeated.
if lastByte := rp.b; len(p) > 0 && p[0] == lastByte {
all := true
for _, b := range p {
if b != lastByte {
all = false
break
}
}
if all {
if bytes.Count(p, []byte{lastByte}) == len(p) {
rp.n += int64(len(p))
return len(p), nil
}
@ -165,6 +159,25 @@ func (r *rleBuffer) Write(p []byte) (n int, err error) {
return len(p), nil
}
func min(x, y int) int {
if x < y {
return x
}
return y
}
func memset(a []byte, b byte) {
if len(a) == 0 {
return
}
// Double, until we reach power of 2 >= len(a), same as bytes.Repeat,
// but without allocation.
a[0] = b
for i, l := 1, len(a); i < l; i *= 2 {
copy(a[i:], a[:i])
}
}
func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
if len(p) == 0 {
return
@ -176,16 +189,13 @@ func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
parts := r.buf[skipParts:]
if len(parts) > 0 {
skipBytes := off - parts[0].off
for len(parts) > 0 {
part := parts[0]
for i := skipBytes; i < part.n; i++ {
if n == len(p) {
return
}
p[n] = part.b
n++
for _, part := range parts {
repeat := min(int(part.n-skipBytes), len(p)-n)
memset(p[n:n+repeat], part.b)
n += repeat
if n == len(p) {
return
}
parts = parts[1:]
skipBytes = 0
}
}
@ -452,6 +462,9 @@ func suffixIsZip64(t *testing.T, zip sizedReaderAt) bool {
// Zip64 is required if the total size of the records is uint32max.
func TestZip64LargeDirectory(t *testing.T) {
if runtime.GOARCH == "wasm" {
t.Skip("too slow on wasm")
}
if testing.Short() {
t.Skip("skipping in short mode")
}

View file

@ -77,7 +77,11 @@ else
rm -rf "pkg/${gohostos}_${gohostarch}" "pkg/tool/${gohostos}_${gohostarch}"
fi
GITREV=$(git rev-parse --short HEAD)
if [ "$BOOTSTRAP_FORMAT" = "mintgz" ]; then
# Fetch git revision before rm -rf .git.
GITREV=$(git rev-parse --short HEAD)
fi
rm -rf pkg/bootstrap pkg/obj .git
# Support for building minimal tar.gz for the builders.

View file

@ -462,6 +462,8 @@ func (b *Reader) ReadString(delim byte) (string, error) {
// WriteTo implements io.WriterTo.
// This may make multiple calls to the Read method of the underlying Reader.
// If the underlying reader supports the WriteTo method,
// this calls the underlying WriteTo without buffering.
func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
n, err = b.writeBuf(w)
if err != nil {
@ -684,7 +686,9 @@ func (b *Writer) WriteString(s string) (int, error) {
return nn, nil
}
// ReadFrom implements io.ReaderFrom.
// ReadFrom implements io.ReaderFrom. If the underlying writer
// supports the ReadFrom method, and b has no buffered data yet,
// this calls the underlying ReadFrom without buffering.
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
if b.Buffered() == 0 {
if w, ok := b.wr.(io.ReaderFrom); ok {

View file

@ -7,6 +7,7 @@
package bytes
import (
"internal/bytealg"
"unicode"
"unicode/utf8"
)
@ -46,12 +47,16 @@ func explode(s []byte, n int) [][]byte {
return a[0:na]
}
// countGeneric actually implements Count
func countGeneric(s, sep []byte) int {
// Count counts the number of non-overlapping instances of sep in s.
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
func Count(s, sep []byte) int {
// special case
if len(sep) == 0 {
return utf8.RuneCount(s) + 1
}
if len(sep) == 1 {
return bytealg.Count(s, sep[0])
}
n := 0
for {
i := Index(s, sep)
@ -800,9 +805,9 @@ func EqualFold(s, t []byte) bool {
tr, sr = sr, tr
}
// Fast check for ASCII.
if tr < utf8.RuneSelf && 'A' <= sr && sr <= 'Z' {
// ASCII, and sr is upper case. tr must be lower case.
if tr == sr+'a'-'A' {
if tr < utf8.RuneSelf {
// ASCII only, sr/tr must be upper/lower case
if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
continue
}
return false
@ -824,6 +829,92 @@ func EqualFold(s, t []byte) bool {
return len(s) == len(t)
}
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
func Index(s, sep []byte) int {
n := len(sep)
switch {
case n == 0:
return 0
case n == 1:
return IndexByte(s, sep[0])
case n == len(s):
if Equal(sep, s) {
return 0
}
return -1
case n > len(s):
return -1
case n <= bytealg.MaxLen:
// Use brute force when s and sep both are small
if len(s) <= bytealg.MaxBruteForce {
return bytealg.Index(s, sep)
}
c := sep[0]
i := 0
t := s[:len(s)-n+1]
fails := 0
for i < len(t) {
if t[i] != c {
// IndexByte is faster than bytealg.Index, so use it as long as
// we're not getting lots of false positives.
o := IndexByte(t[i:], c)
if o < 0 {
return -1
}
i += o
}
if Equal(s[i:i+n], sep) {
return i
}
fails++
i++
// Switch to bytealg.Index when IndexByte produces too many false positives.
if fails > bytealg.Cutover(i) {
r := bytealg.Index(s[i:], sep)
if r >= 0 {
return r + i
}
return -1
}
}
return -1
}
c := sep[0]
i := 0
fails := 0
t := s[:len(s)-n+1]
for i < len(t) {
if t[i] != c {
o := IndexByte(t[i:], c)
if o < 0 {
break
}
i += o
}
if Equal(s[i:i+n], sep) {
return i
}
i++
fails++
if fails >= 4+i>>4 && i < len(t) {
// Give up on IndexByte, it isn't skipping ahead
// far enough to be better than Rabin-Karp.
// Experiments (using IndexPeriodic) suggest
// the cutover is about 16 byte skips.
// TODO: if large prefixes of sep are matching
// we should cutover at even larger average skips,
// because Equal becomes that much more expensive.
// This code does not take that effect into account.
j := indexRabinKarp(s[i:], sep)
if j < 0 {
return -1
}
return i + j
}
}
return -1
}
func indexRabinKarp(s, sep []byte) int {
// Rabin-Karp search
hashsep, pow := hashStr(sep)

View file

@ -1,88 +0,0 @@
// 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 bytes
import "internal/cpu"
//go:noescape
// indexShortStr returns the index of the first instance of c in s, or -1 if c is not present in s.
// indexShortStr requires 2 <= len(c) <= shortStringLen
func indexShortStr(s, c []byte) int // ../runtime/asm_amd64.s
func countByte(s []byte, c byte) int // ../runtime/asm_amd64.s
var shortStringLen int
func init() {
if cpu.X86.HasAVX2 {
shortStringLen = 63
} else {
shortStringLen = 31
}
}
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
func Index(s, sep []byte) int {
n := len(sep)
switch {
case n == 0:
return 0
case n == 1:
return IndexByte(s, sep[0])
case n == len(s):
if Equal(sep, s) {
return 0
}
return -1
case n > len(s):
return -1
case n <= shortStringLen:
// Use brute force when s and sep both are small
if len(s) <= 64 {
return indexShortStr(s, sep)
}
c := sep[0]
i := 0
t := s[:len(s)-n+1]
fails := 0
for i < len(t) {
if t[i] != c {
// IndexByte skips 16/32 bytes per iteration,
// so it's faster than indexShortStr.
o := IndexByte(t[i:], c)
if o < 0 {
return -1
}
i += o
}
if Equal(s[i:i+n], sep) {
return i
}
fails++
i++
// Switch to indexShortStr when IndexByte produces too many false positives.
// Too many means more that 1 error per 8 characters.
// Allow some errors in the beginning.
if fails > (i+16)/8 {
r := indexShortStr(s[i:], sep)
if r >= 0 {
return r + i
}
return -1
}
}
return -1
}
return indexRabinKarp(s, sep)
}
// Count counts the number of non-overlapping instances of sep in s.
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
func Count(s, sep []byte) int {
if len(sep) == 1 && cpu.X86.HasPOPCNT {
return countByte(s, sep[0])
}
return countGeneric(s, sep)
}

View file

@ -1,68 +0,0 @@
// 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.
package bytes
func countByte(s []byte, c byte) int // bytes_arm64.s
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
func Index(s, sep []byte) int {
n := len(sep)
switch {
case n == 0:
return 0
case n == 1:
return IndexByte(s, sep[0])
case n == len(s):
if Equal(sep, s) {
return 0
}
return -1
case n > len(s):
return -1
}
c := sep[0]
i := 0
fails := 0
t := s[:len(s)-n+1]
for i < len(t) {
if t[i] != c {
o := IndexByte(t[i:], c)
if o < 0 {
break
}
i += o
}
if Equal(s[i:i+n], sep) {
return i
}
i++
fails++
if fails >= 4+i>>4 && i < len(t) {
// Give up on IndexByte, it isn't skipping ahead
// far enough to be better than Rabin-Karp.
// Experiments (using IndexPeriodic) suggest
// the cutover is about 16 byte skips.
// TODO: if large prefixes of sep are matching
// we should cutover at even larger average skips,
// because Equal becomes that much more expensive.
// This code does not take that effect into account.
j := indexRabinKarp(s[i:], sep)
if j < 0 {
return -1
}
return i + j
}
}
return -1
}
// Count counts the number of non-overlapping instances of sep in s.
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
func Count(s, sep []byte) int {
if len(sep) == 1 {
return countByte(s, sep[0])
}
return countGeneric(s, sep)
}

View file

@ -6,19 +6,19 @@ package bytes
//go:noescape
// IndexByte returns the index of the first instance of c in s, or -1 if c is not present in s.
func IndexByte(s []byte, c byte) int // ../runtime/asm_$GOARCH.s
// IndexByte returns the index of the first instance of c in b, or -1 if c is not present in b.
func IndexByte(b []byte, c byte) int // in internal/bytealg
//go:noescape
// Equal returns a boolean reporting whether a and b
// are the same length and contain the same bytes.
// A nil argument is equivalent to an empty slice.
func Equal(a, b []byte) bool // ../runtime/asm_$GOARCH.s
func Equal(a, b []byte) bool // in internal/bytealg
//go:noescape
// Compare returns an integer comparing two byte slices lexicographically.
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
// A nil argument is equivalent to an empty slice.
func Compare(a, b []byte) int // ../runtime/noasm.go or ../runtime/asm_{386,amd64}.s
func Compare(a, b []byte) int // in internal/bytealg

View file

@ -1,65 +0,0 @@
// 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.
// +build !amd64,!s390x,!arm64
package bytes
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
func Index(s, sep []byte) int {
n := len(sep)
switch {
case n == 0:
return 0
case n == 1:
return IndexByte(s, sep[0])
case n == len(s):
if Equal(sep, s) {
return 0
}
return -1
case n > len(s):
return -1
}
c := sep[0]
i := 0
fails := 0
t := s[:len(s)-n+1]
for i < len(t) {
if t[i] != c {
o := IndexByte(t[i:], c)
if o < 0 {
break
}
i += o
}
if Equal(s[i:i+n], sep) {
return i
}
i++
fails++
if fails >= 4+i>>4 && i < len(t) {
// Give up on IndexByte, it isn't skipping ahead
// far enough to be better than Rabin-Karp.
// Experiments (using IndexPeriodic) suggest
// the cutover is about 16 byte skips.
// TODO: if large prefixes of sep are matching
// we should cutover at even larger average skips,
// because Equal becomes that much more expensive.
// This code does not take that effect into account.
j := indexRabinKarp(s[i:], sep)
if j < 0 {
return -1
}
return i + j
}
}
return -1
}
// Count counts the number of non-overlapping instances of sep in s.
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
func Count(s, sep []byte) int {
return countGeneric(s, sep)
}

View file

@ -1,86 +0,0 @@
// 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 bytes
//go:noescape
// indexShortStr returns the index of the first instance of sep in s,
// or -1 if sep is not present in s.
// indexShortStr requires 2 <= len(sep) <= shortStringLen
func indexShortStr(s, c []byte) int // ../runtime/asm_s390x.s
// supportsVX reports whether the vector facility is available.
// indexShortStr must not be called if the vector facility is not
// available.
func supportsVX() bool // ../runtime/asm_s390x.s
var shortStringLen = -1
func init() {
if supportsVX() {
shortStringLen = 64
}
}
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
func Index(s, sep []byte) int {
n := len(sep)
switch {
case n == 0:
return 0
case n == 1:
return IndexByte(s, sep[0])
case n == len(s):
if Equal(sep, s) {
return 0
}
return -1
case n > len(s):
return -1
case n <= shortStringLen:
// Use brute force when s and sep both are small
if len(s) <= 64 {
return indexShortStr(s, sep)
}
c := sep[0]
i := 0
t := s[:len(s)-n+1]
fails := 0
for i < len(t) {
if t[i] != c {
// IndexByte skips 16/32 bytes per iteration,
// so it's faster than indexShortStr.
o := IndexByte(t[i:], c)
if o < 0 {
return -1
}
i += o
}
if Equal(s[i:i+n], sep) {
return i
}
fails++
i++
// Switch to indexShortStr when IndexByte produces too many false positives.
// Too many means more that 1 error per 8 characters.
// Allow some errors in the beginning.
if fails > (i+16)/8 {
r := indexShortStr(s[i:], sep)
if r >= 0 {
return r + i
}
return -1
}
}
return -1
}
return indexRabinKarp(s, sep)
}
// Count counts the number of non-overlapping instances of sep in s.
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
func Count(s, sep []byte) int {
return countGeneric(s, sep)
}

View file

@ -410,10 +410,6 @@ func TestCountByte(t *testing.T) {
if p != j+1 {
t.Errorf("TestCountByte.Count(%q, 100) = %d", b[i:i+window], p)
}
pGeneric := CountGeneric(b[i:i+window], []byte{100})
if pGeneric != j+1 {
t.Errorf("TestCountByte.CountGeneric(%q, 100) = %d", b[i:i+window], p)
}
}
}
@ -461,10 +457,6 @@ func TestCountByteNoMatch(t *testing.T) {
if p != 0 {
t.Errorf("TestCountByteNoMatch(%q, 0) = %d", b[i:i+window], p)
}
pGeneric := CountGeneric(b[i:i+window], []byte{0})
if pGeneric != 0 {
t.Errorf("TestCountByteNoMatch.CountGeneric(%q, 100) = %d", b[i:i+window], p)
}
for j := 0; j < window; j++ {
b[i+j] = byte(0)
}

View file

@ -7,4 +7,3 @@ package bytes
// Export func for testing
var IndexBytePortable = indexBytePortable
var EqualPortable = equalPortable
var CountGeneric = countGeneric

Some files were not shown because too many files have changed in this diff Show more