mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
[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:
commit
a3f9ce3313
26
.github/PULL_REQUEST_TEMPLATE
vendored
26
.github/PULL_REQUEST_TEMPLATE
vendored
|
@ -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
159
AUTHORS
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
175
CONTRIBUTORS
175
CONTRIBUTORS
|
@ -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>
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
69
doc/asm.html
69
doc/asm.html
|
@ -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>-></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->16</code>
|
||||
<br>
|
||||
<code>R0>>16</code>
|
||||
<br>
|
||||
<code>R0<<16</code>
|
||||
<br>
|
||||
<code>R0@>16</code>:
|
||||
These are the same as on the 32-bit ARM.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code>$(8<<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<<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<<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<<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<<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>
|
||||
|
|
|
@ -183,7 +183,6 @@ satisfaction of all parties. They are:
|
|||
<li>Aditya Mukerjee <dev@chimeracoder.net>
|
||||
<li>Andrew Gerrand <adg@golang.org>
|
||||
<li>Peggy Li <peggyli.224@gmail.com>
|
||||
<li>Sarah Adams <sadams.codes@gmail.com>
|
||||
<li>Steve Francia <steve.francia@gmail.com>
|
||||
<li>Verónica López <gveronicalg@gmail.com>
|
||||
</ul>
|
||||
|
|
|
@ -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>
|
||||
|
|
1780
doc/contribute.html
1780
doc/contribute.html
File diff suppressed because it is too large
Load diff
|
@ -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<*testing.T>
|
|||
</pre>
|
||||
|
||||
<p>
|
||||
That <code>struct hchan<*testing.T></code> is the
|
||||
That <code>struct</code> <code>hchan<*testing.T></code> is the
|
||||
runtime-internal representation of a channel. It is currently empty,
|
||||
or gdb would have pretty-printed its contents.
|
||||
</p>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
196
doc/editors.html
196
doc/editors.html
|
@ -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 > Go > 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 |
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
284
doc/go1.10.html
284
doc/go1.10.html
|
@ -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> <code><<</code> <code>s]</code> where <code>s</code> is an untyped constant;
|
||||
<code>x[1.0</code> <code><<</code> <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 & 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> <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> </code>install</code> command now installs only the
|
||||
The <code>go</code> <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> <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 <pkg>
|
||||
go tool fix -r jni <pkg>
|
||||
</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> <code>tool</code> <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> <code>tool</code> <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> <code>:</code> <code>j:k]</code> and now
|
||||
format with more consistent spacing: <code>x[i+1</code> <code>:</code> <code>j</code> <code>:</code> <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> ...<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> ...<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.
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>—array, struct, pointer, function,
|
||||
interface, slice, map, and channel types—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><<</code> may legally
|
||||
<code>-</code>, <code>*</code>, <code>/</code>, and <code><<</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 < 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)
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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}}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
package main
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -c
|
||||
#cgo LDFLAGS: -L/nonexist
|
||||
|
||||
void test() {
|
||||
xxx; // ERROR HERE
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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)
|
||||
}
|
54
misc/cgo/test/issue24206.go
Normal file
54
misc/cgo/test/issue24206.go
Normal 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)
|
||||
}
|
||||
}
|
13
misc/cgo/test/issue24206_generic.go
Normal file
13
misc/cgo/test/issue24206_generic.go
Normal 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")
|
||||
}
|
22
misc/cgo/test/issue25143.go
Normal file
22
misc/cgo/test/issue25143.go
Normal 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)
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
74
misc/cgo/test/test22906.go
Normal file
74
misc/cgo/test/test22906.go
Normal 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
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
// that the C code can also use.
|
||||
|
||||
const (
|
||||
fd = 100
|
||||
fd = 30
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
21
misc/cgo/testplugin/src/issue24351/main.go
Normal file
21
misc/cgo/testplugin/src/issue24351/main.go
Normal 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
|
||||
}
|
14
misc/cgo/testplugin/src/issue24351/plugin.go
Normal file
14
misc/cgo/testplugin/src/issue24351/plugin.go
Normal 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
|
||||
}()
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
`
|
||||
|
|
2
misc/nacl/testdata/mime.types
vendored
2
misc/nacl/testdata/mime.types
vendored
|
@ -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
|
||||
# ============================================ ==========
|
||||
|
|
|
@ -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
14
misc/wasm/go_js_wasm_exec
Executable 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
30
misc/wasm/wasm_exec.html
Normal 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
335
misc/wasm/wasm_exec.js
Executable 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);
|
||||
});
|
||||
}
|
||||
})();
|
|
@ -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 ''
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
BIN
src/archive/tar/testdata/file-and-dir.tar
vendored
Normal file
BIN
src/archive/tar/testdata/file-and-dir.tar
vendored
Normal file
Binary file not shown.
BIN
src/archive/tar/testdata/trailing-slash.tar
vendored
BIN
src/archive/tar/testdata/trailing-slash.tar
vendored
Binary file not shown.
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue