Compare commits

..

62 Commits

Author SHA1 Message Date
Andrew Gerrand
883bc6ed0e [release-branch.go1.4] go1.4.2
Change-Id: I0f198e4a94c50a11228c15d6aaac0cea890b5b58
Reviewed-on: https://go-review.googlesource.com/5111
Reviewed-by: Rob Pike <r@golang.org>
2015-02-18 04:24:51 +00:00
Andrew Gerrand
5e9b6cac52 [release-branch.go1.4] doc: document Go 1.4.2
Change-Id: Ia87047cbc720fb03d2f67aec48abe18bce8dbf78
Reviewed-on: https://go-review.googlesource.com/5112
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-on: https://go-review.googlesource.com/5113
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-02-18 03:43:35 +00:00
Keith Randall
e4acac3dfb [release-branch.go1.4] runtime: don't fail if we find a pointer to an invalid span on 32 bit
The 32-bit heap may have holes in it.  Pointers to (non-heap) objects
in those holes shouldn't cause the GC to throw.

This change is somewhat of a band-aid fix for 1.4.2.  We should do
a more thorough fix for tip (keep track of the holes in the heap
with special MSpans, say).

Update #9872

Change-Id: Ife9ba27b77ae6ac5a6792d249c68893b3df62134
Reviewed-on: https://go-review.googlesource.com/4920
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
2015-02-17 23:37:56 +00:00
Ian Lance Taylor
3e5977f99d [release-branch.go1.4] cmd/gc: treat non-local vars inlined into wrapper as escaping
The compiler has a phase ordering problem.  Escape analysis runs
before wrapper generation.  When a generated wrapper calls a method
defined in a different package, if that call is inlined, there will be
no escape information for the variables defined in the inlined call.
Those variables will be placed on the stack, which fails if they
actually do escape.

There are probably various complex ways to fix this.  This is a simple
way to avoid it: when a generated wrapper calls a method defined in a
different package, treat all local variables as escaping.

Fixes #9537.

Change-Id: I530f39346de16ad173371c6c3f69cc189351a4e9
Reviewed-on: https://go-review.googlesource.com/3092
Reviewed-by: Russ Cox <rsc@golang.org>
(cherry picked from commit ec0ebc2281)
Reviewed-on: https://go-review.googlesource.com/5003
Run-TryBot: Andrew Gerrand <adg@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-02-17 23:36:32 +00:00
Shenghou Ma
02cf0526bf [release-branch.go1.4] cmd/gc: don't recurse infinitely when a recursive type references itself more than once
Fixes #9432

Change-Id: I08c92481afa7c7fac890aa780efc1cb2fabad528
Reviewed-on: https://go-review.googlesource.com/2115
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Russ Cox <rsc@golang.org>
(cherry picked from commit fcff3ba740)
Reviewed-on: https://go-review.googlesource.com/5004
Run-TryBot: Andrew Gerrand <adg@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-02-17 23:36:26 +00:00
Shenghou Ma
3124622303 [release-branch.go1.4] runtime: don't panic when given a callback with no input params on windows
Fixes #9871 for Go 1.4.

Change-Id: I550a5bdb29e9a872652e0dd468a434227d7d9502
Reviewed-on: https://go-review.googlesource.com/4937
Run-TryBot: Minux Ma <minux@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-02-17 06:51:18 +00:00
Chris Manghane
a255645770 [release-branch.go1.4] cmd/gc: don't unpack struct arguments to append
Fixes #9634.

Change-Id: I7b18f26c2fb812978fc7adc5bfd39ebfffe48701
Reviewed-on: https://go-review.googlesource.com/3080
Reviewed-by: Minux Ma <minux@golang.org>
(cherry picked from commit f5b8813e93)
Reviewed-on: https://go-review.googlesource.com/5000
Run-TryBot: Andrew Gerrand <adg@golang.org>
2015-02-17 06:49:27 +00:00
Keith Randall
2b7d0b4c0d [release-branch.go1.4] cmd/5g: make sure we normalize after unary ops on small types
We were failing ^uint16(0xffff) == 0, as we computed 0xffff0000 instead.

I could only trigger a failure for the above case, the other two tests
^uint16(0xfffe) == 1 and -uint16(0xffff) == 1 didn't seem to fail
previously.  Somehow they get MOVHUs inserted for other reasons (used
by CMP instead of TST?).  I fixed OMINUS anyway, better safe than
sorry.

Fixes #9604

Change-Id: I4c2d5bdc667742873ac029fdbe3db0cf12893c27
Reviewed-on: https://go-review.googlesource.com/2940
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Minux Ma <minux@golang.org>
(cherry picked from commit daa64ddfe6)
Reviewed-on: https://go-review.googlesource.com/5002
2015-02-17 06:48:55 +00:00
Keith Randall
5caa9d15f2 [release-branch.go1.4] math/big: bug in AndNot(x,y) for x>0,y<0.
The comment says to use (y-1), but then we did add(y.abs, natOne).  We meant sub.

Fixes #9609

Change-Id: I4fe4783326ca082c05588310a0af7895a48fc779
Reviewed-on: https://go-review.googlesource.com/2961
Reviewed-by: Robert Griesemer <gri@golang.org>
(cherry picked from commit c6ddca2aec)
Reviewed-on: https://go-review.googlesource.com/5001
2015-02-17 06:48:38 +00:00
Rob Pike
b64f8f8764 [release-branch.go1.4] cmd/go: handle \r in input text
Remove carriage returns from //go:generate lines.
Carriage returns are the predecessor of BOMs and still
live on Windows.

Fixes #9264

Change-Id: I637748c74335c696b3630f52f2100061153fcdb4
Reviewed-on: https://go-review.googlesource.com/1564
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
(cherry picked from commit fde3ab843f)
Reviewed-on: https://go-review.googlesource.com/4999
Reviewed-by: David Symonds <dsymonds@golang.org>
2015-02-17 06:48:22 +00:00
Rob Pike
15ce943f15 [release-branch.go1.4] cmd/go: document that -run isn't implemented
I am an idiot but the failure to implement this means we can decide
exactly what its design should be for 1.5

Change-Id: Ie2b025fcd899d306ddeddd09d1d0e8f9a99ab7a8
Reviewed-on: https://go-review.googlesource.com/4291
Reviewed-by: Minux Ma <minux@golang.org>
(cherry picked from commit 1e5d8bb544)
Reviewed-on: https://go-review.googlesource.com/4998
Reviewed-by: David Symonds <dsymonds@golang.org>
2015-02-17 06:46:10 +00:00
Andrew Gerrand
886b02d705 [release-branch.go1.4] go1.4.1
Change-Id: If275a5caa07cfd16b7052ad50709e1d0f1258223
Reviewed-on: https://go-review.googlesource.com/2856
Reviewed-by: Rob Pike <r@golang.org>
2015-01-15 21:04:23 +00:00
Andrew Gerrand
590548d7bd [release-branch.go1.4] doc: document Go 1.4.1
Change-Id: I4e9737497f4995657c46e52e0722d921499f8d17
Reviewed-on: https://go-review.googlesource.com/2854
Reviewed-by: Rob Pike <r@golang.org>
(cherry picked from commit 7785be8f22)
Reviewed-on: https://go-review.googlesource.com/2855
2015-01-15 04:50:52 +00:00
Andrew Gerrand
00d88f68bb [release-branch.go1.4] doc: update source install instruction to use tag 'go1.4.1'
Change-Id: I12e531fc0d92d3b6fc7ec2bbd8c029f63f55fbe1
Reviewed-on: https://go-review.googlesource.com/2798
Reviewed-by: Russ Cox <rsc@golang.org>
2015-01-15 03:55:30 +00:00
Mikio Hara
cece1bd03f [release-branch.go1.4] syscall: fix the deprecated way of parsing routing message on openbsd
OpenBSD 5.5 changed its kernel ABI and OpenBSD 5.6 enabled it.
This CL works on both 5.5 and 5.6.

Fixes #9102.

Change-Id: I4a295be9ab8acbc99e550d8cb7e8f8dacf3a03c5
Reviewed-on: https://go-review.googlesource.com/1932
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit 13e16b39fc)
Reviewed-on: https://go-review.googlesource.com/2826
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2015-01-14 23:54:43 +00:00
Keith Randall
ac15ad8a38 [release-branch.go1.4] runtime: fix nacl build, hashmap overflow field offset was incorrect.
Change-Id: Ieb305b2a4d4ef28d70a8b8ece703f495c5af0529
Reviewed-on: https://go-review.googlesource.com/2051
Reviewed-by: Keith Randall <khr@golang.org>
(cherry picked from commit c6669e7af5)
Reviewed-on: https://go-review.googlesource.com/2820
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2015-01-14 20:44:03 +00:00
Russ Cox
7df87f5066 [release-branch.go1.4] cmd/go: adjust error for custom import checkout mismatch
Before:

	...
	imports golang.org/x/net/context: /Users/rsc/g/src/golang.org/x/net is from https://code.google.com/p/go.net, should be from https://go.googlesource.com/net

After:

	...
	imports golang.org/x/net/context: golang.org/x/net is a custom import path for https://go.googlesource.com/net, but /Users/rsc/g/src/golang.org/x/net is checked out from https://code.google.com/p/go.net

Change-Id: I93c35b85f955c7de684f71fbd4baecc717405318
Reviewed-on: https://go-review.googlesource.com/2808
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
(cherry picked from commit b8d67596f6)
Reviewed-on: https://go-review.googlesource.com/2813
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2015-01-14 20:30:19 +00:00
Keith Randall
97b84fc4c8 [release-branch.go1.4] runtime: fix deadlock in runtime.Stack
It shouldn't semacquire() inside an acquirem(), the runtime
thinks that means deadlock.  It actually isn't a deadlock, but it
looks like it because acquirem() does m.locks++.

Candidate for inclusion in 1.4.1.  runtime.Stack with all=true
is pretty unuseable in GOMAXPROCS>1 environment.

fixes #9321

Change-Id: Iac6b664217d24763b9878c20e49229a1ecffc805
Reviewed-on: https://go-review.googlesource.com/1600
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
(cherry picked from commit 50bc3d5bbc)
Reviewed-on: https://go-review.googlesource.com/2807
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-01-14 06:16:34 +00:00
Russ Cox
add1ee0ed5 [release-branch.go1.4] runtime: fix SIGPROF change
CL 2789 backported a change that required a barrage of followup CLs.
This CL backports all the followup CLs together.

There are manual edits to os_plan9.go and syscall_windows.go to take
the place of edits to defs_windows_{amd64,386}.go and os2_plan9.go
in the original. Those files do not exist in the release branch, but the
definition being added must go somewhere.

Original change descriptions below.

---

runtime/cgo: initialize our pthread_create wrapper earlier on openbsd

This is a genuine bug exposed by our test for issue 9456: our wrapper
for pthread_create is not initialized until we initialize cgo itself,
but it is possible that a static constructor could call pthread_create,
and in that case, it will be calling a nil function pointer.

Fix that by also initializing the sys_pthread_create function pointer
inside our pthread_create wrapper function, and use a pthread_once to
make sure it is only initialized once.

Fix build for openbsd.

Change-Id: Ica4da2c21fcaec186fdd3379128ef46f0e767ed7
Reviewed-on: https://go-review.googlesource.com/2232
Reviewed-by: David Crawshaw <crawshaw@golang.org>
(cherry picked from commit 77cd6197d7)

---

runtime: provide a dummy value of _SIGPROF on plan9 and windows

Fixes build on plan9 and windows.

Change-Id: Ic9b02c641ab84e4f6d8149de71b9eb495e3343b2
Reviewed-on: https://go-review.googlesource.com/2233
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
(cherry picked from commit 1f28238557)

---

runtime/cgo: remove unused variable

I missed this one in golang.org/cl/2232 and only tested the patch
on openbsd/amd64.

Change-Id: I4ff437ae0bfc61c989896c01904b6d33f9bdf0ec
Reviewed-on: https://go-review.googlesource.com/2234
Reviewed-by: Minux Ma <minux@golang.org>
(cherry picked from commit 0b2a74e89c)

---

runtime: skip TestCgoExternalThreadSIGPROF on OS X 10.6

The test program requires static constructor, which in turn needs
external linking to work, but external linking never works on 10.6.

This should fix the darwin-{386,amd64} builders.

Change-Id: I714fdd3e35f9a7e5f5659cf26367feec9412444f
Reviewed-on: https://go-review.googlesource.com/2235
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit 2cbe27a272)

---

runtime: fix TestCgoExternalThreadSIGPROF again

Shell out to `uname -r` this time, so that the test will compile
even if the platform doesn't have syscall.Sysctl.

Change-Id: I3a19ab5d820bdb94586a97f4507b3837d7040525
Reviewed-on: https://go-review.googlesource.com/2271
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit 865e5e98b6)

---

runtime: remove unnecessary GOOS switch

Change-Id: I8f518e273c02110042b08f7c50c3d38a648c8b6e
Reviewed-on: https://go-review.googlesource.com/2281
Reviewed-by: Minux Ma <minux@golang.org>
(cherry picked from commit 1ebfb082a7)

---

Change-Id: Ifee9667ca90eda2b074817c319b1b7c66d4f741d
Reviewed-on: https://go-review.googlesource.com/2805
Reviewed-by: Minux Ma <minux@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-01-14 06:14:09 +00:00
Russ Cox
d9e0ca4055 [release-branch.go1.4] all: copy master .gitattributes and .gitignore
Change-Id: I10e60fb6bf2cf3daa2bc1184df7ded0a712a1905
Reviewed-on: https://go-review.googlesource.com/2806
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-01-14 06:13:56 +00:00
Shenghou Ma
ff2ab29914 [release-branch.go1.4] cmd/ld: put .bss from external objects into real .bss section
Fixes #9359.

Change-Id: Iba62935b5a14de23d914f433a09a40417d7e88ed
Signed-off-by: Shenghou Ma <minux@golang.org>
Reviewed-on: https://go-review.googlesource.com/1889
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit 1c0c611fc2)
Reviewed-on: https://go-review.googlesource.com/2802
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-01-14 05:42:14 +00:00
Keith Randall
6609baf2f7 [release-branch.go1.4] runtime: hashmap: move overflow pointer to end of bucket
Pointers to zero-sized values may end up pointing to the next
object in memory, and possibly off the end of a span.  This
can cause memory leaks and/or confuse the garbage collector.

By putting the overflow pointer at the end of the bucket, we
make sure that pointers to any zero-sized keys or values don't
accidentally point to the next object in memory.

fixes #9384

Change-Id: I5d434df176984cb0210b4d0195dd106d6eb28f73
Reviewed-on: https://go-review.googlesource.com/1869
Reviewed-by: Russ Cox <rsc@golang.org>
(cherry picked from commit fbc56cf050)
Reviewed-on: https://go-review.googlesource.com/2801
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-01-14 05:42:05 +00:00
Keith Randall
957ed90d0e [release-branch.go1.4] reflect: add kindNoPointers if a function layout has no pointers.
malloc checks kindNoPointers and if it is not set and the object
is one pointer in size, it assumes it contains a pointer.  So we
must set kindNoPointers correctly; it isn't just a hint.

Fixes #9425

Change-Id: Ia43da23cc3298d6e3d6dbdf66d32e9678f0aedcf
Reviewed-on: https://go-review.googlesource.com/2055
Reviewed-by: Russ Cox <rsc@golang.org>
(cherry picked from commit d11f411181)
Reviewed-on: https://go-review.googlesource.com/2800
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-01-14 05:41:52 +00:00
Shenghou Ma
cc7bbb0ae9 [release-branch.go1.4] runtime: ignore SIGPROF to foreign threads before cgocallback is fully initialized
Some libraries, for example, OpenBLAS, create work threads in a global constructor.
If we're doing cpu profiling, it's possible that SIGPROF might come to some of the
worker threads before we make our first cgo call. Cgocallback used to terminate the
process when that happens, but it's better to miss a couple profiling signals than
to abort in this case.

Fixes #9456.

Change-Id: I112b8e1a6e10e6cc8ac695a4b518c0f577309b6b
Reviewed-on: https://go-review.googlesource.com/2141
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit 5da9c8cd0a)
Reviewed-on: https://go-review.googlesource.com/2789
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-01-14 05:25:22 +00:00
Russ Cox
4482c7b1a1 [release-branch.go1.4] doc: copy contribute.html and install-source.html from master
This incorporates the various git-related updates that have
happened since the Go 1.4 release. Since Go 1.4.1 will be issued
from Git, it is appropriate to replace the Mercurial instructions
with Git instructions.

Change-Id: Idec041002c7f325c4eee6f25c50423b088b11468
Reviewed-on: https://go-review.googlesource.com/2788
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-01-14 05:25:09 +00:00
David Symonds
7cb53b8ca2 cmd/dist: convert dist from Hg to Git.
Change-Id: Ic25d46df6a79c4a18ed3f0a7e900591a115e48e3
Reviewed-on: https://go-review.googlesource.com/1403
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2014-12-12 04:05:44 +00:00
Andrew Gerrand
c303df658d go1.4
LGTM=bradfitz, minux, dsymonds
R=rsc, bradfitz, iant, dsymonds, minux
CC=golang-codereviews
https://golang.org/cl/188920043
2014-12-11 11:27:56 +11:00
Andrew Gerrand
75b53641f2 doc: tweak Go 1.4 release notes
LGTM=dave, dsymonds
R=golang-codereviews, dave, dsymonds
CC=golang-codereviews
https://golang.org/cl/184350043
2014-12-11 11:22:54 +11:00
Andrew Gerrand
7412503a43 doc: document go1.4
LGTM=bradfitz
R=rsc, bradfitz
CC=golang-codereviews
https://golang.org/cl/189810043
2014-12-11 09:16:41 +11:00
Andrew Gerrand
aec78b7a61 doc: remove TODO from go1.4 release notes
LGTM=bradfitz
R=iant, rsc, bradfitz
CC=golang-codereviews
https://golang.org/cl/191750043
2014-12-11 09:11:08 +11:00
Andrew Gerrand
031850b689 misc/makerelease: handle git sub-repositories
Also: checkout sub-repos from Mercurial manually
instead of using "go get". (for the 1.4 release)

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/190720043
2014-12-10 13:04:06 +11:00
Russ Cox
f9ae81edca [release-branch.go1.4] api: create go1.4.txt
I read through and vetted these but others should look too.

LGTM=bradfitz, adg
R=r, minux, bradfitz, adg
CC=adg, golang-codereviews, gri, iant
https://golang.org/cl/182560043
2014-12-10 11:07:40 +11:00
Andrew Gerrand
9820fbcf7b [release-branch.go1.4] [release-branch.go1.4] doc: scrub references to code.google.com
These are the references that affect current Go users.
I left intact references in older release notes;
we can figure out what to do with them later.

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/186140043
2014-12-10 11:01:55 +11:00
Andrew Gerrand
d88fe6146d [release-branch.go1.4] [release-branch.go1.4] doc: update contribution guidelines
LGTM=minux, adg, rsc
R=rsc, r, dsymonds, minux, bradfitz, adg, dave, iant
CC=golang-codereviews
https://golang.org/cl/185190043
2014-12-10 09:29:35 +11:00
Andrew Gerrand
c089afbbd7 [release-branch.go1.4] [release-branch.go1.4] misc/cgo/test: skip test8694 on ARM.
««« CL 185130043 / 586738173884
misc/cgo/test: skip test8694 on ARM.

LGTM=dave, bradfitz, rsc
R=golang-codereviews, dave, bradfitz, rsc
CC=golang-codereviews
https://golang.org/cl/185130043

»»»

LGTM=minux
R=golang-codereviews, minux, bradfitz
CC=golang-codereviews
https://golang.org/cl/188870043
2014-12-10 09:13:58 +11:00
Russ Cox
05560adf62 [release-branch.go1.4] cmd/go: document import path checking
LGTM=adg
R=adg
CC=golang-codereviews
https://golang.org/cl/189760043
2014-12-08 22:25:51 -05:00
Russ Cox
c139772a39 [release-branch.go1.4] [release-branch.go1.4] encoding/xml: remove SyntaxError.Byte
««« CL 182580043 / 2d1ab17a670a
encoding/xml: remove SyntaxError.Byte

It is unused. It was introduced in the CL that added InputOffset.
I suspect it was an editing mistake.

LGTM=bradfitz
R=bradfitz
CC=golang-codereviews
https://golang.org/cl/182580043
»»»

TBR=bradfitz
CC=golang-codereviews
https://golang.org/cl/180630043
2014-12-05 22:19:13 -05:00
Russ Cox
c009bcdd8b [release-branch.go1.4] codereview: add release-branch.go1.4 prefix, like for dev branches
TBR=bradfitz
R=bradfitz
CC=golang-codereviews
https://golang.org/cl/178710043
2014-12-05 15:27:48 -05:00
Russ Cox
75c8a78e61 [release-branch.go1.4] cmd/api: make API check fail for undeclared API in release branch
We forgot to do the usual API review.
Make that not possible in the future.
I'll pull this change over to the main
branch too, but it's more important
(and only testable) here.

LGTM=bradfitz
R=bradfitz
CC=golang-codereviews
https://golang.org/cl/185050043
2014-12-05 14:04:17 -05:00
Russ Cox
f42f5263ad codereview: release-branch.go1.4 is now a work branch
(That is, changes can originate in the branch.
The main branch has diverged enough that this
may be necessary.)

LGTM=bradfitz
R=adg, bradfitz
CC=golang-codereviews
https://golang.org/cl/187810043
2014-12-05 14:02:51 -05:00
Russ Cox
59730b3343 [release-branch.go1.4] cmd/go: fix build
««« CL 182480043 / 8d42099cdc23
cmd/go: fix build
The new semantics of split require the newline be present.
The test was stale.

LGTM=adg
R=golang-codereviews, adg
CC=golang-codereviews
https://golang.org/cl/182480043
»»»

TBR=r
CC=golang-codereviews
https://golang.org/cl/178690043
2014-12-04 23:43:01 -05:00
Russ Cox
7aead4c6fd [release-branch.go1.4] cmd/go: avoid use of bufio.Scanner in generate
««« CL 182970043 / 573a7b5178c4
cmd/go: avoid use of bufio.Scanner in generate

Scanner can't handle stupid long lines and there are
reports of stupid long lines in production.

Note the issue isn't long "//go:generate" lines, but
any long line in any Go source file.

To be fair, if you're going to have a stupid long line
it's not a bad bet you'll want to run it through go
generate, because it's some embeddable asset that
has been machine generated. (One could ask why
that generation process didn't add a newline or two,
but we should cope anyway.)

Rewrite the file scanner in "go generate" so it can
handle arbitrarily long lines, and only stores in memory
those lines that start "//go:generate".

Also: Adjust the documentation to make clear that it
does not parse the file.

Fixes #9143.
Fixes #9196.

LGTM=rsc, dominik.honnef
R=rsc, cespare, minux, dominik.honnef
CC=golang-codereviews
https://golang.org/cl/182970043
»»»

TBR=r
CC=golang-codereviews
https://golang.org/cl/183060044
2014-12-04 23:42:16 -05:00
Russ Cox
19bbff8a32 [release-branch.go1.4] cmd/pprof/internal/commands: add command to open browser on windows
««« CL 180380043 / d56c648b069f
cmd/pprof/internal/commands: add command to open browser on windows

While we're at there, also add a message to prompt the user to install
Graphviz if "dot" command is not found.

Fixes #9178.

LGTM=adg, alex.brainman, cookieo9, rsc
R=rsc, adg, bradfitz, alex.brainman, cookieo9, smyrman
CC=golang-codereviews
https://golang.org/cl/180380043

»»»

TBR=minux
CC=golang-codereviews
https://golang.org/cl/186760043
2014-12-04 11:25:25 -05:00
Andrew Gerrand
c29baa647e [release-branch.go1.4] lib/time: update to ICANN time zone database 2014j
««« CL 178660043 / ac865d86fc2a
lib/time: update to ICANN time zone database 2014j

Fixes #9189.

LGTM=dsymonds
R=golang-codereviews, dsymonds
CC=golang-codereviews
https://golang.org/cl/178660043
»»»

LGTM=minux, dsymonds
R=dsymonds, r, minux
CC=golang-codereviews
https://golang.org/cl/182460043
2014-12-04 15:32:30 +11:00
Russ Cox
4d1f720b70 [release-branch.go1.4] cmd/pprof: fix symbol resolution for remote profiles
««« CL 183080043 / b663cc7e6c15
cmd/pprof: fix symbol resolution for remote profiles

Fixes #9199.

LGTM=iant
R=golang-codereviews, iant
CC=austin, golang-codereviews, minux
https://golang.org/cl/183080043
»»»

TBR=iant
CC=golang-codereviews
https://golang.org/cl/176680043
2014-12-03 14:14:50 -05:00
Andrew Gerrand
79a3df47aa [release-branch.go1.4] cmd/go: regenerate doc.go
««« CL 183000043 / 871468f5ceaf
cmd/go: regenerate doc.go

Move change from CL 170770043 to correct file and regenerate docs
for changes from CL 164120043.

LGTM=adg
R=golang-codereviews, adg, bradfitz
CC=golang-codereviews
https://golang.org/cl/183000043

»»»

LGTM=minux
R=bradfitz, minux
CC=golang-codereviews
https://golang.org/cl/181490043
2014-12-03 10:50:28 +11:00
Andrew Gerrand
3d34461177 go1.4rc2
LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/179700043
2014-12-02 13:43:43 +11:00
Russ Cox
28208eb8e3 [release-branch.go1.4] runtime: fix hang in GC due to shrinkstack vs netpoll race
««« CL 179680043 / 752cd9199639
runtime: fix hang in GC due to shrinkstack vs netpoll race

During garbage collection, after scanning a stack, we think about
shrinking it to reclaim some memory. The shrinking code (called
while the world is stopped) checked that the status was Gwaiting
or Grunnable and then changed the state to Gcopystack, to essentially
lock the stack so that no other GC thread is scanning it.
The same locking happens for stack growth (and is more necessary there).

        oldstatus = runtime·readgstatus(gp);
        oldstatus &= ~Gscan;
        if(oldstatus == Gwaiting || oldstatus == Grunnable)
                runtime·casgstatus(gp, oldstatus, Gcopystack); // oldstatus is Gwaiting or Grunnable
        else
                runtime·throw("copystack: bad status, not Gwaiting or Grunnable");

Unfortunately, "stop the world" doesn't stop everything. It stops all
normal goroutine execution, but the network polling thread is still
blocked in epoll and may wake up. If it does, and it chooses a goroutine
to mark runnable, and that goroutine is the one whose stack is shrinking,
then it can happen that between readgstatus and casgstatus, the status
changes from Gwaiting to Grunnable.

casgstatus assumes that if the status is not what is expected, it is a
transient change (like from Gwaiting to Gscanwaiting and back, or like
from Gwaiting to Gcopystack and back), and it loops until the status
has been restored to the expected value. In this case, the status has
changed semi-permanently from Gwaiting to Grunnable - it won't
change again until the GC is done and the world can continue, but the
GC is waiting for the status to change back. This wedges the program.

To fix, call a special variant of casgstatus that accepts either Gwaiting
or Grunnable as valid statuses.

Without the fix bug with the extra check+throw in casgstatus, the
program below dies in a few seconds (2-10) with GOMAXPROCS=8
on a 2012 Retina MacBook Pro. With the fix, it runs for minutes
and minutes.

package main

import (
        "io"
        "log"
        "net"
        "runtime"
)

func main() {
        const N = 100
        for i := 0; i < N; i++ {
                l, err := net.Listen("tcp", "127.0.0.1:0")
                if err != nil {
                        log.Fatal(err)
                }
                ch := make(chan net.Conn, 1)
                go func() {
                        var err error
                        c1, err := net.Dial("tcp", l.Addr().String())
                        if err != nil {
                                log.Fatal(err)
                        }
                        ch <- c1
                }()
                c2, err := l.Accept()
                if err != nil {
                        log.Fatal(err)
                }
                c1 := <-ch
                l.Close()
                go netguy(c1, c2)
                go netguy(c2, c1)
                c1.Write(make([]byte, 100))
        }
        for {
                runtime.GC()
        }
}

func netguy(r, w net.Conn) {
        buf := make([]byte, 100)
        for {
                bigstack(1000)
                _, err := io.ReadFull(r, buf)
                if err != nil {
                        log.Fatal(err)
                }
                w.Write(buf)
        }
}

var g int

func bigstack(n int) {
        var buf [100]byte
        if n > 0 {
                bigstack(n - 1)
        }
        g = int(buf[0]) + int(buf[99])
}

Fixes #9186.

LGTM=rlh
R=austin, rlh
CC=dvyukov, golang-codereviews, iant, khr, r
https://golang.org/cl/179680043
»»»

TBR=rlh
CC=golang-codereviews
https://golang.org/cl/184030043
2014-12-01 16:42:41 -05:00
Russ Cox
95e92ac420 [release-branch.go1.4] reflect: Fix reflect.funcLayout. The GC bitmap has two bits per
««« CL 182160043 / 321d04dea9d6
reflect: Fix reflect.funcLayout.  The GC bitmap has two bits per
pointer, not one.

Fixes #9179

LGTM=iant, rsc
R=golang-codereviews, iant, rsc
CC=golang-codereviews
https://golang.org/cl/182160043
»»»

TBR=khr
CC=golang-codereviews
https://golang.org/cl/180440044
2014-12-01 11:18:47 -05:00
Andrew Gerrand
783ad67982 [release-branch.go1.4] doc: tidy up "Projects" page; add Go 1.4
««« CL 182750043 / ffe33f1f1f17
doc: tidy up "Projects" page; add Go 1.4

LGTM=r
R=r
CC=golang-codereviews
https://golang.org/cl/182750043
»»»

TBR=r
CC=golang-codereviews
https://golang.org/cl/176350043
2014-11-26 07:57:03 +11:00
Russ Cox
d3ae115c41 [release-branch.go1.4] go/build: build $GOOS_test.go always
««« CL 176290043 / 8025b7d1e6c9
go/build: build $GOOS_test.go always

We decided to build $GOOS.go always
but forgot to test $GOOS_test.go.

Fixes #9159.

LGTM=r
R=r
CC=golang-codereviews
https://golang.org/cl/176290043
»»»

LGTM=r
R=r
CC=golang-codereviews
https://golang.org/cl/182740043
2014-11-24 22:00:01 -05:00
Russ Cox
738ccf32d9 [release-branch.go1.4] image/jpeg: handle Read returning n > 0, err != nil in d.fill
««« CL 178120043 / 95f5614b4648
image/jpeg: handle Read returning n > 0, err != nil in d.fill

Fixes #9127.

LGTM=r
R=bradfitz, r
CC=golang-codereviews, nigeltao
https://golang.org/cl/178120043
»»»

TBR=r
CC=golang-codereviews
https://golang.org/cl/181870043
2014-11-23 11:15:26 -05:00
Russ Cox
f6818121ed [release-branch.go1.4] cmd/go: fix running pprof on windows.
««« CL 176170043 / 61bbf19823d5
cmd/go: fix running pprof on windows.

Fixes #9149.

LGTM=alex.brainman, rsc
R=rsc, dave, alex.brainman
CC=golang-codereviews
https://golang.org/cl/176170043

»»»

TBR=minux
CC=golang-codereviews
https://golang.org/cl/175550043
2014-11-22 13:38:29 -05:00
Russ Cox
791fec05e4 [release-branch.go1.4] runtime: fix atomic operations on non-heap addresses
««« CL 179030043 / e4ab8f908aac
runtime: fix atomic operations on non-heap addresses
Race detector runtime does not tolerate operations on addresses
that was not previously declared with __tsan_map_shadow
(namely, data, bss and heap). The corresponding address
checks for atomic operations were removed in
https://golang.org/cl/111310044
Restore these checks.
It's tricker than just not calling into race runtime,
because it is the race runtime that makes the atomic
operations themselves (if we do not call into race runtime
we skip the atomic operation itself as well). So instead we call
__tsan_go_ignore_sync_start/end around the atomic operation.
This forces race runtime to skip all other processing
except than doing the atomic operation itself.
Fixes #9136.

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/179030043

»»»

TBR=dvyukov
CC=golang-codereviews
https://golang.org/cl/180030043
2014-11-20 10:14:49 -05:00
Russ Cox
a791780bfd [release-branch.go1.4] build: disable race external linking test on OS X 10.6 and earlier
««« CL 176070043 / 500cb52e08e6
build: disable race external linking test on OS X 10.6 and earlier

External linking doesn't work there at all.

LGTM=bradfitz
R=adg, bradfitz
CC=golang-codereviews
https://golang.org/cl/176070043
»»»

LGTM=bradfitz, adg
R=adg, bradfitz
CC=golang-codereviews
https://golang.org/cl/175400043
2014-11-19 21:25:07 -05:00
Russ Cox
427ee80413 [release-branch.go1.4] runtime: remove assumption that noptrdata data bss noptrbss are ordered and contiguous
««« CL 179980043 / d71cc7e8a0e0
runtime: remove assumption that noptrdata data bss noptrbss are ordered and contiguous

The assumption can be violated by external linkers reordering them or
inserting non-Go sections in between them. I looked briefly at trying
to write out the _go_.o in external linking mode in a way that forced
the ordering, but no matter what there's no way to force Go's data
and Go's bss to be next to each other. If there is any data or bss from
non-Go objects, it's very likely to get stuck in between them.

Instead, rewrite the two places we know about that make the assumption.
I grepped for noptrdata to look for more and didn't find any.

The added race test (os/exec in external linking mode) fails without
the changes in the runtime. It crashes with an invalid pointer dereference.

Fixes #9133.

LGTM=dneil
R=dneil
CC=dvyukov, golang-codereviews, iant
https://golang.org/cl/179980043
»»»

LGTM=dneil
R=dneil
CC=golang-codereviews
https://golang.org/cl/173510043
2014-11-19 15:31:31 -05:00
Russ Cox
b4df0154c2 [release-branch.go1.4] undo CL 131750044 / 2d6d44ceb80e
««« CL 174450043 / 699cc091a16d
undo CL 131750044 / 2d6d44ceb80e

Breaks reading from stdin in parent after exec with SysProcAttr{Setpgid: true}.

package main

import (
        "fmt"
        "os"
        "os/exec"
        "syscall"
)

func main() {
        cmd := exec.Command("true")
        cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
        cmd.Run()

        fmt.Printf("Hit enter:")
        os.Stdin.Read(make([]byte, 100))
        fmt.Printf("Bye\n")
}

In go1.3, I type enter at the prompt and the program exits.
With the CL being rolled back, the program wedges at the
prompt.

««« original CL description
syscall: SysProcAttr job control changes

Making the child's process group the foreground process group and
placing the child in a specific process group involves co-ordination
between the parent and child that must be done post-fork but pre-exec.

LGTM=iant
R=golang-codereviews, gobot, iant, mikioh.mikioh
CC=golang-codereviews
https://golang.org/cl/131750044

»»»

LGTM=minux, dneil
R=dneil, minux
CC=golang-codereviews, iant, michael.p.macinnis
https://golang.org/cl/174450043
»»»

LGTM=minux
R=dneil, minux
CC=golang-codereviews
https://golang.org/cl/179970043
2014-11-19 14:38:22 -05:00
Andrew Gerrand
c9e183e781 [release-branch.go1.4] doc/go1.4.html: rewrite first sentence to make it clearer
««« CL 178910043 / 3916b070c5f3
doc/go1.4.html: rewrite first sentence to make it clearer
The grammar was atrocious, probably the victim of an editing error.

LGTM=bradfitz
R=bradfitz
CC=golang-codereviews
https://golang.org/cl/178910043
»»»

LGTM=r
R=r
CC=golang-codereviews
https://golang.org/cl/175310043
2014-11-19 09:47:56 +11:00
Andrew Gerrand
30ef146819 [release-branch.go1.4] remove cmd/link from nacl test zip
LGTM=dsymonds
R=rsc, dsymonds
CC=golang-codereviews
https://golang.org/cl/179830043
2014-11-17 13:55:59 +11:00
Andrew Gerrand
daf5d41471 [release-branch.go1.4] remove cmd/link
LGTM=dsymonds, minux
R=rsc, dsymonds, minux
CC=golang-codereviews
https://golang.org/cl/176910043
2014-11-17 13:46:45 +11:00
Andrew Gerrand
c1fc059b08 [release-branch.go1.4] debug/goobj: move to cmd/internal/goobj
««« CL 174250043 / c16349455e05
debug/goobj: move to cmd/internal/goobj

debug/goobj is not ready to be published but it is
needed for the various binary-reading commands.
Move to cmd/internal/goobj.

(The Go 1.3 release branch deleted it, but that's not
an option anymore due to the command dependencies.
The API is still not vetted nor terribly well designed.)

LGTM=adg, dsymonds
R=adg, dsymonds
CC=golang-codereviews
https://golang.org/cl/174250043
»»»

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/177890043
2014-11-17 12:56:35 +11:00
Andrew Gerrand
335ad3db99 go1.4rc1 2014-11-17 09:37:04 +11:00
1532 changed files with 183039 additions and 229656 deletions

5
.gitignore vendored
View File

@@ -26,14 +26,15 @@ misc/cgo/life/run.out
misc/cgo/stdio/run.out
misc/cgo/testso/main
misc/dashboard/builder/builder
src/cmd/?a/y.output
src/liblink/anames?.c
src/cmd/*/y.output
src/cmd/cc/y.output
src/cmd/cgo/zdefaultcc.go
src/cmd/dist/dist.dSYM
src/cmd/gc/mkbuiltin1
src/cmd/gc/opnames.h
src/cmd/gc/y.output
src/cmd/go/zdefaultcc.go
src/cmd/internal/obj/zbootstrap.go
src/go/doc/headscan
src/runtime/mkversion
src/runtime/zaexperiment.h

58
.hgignore Normal file
View File

@@ -0,0 +1,58 @@
syntax:glob
.DS_Store
.git
.gitignore
*.[568ao]
*.a[568o]
*.so
*.pyc
._*
.nfs.*
[568a].out
*~
*.orig
*.rej
*.exe
.*.swp
core
*.cgo*.go
*.cgo*.c
_cgo_*
_obj
_test
_testmain.go
build.out
test.out
doc/articles/wiki/*.bin
include/plan9/libc_plan9.h
misc/cgo/life/run.out
misc/cgo/stdio/run.out
misc/cgo/testso/main
misc/dashboard/builder/builder
src/cmd/?a/y.output
src/liblink/anames?.c
src/cmd/cc/y.output
src/cmd/cgo/zdefaultcc.go
src/cmd/dist/dist.dSYM
src/cmd/gc/mkbuiltin1
src/cmd/gc/opnames.h
src/cmd/gc/y.output
src/cmd/go/zdefaultcc.go
src/go/doc/headscan
src/runtime/mkversion
src/runtime/z*
src/unicode/maketables
src/*.*/
test/pass.out
test/run.out
test/times.out
test/garbage/*.out
goinstall.log
last-change
VERSION.cache
syntax:regexp
^bin/
^pkg/
^src/cmd/(.*)/6?\1$
^.*/core.[0-9]*$

138
.hgtags Normal file
View File

@@ -0,0 +1,138 @@
1f0a01c93d305f1ab636c68b67346659c5b957f7 weekly.2009-11-06
64e703cb307da550861fe740ff70a482a2c14819 weekly.2009-11-10
b51fd2d6c16034480f26c96ba32a11c598e4638e weekly.2009-11-10.1
cb140bac9ab0fd9f734ee443cea9ebadc9c99737 weekly.2009-11-12
d1b75410b793309532352a6fb6b44453f052f3f4 weekly.2009-11-17
e205103b02e7393d4719df5faac2dac808234d3f weekly.2009-12-07
3a47d2e3882bb12129de05382a2c131bb0c00964 weekly.2009-12-09
a6fcf4303b0a92cce4011556b1c96044252d93af weekly.2009-12-22
3887d4d81bca78b63d620985d93f1cc06c063871 weekly.2010-01-05
40dd722155f6d0c83fa572c1a5abf7c6ff35049f weekly.2010-01-13
0a2770db06efe92b08b5c6f30e14b7e8db012538 weekly.2010-01-27
db4262ce882d8445764312d41547ee8f11a7f7a9 weekly.2010-02-04
53fec18b83e2b93baafba4733b59bb86b8c1988e weekly.2010-02-17
4a0661b86e50eae734dbe43ed1312c4a0304676b weekly.2010-02-23
a215d03e7ee1013b2abe3f1e2c84457ec51c68e4 weekly.2010-03-04
194d473264c1a015803d07bed200e0c312aca43e weekly.2010-03-15
9482fde11a02ffd57ba0561dc8a4ac338061a3ae weekly.2010-03-22
57380d620ee6b65eb88da1c52784b62c94d7e72e weekly.2010-03-30
f98f784927abc56a61501eba0cf225966f2b0142 weekly.2010-04-13
6cc6c0d85fc3234fc0a5ec0a8777aa9d59d05ae8 weekly.2010-04-27
17ded5ad443b41ac05924864798f1bd8750da344 weekly.2010-05-04
a85ad0a640154b5d33626ad8ea15ed17e3828178 weekly.2010-05-27
f776656df34c009f2aad142bf7b34a778404acd1 weekly.2010-06-09
113ec27f29f18825444f6f8a3cdc156c1df28e87 weekly.2010-06-21
b761e0299e9bf66298778cf170b0f64216e3cf7d weekly.2010-07-01
5992bf56aa72efcea87d8dff14985fc8fcc68575 weekly.2010-07-14
db904d88dc0ebf6ee5b55e44088915695c1223ee weekly.2010-07-29
8884f7b4c7750481ed246c249db47b61fe752c56 weekly.2010-08-04
07d3a97302be88af68acff34c8a089589da21d18 weekly.2010-08-11
18926649cda7498b8aa539b3a611abcff548f09f weekly.2010-08-25
92fcf05736e8565a485adc52da1894270e06ed09 weekly.2010-09-06
9329773e204fed50ec686ee78cc715b624bf1b1d weekly.2010-09-15
1eec33c03bceef5d7607ea4636185f7bf773e0e4 weekly.2010-09-22
c2b8c9f13fb8ad2b56920d9da2928c5314ebf725 weekly.2010-09-29
7c2e97710bf49cdbe388260958a6674afefb6c0f weekly.2010-10-13
ca4f9687cec0b9c4732afd57b8c2786c7fe242de weekly.2010-10-13.1
79997f0e5823ee9d13a34ca9971a9d8811df1c4a weekly.2010-10-20
4d5b0816392116d3a3452bb275b6dab6c6456278 weekly.2010-10-27
c627e23260c7ddf4a1fcda6ef3197c98fa22551d weekly.2010-11-02
a7800e20064a39585aa3ee339c2b7454ae1ce6d5 weekly.2010-11-10
c5287468fcff0f8a7bb9ffaece2a4863e7e5d83e weekly.2010-11-23
f7e692dc29b02fba8e5d59b967880a347b53607c weekly.2010-12-02
56e39c466cc1c49b587eb56dc2166d61151637df weekly.2010-12-08
26f4898dc1ca18bb77f9968aca23773637e34f0d weekly.2010-12-15
61b2c52b0d2246430395f2869d7b34e565333cf5 weekly.2010-12-15.1
51c777dbccb9f537ebffb99244f521c05bf65df6 weekly.2010-12-22
8eeee945e358f19405e81792db0e16a1cad14bc0 weekly.2011-01-06
514c7ba501a1dd74d69ea2d0a2b4116802ada2b5 weekly.2011-01-12
72f9cb714f08b98c6a65ab2f2256fad6bb16967a weekly.2011-01-19
d8ba80011a986470a54e5262ec125105aa4adc34 weekly.2011-01-20
5b98b59dd37292e36afb24babb2d22758928e13d weekly.2011-02-01
867d37fb41a4d96ab7a6202fd6ad54c345494051 weekly.2011-02-01.1
b2be017f91348d5f8cbaf42f77a99fc905044b59 weekly.2011-02-15
322350d6fdbf11d9c404d6fc766349d824031339 weekly.2011-02-24
21848430d60167817ca965c813a2118068ca660f weekly.2011-03-07
c5c62aeb6267e124cf05f9622e28dbd0dc6b971d weekly.2011-03-07.1
c5c62aeb6267e124cf05f9622e28dbd0dc6b971d release.r56
3b4e9c85b643a35860805718323b05186dd7f235 weekly.2011-03-15
b84e614e25161f626a6102813c41a80a15e3a625 weekly.2011-03-28
cd89452cfea3d125aaf75a1ec8004e2f6a868d38 weekly.2011-04-04
d6903b7fbff40c13ee7ea3177c0ae54c7f89d2e6 weekly.2011-04-13
2f0fa51fa2da6ab50fcebba526326153da8ed999 weekly.2011-04-27
8493bb64e5592bd20c0e60e78e7f8052c1276fcf release.r57
95d2ce135523c96c4cea049af94ce76dd8c7d981 release.r57.1
c98449d685d2b6aa1df9bfd2e1cce9307efb6e00 weekly.2011-05-22
3418f22c39eb8299053ae681199ee90f8cd29c6d weekly.2011-06-02
c81944152e973a917797679055b8fcdc70fbc802 weekly.2011-06-09
9d7967223815ef6415ff01aa0fe6ad38cdbc7810 release.r57.2
dac76f0b1a18a5de5b54a1dc0b231aceaf1c8583 weekly.2011-06-16
541c445d6c1353fbfa39df7dc4b0eb27558d1fc1 weekly.2011-06-23
1b38d90eebcddefabb3901c5bb63c7e2b04a6ec5 release.r58
16bfa562ba767aefd82e598da8b15ee4729e23b0 weekly.2011-07-07
d292bc7886682d35bb391bf572be28656baee12d release.r58.1
3c21f37b25a3f7a1726265c5339c8a7b0b329336 weekly.2011-07-19
bb28251f6da4aca85658582c370c7df89d34efd4 weekly.2011-07-29
d5785050f61d973fc36775f7bd2e26689529cb3e release.r59
c17ce5ec06b4bd5cf6e7ff2ceb0a60c2e40e0b17 weekly.2011-08-10
6eb2b9dbe489acb57a2bfc1de31ec2239ed94326 weekly.2011-08-17
c934f6f5fe8b30b4b3210ee3f13669e6e4670c32 weekly.2011-09-01
c77997547d546c36c7b969586a36de7ceda74e33 weekly.2011-09-07
b0819469a6df6029a27192fe7b19a73d97404c63 release.r60
8a09ce0cefc64deab4e6d1ed59a08a53e879bbee weekly.2011-09-16
fd30c132d1bdeb79f8f111cb721fb1c78b767b27 release.r60.1
d7322ae4d055a4cf3efaf842d0717a41acd85bac weekly.2011-09-21
32a5db19629897641b2d488de4d1b998942ef80e release.r60.2
3bdabf483805fbf0c7ef013fd09bfd6062b9d3f2 weekly.2011-10-06
c1702f36df0397c19fc333571a771666029aa37e release.r60.3
acaddf1cea75c059d19b20dbef35b20fb3f38954 release.r58.2
6d7136d74b656ba6e1194853a9486375005227ef weekly.2011-10-18
941b8015061a0f6480954821dd589c60dfe35ed1 weekly.2011-10-25
7c1f789e6efd153951e85e3f28722fc69efc2af2 weekly.2011-10-26
e69e528f2afc25a8334cfb9359fa4fcdf2a934b6 weekly.2011-11-01
780c85032b174c9d4b42adf75d82bc85af7d78d1 weekly.2011-11-02
f4397ad6e87c7ce5feac9b01686f1ebd6cbaac4e weekly.2011-11-08
2f4482b89a6b5956828872137b6b96636cd904d3 weekly.2011-11-09
b4a91b6933748db1a7150c06a1b55ad506e52906 weekly.2011-11-18
80db2da6495a20ddff8305c236825811db8c8665 weekly.2011-12-01
0beb796b4ef8747af601ed5ea6766d5b1340086b weekly.2011-12-02
0c39eee85b0d1606b79c8ebcdeb3b67ed5849e39 weekly.2011-12-06
82fdc445f2ff2c85043446eb84a19cc999dfcb95 weekly.2011-12-14
4a82689277582a2a60f006e3f158985f2f8d1da3 weekly.2011-12-22
354b17404643c0f1a710bdc48927dff02f203ae3 weekly.2012-01-15
9f2be4fbbf690b9562c6e98b91daa0003f0913c7 weekly.2012-01-20
1107a7d3cb075836387adfab5ce56d1b3e56637d weekly.2012-01-27
52ba9506bd993663a0a033c2bd68699e25d061ab weekly.2012-02-07
43cf9b39b6477d3144b0353ee91096e55db6107f weekly.2012-02-14
96bd78e7d35e892113bdfa1bdc392d3a5f2e644b weekly.2012-02-22
f4470a54e6dbcdd52d8d404e12e4754adcd2c948 weekly.2012-03-04
3cdba7b0650c6c906ef3e782654f61701abd7dd2 weekly.2012-03-13
bce220d0377405146527ab9478867cbc572a6886 weekly.2012-03-22
dc5e410f0b4c32ab11dc992593a2bcf5f607381b weekly.2012-03-27
dc5e410f0b4c32ab11dc992593a2bcf5f607381b weekly
920e9d1ffd1f46665dd152aa9cf3c0f17d68dd88 go1
2ccfd4b451d319941bfe3e08037e1462d3c15093 go1.0.1
5e806355a9e1491aaab53d3612fed4c550b130c0 go1.0.2
2d8bc3c94ecb3ec8f70556d5fd237788903c7281 go1.0.3
35da6063e57f8cefc82ba1ea542c4d9393ea9dfd go1.1rc2
5a15f0dae37931da46f0356cf4cffe775a061c12 go1.1rc3
e570c2daeaca10663d36d6dee7f8d1d76e8f7b92 go1.1
a7bd9a33067b3537351276e0178a045748ad046a go1.1.1
414057ac1f1fc850957088e4c5e95cdbccd2d594 go1.1.2
45475ec7eab1c588fc4210b34d5901b15ca1e479 go1.2rc2
7422495a6bf9d5e84828ee466406293be84f565a go1.2rc3
94af58f9fd71feda5c316d791ed11aaf015f9e82 go1.2rc4
b3d5a20b070a92da2458c5788694d1359b353f4a go1.2rc5
87dea3f5ebe7510998c84dbeeec89382b7d42f9c go1.2
0ddbdc3c7ce27e66508fe58ab81ff29324786026 go1.2.1
9c4fdd8369ca4483fbed1cb8e67f02643ca10f79 go1.2.2
f8b50ad4cac4d4c4ecf48324b4f512f65e82cc1c go1.3beta1
9e1652c32289c164126b6171f024afad5665fc9e go1.3beta2
9d5451df4e53acc58a848005b7ec3a24c4b6050c go1.3rc1
3f66a43d5180052e2e1e38d979d1aa5ad05b21f9 go1.3rc2
9895f9e36435468d503eaa74ee217f28d5e28dd4 go1.3
073fc578434bf3e1e22749b559d273c8da728ebb go1.3.1
85518b1d6f8d6e16133b9ed2c9db6807522d37de go1.3.2
f44017549ff9c3cc5eef74ebe7276cd0dfc066b6 go1.3.3
f44017549ff9c3cc5eef74ebe7276cd0dfc066b6 release
1fdfd7dfaedb1b7702141617e621ab7328a236a1 go1.4beta1

View File

@@ -1,31 +0,0 @@
# Contributing to Go
Go is an open source project.
It is the work of hundreds of contributors. We appreciate your help!
## Filing issues
When filing an issue, make sure to answer these five questions:
1. What version of Go are you using (`go version`)?
2. What operating system and processor architecture are you using?
3. What did you do?
4. What did you expect to see?
5. What did you see instead?
General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
The gophers there will answer or ask you to file an issue if you've tripped over a bug.
## Contributing code
Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
before sending patches.
**We do not accept GitHub pull requests**
(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review).
Unless otherwise noted, the Go source files are distributed under
the BSD-style license found in the LICENSE file.

32
README Normal file
View File

@@ -0,0 +1,32 @@
This is the source code repository for the Go programming language.
For documentation about how to install and use Go,
visit http://golang.org/ or load doc/install-source.html
in your web browser.
After installing Go, you can view a nicely formatted
doc/install-source.html by running godoc --http=:6060
and then visiting http://localhost:6060/doc/install/source.
Unless otherwise noted, the Go source files are distributed
under the BSD-style license found in the LICENSE file.
--
Binary Distribution Notes
If you have just untarred a binary Go distribution, you need to set
the environment variable $GOROOT to the full path of the go
directory (the one containing this README). You can omit the
variable if you unpack it into /usr/local/go, or if you rebuild
from sources by running all.bash (see doc/install.html).
You should also add the Go binary directory $GOROOT/bin
to your shell's path.
For example, if you extracted the tar file into $HOME/go, you might
put the following in your .profile:
export GOROOT=$HOME/go
export PATH=$PATH:$GOROOT/bin
See doc/install.html for more details.

View File

@@ -1,45 +0,0 @@
# The Go Programming Language
Go is an open source programming language that makes it easy to build simple,
reliable, and efficient software.
![Gopher image](doc/gopher/fiveyears.jpg)
For documentation about how to install and use Go,
visit https://golang.org/ or load doc/install-source.html
in your web browser.
Our canonical Git repository is located at https://go.googlesource.com/go.
There is a mirror of the repository at https://github.com/golang/go.
Please report issues here: https://golang.org/issue/new
Go is the work of hundreds of contributors. We appreciate your help!
To contribute, please read the contribution guidelines:
https://golang.org/doc/contribute.html
##### Please note that we do not use pull requests.
Unless otherwise noted, the Go source files are distributed
under the BSD-style license found in the LICENSE file.
--
## Binary Distribution Notes
If you have just untarred a binary Go distribution, you need to set
the environment variable $GOROOT to the full path of the go
directory (the one containing this file). You can omit the
variable if you unpack it into /usr/local/go, or if you rebuild
from sources by running all.bash (see doc/install-source.html).
You should also add the Go binary directory $GOROOT/bin
to your shell's path.
For example, if you extracted the tar file into $HOME/go, you might
put the following in your .profile:
export GOROOT=$HOME/go
export PATH=$PATH:$GOROOT/bin
See https://golang.org/doc/install or doc/install.html for more details.

1
VERSION Normal file
View File

@@ -0,0 +1 @@
go1.4.2

View File

@@ -1,249 +1,141 @@
pkg debug/elf, const R_PPC64_ADDR14 = 7
pkg debug/elf, const R_PPC64_ADDR14 R_PPC64
pkg debug/elf, const R_PPC64_ADDR14_BRNTAKEN = 9
pkg debug/elf, const R_PPC64_ADDR14_BRNTAKEN R_PPC64
pkg debug/elf, const R_PPC64_ADDR14_BRTAKEN = 8
pkg debug/elf, const R_PPC64_ADDR14_BRTAKEN R_PPC64
pkg debug/elf, const R_PPC64_ADDR16 = 3
pkg debug/elf, const R_PPC64_ADDR16 R_PPC64
pkg debug/elf, const R_PPC64_ADDR16_DS = 56
pkg debug/elf, const R_PPC64_ADDR16_DS R_PPC64
pkg debug/elf, const R_PPC64_ADDR16_HA = 6
pkg debug/elf, const R_PPC64_ADDR16_HA R_PPC64
pkg debug/elf, const R_PPC64_ADDR16_HI = 5
pkg debug/elf, const R_PPC64_ADDR16_HI R_PPC64
pkg debug/elf, const R_PPC64_ADDR16_HIGHER = 39
pkg debug/elf, const R_PPC64_ADDR16_HIGHER R_PPC64
pkg debug/elf, const R_PPC64_ADDR16_HIGHERA = 40
pkg debug/elf, const R_PPC64_ADDR16_HIGHERA R_PPC64
pkg debug/elf, const R_PPC64_ADDR16_HIGHEST = 41
pkg debug/elf, const R_PPC64_ADDR16_HIGHEST R_PPC64
pkg debug/elf, const R_PPC64_ADDR16_HIGHESTA = 42
pkg debug/elf, const R_PPC64_ADDR16_HIGHESTA R_PPC64
pkg debug/elf, const R_PPC64_ADDR16_LO = 4
pkg debug/elf, const R_PPC64_ADDR16_LO R_PPC64
pkg debug/elf, const R_PPC64_ADDR16_LO_DS = 57
pkg debug/elf, const R_PPC64_ADDR16_LO_DS R_PPC64
pkg debug/elf, const R_PPC64_ADDR24 = 2
pkg debug/elf, const R_PPC64_ADDR24 R_PPC64
pkg debug/elf, const R_PPC64_ADDR32 = 1
pkg debug/elf, const R_PPC64_ADDR32 R_PPC64
pkg debug/elf, const R_PPC64_ADDR64 = 38
pkg debug/elf, const R_PPC64_ADDR64 R_PPC64
pkg debug/elf, const R_PPC64_DTPMOD64 = 68
pkg debug/elf, const R_PPC64_DTPMOD64 R_PPC64
pkg debug/elf, const R_PPC64_DTPREL16 = 74
pkg debug/elf, const R_PPC64_DTPREL16 R_PPC64
pkg debug/elf, const R_PPC64_DTPREL16_DS = 101
pkg debug/elf, const R_PPC64_DTPREL16_DS R_PPC64
pkg debug/elf, const R_PPC64_DTPREL16_HA = 77
pkg debug/elf, const R_PPC64_DTPREL16_HA R_PPC64
pkg debug/elf, const R_PPC64_DTPREL16_HI = 76
pkg debug/elf, const R_PPC64_DTPREL16_HI R_PPC64
pkg debug/elf, const R_PPC64_DTPREL16_HIGHER = 103
pkg debug/elf, const R_PPC64_DTPREL16_HIGHER R_PPC64
pkg debug/elf, const R_PPC64_DTPREL16_HIGHERA = 104
pkg debug/elf, const R_PPC64_DTPREL16_HIGHERA R_PPC64
pkg debug/elf, const R_PPC64_DTPREL16_HIGHEST = 105
pkg debug/elf, const R_PPC64_DTPREL16_HIGHEST R_PPC64
pkg debug/elf, const R_PPC64_DTPREL16_HIGHESTA = 106
pkg debug/elf, const R_PPC64_DTPREL16_HIGHESTA R_PPC64
pkg debug/elf, const R_PPC64_DTPREL16_LO = 75
pkg debug/elf, const R_PPC64_DTPREL16_LO R_PPC64
pkg debug/elf, const R_PPC64_DTPREL16_LO_DS = 102
pkg debug/elf, const R_PPC64_DTPREL16_LO_DS R_PPC64
pkg debug/elf, const R_PPC64_DTPREL64 = 78
pkg debug/elf, const R_PPC64_DTPREL64 R_PPC64
pkg debug/elf, const R_PPC64_GOT16 = 14
pkg debug/elf, const R_PPC64_GOT16 R_PPC64
pkg debug/elf, const R_PPC64_GOT16_DS = 58
pkg debug/elf, const R_PPC64_GOT16_DS R_PPC64
pkg debug/elf, const R_PPC64_GOT16_HA = 17
pkg debug/elf, const R_PPC64_GOT16_HA R_PPC64
pkg debug/elf, const R_PPC64_GOT16_HI = 16
pkg debug/elf, const R_PPC64_GOT16_HI R_PPC64
pkg debug/elf, const R_PPC64_GOT16_LO = 15
pkg debug/elf, const R_PPC64_GOT16_LO R_PPC64
pkg debug/elf, const R_PPC64_GOT16_LO_DS = 59
pkg debug/elf, const R_PPC64_GOT16_LO_DS R_PPC64
pkg debug/elf, const R_PPC64_GOT_DTPREL16_DS = 91
pkg debug/elf, const R_PPC64_GOT_DTPREL16_DS R_PPC64
pkg debug/elf, const R_PPC64_GOT_DTPREL16_HA = 94
pkg debug/elf, const R_PPC64_GOT_DTPREL16_HA R_PPC64
pkg debug/elf, const R_PPC64_GOT_DTPREL16_HI = 93
pkg debug/elf, const R_PPC64_GOT_DTPREL16_HI R_PPC64
pkg debug/elf, const R_PPC64_GOT_DTPREL16_LO_DS = 92
pkg debug/elf, const R_PPC64_GOT_DTPREL16_LO_DS R_PPC64
pkg debug/elf, const R_PPC64_GOT_TLSGD16 = 79
pkg debug/elf, const R_PPC64_GOT_TLSGD16 R_PPC64
pkg debug/elf, const R_PPC64_GOT_TLSGD16_HA = 82
pkg debug/elf, const R_PPC64_GOT_TLSGD16_HA R_PPC64
pkg debug/elf, const R_PPC64_GOT_TLSGD16_HI = 81
pkg debug/elf, const R_PPC64_GOT_TLSGD16_HI R_PPC64
pkg debug/elf, const R_PPC64_GOT_TLSGD16_LO = 80
pkg debug/elf, const R_PPC64_GOT_TLSGD16_LO R_PPC64
pkg debug/elf, const R_PPC64_GOT_TLSLD16 = 83
pkg debug/elf, const R_PPC64_GOT_TLSLD16 R_PPC64
pkg debug/elf, const R_PPC64_GOT_TLSLD16_HA = 86
pkg debug/elf, const R_PPC64_GOT_TLSLD16_HA R_PPC64
pkg debug/elf, const R_PPC64_GOT_TLSLD16_HI = 85
pkg debug/elf, const R_PPC64_GOT_TLSLD16_HI R_PPC64
pkg debug/elf, const R_PPC64_GOT_TLSLD16_LO = 84
pkg debug/elf, const R_PPC64_GOT_TLSLD16_LO R_PPC64
pkg debug/elf, const R_PPC64_GOT_TPREL16_DS = 87
pkg debug/elf, const R_PPC64_GOT_TPREL16_DS R_PPC64
pkg debug/elf, const R_PPC64_GOT_TPREL16_HA = 90
pkg debug/elf, const R_PPC64_GOT_TPREL16_HA R_PPC64
pkg debug/elf, const R_PPC64_GOT_TPREL16_HI = 89
pkg debug/elf, const R_PPC64_GOT_TPREL16_HI R_PPC64
pkg debug/elf, const R_PPC64_GOT_TPREL16_LO_DS = 88
pkg debug/elf, const R_PPC64_GOT_TPREL16_LO_DS R_PPC64
pkg debug/elf, const R_PPC64_JMP_SLOT = 21
pkg debug/elf, const R_PPC64_JMP_SLOT R_PPC64
pkg debug/elf, const R_PPC64_NONE = 0
pkg debug/elf, const R_PPC64_NONE R_PPC64
pkg debug/elf, const R_PPC64_REL14 = 11
pkg debug/elf, const R_PPC64_REL14 R_PPC64
pkg debug/elf, const R_PPC64_REL14_BRNTAKEN = 13
pkg debug/elf, const R_PPC64_REL14_BRNTAKEN R_PPC64
pkg debug/elf, const R_PPC64_REL14_BRTAKEN = 12
pkg debug/elf, const R_PPC64_REL14_BRTAKEN R_PPC64
pkg debug/elf, const R_PPC64_REL16 = 249
pkg debug/elf, const R_PPC64_REL16 R_PPC64
pkg debug/elf, const R_PPC64_REL16_HA = 252
pkg debug/elf, const R_PPC64_REL16_HA R_PPC64
pkg debug/elf, const R_PPC64_REL16_HI = 251
pkg debug/elf, const R_PPC64_REL16_HI R_PPC64
pkg debug/elf, const R_PPC64_REL16_LO = 250
pkg debug/elf, const R_PPC64_REL16_LO R_PPC64
pkg debug/elf, const R_PPC64_REL24 = 10
pkg debug/elf, const R_PPC64_REL24 R_PPC64
pkg debug/elf, const R_PPC64_REL32 = 26
pkg debug/elf, const R_PPC64_REL32 R_PPC64
pkg debug/elf, const R_PPC64_REL64 = 44
pkg debug/elf, const R_PPC64_REL64 R_PPC64
pkg debug/elf, const R_PPC64_TLS = 67
pkg debug/elf, const R_PPC64_TLS R_PPC64
pkg debug/elf, const R_PPC64_TLSGD = 107
pkg debug/elf, const R_PPC64_TLSGD R_PPC64
pkg debug/elf, const R_PPC64_TLSLD = 108
pkg debug/elf, const R_PPC64_TLSLD R_PPC64
pkg debug/elf, const R_PPC64_TOC = 51
pkg debug/elf, const R_PPC64_TOC R_PPC64
pkg debug/elf, const R_PPC64_TOC16 = 47
pkg debug/elf, const R_PPC64_TOC16 R_PPC64
pkg debug/elf, const R_PPC64_TOC16_DS = 63
pkg debug/elf, const R_PPC64_TOC16_DS R_PPC64
pkg debug/elf, const R_PPC64_TOC16_HA = 50
pkg debug/elf, const R_PPC64_TOC16_HA R_PPC64
pkg debug/elf, const R_PPC64_TOC16_HI = 49
pkg debug/elf, const R_PPC64_TOC16_HI R_PPC64
pkg debug/elf, const R_PPC64_TOC16_LO = 48
pkg debug/elf, const R_PPC64_TOC16_LO R_PPC64
pkg debug/elf, const R_PPC64_TOC16_LO_DS = 64
pkg debug/elf, const R_PPC64_TOC16_LO_DS R_PPC64
pkg debug/elf, const R_PPC64_TPREL16 = 69
pkg debug/elf, const R_PPC64_TPREL16 R_PPC64
pkg debug/elf, const R_PPC64_TPREL16_DS = 95
pkg debug/elf, const R_PPC64_TPREL16_DS R_PPC64
pkg debug/elf, const R_PPC64_TPREL16_HA = 72
pkg debug/elf, const R_PPC64_TPREL16_HA R_PPC64
pkg debug/elf, const R_PPC64_TPREL16_HI = 71
pkg debug/elf, const R_PPC64_TPREL16_HI R_PPC64
pkg debug/elf, const R_PPC64_TPREL16_HIGHER = 97
pkg debug/elf, const R_PPC64_TPREL16_HIGHER R_PPC64
pkg debug/elf, const R_PPC64_TPREL16_HIGHERA = 98
pkg debug/elf, const R_PPC64_TPREL16_HIGHERA R_PPC64
pkg debug/elf, const R_PPC64_TPREL16_HIGHEST = 99
pkg debug/elf, const R_PPC64_TPREL16_HIGHEST R_PPC64
pkg debug/elf, const R_PPC64_TPREL16_HIGHESTA = 100
pkg debug/elf, const R_PPC64_TPREL16_HIGHESTA R_PPC64
pkg debug/elf, const R_PPC64_TPREL16_LO = 70
pkg debug/elf, const R_PPC64_TPREL16_LO R_PPC64
pkg debug/elf, const R_PPC64_TPREL16_LO_DS = 96
pkg debug/elf, const R_PPC64_TPREL16_LO_DS R_PPC64
pkg debug/elf, const R_PPC64_TPREL64 = 73
pkg debug/elf, const R_PPC64_TPREL64 R_PPC64
pkg debug/elf, method (R_PPC64) GoString() string
pkg debug/elf, method (R_PPC64) String() string
pkg debug/elf, type R_PPC64 int
pkg runtime (openbsd-386), const CLOCK_MONOTONIC = 3
pkg runtime (openbsd-386), const CLOCK_MONOTONIC ideal-int
pkg runtime (openbsd-386), const CLOCK_PROF = 2
pkg runtime (openbsd-386), const CLOCK_PROF ideal-int
pkg runtime (openbsd-386), const CLOCK_REALTIME = 0
pkg runtime (openbsd-386), const CLOCK_REALTIME ideal-int
pkg runtime (openbsd-386), const CLOCK_VIRTUAL = 1
pkg runtime (openbsd-386), const CLOCK_VIRTUAL ideal-int
pkg runtime (openbsd-386), const CTL_HW = 6
pkg runtime (openbsd-386), const CTL_HW ideal-int
pkg runtime (openbsd-386), const EAGAIN = 35
pkg runtime (openbsd-386), const EAGAIN ideal-int
pkg runtime (openbsd-386), const ENOTSUP = 91
pkg runtime (openbsd-386), const ENOTSUP ideal-int
pkg runtime (openbsd-386), const ESRCH = 3
pkg runtime (openbsd-386), const ESRCH ideal-int
pkg runtime (openbsd-386), const EWOULDBLOCK = 35
pkg runtime (openbsd-386), const EWOULDBLOCK ideal-int
pkg runtime (openbsd-386), const HW_NCPU = 3
pkg runtime (openbsd-386), const HW_NCPU ideal-int
pkg runtime (openbsd-386-cgo), const CLOCK_MONOTONIC = 3
pkg runtime (openbsd-386-cgo), const CLOCK_MONOTONIC ideal-int
pkg runtime (openbsd-386-cgo), const CLOCK_PROF = 2
pkg runtime (openbsd-386-cgo), const CLOCK_PROF ideal-int
pkg runtime (openbsd-386-cgo), const CLOCK_REALTIME = 0
pkg runtime (openbsd-386-cgo), const CLOCK_REALTIME ideal-int
pkg runtime (openbsd-386-cgo), const CLOCK_VIRTUAL = 1
pkg runtime (openbsd-386-cgo), const CLOCK_VIRTUAL ideal-int
pkg runtime (openbsd-386-cgo), const CTL_HW = 6
pkg runtime (openbsd-386-cgo), const CTL_HW ideal-int
pkg runtime (openbsd-386-cgo), const EAGAIN = 35
pkg runtime (openbsd-386-cgo), const EAGAIN ideal-int
pkg runtime (openbsd-386-cgo), const ENOTSUP = 91
pkg runtime (openbsd-386-cgo), const ENOTSUP ideal-int
pkg runtime (openbsd-386-cgo), const ESRCH = 3
pkg runtime (openbsd-386-cgo), const ESRCH ideal-int
pkg runtime (openbsd-386-cgo), const EWOULDBLOCK = 35
pkg runtime (openbsd-386-cgo), const EWOULDBLOCK ideal-int
pkg runtime (openbsd-386-cgo), const HW_NCPU = 3
pkg runtime (openbsd-386-cgo), const HW_NCPU ideal-int
pkg runtime (openbsd-amd64), const CLOCK_MONOTONIC = 3
pkg runtime (openbsd-amd64), const CLOCK_MONOTONIC ideal-int
pkg runtime (openbsd-amd64), const CLOCK_PROF = 2
pkg runtime (openbsd-amd64), const CLOCK_PROF ideal-int
pkg runtime (openbsd-amd64), const CLOCK_REALTIME = 0
pkg runtime (openbsd-amd64), const CLOCK_REALTIME ideal-int
pkg runtime (openbsd-amd64), const CLOCK_VIRTUAL = 1
pkg runtime (openbsd-amd64), const CLOCK_VIRTUAL ideal-int
pkg runtime (openbsd-amd64), const CTL_HW = 6
pkg runtime (openbsd-amd64), const CTL_HW ideal-int
pkg runtime (openbsd-amd64), const EAGAIN = 35
pkg runtime (openbsd-amd64), const EAGAIN ideal-int
pkg runtime (openbsd-amd64), const ENOTSUP = 91
pkg runtime (openbsd-amd64), const ENOTSUP ideal-int
pkg runtime (openbsd-amd64), const ESRCH = 3
pkg runtime (openbsd-amd64), const ESRCH ideal-int
pkg runtime (openbsd-amd64), const EWOULDBLOCK = 35
pkg runtime (openbsd-amd64), const EWOULDBLOCK ideal-int
pkg runtime (openbsd-amd64), const HW_NCPU = 3
pkg runtime (openbsd-amd64), const HW_NCPU ideal-int
pkg runtime (openbsd-amd64-cgo), const CLOCK_MONOTONIC = 3
pkg runtime (openbsd-amd64-cgo), const CLOCK_MONOTONIC ideal-int
pkg runtime (openbsd-amd64-cgo), const CLOCK_PROF = 2
pkg runtime (openbsd-amd64-cgo), const CLOCK_PROF ideal-int
pkg runtime (openbsd-amd64-cgo), const CLOCK_REALTIME = 0
pkg runtime (openbsd-amd64-cgo), const CLOCK_REALTIME ideal-int
pkg runtime (openbsd-amd64-cgo), const CLOCK_VIRTUAL = 1
pkg runtime (openbsd-amd64-cgo), const CLOCK_VIRTUAL ideal-int
pkg runtime (openbsd-amd64-cgo), const CTL_HW = 6
pkg runtime (openbsd-amd64-cgo), const CTL_HW ideal-int
pkg runtime (openbsd-amd64-cgo), const EAGAIN = 35
pkg runtime (openbsd-amd64-cgo), const EAGAIN ideal-int
pkg runtime (openbsd-amd64-cgo), const ENOTSUP = 91
pkg runtime (openbsd-amd64-cgo), const ENOTSUP ideal-int
pkg runtime (openbsd-amd64-cgo), const ESRCH = 3
pkg runtime (openbsd-amd64-cgo), const ESRCH ideal-int
pkg runtime (openbsd-amd64-cgo), const EWOULDBLOCK = 35
pkg runtime (openbsd-amd64-cgo), const EWOULDBLOCK ideal-int
pkg runtime (openbsd-amd64-cgo), const HW_NCPU = 3
pkg runtime (openbsd-amd64-cgo), const HW_NCPU ideal-int
pkg debug/goobj, const SBSS = 21
pkg debug/goobj, const SBSS SymKind
pkg debug/goobj, const SCONST = 31
pkg debug/goobj, const SCONST SymKind
pkg debug/goobj, const SDATA = 19
pkg debug/goobj, const SDATA SymKind
pkg debug/goobj, const SDYNIMPORT = 32
pkg debug/goobj, const SDYNIMPORT SymKind
pkg debug/goobj, const SELFROSECT = 12
pkg debug/goobj, const SELFROSECT SymKind
pkg debug/goobj, const SELFRXSECT = 2
pkg debug/goobj, const SELFRXSECT SymKind
pkg debug/goobj, const SELFSECT = 14
pkg debug/goobj, const SELFSECT SymKind
pkg debug/goobj, const SFILE = 29
pkg debug/goobj, const SFILE SymKind
pkg debug/goobj, const SFILEPATH = 30
pkg debug/goobj, const SFILEPATH SymKind
pkg debug/goobj, const SFUNCTAB = 8
pkg debug/goobj, const SFUNCTAB SymKind
pkg debug/goobj, const SGOFUNC = 6
pkg debug/goobj, const SGOFUNC SymKind
pkg debug/goobj, const SGOSTRING = 5
pkg debug/goobj, const SGOSTRING SymKind
pkg debug/goobj, const SHOSTOBJ = 33
pkg debug/goobj, const SHOSTOBJ SymKind
pkg debug/goobj, const SINITARR = 18
pkg debug/goobj, const SINITARR SymKind
pkg debug/goobj, const SMACHO = 15
pkg debug/goobj, const SMACHO SymKind
pkg debug/goobj, const SMACHOGOT = 16
pkg debug/goobj, const SMACHOGOT SymKind
pkg debug/goobj, const SMACHOINDIRECTGOT = 28
pkg debug/goobj, const SMACHOINDIRECTGOT SymKind
pkg debug/goobj, const SMACHOINDIRECTPLT = 27
pkg debug/goobj, const SMACHOINDIRECTPLT SymKind
pkg debug/goobj, const SMACHOPLT = 13
pkg debug/goobj, const SMACHOPLT SymKind
pkg debug/goobj, const SMACHOSYMSTR = 25
pkg debug/goobj, const SMACHOSYMSTR SymKind
pkg debug/goobj, const SMACHOSYMTAB = 26
pkg debug/goobj, const SMACHOSYMTAB SymKind
pkg debug/goobj, const SNOPTRBSS = 22
pkg debug/goobj, const SNOPTRBSS SymKind
pkg debug/goobj, const SNOPTRDATA = 17
pkg debug/goobj, const SNOPTRDATA SymKind
pkg debug/goobj, const SPCLNTAB = 11
pkg debug/goobj, const SPCLNTAB SymKind
pkg debug/goobj, const SRODATA = 7
pkg debug/goobj, const SRODATA SymKind
pkg debug/goobj, const SSTRING = 4
pkg debug/goobj, const SSTRING SymKind
pkg debug/goobj, const SSYMTAB = 10
pkg debug/goobj, const SSYMTAB SymKind
pkg debug/goobj, const STEXT = 1
pkg debug/goobj, const STEXT SymKind
pkg debug/goobj, const STLSBSS = 23
pkg debug/goobj, const STLSBSS SymKind
pkg debug/goobj, const STYPE = 3
pkg debug/goobj, const STYPE SymKind
pkg debug/goobj, const STYPELINK = 9
pkg debug/goobj, const STYPELINK SymKind
pkg debug/goobj, const SWINDOWS = 20
pkg debug/goobj, const SWINDOWS SymKind
pkg debug/goobj, const SXREF = 24
pkg debug/goobj, const SXREF SymKind
pkg debug/goobj, func Parse(io.ReadSeeker, string) (*Package, error)
pkg debug/goobj, method (Sym) String() string
pkg debug/goobj, method (SymID) String() string
pkg debug/goobj, method (SymKind) String() string
pkg debug/goobj, type Data struct
pkg debug/goobj, type Data struct, Offset int64
pkg debug/goobj, type Data struct, Size int64
pkg debug/goobj, type Func struct
pkg debug/goobj, type Func struct, Args int
pkg debug/goobj, type Func struct, File []string
pkg debug/goobj, type Func struct, Frame int
pkg debug/goobj, type Func struct, FuncData []FuncData
pkg debug/goobj, type Func struct, Leaf bool
pkg debug/goobj, type Func struct, NoSplit bool
pkg debug/goobj, type Func struct, PCData []Data
pkg debug/goobj, type Func struct, PCFile Data
pkg debug/goobj, type Func struct, PCLine Data
pkg debug/goobj, type Func struct, PCSP Data
pkg debug/goobj, type Func struct, Var []Var
pkg debug/goobj, type FuncData struct
pkg debug/goobj, type FuncData struct, Offset int64
pkg debug/goobj, type FuncData struct, Sym SymID
pkg debug/goobj, type Package struct
pkg debug/goobj, type Package struct, ImportPath string
pkg debug/goobj, type Package struct, Imports []string
pkg debug/goobj, type Package struct, MaxVersion int
pkg debug/goobj, type Package struct, Syms []*Sym
pkg debug/goobj, type Reloc struct
pkg debug/goobj, type Reloc struct, Add int
pkg debug/goobj, type Reloc struct, Offset int
pkg debug/goobj, type Reloc struct, Size int
pkg debug/goobj, type Reloc struct, Sym SymID
pkg debug/goobj, type Reloc struct, Type int
pkg debug/goobj, type Sym struct
pkg debug/goobj, type Sym struct, Data Data
pkg debug/goobj, type Sym struct, DupOK bool
pkg debug/goobj, type Sym struct, Func *Func
pkg debug/goobj, type Sym struct, Kind SymKind
pkg debug/goobj, type Sym struct, Reloc []Reloc
pkg debug/goobj, type Sym struct, Size int
pkg debug/goobj, type Sym struct, Type SymID
pkg debug/goobj, type Sym struct, embedded SymID
pkg debug/goobj, type SymID struct
pkg debug/goobj, type SymID struct, Name string
pkg debug/goobj, type SymID struct, Version int
pkg debug/goobj, type SymKind int
pkg debug/goobj, type Var struct
pkg debug/goobj, type Var struct, Kind int
pkg debug/goobj, type Var struct, Name string
pkg debug/goobj, type Var struct, Offset int
pkg debug/goobj, type Var struct, Type SymID
pkg unicode, const Version = "7.0.0"
pkg unicode, var Bassa_Vah *RangeTable
pkg unicode, var Caucasian_Albanian *RangeTable
pkg unicode, var Duployan *RangeTable
pkg unicode, var Elbasan *RangeTable
pkg unicode, var Grantha *RangeTable
pkg unicode, var Khojki *RangeTable
pkg unicode, var Khudawadi *RangeTable
pkg unicode, var Linear_A *RangeTable
pkg unicode, var Mahajani *RangeTable
pkg unicode, var Manichaean *RangeTable
pkg unicode, var Mende_Kikakui *RangeTable
pkg unicode, var Modi *RangeTable
pkg unicode, var Mro *RangeTable
pkg unicode, var Nabataean *RangeTable
pkg unicode, var Old_North_Arabian *RangeTable
pkg unicode, var Old_Permic *RangeTable
pkg unicode, var Pahawh_Hmong *RangeTable
pkg unicode, var Palmyrene *RangeTable
pkg unicode, var Pau_Cin_Hau *RangeTable
pkg unicode, var Psalter_Pahlavi *RangeTable
pkg unicode, var Siddham *RangeTable
pkg unicode, var Tirhuta *RangeTable
pkg unicode, var Warang_Citi *RangeTable

View File

@@ -350,11 +350,7 @@ live pointers in its arguments, results, and local stack frame.
For an assembly function with no pointer results and
either no local stack frame or no function calls,
the only requirement is to define a Go prototype for the function
in a Go source file in the same package. The name of the assembly
function must not contain the package name component (for example,
function <code>Syscall</code> in package <code>syscall</code> should
use the name <code>·Syscall</code> instead of the equivalent name
<code>syscall·Syscall</code> in its <code>TEXT</code> directive).
in a Go source file in the same package.
For more complex situations, explicit annotation is needed.
These annotations use pseudo-instructions defined in the standard
<code>#include</code> file <code>funcdata.h</code>.

View File

@@ -108,14 +108,13 @@ when developing Go code.
<p>
To get started, create a workspace directory and set <code>GOPATH</code>
accordingly. Your workspace can be located wherever you like, but we'll use
<code>$HOME/work</code> in this document. Note that this must <b>not</b> be the
<code>$HOME/go</code> in this document. Note that this must <b>not</b> be the
same path as your Go installation.
(Another common setup is to set <code>GOPATH=$HOME</code>.)
</p>
<pre>
$ <b>mkdir $HOME/work</b>
$ <b>export GOPATH=$HOME/work</b>
$ <b>mkdir $HOME/go</b>
$ <b>export GOPATH=$HOME/go</b>
</pre>
<p>
@@ -127,11 +126,6 @@ to your <code>PATH</code>:
$ <b>export PATH=$PATH:$GOPATH/bin</b>
</pre>
<p>
To learn more about setting up the <code>GOPATH</code> environment variable,
please see
<a href="/cmd/go/#hdr-GOPATH_environment_variable"><code>go help gopath</code></a>
</p>
<h3 id="PackagePaths">Package paths</h3>
@@ -224,7 +218,7 @@ This command builds the <code>hello</code> command, producing an executable
binary. It then installs that binary to the workspace's <code>bin</code>
directory as <code>hello</code> (or, under Windows, <code>hello.exe</code>).
In our example, that will be <code>$GOPATH/bin/hello</code>, which is
<code>$HOME/work/bin/hello</code>.
<code>$HOME/go/bin/hello</code>.
</p>
<p>
@@ -260,7 +254,7 @@ optional: you do not need to use source control to write Go code.
<pre>
$ <b>cd $GOPATH/src/github.com/user/hello</b>
$ <b>git init</b>
Initialized empty Git repository in /home/user/work/src/github.com/user/hello/.git/
Initialized empty Git repository in /home/user/go/src/github.com/user/hello/.git/
$ <b>git add hello.go</b>
$ <b>git commit -m "initial commit"</b>
[master (root-commit) 0b4507d] initial commit

View File

@@ -8,8 +8,8 @@ The <a href="//golang.org/change">change log</a> has the full details.</p>
<p>To update to a specific release, use:</p>
<pre>
git pull
git checkout <i>release-branch</i>
hg pull
hg update <i>tag</i>
</pre>
<h2 id="go1.4">go1.4 (released 2014/12/10)</h2>

View File

@@ -40,7 +40,7 @@ is mirrored to the <code>gcc/go/gofrontend</code> directory in the GCC
repository, and the <code>gofrontend</code> <code>libgo</code>
directory is mirrored to the GCC <code>libgo</code> directory. In
addition, the <code>test</code> directory
from <a href="//go.googlesource.com/go">the main Go repository</a>
from <a href="//code.google.com/p/go">the main Go repository</a>
is mirrored to the <code>gcc/testsuite/go.test/test</code> directory
in the GCC repository.
</p>
@@ -65,7 +65,7 @@ from <code>gcc/go/gofrontend</code> to <code>gcc/go</code>.
<p>
The run-time library for gccgo is mostly the same as the library
in <a href="//go.googlesource.com/go">the main Go repository</a>.
in <a href="//code.google.com/p/go">the main Go repository</a>.
The library code in the Go repository is periodically merged into
the <code>libgo/go</code> directory of the <code>gofrontend</code> and
then the GCC repositories, using the shell
@@ -105,7 +105,7 @@ or <code>gcc/testsuite/go.dg</code> directories in the GCC repository.
<p>
Changes to the Go frontend should follow the same process as for the
main Go repository, only for the <code>gofrontend</code> project and
the <code>gofrontend-dev@googlegroups.com</code> mailing list
the<code>gofrontend-dev@googlegroups.com</code> mailing list
rather than the <code>go</code> project and the
<code>golang-dev@googlegroups.com</code> mailing list. Those changes
will then be merged into the GCC sources.

View File

@@ -1,55 +0,0 @@
Overall:
build: Go 1.4 required to build (https://golang.org/cl/2470, https://golang.org/cl/2993)
New Ports:
Darwin/ARM, a.k.a iOS. (https://golang.org/cl/2118, 2119, 3273, 2121, 2122, ..., 2127)
API additions and behavior changes:
bufio: add Reader.Discard (https://golang.org/cl/2260)
crypto/cipher: clarify what will happen if len(src) != len(dst) for the Stream interface. (https://golang.org/cl/1754)
crypto/elliptic: add Name field to CurveParams struct (https://golang.org/cl/2133)
crypto/tls: change default minimum version to TLS 1.0. (https://golang.org/cl/1791)
encoding/base64: add unpadded encodings (https://golang.org/cl/1511)
log: add SetOutput functions (https://golang.org/cl/2686, https://golang.org/cl/3023)
net/http: support for setting trailers from a server Handler (https://golang.org/cl/2157)
net/http/cgi: fix REMOTE_ADDR, REMOTE_HOST, add REMOTE_PORT (https://golang.org/cl/4933)
net/smtp: add TLSConnectionState accessor (https://golang.org/cl/2151)
os/signal: add Ignore and Reset (https://golang.org/cl/3580)
runtime, syscall: use SYSCALL instruction on FreeBSD (Go 1.5 now requires FreeBSD 8-STABLE+) (https://golang.org/cl/3020)
strings: add Compare(x, y string) int, for symmetry with bytes.Compare (https://golang.org/cl/2828)
testing/quick: support generation of arrays (https://golang.org/cl/3865)
Tools:
cmd/go: std wildcard now excludes commands in main repo (https://golang.org/cl/5550)
cmd/vet: better validation of struct tags (https://golang.org/cl/2685)
cmd/ld: no longer record build timestamp in Windows PE file header (https://golang.org/cl/3740)
Performance:
cmd/gc: optimize memclr of slices and arrays (https://golang.org/cl/2520)
sort: number of Sort performance optimizations (https://golang.org/cl/2100, https://golang.org/cl/2614, ...)
strconv: optimize decimal to string conversion (https://golang.org/cl/2105)
math/big: faster assembly kernels for amd64 and 386 (https://golang.org/cl/2503, https://golang.org/cl/2560)
math/big: faster "pure Go" kernels for platforms w/o assembly kernels (https://golang.org/cl/2480)
Assembler:
ARM assembly syntax has had some features removed.
- mentioning SP or PC as a hardware register
These are always pseudo-registers except that in some contexts
they're not, and it's confusing because the context should not affect
which register you mean. Change the references to the hardware
registers to be explicit: R13 for SP, R15 for PC.
- constant creation using assignment
The files say a=b when they could instead say #define a b.
There is no reason to have both mechanisms.
- R(0) to refer to R0.
Some macros use this to a great extent. Again, it's easy just to
use a #define to rename a register.
Also expression evaluation now uses uint64s instead of signed integers and the
precedence of operators is now Go-like rather than C-like.

View File

@@ -228,7 +228,7 @@ document server running in a production configuration on
</p>
<p>
Other examples include the <a href="//github.com/youtube/vitess/">Vitess</a>
Other examples include the <a href="//code.google.com/p/vitess/">Vitess</a>
system for large-scale SQL installations and Google's download server, <code>dl.google.com</code>,
which delivers Chrome binaries and other large installables such as <code>apt-get</code>
packages.
@@ -260,7 +260,7 @@ Does Go support Google's protocol buffers?</h3>
<p>
A separate open source project provides the necessary compiler plugin and library.
It is available at
<a href="//github.com/golang/protobuf">github.com/golang/protobuf/</a>
<a href="//code.google.com/p/goprotobuf/">code.google.com/p/goprotobuf/</a>
</p>

View File

@@ -1,6 +1,6 @@
<!--{
"Title": "The Go Programming Language Specification",
"Subtitle": "Version of December 26, 2014",
"Subtitle": "Version of November 11, 2014",
"Path": "/ref/spec"
}-->
@@ -1981,7 +1981,7 @@ with no explicit type.
</p>
<pre>
var d = math.Sin(0.5) // d is float64
var d = math.Sin(0.5) // d is int64
var i = 42 // i is int
var t, ok = x.(T) // t is T, ok is bool
var n = nil // illegal
@@ -5455,7 +5455,7 @@ const (
c2 = len([10]float64{2}) // [10]float64{2} contains no function calls
c3 = len([10]float64{c1}) // [10]float64{c1} contains no function calls
c4 = len([10]float64{imag(2i)}) // imag(2i) is a constant and no function call is issued
c5 = len([10]float64{imag(z)}) // invalid: imag(z) is a (non-constant) function call
c5 = len([10]float64{imag(z)}) // invalid: imag(x) is a (non-constant) function call
)
var z complex128
</pre>
@@ -5579,7 +5579,7 @@ s3 := append(s2, s0...) // append a slice s3 == []int{0,
s4 := append(s3[3:6], s3[2:]...) // append overlapping slice s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
var t []interface{}
t = append(t, 42, 3.1415, "foo") // t == []interface{}{42, 3.1415, "foo"}
t = append(t, 42, 3.1415, "foo") t == []interface{}{42, 3.1415, "foo"}
var b []byte
b = append(b, "bar"...) // append string contents b == []byte{'b', 'a', 'r' }

View File

@@ -77,25 +77,12 @@ The full set of supported combinations is listed in the discussion of
</div>
<h2 id="go14">Install Go compiler binaries</h2>
<h2 id="ctools">Install C tools, if needed</h2>
<p>
The Go tool chain 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>$HOME/go1.4</code>.
(This path may be overridden by setting the <code>GOROOT_BOOTSTRAP</code>
environment variable.)
</p>
<p>
Build the tools with Go version 1.4 or a point release (1.4.1, 1.4.2 etc.).
Go 1.4 binaries can be found at <a href="/dl/">the downloads page</a>.
</p>
<p>
Download the zip or tarball of Go 1.4 for your platform and extract it to
<code>$HOME/go1.4</code> (or your nominated <code>GOROOT_BOOTSTRAP</code>
location).
The Go tool chain is written in C. To build it, you need a C compiler installed.
Please refer to the <a href="//golang.org/wiki/InstallFromSource#install-c-tools">InstallFromSource</a>
page on the Go community Wiki for operating system specific instructions.
</p>
<h2 id="git">Install Git, if needed</h2>
@@ -122,7 +109,7 @@ Then clone the repository and check out the latest release tag:</p>
<pre>
$ git clone https://go.googlesource.com/go
$ cd go
$ git checkout go1.4
$ git checkout go1.4.1
</pre>
<h2 id="head">(Optional) Switch to the master branch</h2>

View File

@@ -14,10 +14,9 @@
<p>
<a href="https://golang.org/dl/" target="_blank">Official binary
distributions</a> are available for the FreeBSD (release 8-STABLE and above),
Linux, Mac OS X (Snow Leopard and above), and Windows operating systems and
the 32-bit (<code>386</code>) and 64-bit (<code>amd64</code>) x86 processor
architectures.
distributions</a> are available for the FreeBSD (release 8 and above), Linux, Mac OS X (Snow Leopard
and above), and Windows operating systems and the 32-bit (<code>386</code>) and
64-bit (<code>amd64</code>) x86 processor architectures.
</p>
<p>
@@ -45,7 +44,7 @@ proceeding. If your OS or architecture is not on the list, it's possible that
<th align="center">Notes</th>
</tr>
<tr><td colspan="3"><hr></td></tr>
<tr><td>FreeBSD 8-STABLE or later</td> <td>amd64, 386, arm</td> <td>Debian GNU/kFreeBSD not supported; FreeBSD/ARM needs FreeBSD 10 or later</td></tr>
<tr><td>FreeBSD 8 or later</td> <td>amd64, 386, arm</td> <td>Debian GNU/kFreeBSD not supported; FreeBSD/ARM needs FreeBSD 10 or later</td></tr>
<tr><td>Linux 2.6.23 or later with glibc</td> <td>amd64, 386, arm</td> <td>CentOS/RHEL 5.x not supported; no binary distribution for ARM yet</td></tr>
<tr><td>Mac OS X 10.6 or later</td> <td>amd64, 386</td> <td>use the gcc<sup>&#8224;</sup> that comes with Xcode<sup>&#8225;</sup></td></tr>
<tr><td>Windows XP or later</td> <td>amd64, 386</td> <td>use MinGW gcc<sup>&#8224;</sup>. No need for cygwin or msys.</td></tr>

BIN
doc/logo-153x55.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -3,9 +3,9 @@
// (the nodes are the data).
// http://en.wikipedia.org/wiki/Peano_axioms
// This program demonstrates that Go's automatic
// stack management can handle heavily recursive
// computations.
// This program demonstrates the power of Go's
// segmented stacks when doing massively
// recursive computations.
package main

BIN
doc/sieve.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -292,8 +292,6 @@ extern char* getgoversion(void);
extern char* getgoarm(void);
extern char* getgo386(void);
extern char* getgoextlinkenabled(void);
extern char* getgohostos(void);
extern char* getgohostarch(void);
extern char* mktempdir(void);
extern void removeall(char*);
@@ -312,15 +310,24 @@ extern void flagprint(int);
#ifdef _WIN32
#if !defined(_WIN64) && !defined(__MINGW64_VERSION_MAJOR)
struct timespec {
int tv_sec;
long tv_nsec;
};
#define execv(prog, argv) execv(prog, (const char* const*)(argv))
#define execvp(prog, argv) execvp(prog, (const char**)(argv))
#endif
extern int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
extern int fork(void);
extern int pread(int fd, void *buf, int n, int off);
extern int pwrite(int fd, void *buf, int n, int off);
#undef getwd
#define getwd(s, ns) getcwd(s, ns)
#undef lseek
#define lseek(fd, n, base) _lseeki64(fd, n, base)
#define mkdir(path, perm) mkdir(path)
#define pipe(fd) _pipe(fd, 512, O_BINARY)
#else
#define O_BINARY 0
#endif

View File

@@ -43,156 +43,32 @@ typedef struct Pcln Pcln;
typedef struct Pcdata Pcdata;
typedef struct Pciter Pciter;
// An Addr is an argument to an instruction.
// The general forms and their encodings are:
//
// sym±offset(symkind)(reg)(index*scale)
// Memory reference at address &sym(symkind) + offset + reg + index*scale.
// Any of sym(symkind), ±offset, (reg), (index*scale), and *scale can be omitted.
// If (reg) and *scale are both omitted, the resulting expression (index) is parsed as (reg).
// To force a parsing as index*scale, write (index*1).
// Encoding:
// type = TYPE_MEM
// name = symkind (NAME_AUTO, ...) or 0 (NAME_NONE)
// sym = sym
// offset = ±offset
// reg = reg (REG_*)
// index = index (REG_*)
// scale = scale (1, 2, 4, 8)
//
// $<mem>
// Effective address of memory reference <mem>, defined above.
// Encoding: same as memory reference, but type = TYPE_ADDR.
//
// $<±integer value>
// This is a special case of $<mem>, in which only ±offset is present.
// It has a separate type for easy recognition.
// Encoding:
// type = TYPE_CONST
// offset = ±integer value
//
// *<mem>
// Indirect reference through memory reference <mem>, defined above.
// Only used on x86 for CALL/JMP *sym(SB), which calls/jumps to a function
// pointer stored in the data word sym(SB), not a function named sym(SB).
// Encoding: same as above, but type = TYPE_INDIR.
//
// $*$<mem>
// No longer used.
// On machines with actual SB registers, $*$<mem> forced the
// instruction encoding to use a full 32-bit constant, never a
// reference relative to SB.
//
// $<floating point literal>
// Floating point constant value.
// Encoding:
// type = TYPE_FCONST
// u.dval = floating point value
//
// $<string literal, up to 8 chars>
// String literal value (raw bytes used for DATA instruction).
// Encoding:
// type = TYPE_SCONST
// u.sval = string
//
// <register name>
// Any register: integer, floating point, control, segment, and so on.
// If looking for specific register kind, must check type and reg value range.
// Encoding:
// type = TYPE_REG
// reg = reg (REG_*)
//
// x(PC)
// Encoding:
// type = TYPE_BRANCH
// u.branch = Prog* reference OR ELSE offset = target pc (branch takes priority)
//
// $±x-±y
// Final argument to TEXT, specifying local frame size x and argument size y.
// In this form, x and y are integer literals only, not arbitrary expressions.
// This avoids parsing ambiguities due to the use of - as a separator.
// The ± are optional.
// If the final argument to TEXT omits the -±y, the encoding should still
// use TYPE_TEXTSIZE (not TYPE_CONST), with u.argsize = ArgsSizeUnknown.
// Encoding:
// type = TYPE_TEXTSIZE
// offset = x
// u.argsize = y
//
// reg<<shift, reg>>shift, reg->shift, reg@>shift
// Shifted register value, for ARM.
// In this form, reg must be a register and shift can be a register or an integer constant.
// Encoding:
// type = TYPE_SHIFT
// offset = (reg&15) | shifttype<<5 | count
// shifttype = 0, 1, 2, 3 for <<, >>, ->, @>
// count = (reg&15)<<8 | 1<<4 for a register shift count, (n&31)<<7 for an integer constant.
//
// (reg, reg)
// A destination register pair. When used as the last argument of an instruction,
// this form makes clear that both registers are destinations.
// Encoding:
// type = TYPE_REGREG
// reg = first register
// offset = second register
//
// reg, reg
// TYPE_REGREG2, to be removed.
//
// prevent incompatible type signatures between liblink and 8l on Plan 9
#pragma incomplete struct Node
struct Addr
{
int16 type; // could be int8
int16 reg;
int16 index;
int8 scale;
int8 name;
int64 offset;
LSym* sym;
vlong offset;
union
{
char sval[8];
float64 dval;
Prog* branch;
int32 argsize; // for 5l, 8l
uint64 bits; // raw union bits, for testing if anything has been written to any field
Prog* branch; // for 5g, 6g, 8g
} u;
// gotype is the name of the Go type descriptor for sym.
// It cannot be set using assembly syntax.
// It is generated by the Go compiler for global declarations,
// to convey information about pointer locations to the back end
// and for use in generating debug information.
LSym* sym;
LSym* gotype;
int8 class; // for internal use by liblink
uint8 etype; // for internal use by 5g, 6g, 8g
void* node; // for internal use by 5g, 6g, 8g
int64 width; // for internal use by 5g, 6g, 8g
};
enum {
NAME_NONE = 0,
NAME_EXTERN,
NAME_STATIC,
NAME_AUTO,
NAME_PARAM,
};
enum {
TYPE_NONE = 0,
TYPE_BRANCH = 5, // avoid accidental conflicts with NAME_*
TYPE_TEXTSIZE,
TYPE_MEM,
TYPE_CONST,
TYPE_FCONST,
TYPE_SCONST,
TYPE_REG,
TYPE_ADDR,
TYPE_SHIFT,
TYPE_REGREG,
TYPE_REGREG2,
TYPE_INDIR,
short type;
uint8 index;
int8 scale;
int8 reg; // for 5l
int8 name; // for 5l
int8 class; // for 5l
uint8 etype; // for 5g, 6g, 8g
int32 offset2; // for 5l, 8l
struct Node* node; // for 5g, 6g, 8g
int64 width; // for 5g, 6g, 8g
};
struct Reloc
@@ -201,86 +77,45 @@ struct Reloc
uchar siz;
uchar done;
int32 type;
int32 variant; // RV_*: variant on computed value
int64 add;
int64 xadd;
LSym* sym;
LSym* xsym;
};
// TODO(rsc): Describe prog.
// TODO(rsc): Describe TEXT/GLOBL flag in from3, DATA width in from3.
struct Prog
{
vlong pc;
int32 lineno;
Prog* link;
short as;
uchar scond; // arm only; condition codes
// operands
uchar reg; // arm only
uchar scond; // arm only
Addr from;
int16 reg; // arm, ppc64 only (e.g., ADD from, reg, to);
// starts at 0 for both GPRs and FPRs;
// also used for ADATA width on arm, ppc64
Addr from3; // addl source argument (e.g., RLWM/FMADD from, reg, from3, to)
Addr to;
// for 5g, 6g, 8g internal use
void* opt;
// for liblink internal use
// for 5l, 6l, 8l internal use
Prog* forwd;
Prog* pcond;
Prog* comefrom; // amd64, 386
Prog* pcrel; // arm
Prog* comefrom; // 6l, 8l
Prog* pcrel; // 5l
int32 spadj;
uint16 mark;
uint16 optab; // arm, ppc64
uchar back; // amd64, 386
uchar ft; // oclass cache
uchar tt; // oclass cache
uchar isize; // amd64, 386
uchar printed;
uchar mark;
uchar back; // 6l, 8l
uchar ft; /* 6l, 8l oclass cache */
uchar tt; // 6l, 8l
uint16 optab; // 5l
uchar isize; // 6l, 8l
char width; /* fake for DATA */
char mode; /* 16, 32, or 64 in 6l, 8l; internal use in 5g, 6g, 8g */
};
extern Prog zprog; // zeroed Prog
// Prog.as opcodes.
// These are the portable opcodes, common to all architectures.
// Each architecture defines many more arch-specific opcodes,
// with values starting at A_ARCHSPECIFIC.
enum {
AXXX = 0,
ACALL,
ACHECKNIL,
ADATA,
ADUFFCOPY,
ADUFFZERO,
AEND,
AFUNCDATA,
AGLOBL,
AJMP,
ANOP,
APCDATA,
ARET,
ATEXT,
ATYPE,
AUNDEF,
AUSEFIELD,
AVARDEF,
AVARKILL,
A_ARCHSPECIFIC, // first architecture-specific opcode value
/*c2go uchar TEXTFLAG; */
};
void nopout(Prog*);
void nocache(Prog*);
// prevent incompatible type signatures between liblink and 8l on Plan 9
#pragma incomplete struct Section
@@ -301,10 +136,8 @@ struct LSym
uchar hide;
uchar leaf; // arm only
uchar fnptr; // arm only
uchar localentry; // ppc64: instrs between global & local entry
uchar seenglobl;
uchar onlist; // on the textp or datap lists
uchar printed;
int16 symid; // for writing .5/.6/.8 files
int32 dynid;
int32 sig;
@@ -372,7 +205,6 @@ enum
SMACHO, /* Mach-O __nl_symbol_ptr */
SMACHOGOT,
SWINDOWS,
SELFGOT, /* also .toc in ppc64 ABI */
SNOPTRDATA,
SINITARR,
SDATA,
@@ -401,12 +233,10 @@ enum
enum
{
R_ADDR = 1,
R_ADDRPOWER, // relocation for loading 31-bit address using addis and addi/ld/st for Power
R_SIZE,
R_CALL, // relocation for direct PC-relative call
R_CALLARM, // relocation for ARM direct call
R_CALLIND, // marker for indirect call (no actual relocating necessary)
R_CALLPOWER, // relocation for Power direct call
R_CONST,
R_PCREL,
R_TLS,
@@ -417,23 +247,9 @@ enum
R_PLT1,
R_PLT2,
R_USEFIELD,
R_POWER_TOC, // ELF R_PPC64_TOC16*
};
// Reloc.variant
enum
{
RV_NONE, // identity variant
RV_POWER_LO, // x & 0xFFFF
RV_POWER_HI, // x >> 16
RV_POWER_HA, // (x + 0x8000) >> 16
RV_POWER_DS, // x & 0xFFFC, check x&0x3 == 0
RV_CHECK_OVERFLOW = 1<<8, // check overflow flag
RV_TYPE_MASK = (RV_CHECK_OVERFLOW - 1),
};
// Auto.name
// Auto.type
enum
{
A_AUTO = 1,
@@ -445,7 +261,7 @@ struct Auto
LSym* asym;
Auto* link;
int32 aoffset;
int16 name;
int16 type;
LSym* gotype;
};
@@ -460,7 +276,6 @@ struct Hist
char* name;
int32 line;
int32 offset;
uchar printed;
};
struct Plist
@@ -630,14 +445,47 @@ struct LinkArch
int thechar; // '5', '6', and so on
int32 endian; // LittleEndian or BigEndian
void (*preprocess)(Link*, LSym*);
void (*addstacksplit)(Link*, LSym*);
void (*assemble)(Link*, LSym*);
int (*datasize)(Prog*);
void (*follow)(Link*, LSym*);
int (*iscall)(Prog*);
int (*isdata)(Prog*);
Prog* (*prg)(void);
void (*progedit)(Link*, Prog*);
void (*settextflag)(Prog*, int);
int (*symtype)(Addr*);
int (*textflag)(Prog*);
int minlc;
int ptrsize;
int regsize;
// TODO: Give these the same values on all systems.
int D_ADDR;
int D_AUTO;
int D_BRANCH;
int D_CONST;
int D_EXTERN;
int D_FCONST;
int D_NONE;
int D_PARAM;
int D_SCONST;
int D_STATIC;
int D_OREG;
int ACALL;
int ADATA;
int AEND;
int AFUNCDATA;
int AGLOBL;
int AJMP;
int ANOP;
int APCDATA;
int ARET;
int ATEXT;
int ATYPE;
int AUSEFIELD;
};
/* executable header types */
@@ -681,9 +529,6 @@ void span6(Link *ctxt, LSym *s);
// asm8.c
void span8(Link *ctxt, LSym *s);
// asm9.c
void span9(Link *ctxt, LSym *s);
// data.c
vlong addaddr(Link *ctxt, LSym *s, LSym *t);
vlong addaddrplus(Link *ctxt, LSym *s, LSym *t, vlong add);
@@ -714,11 +559,6 @@ void* emallocz(long n);
void* erealloc(void *p, long n);
char* estrdup(char *p);
char* expandpkg(char *t0, char *pkg);
void linksetexp(void);
char* expstring(void);
extern int fieldtrack_enabled;
extern int framepointer_enabled;
// ld.c
void addhist(Link *ctxt, int32 line, int type);
@@ -736,11 +576,10 @@ Prog* copyp(Link*, Prog*);
Prog* appendp(Link*, Prog*);
vlong atolwhex(char*);
// list[5689].c
// list[568].c
void listinit5(void);
void listinit6(void);
void listinit8(void);
void listinit9(void);
// obj.c
int linklinefmt(Link *ctxt, Fmt *fp);
@@ -772,33 +611,20 @@ char* headstr(int);
extern char* anames5[];
extern char* anames6[];
extern char* anames8[];
extern char* anames9[];
extern char* cnames5[];
extern char* cnames9[];
extern char* dnames5[];
extern char* dnames6[];
extern char* dnames8[];
extern char* dnames9[];
extern LinkArch link386;
extern LinkArch linkamd64;
extern LinkArch linkamd64p32;
extern LinkArch linkarm;
extern LinkArch linkppc64;
extern LinkArch linkppc64le;
extern int linkbasepointer;
extern void linksetexp(void);
#pragma varargck type "A" int
#pragma varargck type "E" uint
#pragma varargck type "D" Addr*
#pragma varargck type "lD" Addr*
#pragma varargck type "P" Prog*
#pragma varargck type "R" int
#pragma varargck type "^" int // for 5l/9l, C_* classes (liblink internal)
#pragma varargck type "^" int
// TODO(ality): remove this workaround.
// It's here because Pconv in liblink/list?.c references %L.

View File

@@ -14,10 +14,6 @@ char* getgoversion(void);
char* getgoarm(void);
char* getgo386(void);
char* getgoextlinkenabled(void);
char* getgohostos(void);
char* getgohostarch(void);
int runcmd(char**);
void flagcount(char*, char*, int*);
void flagint32(char*, char*, int32*);

View File

@@ -42,7 +42,7 @@ extern "C" {
#define _NETBSD_SOURCE 1 /* NetBSD */
#define _DEFAULT_SOURCE 1 /* glibc > 2.19 */
#define _SVID_SOURCE 1
#if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__sun__)
#if !defined(__APPLE__) && !defined(__OpenBSD__)
# define _XOPEN_SOURCE 1000
# define _XOPEN_SOURCE_EXTENDED 1
#endif
@@ -69,11 +69,8 @@ extern "C" {
#include <stddef.h>
#include <math.h>
#include <ctype.h> /* for tolower */
#include <time.h>
#ifdef _WIN32
#include <signal.h>
#endif
#include <time.h>
/*
* OS-specific crap

View File

@@ -0,0 +1 @@
defaultcc: golang-codereviews@googlegroups.com

3692
lib/codereview/codereview.py Normal file

File diff suppressed because it is too large Load Diff

199
lib/codereview/test.sh Executable file
View File

@@ -0,0 +1,199 @@
#!/bin/bash
# Copyright 2011 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
# Test the code review plugin.
# Assumes a local Rietveld is running using the App Engine SDK
# at http://localhost:7777/
#
# dev_appserver.py --port 7777 $HOME/pub/rietveld
codereview_script=$(pwd)/codereview.py
server=localhost:7777
master=/tmp/go.test
clone1=/tmp/go.test1
clone2=/tmp/go.test2
export HGEDITOR=true
must() {
if ! "$@"; then
echo "$@" failed >&2
exit 1
fi
}
not() {
if "$@"; then
false
else
true
fi
}
status() {
echo '+++' "$@" >&2
}
firstcl() {
hg pending | sed 1q | tr -d ':'
}
# Initial setup.
status Create repositories.
rm -rf $master $clone1 $clone2
mkdir $master
cd $master
must hg init .
echo Initial state >file
must hg add file
must hg ci -m 'first commit' file
must hg clone $master $clone1
must hg clone $master $clone2
echo "
[ui]
username=Grace R Emlin <gre@golang.org>
[extensions]
codereview=$codereview_script
[codereview]
testing=true
server=$server
" >>$clone1/.hg/hgrc
cp $clone1/.hg/hgrc $clone2/.hg/hgrc
status Codereview should be disabled.
cd $clone1
must hg status
must not hg pending
status Enabling code review.
must mkdir lib lib/codereview
must touch lib/codereview/codereview.cfg
status Code review should work even without CONTRIBUTORS.
must hg pending
status Add CONTRIBUTORS.
echo 'Grace R Emlin <gre@golang.org>' >CONTRIBUTORS
must hg add lib/codereview/codereview.cfg CONTRIBUTORS
status First submit.
must hg submit --tbr gre@golang.org -m codereview \
lib/codereview/codereview.cfg CONTRIBUTORS
status Should see change in other client.
cd $clone2
must hg pull -u
must test -f lib/codereview/codereview.cfg
must test -f CONTRIBUTORS
test_clpatch() {
# The email address must be test@example.com to match
# the test code review server's default user.
# Clpatch will check.
cd $clone1
# dev_appserver.py used to crash with UTF-8 input.
if true; then
status Using UTF-8.
name="Grácè T Emlïn <test@example.com>"
else
status Using ASCII.
name="Grace T Emlin <test@example.com>"
fi
echo "$name" >>CONTRIBUTORS
cat .hg/hgrc | sed "s/Grace.*/$name/" >/tmp/x && mv /tmp/x .hg/hgrc
echo "
Reviewer: gre@golang.org
Description:
CONTRIBUTORS: add $name
Files:
CONTRIBUTORS
" | must hg change -i
num=$(hg pending | sed 1q | tr -d :)
status Patch CL.
cd $clone2
must hg clpatch $num
must [ "$num" = "$(firstcl)" ]
must hg submit --tbr gre@golang.org $num
status Issue should be open with no reviewers.
must curl http://$server/api/$num >/tmp/x
must not grep '"closed":true' /tmp/x
must grep '"reviewers":\[\]' /tmp/x
status Sync should close issue.
cd $clone1
must hg sync
must curl http://$server/api/$num >/tmp/x
must grep '"closed":true' /tmp/x
must grep '"reviewers":\[\]' /tmp/x
must [ "$(firstcl)" = "" ]
}
test_reviewer() {
status Submit without reviewer should fail.
cd $clone1
echo dummy >dummy
must hg add dummy
echo '
Description:
no reviewer
Files:
dummy
' | must hg change -i
num=$(firstcl)
must not hg submit $num
must hg revert dummy
must rm dummy
must hg change -d $num
}
test_linearity() {
status Linearity of changes.
cd $clone1
echo file1 >file1
must hg add file1
echo '
Reviewer: gre@golang.org
Description: file1
Files: file1
' | must hg change -i
must hg submit --tbr gre@golang.org $(firstcl)
cd $clone2
echo file2 >file2
must hg add file2
echo '
Reviewer: gre@golang.org
Description: file2
Files: file2
' | must hg change -i
must not hg submit --tbr gre@golang.org $(firstcl)
must hg sync
must hg submit --tbr gre@golang.org $(firstcl)
}
test_restrict() {
status Cannot use hg ci.
cd $clone1
echo file1a >file1a
hg add file1a
must not hg ci -m commit file1a
must rm file1a
must hg revert file1a
status Cannot use hg rollback.
must not hg rollback
status Cannot use hg backout
must not hg backout -r -1
}
test_reviewer
test_clpatch
test_linearity
test_restrict
status ALL TESTS PASSED.

View File

@@ -2,9 +2,9 @@ Android
=======
For details on developing Go for Android, see the documentation in the
mobile subrepository:
go.mobile subrepository:
https://github.com/golang/mobile
https://code.google.com/p/go/source/browse/README?repo=mobile
To run the standard library tests, see androidtest.bash. Run it as

View File

@@ -9,7 +9,6 @@ package main
import (
"bytes"
"fmt"
"go/build"
"io"
"log"
"os"
@@ -33,36 +32,33 @@ func run(args ...string) string {
return buf.String()
}
const (
// Directory structure on the target device androidtest.bash assumes.
deviceGoroot = "/data/local/tmp/goroot"
deviceGopath = "/data/local/tmp/gopath"
)
func main() {
log.SetFlags(0)
log.SetPrefix("go_android_exec: ")
// Prepare a temporary directory that will be cleaned up at the end.
deviceGotmp := fmt.Sprintf("/data/local/tmp/%s-%d",
filepath.Base(os.Args[1]), os.Getpid())
run("shell", "mkdir", "-p", deviceGotmp)
// Determine the package by examining the current working
// Determine thepackage by examining the current working
// directory, which will look something like
// "$GOROOT/src/mime/multipart" or "$GOPATH/src/golang.org/x/mobile".
// We extract everything after the $GOROOT or $GOPATH to run on the
// same relative directory on the target device.
subdir, inGoRoot := subdir()
deviceCwd := filepath.Join(deviceGoroot, subdir)
if !inGoRoot {
deviceCwd = filepath.Join(deviceGopath, subdir)
// "$GOROOT/src/mime/multipart". We extract everything
// after the $GOROOT to run on the same relative directory
// on the target device.
//
// TODO(crawshaw): Pick useful subdir when we are not
// inside a GOROOT, e.g. we are in a GOPATH.
cwd, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
subdir, err := filepath.Rel(runtime.GOROOT(), cwd)
if err != nil {
log.Fatal(err)
}
subdir = filepath.ToSlash(subdir)
// Binary names can conflict.
// E.g. template.test from the {html,text}/template packages.
binName := filepath.Base(os.Args[1])
deviceBin := fmt.Sprintf("%s/%s-%d", deviceGotmp, binName, os.Getpid())
deviceGoroot := "/data/local/tmp/goroot"
deviceBin := fmt.Sprintf("%s/%s-%d", deviceGoroot, binName, os.Getpid())
// The push of the binary happens in parallel with other tests.
// Unfortunately, a simultaneous call to adb shell hold open
@@ -75,22 +71,19 @@ func main() {
// The adb shell command will return an exit code of 0 regardless
// of the command run. E.g.
// $ adb shell false
// $ echo $?
// 0
// $ adb shell false
// $ echo $?
// 0
// https://code.google.com/p/android/issues/detail?id=3254
// So we append the exitcode to the output and parse it from there.
const exitstr = "exitcode="
cmd := `export TMPDIR="` + deviceGotmp + `"` +
cmd := `export TMPDIR="/data/local/tmp"` +
`; export GOROOT="` + deviceGoroot + `"` +
`; export GOPATH="` + deviceGopath + `"` +
`; cd "` + deviceCwd + `"` +
`; cd "$GOROOT/` + subdir + `"` +
"; '" + deviceBin + "' " + strings.Join(os.Args[2:], " ") +
"; echo -n " + exitstr + "$?"
output := run("shell", cmd)
run("shell", "rm", "-rf", deviceGotmp) // Clean up.
run("shell", "rm '"+deviceBin+"'") // cleanup
output = output[strings.LastIndex(output, "\n")+1:]
if !strings.HasPrefix(output, exitstr) {
log.Fatalf("no exit code: %q", output)
@@ -101,32 +94,3 @@ func main() {
}
os.Exit(code)
}
// subdir determines the package based on the current working directory,
// and returns the path to the package source relative to $GOROOT (or $GOPATH).
func subdir() (pkgpath string, underGoRoot bool) {
cwd, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
if root := runtime.GOROOT(); strings.HasPrefix(cwd, root) {
subdir, err := filepath.Rel(root, cwd)
if err != nil {
log.Fatal(err)
}
return subdir, true
}
for _, p := range filepath.SplitList(build.Default.GOPATH) {
if !strings.HasPrefix(cwd, p) {
continue
}
subdir, err := filepath.Rel(p, cwd)
if err == nil {
return subdir, false
}
}
log.Fatalf("the current path %q is not in either GOROOT(%q) or GOPATH(%q)",
cwd, runtime.GOROOT(), build.Default.GOPATH)
return "", false
}

View File

@@ -1,11 +0,0 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cgotest
import _ "unsafe"
//go:linkname lockedOSThread runtime.lockedOSThread
//extern runtime_lockedOSThread
func lockedOSThread() bool

View File

@@ -0,0 +1,7 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package backdoor
func LockedOSThread() bool // in thunk.s

View File

@@ -0,0 +1,18 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Expose some runtime functions for testing.
// This is the gccgo version of runtime.c.
// +build gccgo
_Bool runtime_lockedOSThread(void);
_Bool LockedOSThread(void) asm(GOPKGPATH ".LockedOSThread");
_Bool
LockedOSThread(void)
{
return runtime_lockedOSThread();
}

View File

@@ -0,0 +1,16 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Assembly to get into package runtime without using exported symbols.
// +build amd64 amd64p32 arm 386
#include "textflag.h"
#ifdef GOARCH_arm
#define JMP B
#endif
TEXT ·LockedOSThread(SB),NOSPLIT,$0-0
JMP runtime·lockedOSThread(SB)

View File

@@ -17,12 +17,13 @@ int returnAfterGrowFromGo(void);
import "C"
import (
"os"
"path"
"runtime"
"strings"
"testing"
"unsafe"
"./backdoor"
)
// nestedCall calls into C, back into Go, and finally to f.
@@ -49,6 +50,8 @@ func testCallbackGC(t *testing.T) {
nestedCall(runtime.GC)
}
var lockedOSThread = backdoor.LockedOSThread
func testCallbackPanic(t *testing.T) {
// Make sure panic during callback unwinds properly.
if lockedOSThread() {
@@ -168,9 +171,6 @@ func testCallbackCallers(t *testing.T) {
"testing.tRunner",
"runtime.goexit",
}
if unsafe.Sizeof((*byte)(nil)) == 8 {
name[1] = "runtime.call32"
}
nestedCall(func() {
n = runtime.Callers(2, pc)
})
@@ -212,19 +212,6 @@ func testPanicFromC(t *testing.T) {
}
func testAllocateFromC(t *testing.T) {
if strings.Contains(os.Getenv("GODEBUG"), "wbshadow=") {
// This test is writing pointers to Go heap objects from C.
// As such, those writes have no write barriers, and
// wbshadow=2 mode correctly discovers that and crashes.
// Disable test if any wbshadow mode is enabled.
// TODO(rsc): I am not sure whether the test is fundamentally
// incompatible with concurrent collection and should be
// turned off or rewritten entirely. The test is attempting to
// mimic some SWIG behavior, so it is important to work
// through what we expect before trying SWIG and C++
// with the concurrent collector.
t.Skip("test is incompatible with wbshadow=")
}
C.callCgoAllocate() // crashes or exits on failure
}

View File

@@ -4,7 +4,7 @@
// Test that the #cgo CFLAGS directive works,
// with and without platform filters.
// See http://golang.org/issue/5224 for details.
// See http://code.google.com/p/go/issues/detail?id=5224 for details.
package cgotest
/*

View File

@@ -9,4 +9,3 @@ import "testing"
func TestSetgid(t *testing.T) { testSetgid(t) }
func Test6997(t *testing.T) { test6997(t) }
func TestBuildID(t *testing.T) { testBuildID(t) }
func Test9400(t *testing.T) { test9400(t) }

View File

@@ -63,6 +63,5 @@ func Test8811(t *testing.T) { test8811(t) }
func TestReturnAfterGrow(t *testing.T) { testReturnAfterGrow(t) }
func TestReturnAfterGrowFromGo(t *testing.T) { testReturnAfterGrowFromGo(t) }
func Test9026(t *testing.T) { test9026(t) }
func Test9557(t *testing.T) { test9557(t) }
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }

View File

@@ -14,7 +14,7 @@ import "testing"
var v7234 = [...]string{"runtime/cgo"}
func Test7234(t *testing.T) {
func TestIssue7234(t *testing.T) {
if v7234[0] != "runtime/cgo" {
t.Errorf("bad string constant %q", v7234[0])
}

View File

@@ -12,23 +12,9 @@ package cgotest
void issue7978cb(void);
#if defined(__APPLE__) && defined(__arm__)
// on Darwin/ARM, libSystem doesn't provide implementation of the __sync_fetch_and_add
// primitive, and although gcc supports it, it doesn't inline its definition.
// Clang could inline its definition, so we require clang on Darwin/ARM.
#if defined(__clang__)
#define HAS_SYNC_FETCH_AND_ADD 1
#else
#define HAS_SYNC_FETCH_AND_ADD 0
#endif
#else
#define HAS_SYNC_FETCH_AND_ADD 1
#endif
// use ugly atomic variable sync since that doesn't require calling back into
// Go code or OS dependencies
static void issue7978c(uint32_t *sync) {
#if HAS_SYNC_FETCH_AND_ADD
while(__sync_fetch_and_add(sync, 0) != 0)
;
__sync_fetch_and_add(sync, 1);
@@ -38,7 +24,6 @@ static void issue7978c(uint32_t *sync) {
__sync_fetch_and_add(sync, 1);
while(__sync_fetch_and_add(sync, 0) != 6)
;
#endif
}
*/
import "C"
@@ -97,12 +82,6 @@ func issue7978go() {
}
func test7978(t *testing.T) {
if runtime.Compiler == "gccgo" {
t.Skip("gccgo can not do stack traces of C code")
}
if C.HAS_SYNC_FETCH_AND_ADD == 0 {
t.Skip("clang required for __sync_fetch_and_add support on darwin/arm")
}
if os.Getenv("GOTRACEBACK") != "2" {
t.Fatalf("GOTRACEBACK must be 2")
}

View File

@@ -1,20 +0,0 @@
#include "textflag.h"
TEXT ·RewindAndSetgid(SB),NOSPLIT,$0-0
// Rewind stack pointer so anything that happens on the stack
// will clobber the test pattern created by the caller
ADDL $(1024 * 8), SP
// Ask signaller to setgid
MOVL $1, ·Baton(SB)
// Wait for setgid completion
loop:
PAUSE
MOVL ·Baton(SB), AX
CMPL AX, $0
JNE loop
// Restore stack
SUBL $(1024 * 8), SP
RET

View File

@@ -1,22 +0,0 @@
// +build amd64 amd64p32
#include "textflag.h"
TEXT ·RewindAndSetgid(SB),NOSPLIT,$0-0
// Rewind stack pointer so anything that happens on the stack
// will clobber the test pattern created by the caller
ADDQ $(1024 * 8), SP
// Ask signaller to setgid
MOVL $1, ·Baton(SB)
// Wait for setgid completion
loop:
PAUSE
MOVL ·Baton(SB), AX
CMPL AX, $0
JNE loop
// Restore stack
SUBQ $(1024 * 8), SP
RET

View File

@@ -1,33 +0,0 @@
#include "textflag.h"
TEXT cas<>(SB),NOSPLIT,$0
MOVW $0xffff0fc0, R15 // R15 is PC
TEXT ·RewindAndSetgid(SB),NOSPLIT,$-4-0
// Save link register
MOVW R14, R4
// Rewind stack pointer so anything that happens on the stack
// will clobber the test pattern created by the caller
ADD $(1024 * 8), R13
// Ask signaller to setgid
MOVW $·Baton(SB), R2
storeloop:
MOVW 0(R2), R0
MOVW $1, R1
BL cas<>(SB)
BCC storeloop
// Wait for setgid completion
loop:
MOVW $0, R0
MOVW $0, R1
BL cas<>(SB)
BCC loop
// Restore stack
SUB $(1024 * 8), R13
MOVW R4, R14
RET

View File

@@ -1,27 +0,0 @@
// +build ppc64 ppc64le
#include "textflag.h"
TEXT ·RewindAndSetgid(SB),NOSPLIT,$-8-0
// Rewind stack pointer so anything that happens on the stack
// will clobber the test pattern created by the caller
ADD $(1024 * 8), R1
// Ask signaller to setgid
MOVW $1, R3
SYNC
MOVW R3, ·Baton(SB)
// Wait for setgid completion
loop:
SYNC
MOVW ·Baton(SB), R3
CMP R3, $0
// Hint that we're in a spin loop
OR R1, R1, R1
BNE loop
ISYNC
// Restore stack
SUB $(1024 * 8), R1
RET

View File

@@ -1,9 +0,0 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package issue9400
var Baton int32
func RewindAndSetgid()

View File

@@ -1,58 +0,0 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test that SIGSETXID runs on signal stack, since it's likely to
// overflow if it runs on the Go stack.
package cgotest
/*
#include <sys/types.h>
#include <unistd.h>
*/
import "C"
import (
"runtime"
"sync/atomic"
"testing"
"./issue9400"
)
func test9400(t *testing.T) {
// We synchronize through a shared variable, so we need two procs
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
// Start signaller
atomic.StoreInt32(&issue9400.Baton, 0)
go func() {
// Wait for RewindAndSetgid
for atomic.LoadInt32(&issue9400.Baton) == 0 {
runtime.Gosched()
}
// Broadcast SIGSETXID
runtime.LockOSThread()
C.setgid(0)
// Indicate that signalling is done
atomic.StoreInt32(&issue9400.Baton, 0)
}()
// Grow the stack and put down a test pattern
const pattern = 0x123456789abcdef
var big [1024]uint64 // len must match assmebly
for i := range big {
big[i] = pattern
}
// Temporarily rewind the stack and trigger SIGSETXID
issue9400.RewindAndSetgid()
// Check test pattern
for i := range big {
if big[i] != pattern {
t.Fatalf("entry %d of test pattern is wrong; %#x != %#x", i, big[i], uint64(pattern))
}
}
}

View File

@@ -1,36 +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.
// cgo rewrote C.var to *_Cvar_var, but left
// C.var.field as _Cvar.var.field. It now rewrites
// the latter as (*_Cvar_var).field.
// See https://golang.org/issue/9557.
package cgotest
// struct issue9557_t {
// int a;
// } test9557bar = { 42 };
//
// struct issue9557_t *issue9557foo = &test9557bar;
import "C"
import "testing"
func test9557(t *testing.T) {
// implicitly dereference a Go variable
foo := C.issue9557foo
if v := foo.a; v != 42 {
t.Fatalf("foo.a expected 42, but got %d", v)
}
// explicitly dereference a C variable
if v := (*C.issue9557foo).a; v != 42 {
t.Fatalf("(*C.issue9557foo).a expected 42, but is %d", v)
}
// implicitly dereference a C variable
if v := C.issue9557foo.a; v != 42 {
t.Fatalf("C.issue9557foo.a expected 42, but is %d", v)
}
}

View File

@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// Test that setgid does not hang on GNU/Linux.
// See http://golang.org/issue/3871 for details.
// See http://code.google.com/p/go/issues/detail?id=3871 for details.
package cgotest

View File

@@ -0,0 +1,9 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "runtime.h"
#include "cdefstest.h"
struct CdefsTest test;
struct PackedTest packed;

View File

@@ -0,0 +1,60 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// +build ignore
package cgotest
/*
// This file tests a bug found in the cgo -cdefs tool that incorrectly
// translated Go pointer arrays generated by the cgo godefs tool back into C
// pointer arrays.
//
// The comments below show how the type is translated from gcc-style C into Go
// and back into C for both the buggy version and the correct version
struct cdefsTest {
// This was already being handled correctly
// Correct: -> Array [20]int8 -> int8 array[20]
char array1[20];
// Buggy: -> Array [20][20]int8 -> [20]int8 array[20]
// Correct: -> Array [20][20]int8 -> int8 array[20][20]
char array2[20][20];
// Buggy: -> Array [20]*int8 -> *int8 array[20]
// Correct: -> Array [20]*int8 -> int8 *array[20]
char *array3[20];
// Buggy: -> Array [20][20]*int8 -> [20]*int8 array[20]
// Correct: -> Array [20]**int8 -> int8 *array[20][20]
char *array4[20][20];
// Buggy: -> Array [20][20]**int8 -> [20]**int8 array[20]
// Correct: -> Array [20][20]**int8 -> int8 **array[20][20]
char **array5[20][20];
};
// Test that packed structures can be translated to C correctly too.
// See issue 8477.
struct packedTest {
char first;
int second;
long long third;
} __attribute__((packed));
// Test that conflicting type definitions don't cause problems with cgo.
// See issue 8477.
typedef struct timespec {
double bogus;
} pid_t;
*/
import "C"
type CdefsTest C.struct_cdefsTest
//type PackedTest C.struct_packedTest

76
misc/cgo/testcdefs/main.c Normal file
View File

@@ -0,0 +1,76 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "runtime.h"
#include "cdefstest.h"
void runtime·printf(int8*, ...);
// From cdefstest.go.
typedef struct CdefsOrig CdefsOrig;
struct CdefsOrig {
int8 array1[20];
int8 array2[20][20];
int8 *array3[20];
int8 *array4[20][20];
int8 **array5[20][20];
};
// Packed structs are no longer supported for -cdefs.
/*
typedef struct PackedOrig PackedOrig;
#pragma pack on
struct PackedOrig {
int8 first;
int32 second;
int64 third;
};
#pragma pack off
*/
void
main·test(int32 ret)
{
CdefsOrig o;
CdefsTest t;
// PackedOrig po;
// PackedTest pt;
ret = 0;
if(sizeof(t.array1) != sizeof(o.array1) || offsetof(CdefsTest, array1[0]) != offsetof(CdefsOrig, array1[0])) {
runtime·printf("array1: size, offset = %d, %d, want %d, %d\n", sizeof(t.array1), offsetof(CdefsTest, array1[0]), sizeof(o.array1), offsetof(CdefsOrig, array1[0]));
ret = 1;
}
if(sizeof(t.array2) != sizeof(o.array2) || offsetof(CdefsTest, array2[0][0]) != offsetof(CdefsOrig, array2[0][0])) {
runtime·printf("array2: size, offset = %d, %d, want %d, %d\n", sizeof(t.array2), offsetof(CdefsTest, array2[0][0]), sizeof(o.array2), offsetof(CdefsOrig, array2[0][0]));
ret = 1;
}
if(sizeof(t.array3) != sizeof(o.array3) || offsetof(CdefsTest, array3[0]) != offsetof(CdefsOrig, array3[0])) {
runtime·printf("array3: size, offset = %d, %d, want %d, %d\n", sizeof(t.array3), offsetof(CdefsTest, array3[0]), sizeof(o.array3), offsetof(CdefsOrig, array3[0]));
ret = 1;
}
if(sizeof(t.array4) != sizeof(o.array4) || offsetof(CdefsTest, array4[0][0]) != offsetof(CdefsOrig, array4[0][0])) {
runtime·printf("array4: size, offset = %d, %d, want %d, %d\n", sizeof(t.array4), offsetof(CdefsTest, array4[0][0]), sizeof(o.array4), offsetof(CdefsOrig, array4[0][0]));
ret = 1;
}
if(sizeof(t.array5) != sizeof(o.array5) || offsetof(CdefsTest, array5[0][0]) != offsetof(CdefsOrig, array5[0][0])) {
runtime·printf("array5: size, offset = %d, %d, want %d, %d\n", sizeof(t.array5), offsetof(CdefsTest, array5[0][0]), sizeof(o.array5), offsetof(CdefsOrig, array5[0][0]));
ret = 1;
}
/*
if(sizeof(pt.first) != sizeof(po.first) || offsetof(PackedTest, first) != offsetof(PackedOrig, first)) {
runtime·printf("first: size, offset = %d, %d, want %d, %d\n", sizeof(pt.first), offsetof(PackedTest, first), sizeof(po.first), offsetof(PackedOrig, first));
ret = 1;
}
if(sizeof(pt.second) != sizeof(po.second) || offsetof(PackedTest, second) != offsetof(PackedOrig, second)) {
runtime·printf("second: size, offset = %d, %d, want %d, %d\n", sizeof(pt.second), offsetof(PackedTest, second), sizeof(po.second), offsetof(PackedOrig, second));
ret = 1;
}
if(sizeof(pt.third) != sizeof(po.third) || offsetof(PackedTest, third) != offsetof(PackedOrig, third)) {
runtime·printf("third: size, offset = %d, %d, want %d, %d\n", sizeof(pt.third), offsetof(PackedTest, third), sizeof(po.third), offsetof(PackedOrig, third));
ret = 1;
}
*/
FLUSH(&ret); // flush return value
}

View File

@@ -2,8 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gc
package main
const (
DEFAULTCAPACITY = 16
)
import "os"
func test() int32 // in main.c
func main() {
os.Exit(int(test()))
}

16
misc/cgo/testcdefs/test.bash Executable file
View File

@@ -0,0 +1,16 @@
# Copyright 2013 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
# Just add issue file prefixes to this list if more issues come up
FILE_PREFIXES="cdefstest"
for FP in $FILE_PREFIXES
do
go tool cgo -cdefs ${FP}.go > ${FP}.h
done
go build . && ./testcdefs
EXIT=$?
rm -rf _obj testcdefs *.h
exit $EXIT

View File

@@ -5,12 +5,6 @@
set -e
if [ "$(uname -m)" == ppc64 -o "$(uname -m)" == ppc64le ]; then
# External linking not implemented on ppc64
echo "skipping test on ppc64 (issue #8912)"
exit
fi
args=
dyld_envvar=LD_LIBRARY_PATH
ext=so

View File

@@ -3,8 +3,7 @@
// license that can be found in the LICENSE file.
var numericRE = /^\d+$/;
var commitRE = /^(?:\d+:)?([0-9a-f]{6,40})$/; // e.g "8486:ab29d2698a47" or "ab29d2698a47"
var gerritChangeIdRE = /^I[0-9a-f]{4,40}$/; // e.g. Id69c00d908d18151486007ec03da5495b34b05f5
var commitRE = /^(?:\d+:)?([0-9a-f]{6,20})$/; // e.g "8486:ab29d2698a47" or "ab29d2698a47"
var pkgRE = /^[a-z0-9_\/]+$/;
function urlForInput(t) {
@@ -14,26 +13,20 @@ function urlForInput(t) {
if (numericRE.test(t)) {
if (t < 150000) {
// We could use the golang.org/cl/ handler here, but
// avoid some redirect latency and go right there, since
// one is easy. (no server-side mapping)
return "https://github.com/golang/go/issues/" + t;
return "http://code.google.com/p/go/issues/detail?id=" + t;
}
return "https://golang.org/cl/" + t;
}
if (gerritChangeIdRE.test(t)) {
return "http://golang.org/cl/" + t;
return "http://codereview.appspot.com/" + t + "/";
}
var match = commitRE.exec(t);
if (match) {
return "https://golang.org/change/" + match[1];
return "http://code.google.com/p/go/source/detail?r=" + match[1];
}
if (pkgRE.test(t)) {
// TODO: make this smarter, using a list of packages + substring matches.
// Get the list from godoc itself in JSON format?
// TODO: prefer localhost:6060 to golang.org if localhost:6060 is responding.
return "http://golang.org/pkg/" + t;
}

View File

@@ -9,13 +9,11 @@
<script src="popup.js"></script>
</head>
<body style='margin: 0.5em; font-family: sans;'>
<small><a href="#" url="https://golang.org/issue">issue</a>,
<a href="#" url="https://golang.org/cl">codereview</a>,
<a href="#" url="https://golang.org/change">commit</a>, or
<a href="#" url="https://golang.org/pkg/">pkg</a> id/name:</small>
<small><a href="#" url="http://code.google.com/p/go/issues/list">issue</a>,
<a href="#" url="http://codereview.appspot.com/">codereview</a>,
<a href="#" url="http://code.google.com/p/go/source/list">commit</a>, or
<a href="#" url="http://golang.org/pkg/">pkg</a> id/name:</small>
<form style='margin: 0' id='navform'><nobr><input id="inputbox" size=10 tabindex=1 /><input type="submit" value="go" /></nobr></form>
<small>Also: <a href="#" url="https://build.golang.org">buildbots</a>
<a href="#" url="https://github.com/golang/go">Github</a>
</small>
<small>Also: <a href="#" url="http://build.golang.org">buildbots</a></small>
</body>
</html>

View File

@@ -0,0 +1,24 @@
application: gocodereview
version: 1
runtime: go
api_version: go1
inbound_services:
- mail
handlers:
- url: /static/(.*)
static_files: static/\1
upload: static/.*
- url: /_ah/mail/.*
script: _go_app
login: admin
- url: /_ah/queue/go/delay
script: _go_app
login: admin
- url: /(gc|update-cl)
script: _go_app
login: admin
- url: /.*
script: _go_app
login: required

View File

@@ -0,0 +1,4 @@
cron:
- description: GC
url: /gc
schedule: every 6 hours

View File

@@ -0,0 +1,493 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package dashboard
// This file handles operations on the CL entity kind.
import (
"bytes"
"encoding/json"
"fmt"
"html/template"
"io"
"io/ioutil"
"net/http"
"net/url"
"regexp"
"sort"
"strings"
"time"
"appengine"
"appengine/datastore"
"appengine/taskqueue"
"appengine/urlfetch"
"appengine/user"
)
func init() {
http.HandleFunc("/assign", handleAssign)
http.HandleFunc("/update-cl", handleUpdateCL)
}
const codereviewBase = "http://codereview.appspot.com"
const gobotBase = "http://research.swtch.com/gobot_codereview"
var clRegexp = regexp.MustCompile(`\d+`)
// CL represents a code review.
type CL struct {
Number string // e.g. "5903061"
Closed bool
Owner string // email address
Created, Modified time.Time
Description []byte `datastore:",noindex"`
FirstLine string `datastore:",noindex"`
LGTMs []string
NotLGTMs []string
LastUpdateBy string // author of most recent review message
LastUpdate string `datastore:",noindex"` // first line of most recent review message
// Mail information.
Subject string `datastore:",noindex"`
Recipients []string `datastore:",noindex"`
LastMessageID string `datastore:",noindex"`
// These are person IDs (e.g. "rsc"); they may be empty
Author string
Reviewer string
}
// Reviewed reports whether the reviewer has replied to the CL.
// The heuristic is that the CL has been replied to if it is LGTMed
// or if the last CL message was from the reviewer.
func (cl *CL) Reviewed() bool {
if cl.LastUpdateBy == cl.Reviewer {
return true
}
if person := emailToPerson[cl.LastUpdateBy]; person != "" && person == cl.Reviewer {
return true
}
for _, who := range cl.LGTMs {
if who == cl.Reviewer {
return true
}
}
return false
}
// DisplayOwner returns the CL's owner, either as their email address
// or the person ID if it's a reviewer. It is for display only.
func (cl *CL) DisplayOwner() string {
if p, ok := emailToPerson[cl.Owner]; ok {
return p
}
return cl.Owner
}
func (cl *CL) FirstLineHTML() template.HTML {
s := template.HTMLEscapeString(cl.FirstLine)
// Embolden the package name.
if i := strings.Index(s, ":"); i >= 0 {
s = "<b>" + s[:i] + "</b>" + s[i:]
}
return template.HTML(s)
}
func formatEmails(e []string) template.HTML {
x := make([]string, len(e))
for i, s := range e {
s = template.HTMLEscapeString(s)
if !strings.Contains(s, "@") {
s = "<b>" + s + "</b>"
}
s = `<span class="email">` + s + "</span>"
x[i] = s
}
return template.HTML(strings.Join(x, ", "))
}
func (cl *CL) LGTMHTML() template.HTML {
return formatEmails(cl.LGTMs)
}
func (cl *CL) NotLGTMHTML() template.HTML {
return formatEmails(cl.NotLGTMs)
}
func (cl *CL) ModifiedAgo() string {
// Just the first non-zero unit.
units := [...]struct {
suffix string
unit time.Duration
}{
{"d", 24 * time.Hour},
{"h", time.Hour},
{"m", time.Minute},
{"s", time.Second},
}
d := time.Now().Sub(cl.Modified)
for _, u := range units {
if d > u.unit {
return fmt.Sprintf("%d%s", d/u.unit, u.suffix)
}
}
return "just now"
}
func handleAssign(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
if r.Method != "POST" {
http.Error(w, "Bad method "+r.Method, 400)
return
}
u := user.Current(c)
person, ok := emailToPerson[u.Email]
if !ok {
http.Error(w, "Not allowed", http.StatusUnauthorized)
return
}
n, rev := r.FormValue("cl"), r.FormValue("r")
if !clRegexp.MatchString(n) {
c.Errorf("Bad CL %q", n)
http.Error(w, "Bad CL", 400)
return
}
if _, ok := preferredEmail[rev]; !ok && rev != "" {
c.Errorf("Unknown reviewer %q", rev)
http.Error(w, "Unknown reviewer", 400)
return
}
key := datastore.NewKey(c, "CL", n, 0, nil)
if rev != "" {
// Make sure the reviewer is listed in Rietveld as a reviewer.
url := codereviewBase + "/" + n + "/fields"
resp, err := urlfetch.Client(c).Get(url + "?field=reviewers")
if err != nil {
c.Errorf("Retrieving CL reviewer list failed: %v", err)
http.Error(w, err.Error(), 500)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
c.Errorf("Failed reading body: %v", err)
http.Error(w, err.Error(), 500)
return
}
if resp.StatusCode != 200 {
c.Errorf("Retrieving CL reviewer list failed: got HTTP response %d\nBody: %s", resp.StatusCode, body)
http.Error(w, "Failed contacting Rietveld", 500)
return
}
var apiResp struct {
Reviewers []string `json:"reviewers"`
}
if err := json.Unmarshal(body, &apiResp); err != nil {
// probably can't be retried
msg := fmt.Sprintf("Malformed JSON from %v: %v", url, err)
c.Errorf("%s", msg)
http.Error(w, msg, 500)
return
}
found := false
for _, r := range apiResp.Reviewers {
if emailToPerson[r] == rev {
found = true
break
}
}
if !found {
c.Infof("Adding %v as a reviewer of CL %v", rev, n)
url := fmt.Sprintf("%s?cl=%s&r=%s&obo=%s", gobotBase, n, rev, person)
resp, err := urlfetch.Client(c).Get(url)
if err != nil {
c.Errorf("Gobot GET failed: %v", err)
http.Error(w, err.Error(), 500)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
c.Errorf("Failed reading Gobot body: %v", err)
http.Error(w, err.Error(), 500)
return
}
if resp.StatusCode != 200 {
c.Errorf("Gobot GET failed: got HTTP response %d\nBody: %s", resp.StatusCode, body)
http.Error(w, "Failed contacting Gobot", 500)
return
}
c.Infof("Gobot said %q", resp.Status)
}
}
// Update our own record.
err := datastore.RunInTransaction(c, func(c appengine.Context) error {
cl := new(CL)
err := datastore.Get(c, key, cl)
if err != nil {
return err
}
cl.Reviewer = rev
_, err = datastore.Put(c, key, cl)
return err
}, nil)
if err != nil {
msg := fmt.Sprintf("Assignment failed: %v", err)
c.Errorf("%s", msg)
http.Error(w, msg, 500)
return
}
c.Infof("Assigned CL %v to %v", n, rev)
}
func UpdateCLLater(c appengine.Context, n string, delay time.Duration) {
t := taskqueue.NewPOSTTask("/update-cl", url.Values{
"cl": []string{n},
})
t.Delay = delay
if _, err := taskqueue.Add(c, t, "update-cl"); err != nil {
c.Errorf("Failed adding task: %v", err)
}
}
func handleUpdateCL(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
n := r.FormValue("cl")
if !clRegexp.MatchString(n) {
c.Errorf("Bad CL %q", n)
http.Error(w, "Bad CL", 400)
return
}
if err := updateCL(c, n); err != nil {
c.Errorf("Failed updating CL %v: %v", n, err)
http.Error(w, "Failed update", 500)
return
}
io.WriteString(w, "OK")
}
// apiMessage describes the JSON sent back by Rietveld in the CL messages list.
type apiMessage struct {
Date string `json:"date"`
Text string `json:"text"`
Sender string `json:"sender"`
Recipients []string `json:"recipients"`
Approval bool `json:"approval"`
}
// byDate implements sort.Interface to order the messages by date, earliest first.
// The dates are sent in RFC 3339 format, so string comparison matches time value comparison.
type byDate []*apiMessage
func (x byDate) Len() int { return len(x) }
func (x byDate) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x byDate) Less(i, j int) bool { return x[i].Date < x[j].Date }
// updateCL updates a single CL. If a retryable failure occurs, an error is returned.
func updateCL(c appengine.Context, n string) error {
c.Debugf("Updating CL %v", n)
key := datastore.NewKey(c, "CL", n, 0, nil)
url := codereviewBase + "/api/" + n + "?messages=true"
resp, err := urlfetch.Client(c).Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
raw, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("Failed reading HTTP body: %v", err)
}
// Special case for abandoned CLs.
if resp.StatusCode == 404 && bytes.Contains(raw, []byte("No issue exists with that id")) {
// Don't bother checking for errors. The CL might never have been saved, for instance.
datastore.Delete(c, key)
c.Infof("Deleted abandoned CL %v", n)
return nil
}
if resp.StatusCode != 200 {
return fmt.Errorf("Update: got HTTP response %d", resp.StatusCode)
}
var apiResp struct {
Description string `json:"description"`
Reviewers []string `json:"reviewers"`
Created string `json:"created"`
OwnerEmail string `json:"owner_email"`
Modified string `json:"modified"`
Closed bool `json:"closed"`
Subject string `json:"subject"`
Messages []*apiMessage `json:"messages"`
}
if err := json.Unmarshal(raw, &apiResp); err != nil {
// probably can't be retried
c.Errorf("Malformed JSON from %v: %v", url, err)
return nil
}
//c.Infof("RAW: %+v", apiResp)
sort.Sort(byDate(apiResp.Messages))
cl := &CL{
Number: n,
Closed: apiResp.Closed,
Owner: apiResp.OwnerEmail,
Description: []byte(apiResp.Description),
FirstLine: apiResp.Description,
Subject: apiResp.Subject,
Author: emailToPerson[apiResp.OwnerEmail],
}
cl.Created, err = time.Parse("2006-01-02 15:04:05.000000", apiResp.Created)
if err != nil {
c.Errorf("Bad creation time %q: %v", apiResp.Created, err)
}
cl.Modified, err = time.Parse("2006-01-02 15:04:05.000000", apiResp.Modified)
if err != nil {
c.Errorf("Bad modification time %q: %v", apiResp.Modified, err)
}
if i := strings.Index(cl.FirstLine, "\n"); i >= 0 {
cl.FirstLine = cl.FirstLine[:i]
}
// Treat zero reviewers as a signal that the CL is completed.
// This could be after the CL has been submitted, but before the CL author has synced,
// but it could also be a CL manually edited to remove reviewers.
if len(apiResp.Reviewers) == 0 {
cl.Closed = true
}
lgtm := make(map[string]bool)
notLGTM := make(map[string]bool)
rcpt := make(map[string]bool)
for _, msg := range apiResp.Messages {
s, rev := msg.Sender, false
if p, ok := emailToPerson[s]; ok {
s, rev = p, true
}
line := firstLine(msg.Text)
if line != "" {
cl.LastUpdateBy = msg.Sender
cl.LastUpdate = line
}
// CLs submitted by someone other than the CL owner do not immediately
// transition to "closed". Let's simulate the intention by treating
// messages starting with "*** Submitted as " from a reviewer as a
// signal that the CL is now closed.
if rev && strings.HasPrefix(msg.Text, "*** Submitted as ") {
cl.Closed = true
}
if msg.Approval {
lgtm[s] = true
delete(notLGTM, s) // "LGTM" overrules previous "NOT LGTM"
}
if strings.Contains(line, "NOT LGTM") {
notLGTM[s] = true
delete(lgtm, s) // "NOT LGTM" overrules previous "LGTM"
}
for _, r := range msg.Recipients {
rcpt[r] = true
}
}
for l := range lgtm {
cl.LGTMs = append(cl.LGTMs, l)
}
for l := range notLGTM {
cl.NotLGTMs = append(cl.NotLGTMs, l)
}
for r := range rcpt {
cl.Recipients = append(cl.Recipients, r)
}
sort.Strings(cl.LGTMs)
sort.Strings(cl.NotLGTMs)
sort.Strings(cl.Recipients)
err = datastore.RunInTransaction(c, func(c appengine.Context) error {
ocl := new(CL)
err := datastore.Get(c, key, ocl)
if err != nil && err != datastore.ErrNoSuchEntity {
return err
} else if err == nil {
// LastMessageID and Reviewer need preserving.
cl.LastMessageID = ocl.LastMessageID
cl.Reviewer = ocl.Reviewer
}
_, err = datastore.Put(c, key, cl)
return err
}, nil)
if err != nil {
return err
}
c.Infof("Updated CL %v", n)
return nil
}
// trailingSpaceRE matches trailing spaces.
var trailingSpaceRE = regexp.MustCompile(`(?m)[ \t\r]+$`)
// removeRE is the list of patterns to skip over at the beginning of a
// message when looking for message text.
var removeRE = regexp.MustCompile(`(?m-s)\A(` +
// Skip leading "Hello so-and-so," generated by codereview plugin.
`(Hello(.|\n)*?\n\n)` +
// Skip quoted text.
`|((On.*|.* writes|.* wrote):\n)` +
`|((>.*\n)+)` +
// Skip lines with no letters.
`|(([^A-Za-z]*\n)+)` +
// Skip links to comments and file info.
`|(http://codereview.*\n([^ ]+:[0-9]+:.*\n)?)` +
`|(File .*:\n)` +
`)`,
)
// firstLine returns the first interesting line of the message text.
func firstLine(text string) string {
// Cut trailing spaces.
text = trailingSpaceRE.ReplaceAllString(text, "")
// Skip uninteresting lines.
for {
text = strings.TrimSpace(text)
m := removeRE.FindStringIndex(text)
if m == nil || m[0] != 0 {
break
}
text = text[m[1]:]
}
// Chop line at newline or else at 74 bytes.
i := strings.Index(text, "\n")
if i >= 0 {
text = text[:i]
}
if len(text) > 74 {
text = text[:70] + "..."
}
return text
}

View File

@@ -0,0 +1,299 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package dashboard
// This file handles the front page.
import (
"bytes"
"html/template"
"io"
"net/http"
"strings"
"sync"
"time"
"appengine"
"appengine/datastore"
"appengine/user"
)
func init() {
http.HandleFunc("/", handleFront)
http.HandleFunc("/favicon.ico", http.NotFound)
}
// maximum number of active CLs to show in person-specific tables.
const maxCLs = 100
func handleFront(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
data := &frontPageData{
Reviewers: personList,
User: user.Current(c).Email,
IsAdmin: user.IsAdmin(c),
}
var currentPerson string
u := data.User
you := "you"
if e := r.FormValue("user"); e != "" {
u = e
you = e
}
currentPerson, data.UserIsReviewer = emailToPerson[u]
if !data.UserIsReviewer {
currentPerson = u
}
var wg sync.WaitGroup
errc := make(chan error, 10)
activeCLs := datastore.NewQuery("CL").
Filter("Closed =", false).
Order("-Modified")
tableFetch := func(index int, f func(tbl *clTable) error) {
wg.Add(1)
go func() {
defer wg.Done()
start := time.Now()
if err := f(&data.Tables[index]); err != nil {
errc <- err
}
data.Timing[index] = time.Now().Sub(start)
}()
}
data.Tables[0].Title = "CLs assigned to " + you + " for review"
if data.UserIsReviewer {
tableFetch(0, func(tbl *clTable) error {
q := activeCLs.Filter("Reviewer =", currentPerson).Limit(maxCLs)
tbl.Assignable = true
_, err := q.GetAll(c, &tbl.CLs)
return err
})
}
tableFetch(1, func(tbl *clTable) error {
q := activeCLs
if data.UserIsReviewer {
q = q.Filter("Author =", currentPerson)
} else {
q = q.Filter("Owner =", currentPerson)
}
q = q.Limit(maxCLs)
tbl.Title = "CLs sent by " + you
tbl.Assignable = true
_, err := q.GetAll(c, &tbl.CLs)
return err
})
tableFetch(2, func(tbl *clTable) error {
q := activeCLs.Limit(50)
tbl.Title = "Other active CLs"
tbl.Assignable = true
if _, err := q.GetAll(c, &tbl.CLs); err != nil {
return err
}
// filter
for i := len(tbl.CLs) - 1; i >= 0; i-- {
cl := tbl.CLs[i]
if cl.Owner == currentPerson || cl.Author == currentPerson || cl.Reviewer == currentPerson {
// Preserve order.
copy(tbl.CLs[i:], tbl.CLs[i+1:])
tbl.CLs = tbl.CLs[:len(tbl.CLs)-1]
}
}
return nil
})
tableFetch(3, func(tbl *clTable) error {
q := datastore.NewQuery("CL").
Filter("Closed =", true).
Order("-Modified").
Limit(10)
tbl.Title = "Recently closed CLs"
tbl.Assignable = false
_, err := q.GetAll(c, &tbl.CLs)
return err
})
// Not really a table fetch.
tableFetch(0, func(_ *clTable) error {
var err error
data.LogoutURL, err = user.LogoutURL(c, "/")
return err
})
wg.Wait()
select {
case err := <-errc:
c.Errorf("%v", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
default:
}
var b bytes.Buffer
if err := frontPage.ExecuteTemplate(&b, "front", &data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
io.Copy(w, &b)
}
type frontPageData struct {
Tables [4]clTable
Timing [4]time.Duration
Reviewers []string
UserIsReviewer bool
User, LogoutURL string // actual logged in user
IsAdmin bool
}
type clTable struct {
Title string
Assignable bool
CLs []*CL
}
var frontPage = template.Must(template.New("front").Funcs(template.FuncMap{
"selected": func(a, b string) string {
if a == b {
return "selected"
}
return ""
},
"shortemail": func(s string) string {
if i := strings.Index(s, "@"); i >= 0 {
s = s[:i]
}
return s
},
}).Parse(`
<!doctype html>
<html>
<head>
<title>Go code reviews</title>
<link rel="icon" type="image/png" href="/static/icon.png" />
<style type="text/css">
body {
font-family: Helvetica, sans-serif;
}
img#gopherstamp {
float: right;
height: auto;
width: 250px;
}
h1, h2, h3 {
color: #777;
margin-bottom: 0;
}
table {
border-spacing: 0;
}
td {
vertical-align: top;
padding: 2px 5px;
}
tr.unreplied td.email {
border-left: 2px solid blue;
}
tr.pending td {
background: #fc8;
}
tr.failed td {
background: #f88;
}
tr.saved td {
background: #8f8;
}
.cls {
margin-top: 0;
}
a {
color: blue;
text-decoration: none; /* no link underline */
}
address {
font-size: 10px;
text-align: right;
}
.email {
font-family: monospace;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
</head>
<body>
<img id="gopherstamp" src="/static/gopherstamp.jpg" />
<h1>Go code reviews</h1>
<table class="cls">
{{range $i, $tbl := .Tables}}
<tr><td colspan="5"><h3>{{$tbl.Title}}</h3></td></tr>
{{if .CLs}}
{{range $cl := .CLs}}
<tr id="cl-{{$cl.Number}}" class="{{if not $i}}{{if not .Reviewed}}unreplied{{end}}{{end}}">
<td class="email">{{$cl.DisplayOwner}}</td>
<td>
{{if $tbl.Assignable}}
<select id="cl-rev-{{$cl.Number}}" {{if not $.UserIsReviewer}}disabled{{end}}>
<option></option>
{{range $.Reviewers}}
<option {{selected . $cl.Reviewer}}>{{.}}</option>
{{end}}
</select>
<script type="text/javascript">
$(function() {
$('#cl-rev-{{$cl.Number}}').change(function() {
var r = $(this).val();
var row = $('tr#cl-{{$cl.Number}}');
row.addClass('pending');
$.post('/assign', {
'cl': '{{$cl.Number}}',
'r': r
}).success(function() {
row.removeClass('pending');
row.addClass('saved');
}).error(function() {
row.removeClass('pending');
row.addClass('failed');
});
});
});
</script>
{{end}}
</td>
<td>
<a href="http://codereview.appspot.com/{{.Number}}/" title="{{ printf "%s" .Description}}">{{.Number}}: {{.FirstLineHTML}}</a>
{{if and .LGTMs $tbl.Assignable}}<br /><span style="font-size: smaller;">LGTMs: {{.LGTMHTML}}</span>{{end}}
{{if and .NotLGTMs $tbl.Assignable}}<br /><span style="font-size: smaller; color: #f74545;">NOT LGTMs: {{.NotLGTMHTML}}</span>{{end}}
{{if .LastUpdateBy}}<br /><span style="font-size: smaller; color: #777777;">(<span title="{{.LastUpdateBy}}">{{.LastUpdateBy | shortemail}}</span>) {{.LastUpdate}}</span>{{end}}
</td>
<td title="Last modified">{{.ModifiedAgo}}</td>
<td>{{if $.IsAdmin}}<a href="/update-cl?cl={{.Number}}" title="Update this CL">&#x27f3;</a>{{end}}</td>
</tr>
{{end}}
{{else}}
<tr><td colspan="5"><em>none</em></td></tr>
{{end}}
{{end}}
</table>
<hr />
<address>
You are <span class="email">{{.User}}</span> &middot; <a href="{{.LogoutURL}}">logout</a><br />
datastore timing: {{range .Timing}} {{.}}{{end}}
</address>
</body>
</html>
`))

View File

@@ -0,0 +1,47 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package dashboard
// This file handles garbage collection of old CLs.
import (
"net/http"
"time"
"appengine"
"appengine/datastore"
)
func init() {
http.HandleFunc("/gc", handleGC)
}
func handleGC(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
// Delete closed CLs that haven't been modified in 168 hours (7 days).
cutoff := time.Now().Add(-168 * time.Hour)
q := datastore.NewQuery("CL").
Filter("Closed =", true).
Filter("Modified <", cutoff).
Limit(100).
KeysOnly()
keys, err := q.GetAll(c, nil)
if err != nil {
c.Errorf("GetAll failed for old CLs: %v", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if len(keys) == 0 {
return
}
if err := datastore.DeleteMulti(c, keys); err != nil {
c.Errorf("DeleteMulti failed for old CLs: %v", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
c.Infof("Deleted %d old CLs", len(keys))
}

View File

@@ -0,0 +1,68 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package dashboard
// This file handles receiving mail.
import (
"net/http"
"net/mail"
"regexp"
"time"
"appengine"
"appengine/datastore"
)
func init() {
http.HandleFunc("/_ah/mail/", handleMail)
}
var subjectRegexp = regexp.MustCompile(`.*code review (\d+):.*`)
func handleMail(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
defer r.Body.Close()
msg, err := mail.ReadMessage(r.Body)
if err != nil {
c.Errorf("mail.ReadMessage: %v", err)
return
}
subj := msg.Header.Get("Subject")
m := subjectRegexp.FindStringSubmatch(subj)
if len(m) != 2 {
c.Debugf("Subject %q did not match /%v/", subj, subjectRegexp)
return
}
c.Infof("Found issue %q", m[1])
// Track the MessageID.
key := datastore.NewKey(c, "CL", m[1], 0, nil)
err = datastore.RunInTransaction(c, func(c appengine.Context) error {
cl := new(CL)
err := datastore.Get(c, key, cl)
if err != nil && err != datastore.ErrNoSuchEntity {
return err
}
if err == datastore.ErrNoSuchEntity {
// Must set sentinel values for time.Time fields
// if this is a new entity.
cl.Created = time.Unix(0, 0)
cl.Modified = time.Unix(0, 0)
}
cl.LastMessageID = msg.Header.Get("Message-ID")
_, err = datastore.Put(c, key, cl)
return err
}, nil)
if err != nil {
c.Errorf("datastore transaction failed: %v", err)
}
// Update the CL after a delay to give Rietveld a chance to catch up.
UpdateCLLater(c, m[1], 10*time.Second)
}

View File

@@ -0,0 +1,65 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package dashboard
// This file handles identities of people.
import (
"sort"
)
var (
emailToPerson = make(map[string]string) // email => person
preferredEmail = make(map[string]string) // person => email
personList []string
)
func init() {
// People we assume have golang.org and google.com accounts,
// and prefer to use their golang.org address for code review.
gophers := [...]string{
"adg",
"agl",
"bradfitz",
"campoy",
"cshapiro",
"dsymonds",
"gri",
"iant",
"khr",
"mpvl",
"nigeltao",
"r",
"rsc",
"sameer",
}
for _, p := range gophers {
personList = append(personList, p)
emailToPerson[p+"@golang.org"] = p
emailToPerson[p+"@google.com"] = p
preferredEmail[p] = p + "@golang.org"
}
// Other people.
others := map[string]string{
"adonovan": "adonovan@google.com",
"brainman": "alex.brainman@gmail.com",
"ality": "ality@pbrane.org",
"dfc": "dave@cheney.net",
"dvyukov": "dvyukov@google.com",
"gustavo": "gustavo@niemeyer.net",
"jsing": "jsing@google.com",
"mikio": "mikioh.mikioh@gmail.com",
"minux": "minux.ma@gmail.com",
"remy": "remyoudompheng@gmail.com",
"rminnich": "rminnich@gmail.com",
}
for p, e := range others {
personList = append(personList, p)
emailToPerson[e] = p
preferredEmail[p] = e
}
sort.Strings(personList)
}

View File

@@ -0,0 +1,25 @@
indexes:
- kind: CL
properties:
- name: Author
- name: Modified
direction: desc
- kind: CL
properties:
- name: Owner
- name: Modified
direction: desc
- kind: CL
properties:
- name: Closed
- name: Modified
direction: desc
- kind: CL
properties:
- name: Reviewer
- name: Modified
direction: desc

View File

@@ -0,0 +1,4 @@
queue:
- name: update-cl
rate: 12/m
bucket_size: 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

View File

@@ -1,5 +1,5 @@
For information about plugins and other support for Go in editors and shells,
see this page on the Go Wiki:
https://golang.org/wiki/IDEsAndTextEditorPlugins
https://code.google.com/p/go-wiki/wiki/IDEsAndTextEditorPlugins

View File

@@ -1,44 +0,0 @@
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:
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
To build a program, use the normal go build command:
CGO_ENABLED=1 GOARCH=arm go build import/path
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.)
# 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.
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.
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.

View File

@@ -1,10 +0,0 @@
#!/bin/sh
# This uses the latest available iOS SDK, which is recommended.
# To select a specific SDK, run 'xcodebuild -showsdks'
# to see the available SDKs and replace iphoneos with one of them.
SDK=iphoneos
SDK_PATH=`xcrun --sdk $SDK --show-sdk-path`
export IPHONEOS_DEPLOYMENT_TARGET=5.1
# cmd/cgo doesn't support llvm-gcc-4.2, so we have to use clang.
CLANG=`xcrun --sdk $SDK --find clang`
exec $CLANG -arch armv7 -isysroot $SDK_PATH "$@"

View File

@@ -30,16 +30,15 @@ import (
"runtime"
"strings"
"code.google.com/p/goauth2/oauth"
storage "code.google.com/p/google-api-go-client/storage/v1"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
)
var (
tag = flag.String("tag", "", "git revision to check out")
toolTag = flag.String("tool", defaultToolTag, "go.tools revision to check out")
tag = flag.String("tag", "release", "mercurial tag to check out")
toolTag = flag.String("tool", defaultToolTag, "go.tools tag to check out")
tourTag = flag.String("tour", defaultTourTag, "go-tour tag to check out")
repo = flag.String("repo", "https://go.googlesource.com/go", "repo URL")
repo = flag.String("repo", "https://code.google.com/p/go", "repo URL")
verbose = flag.Bool("v", false, "verbose output")
upload = flag.Bool("upload", false, "upload resulting files to Google Code")
addLabel = flag.String("label", "", "additional label to apply to file when uploading")
@@ -81,9 +80,9 @@ var preBuildCleanFiles = []string{
}
var cleanFiles = []string{
".git",
".gitignore",
".gitattributes",
".hg",
".hgtags",
".hgignore",
"VERSION.cache",
}
@@ -206,10 +205,6 @@ func main() {
}
}
}
if *tag == "" {
fmt.Fprintln(os.Stderr, "you must specify a -tag")
os.Exit(2)
}
if err := b.Do(); err != nil {
log.Printf("%s: %v", targ, err)
ok = false
@@ -241,11 +236,11 @@ func (b *Build) Do() error {
b.gopath = work
// Clone Go distribution and update to tag.
_, err = b.run(work, "git", "clone", *repo, b.root)
_, err = b.hgCmd(work, "clone", *repo, b.root)
if err != nil {
return err
}
_, err = b.run(b.root, "git", "checkout", *tag)
_, err = b.hgCmd(b.root, "update", *tag)
if err != nil {
return err
}
@@ -277,27 +272,13 @@ func (b *Build) Do() error {
if b.OS == "windows" {
goCmd += ".exe"
}
// Because on release branches, go install -a std is a NOP,
// we have to resort to delete pkg/$GOOS_$GOARCH, install -race,
// and then reinstall std so that we're not left with a slower,
// race-enabled cmd/go, etc.
goPkg := filepath.Join(b.root, "pkg", b.OS+"_"+b.Arch)
err = os.RemoveAll(goPkg)
if err != nil {
return err
}
_, err = b.run(src, goCmd, "tool", "dist", "install", "runtime")
if err != nil {
return err
}
_, err = b.run(src, goCmd, "install", "-race", "std")
if err != nil {
return err
}
_, err = b.run(src, goCmd, "install", "std")
if err != nil {
return err
}
// Re-install std without -race, so that we're not left
// with a slower, race-enabled cmd/go, etc.
_, err = b.run(src, goCmd, "install", "-a", "std")
// Re-building go command leaves old versions of go.exe as go.exe~ on windows.
// See (*builder).copyFile in $GOROOT/src/cmd/go/build.go for details.
// Remove it manually.
@@ -524,15 +505,30 @@ func (b *Build) extras() error {
}
func (b *Build) get(repoPath, revision string) error {
// Fetch the packages (without building/installing).
_, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"),
"get", "-d", repoPath+"/...")
if err != nil {
return err
dest := filepath.Join(b.gopath, "src", filepath.FromSlash(repoPath))
if strings.HasPrefix(repoPath, "golang.org/x/") {
// For sub-repos, fetch the old Mercurial repo; bypass "go get".
// DO NOT import this special case into the git tree.
if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil {
return err
}
repo := strings.Replace(repoPath, "golang.org/x/", "https://code.google.com/p/go.", 1)
if _, err := b.run(b.gopath, "hg", "clone", repo, dest); err != nil {
return err
}
} else {
// Fetch the packages (without building/installing).
_, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"),
"get", "-d", repoPath+"/...")
if err != nil {
return err
}
}
// Update the repo to the specified revision.
dest := filepath.Join(b.gopath, "src", filepath.FromSlash(repoPath))
var err error
switch {
case exists(filepath.Join(dest, ".git")):
_, err = b.run(dest, "git", "checkout", revision)
@@ -639,6 +635,10 @@ func ext() string {
return ""
}
func (b *Build) hgCmd(dir string, args ...string) ([]byte, error) {
return b.run(dir, "hg", append([]string{"--config", "extensions.codereview=!"}, args...)...)
}
func (b *Build) run(dir, name string, args ...string) ([]byte, error) {
buf := new(bytes.Buffer)
absName, err := lookPath(name)
@@ -736,7 +736,6 @@ func (b *Build) Upload(version string, filename string) error {
OS: b.OS,
Arch: b.Arch,
Checksum: sum,
Size: len(file),
Kind: kind,
})
if err != nil {
@@ -761,50 +760,43 @@ type File struct {
Arch string
Version string
Checksum string `datastore:",noindex"`
Size int `datastore:",noindex"`
Kind string // "archive", "installer", "source"
}
func setupOAuthClient() error {
config := &oauth2.Config{
ClientID: "999119582588-h7kpj5pcm6d9solh5lgrbusmvvk4m9dn.apps.googleusercontent.com",
config := &oauth.Config{
ClientId: "999119582588-h7kpj5pcm6d9solh5lgrbusmvvk4m9dn.apps.googleusercontent.com",
ClientSecret: "8YLFgOhXIELWbO-NtF3iqIQz",
Endpoint: google.Endpoint,
Scopes: []string{storage.DevstorageRead_writeScope},
Scope: storage.DevstorageRead_writeScope,
AuthURL: "https://accounts.google.com/o/oauth2/auth",
TokenURL: "https://accounts.google.com/o/oauth2/token",
TokenCache: oauth.CacheFile(*tokenCache),
RedirectURL: "oob",
}
url := config.AuthCodeURL("junk")
fmt.Println("Visit the following URL, obtain an authentication" +
"code, and enter it below.")
fmt.Println(url)
fmt.Print("Enter authentication code: ")
code := ""
if _, err := fmt.Scan(&code); err != nil {
return err
transport := &oauth.Transport{Config: config}
if token, err := config.TokenCache.Token(); err != nil {
url := transport.Config.AuthCodeURL("")
fmt.Println("Visit the following URL, obtain an authentication" +
"code, and enter it below.")
fmt.Println(url)
fmt.Print("Enter authentication code: ")
code := ""
if _, err := fmt.Scan(&code); err != nil {
return err
}
if _, err := transport.Exchange(code); err != nil {
return err
}
} else {
transport.Token = token
}
tok, err := config.Exchange(oauth2.NoContext, code)
if err != nil {
return err
}
oauthClient = config.Client(oauth2.NoContext, tok)
oauthClient = transport.Client()
return nil
}
func (b *Build) clean(files []string) error {
for _, name := range files {
path := filepath.Join(b.root, name)
var err error
if b.OS == "windows" {
// Git sets some of its packfiles as 'read only',
// so os.RemoveAll will fail for the ".git" directory.
// Instead, shell out to cmd's 'del' subcommand.
cmd := exec.Command("cmd.exe", "/C", "del", "/Q", "/F", "/S", path)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
} else {
err = os.RemoveAll(path)
}
err := os.RemoveAll(filepath.Join(b.root, name))
if err != nil {
return err
}
@@ -1034,11 +1026,6 @@ var hgTool = tool{
},
}
var gitTool = tool{
"http://git-scm.com/download/win",
[]string{`C:\Program Files\Git`, `C:\Program Files (x86)\Git`},
}
var gccTool = tool{
"Mingw gcc; http://sourceforge.net/projects/mingw/files/Installer/mingw-get-inst/",
[]string{`C:\Mingw\bin`},
@@ -1050,7 +1037,6 @@ var windowsDeps = map[string]tool{
"candle": wixTool,
"light": wixTool,
"cmd": {"Windows cmd.exe", nil},
"git": gitTool,
"hg": hgTool,
}

View File

@@ -10,31 +10,14 @@ usr src=../misc/nacl/testdata
go src=..
src
cmd
asm
internal
asm
testdata
+
internal
objfile
objfile.go
rsc.io
arm
armasm
testdata
+
x86
x86asm
testdata
+
gofmt
gofmt.go
gofmt_test.go
testdata
+
link
testdata
+
archive
tar
testdata

View File

@@ -10,7 +10,7 @@ import "testing"
// as expected.
func TestRead(t *testing.T) {
f := Fopen("file_test.go", "r")
if f.Swigcptr() == 0 {
if f == nil {
t.Fatal("fopen failed")
}
if Fgetc(f) != '/' || Fgetc(f) != '/' || Fgetc(f) != ' ' || Fgetc(f) != 'C' {

View File

@@ -1,6 +0,0 @@
This directory contains helper file for trace viewer (go tool trace).
trace_viewer_lean.html was generated following instructions in:
https://github.com/google/trace-viewer/wiki/Embedding
on revision 895aa74558d19d91906fb720df6458244ef160c6 using:
trace-viewer$ ./vulcanize_trace_viewer --config=lean

File diff suppressed because one or more lines are too long

View File

@@ -11,7 +11,7 @@ set -e
ulimit -c 0 # no core files
if [ ! -f make.bash ]; then
echo 'androidtest.bash must be run from $GOROOT/src' 1>&2
echo 'nacl.bash must be run from $GOROOT/src' 1>&2
exit 1
fi
@@ -38,15 +38,14 @@ GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH go build \
#
# The adb sync command will sync either the /system or /data
# directories of an android device from a similar directory
# on the host. We copy the files required for running tests under
# /data/local/tmp/goroot. The adb sync command does not follow
# symlinks so we have to copy.
# on the host. So we fake one with symlinks to push the GOROOT
# into a subdirectory of /data.
export ANDROID_PRODUCT_OUT=/tmp/androidtest-$$
FAKE_GOROOT=$ANDROID_PRODUCT_OUT/data/local/tmp/goroot
mkdir -p $FAKE_GOROOT
cp -a "${GOROOT}/src" "${FAKE_GOROOT}/"
cp -a "${GOROOT}/test" "${FAKE_GOROOT}/"
cp -a "${GOROOT}/lib" "${FAKE_GOROOT}/"
ln -s $GOROOT/src $FAKE_GOROOT/src
ln -s $GOROOT/test $FAKE_GOROOT/test
ln -s $GOROOT/lib $FAKE_GOROOT/lib
echo '# Syncing test files to android device'
time adb sync data &> /dev/null
echo ''

View File

@@ -31,7 +31,6 @@ func Example() {
for _, file := range files {
hdr := &tar.Header{
Name: file.Name,
Mode: 0600,
Size: int64(len(file.Body)),
}
if err := tw.WriteHeader(hdr); err != nil {

View File

@@ -85,8 +85,6 @@ const (
func NewReader(r io.Reader) *Reader { return &Reader{r: r} }
// Next advances to the next entry in the tar archive.
//
// io.EOF is returned at the end of the input.
func (tr *Reader) Next() (*Header, error) {
var hdr *Header
if tr.err == nil {

View File

@@ -144,39 +144,6 @@ func (b *Reader) Peek(n int) ([]byte, error) {
return b.buf[b.r : b.r+n], err
}
// Discard skips the next n bytes, returning the number of bytes discarded.
//
// If Discard skips fewer than n bytes, it also returns an error.
// If 0 <= n <= b.Buffered(), Discard is guaranteed to succeed without
// reading from the underlying io.Reader.
func (b *Reader) Discard(n int) (discarded int, err error) {
if n < 0 {
return 0, ErrNegativeCount
}
if n == 0 {
return
}
remain := n
for {
skip := b.Buffered()
if skip == 0 {
b.fill()
skip = b.Buffered()
}
if skip > remain {
skip = remain
}
b.r += skip
remain -= skip
if remain == 0 {
return n, nil
}
if b.err != nil {
return n - remain, b.readErr()
}
}
}
// Read reads data into p.
// It returns the number of bytes read into p.
// It calls Read at most once on the underlying Reader,

View File

@@ -1268,135 +1268,6 @@ func TestWriterReset(t *testing.T) {
}
}
func TestReaderDiscard(t *testing.T) {
tests := []struct {
name string
r io.Reader
bufSize int // 0 means 16
peekSize int
n int // input to Discard
want int // from Discard
wantErr error // from Discard
wantBuffered int
}{
{
name: "normal case",
r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
peekSize: 16,
n: 6,
want: 6,
wantBuffered: 10,
},
{
name: "discard causing read",
r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
n: 6,
want: 6,
wantBuffered: 10,
},
{
name: "discard all without peek",
r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
n: 26,
want: 26,
wantBuffered: 0,
},
{
name: "discard more than end",
r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
n: 27,
want: 26,
wantErr: io.EOF,
wantBuffered: 0,
},
// Any error from filling shouldn't show up until we
// get past the valid bytes. Here we return we return 5 valid bytes at the same time
// as an error, but test that we don't see the error from Discard.
{
name: "fill error, discard less",
r: newScriptedReader(func(p []byte) (n int, err error) {
if len(p) < 5 {
panic("unexpected small read")
}
return 5, errors.New("5-then-error")
}),
n: 4,
want: 4,
wantErr: nil,
wantBuffered: 1,
},
{
name: "fill error, discard equal",
r: newScriptedReader(func(p []byte) (n int, err error) {
if len(p) < 5 {
panic("unexpected small read")
}
return 5, errors.New("5-then-error")
}),
n: 5,
want: 5,
wantErr: nil,
wantBuffered: 0,
},
{
name: "fill error, discard more",
r: newScriptedReader(func(p []byte) (n int, err error) {
if len(p) < 5 {
panic("unexpected small read")
}
return 5, errors.New("5-then-error")
}),
n: 6,
want: 5,
wantErr: errors.New("5-then-error"),
wantBuffered: 0,
},
// Discard of 0 shouldn't cause a read:
{
name: "discard zero",
r: newScriptedReader(), // will panic on Read
n: 0,
want: 0,
wantErr: nil,
wantBuffered: 0,
},
{
name: "discard negative",
r: newScriptedReader(), // will panic on Read
n: -1,
want: 0,
wantErr: ErrNegativeCount,
wantBuffered: 0,
},
}
for _, tt := range tests {
br := NewReaderSize(tt.r, tt.bufSize)
if tt.peekSize > 0 {
peekBuf, err := br.Peek(tt.peekSize)
if err != nil {
t.Errorf("%s: Peek(%d): %v", tt.name, tt.peekSize, err)
continue
}
if len(peekBuf) != tt.peekSize {
t.Errorf("%s: len(Peek(%d)) = %v; want %v", tt.name, tt.peekSize, len(peekBuf), tt.peekSize)
continue
}
}
discarded, err := br.Discard(tt.n)
if ge, we := fmt.Sprint(err), fmt.Sprint(tt.wantErr); discarded != tt.want || ge != we {
t.Errorf("%s: Discard(%d) = (%v, %v); want (%v, %v)", tt.name, tt.n, discarded, ge, tt.want, we)
continue
}
if bn := br.Buffered(); bn != tt.wantBuffered {
t.Errorf("%s: after Discard, Buffered = %d; want %d", tt.name, bn, tt.wantBuffered)
}
}
}
// An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
type onlyReader struct {
io.Reader
@@ -1407,23 +1278,6 @@ type onlyWriter struct {
io.Writer
}
// A scriptedReader is an io.Reader that executes its steps sequentially.
type scriptedReader []func(p []byte) (n int, err error)
func (sr *scriptedReader) Read(p []byte) (n int, err error) {
if len(*sr) == 0 {
panic("too many Read calls on scripted Reader. No steps remain.")
}
step := (*sr)[0]
*sr = (*sr)[1:]
return step(p)
}
func newScriptedReader(steps ...func(p []byte) (n int, err error)) io.Reader {
sr := scriptedReader(steps)
return &sr
}
func BenchmarkReaderCopyOptimal(b *testing.B) {
// Optimal case is where the underlying reader implements io.WriterTo
srcBuf := bytes.NewBuffer(make([]byte, 8192))

View File

@@ -23,7 +23,7 @@ func equalPortable(a, b []byte) bool {
return true
}
// explode splits s into a slice of UTF-8 sequences, one per Unicode code point (still slices of bytes),
// explode splits s into a slice of UTF-8 sequences, one per Unicode character (still slices of bytes),
// up to a maximum of n byte slices. Invalid UTF-8 sequences are chopped into individual bytes.
func explode(s []byte, n int) [][]byte {
if n <= 0 {
@@ -47,7 +47,6 @@ func explode(s []byte, n int) [][]byte {
}
// Count counts the number of non-overlapping instances of sep in s.
// If sep is an empty slice, Count returns 1 + the number of Unicode code points in s.
func Count(s, sep []byte) int {
n := len(sep)
if n == 0 {

View File

@@ -21,4 +21,4 @@ func Equal(a, b []byte) bool // ../runtime/asm_$GOARCH.s
// 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 // ../runtime/noasm_arm.goc or ../runtime/asm_{386,amd64}.s

10
src/cmd/5a/Makefile Normal file
View File

@@ -0,0 +1,10 @@
# Copyright 2012 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
include ../../Make.dist
install: y.tab.h
y.tab.h: a.y
LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y

169
src/cmd/5a/a.h Normal file
View File

@@ -0,0 +1,169 @@
// Inferno utils/5a/a.h
// http://code.google.com/p/inferno-os/source/browse/utils/5a/a.h
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <bio.h>
#include <link.h>
#include "../5l/5.out.h"
#ifndef EXTERN
#define EXTERN extern
#endif
#undef getc
#undef ungetc
#undef BUFSIZ
#define getc ccgetc
#define ungetc ccungetc
typedef struct Sym Sym;
typedef struct Io Io;
#define MAXALIGN 7
#define FPCHIP 1
#define NSYMB 8192
#define BUFSIZ 8192
#define HISTSZ 20
#ifndef EOF
#define EOF (-1)
#endif
#define IGN (-2)
#define GETC() ((--fi.c < 0)? filbuf(): *fi.p++ & 0xff)
#define NHASH 503
#define STRINGSZ 200
#define NMACRO 10
struct Sym
{
Sym* link;
char* macro;
int32 value;
ushort type;
char *name;
char sym;
};
#define S ((Sym*)0)
EXTERN struct
{
char* p;
int c;
} fi;
struct Io
{
Io* link;
char b[BUFSIZ];
char* p;
short c;
short f;
};
#define I ((Io*)0)
enum
{
CLAST,
CMACARG,
CMACRO,
CPREPROC,
Always = 14,
};
EXTERN int debug[256];
EXTERN Sym* hash[NHASH];
EXTERN char** Dlist;
EXTERN int nDlist;
EXTERN int newflag;
EXTERN char* hunk;
EXTERN char** include;
EXTERN Io* iofree;
EXTERN Io* ionext;
EXTERN Io* iostack;
EXTERN int32 lineno;
EXTERN int nerrors;
EXTERN int32 nhunk;
EXTERN int ninclude;
EXTERN int32 nsymb;
EXTERN Addr nullgen;
EXTERN char* outfile;
EXTERN int pass;
EXTERN int32 pc;
EXTERN int peekc;
EXTERN int32 stmtline;
EXTERN int sym;
EXTERN char* symb;
EXTERN int thechar;
EXTERN char* thestring;
EXTERN int32 thunk;
EXTERN Biobuf obuf;
EXTERN Link* ctxt;
EXTERN Biobuf bstdout;
void* alloc(int32);
void* allocn(void*, int32, int32);
void ensuresymb(int32);
void errorexit(void);
void pushio(void);
void newio(void);
void newfile(char*, int);
Sym* slookup(char*);
Sym* lookup(void);
void syminit(Sym*);
int32 yylex(void);
int getc(void);
int getnsc(void);
void unget(int);
int escchar(int);
void cinit(void);
void pinit(char*);
void cclean(void);
int isreg(Addr*);
void outcode(int, int, Addr*, int, Addr*);
int filbuf(void);
Sym* getsym(void);
void domacro(void);
void macund(void);
void macdef(void);
void macexpand(Sym*, char*);
void macinc(void);
void maclin(void);
void macprag(void);
void macif(int);
void macend(void);
void dodefine(char*);
void prfile(int32);
void linehist(char*, int);
void gethunk(void);
void yyerror(char*, ...);
int yyparse(void);
void setinclude(char*);
int assemble(char*);
void listinit(void);

View File

@@ -29,23 +29,20 @@
// THE SOFTWARE.
%{
package main
import (
"cmd/internal/asm"
"cmd/internal/obj"
. "cmd/internal/obj/arm"
)
#include <u.h>
#include <stdio.h> /* if we don't, bison will, and a.h re-#defines getc */
#include <libc.h>
#include "a.h"
#include "../../runtime/funcdata.h"
%}
%union {
sym *asm.Sym
lval int32
dval float64
sval string
addr obj.Addr
%union
{
Sym *sym;
int32 lval;
double dval;
char sval[8];
Addr addr;
}
%left '|'
%left '^'
%left '&'
@@ -59,44 +56,46 @@ import (
%token <lval> LTYPEL LTYPEM LTYPEN LTYPEBX LTYPEPLD
%token <lval> LCONST LSP LSB LFP LPC
%token <lval> LTYPEX LTYPEPC LTYPEF LR LREG LF LFREG LC LCREG LPSR LFCR
%token <lval> LCOND LS LAT LGLOBL
%token <lval> LCOND LS LAT
%token <dval> LFCONST
%token <sval> LSCONST
%token <sym> LNAME LLAB LVAR
%type <lval> con expr oexpr pointer offset sreg spreg creg
%type <lval> rcon cond reglist
%type <addr> gen rel reg regreg freg shift fcon frcon textsize
%type <addr> gen rel reg regreg freg shift fcon frcon
%type <addr> imm ximm name oreg ireg nireg ioreg imsr
%%
prog:
| prog
{
stmtline = asm.Lineno;
stmtline = lineno;
}
line
line:
LNAME ':'
LLAB ':'
{
$1 = asm.LabelLookup($1);
if $1.Type == LLAB && $1.Value != int64(asm.PC) {
yyerror("redeclaration of %s", $1.Labelname)
}
$1.Type = LLAB;
$1.Value = int64(asm.PC)
if($1->value != pc)
yyerror("redeclaration of %s", $1->name);
$1->value = pc;
}
line
| LNAME ':'
{
$1->type = LLAB;
$1->value = pc;
}
line
| LNAME '=' expr ';'
{
$1.Type = LVAR;
$1.Value = int64($3);
$1->type = LVAR;
$1->value = $3;
}
| LVAR '=' expr ';'
{
if $1.Value != int64($3) {
yyerror("redeclaration of %s", $1.Name)
}
$1.Value = int64($3);
if($1->value != $3)
yyerror("redeclaration of %s", $1->name);
$1->value = $3;
}
| ';'
| inst ';'
@@ -116,53 +115,53 @@ inst:
}
| LTYPE1 cond imsr ',' reg
{
outcode($1, $2, &$3, 0, &$5);
outcode($1, $2, &$3, NREG, &$5);
}
/*
* MVN
*/
| LTYPE2 cond imsr ',' reg
{
outcode($1, $2, &$3, 0, &$5);
outcode($1, $2, &$3, NREG, &$5);
}
/*
* MOVW
*/
| LTYPE3 cond gen ',' gen
{
outcode($1, $2, &$3, 0, &$5);
outcode($1, $2, &$3, NREG, &$5);
}
/*
* B/BL
*/
| LTYPE4 cond comma rel
{
outcode($1, $2, &nullgen, 0, &$4);
outcode($1, $2, &nullgen, NREG, &$4);
}
| LTYPE4 cond comma nireg
{
outcode($1, $2, &nullgen, 0, &$4);
outcode($1, $2, &nullgen, NREG, &$4);
}
/*
* BX
*/
| LTYPEBX comma ireg
{
outcode($1, Always, &nullgen, 0, &$3);
outcode($1, Always, &nullgen, NREG, &$3);
}
/*
* BEQ
*/
| LTYPE5 comma rel
{
outcode($1, Always, &nullgen, 0, &$3);
outcode($1, Always, &nullgen, NREG, &$3);
}
/*
* SWI
*/
| LTYPE6 cond comma gen
{
outcode($1, $2, &nullgen, 0, &$4);
outcode($1, $2, &nullgen, NREG, &$4);
}
/*
* CMP
@@ -176,114 +175,96 @@ inst:
*/
| LTYPE8 cond ioreg ',' '[' reglist ']'
{
var g obj.Addr
Addr g;
g = nullgen;
g.Type = obj.TYPE_CONST;
g.Offset = int64($6);
outcode($1, $2, &$3, 0, &g);
g.type = D_CONST;
g.offset = $6;
outcode($1, $2, &$3, NREG, &g);
}
| LTYPE8 cond '[' reglist ']' ',' ioreg
{
var g obj.Addr
Addr g;
g = nullgen;
g.Type = obj.TYPE_CONST;
g.Offset = int64($4);
outcode($1, $2, &g, 0, &$7);
g.type = D_CONST;
g.offset = $4;
outcode($1, $2, &g, NREG, &$7);
}
/*
* SWAP
*/
| LTYPE9 cond reg ',' ireg ',' reg
{
outcode($1, $2, &$5, int32($3.Reg), &$7);
outcode($1, $2, &$5, $3.reg, &$7);
}
| LTYPE9 cond reg ',' ireg comma
{
outcode($1, $2, &$5, int32($3.Reg), &$3);
outcode($1, $2, &$5, $3.reg, &$3);
}
| LTYPE9 cond comma ireg ',' reg
{
outcode($1, $2, &$4, int32($6.Reg), &$6);
outcode($1, $2, &$4, $6.reg, &$6);
}
/*
* RET
*/
| LTYPEA cond comma
{
outcode($1, $2, &nullgen, 0, &nullgen);
outcode($1, $2, &nullgen, NREG, &nullgen);
}
/*
* TEXT
* TEXT/GLOBL
*/
| LTYPEB name ',' '$' textsize
| LTYPEB name ',' imm
{
asm.Settext($2.Sym);
outcode($1, Always, &$2, 0, &$5);
$4.type = D_CONST2;
$4.offset2 = ArgsSizeUnknown;
outcode($1, Always, &$2, 0, &$4);
}
| LTYPEB name ',' con ',' '$' textsize
| LTYPEB name ',' con ',' imm
{
asm.Settext($2.Sym);
outcode($1, Always, &$2, 0, &$7);
if asm.Pass > 1 {
lastpc.From3.Type = obj.TYPE_CONST;
lastpc.From3.Offset = int64($4)
}
$6.type = D_CONST2;
$6.offset2 = ArgsSizeUnknown;
outcode($1, Always, &$2, $4, &$6);
}
/*
* GLOBL
*/
| LGLOBL name ',' imm
| LTYPEB name ',' con ',' imm '-' con
{
asm.Settext($2.Sym)
outcode($1, Always, &$2, 0, &$4)
$6.type = D_CONST2;
$6.offset2 = $8;
outcode($1, Always, &$2, $4, &$6);
}
| LGLOBL name ',' con ',' imm
{
asm.Settext($2.Sym)
outcode($1, Always, &$2, 0, &$6)
if asm.Pass > 1 {
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = int64($4)
}
}
/*
* DATA
*/
| LTYPEC name '/' con ',' ximm
{
outcode($1, Always, &$2, 0, &$6)
if asm.Pass > 1 {
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = int64($4)
}
outcode($1, Always, &$2, $4, &$6);
}
/*
* CASE
*/
| LTYPED cond reg comma
{
outcode($1, $2, &$3, 0, &nullgen);
outcode($1, $2, &$3, NREG, &nullgen);
}
/*
* word
*/
| LTYPEH comma ximm
{
outcode($1, Always, &nullgen, 0, &$3);
outcode($1, Always, &nullgen, NREG, &$3);
}
/*
* floating-point coprocessor
*/
| LTYPEI cond freg ',' freg
{
outcode($1, $2, &$3, 0, &$5);
outcode($1, $2, &$3, NREG, &$5);
}
| LTYPEK cond frcon ',' freg
{
outcode($1, $2, &$3, 0, &$5);
outcode($1, $2, &$3, NREG, &$5);
}
| LTYPEK cond frcon ',' LFREG ',' freg
{
@@ -291,113 +272,80 @@ inst:
}
| LTYPEL cond freg ',' freg comma
{
outcode($1, $2, &$3, int32($5.Reg), &nullgen);
outcode($1, $2, &$3, $5.reg, &nullgen);
}
/*
* MCR MRC
*/
| LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
{
var g obj.Addr
Addr g;
g = nullgen;
g.Type = obj.TYPE_CONST;
g.Offset = int64(
g.type = D_CONST;
g.offset =
(0xe << 24) | /* opcode */
($1 << 20) | /* MCR/MRC */
(($2^C_SCOND_XOR) << 28) | /* scond */
($2 << 28) | /* scond */
(($3 & 15) << 8) | /* coprocessor number */
(($5 & 7) << 21) | /* coprocessor operation */
(($7 & 15) << 12) | /* arm register */
(($9 & 15) << 16) | /* Crn */
(($11 & 15) << 0) | /* Crm */
(($12 & 7) << 5) | /* coprocessor information */
(1<<4)); /* must be set */
outcode(AMRC, Always, &nullgen, 0, &g);
(1<<4); /* must be set */
outcode(AMRC, Always, &nullgen, NREG, &g);
}
/*
* MULL r1,r2,(hi,lo)
*/
| LTYPEM cond reg ',' reg ',' regreg
{
outcode($1, $2, &$3, int32($5.Reg), &$7);
outcode($1, $2, &$3, $5.reg, &$7);
}
/*
* MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff . r4
* MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff -> r4
* MULAW{T,B} r1,r2,r3,r4
*/
| LTYPEN cond reg ',' reg ',' reg ',' spreg
{
$7.Type = obj.TYPE_REGREG2;
$7.Offset = int64($9);
outcode($1, $2, &$3, int32($5.Reg), &$7);
$7.type = D_REGREG2;
$7.offset = $9;
outcode($1, $2, &$3, $5.reg, &$7);
}
/*
* PLD
*/
| LTYPEPLD oreg
{
outcode($1, Always, &$2, 0, &nullgen);
outcode($1, Always, &$2, NREG, &nullgen);
}
/*
* PCDATA
*/
| LTYPEPC gen ',' gen
{
if $2.Type != obj.TYPE_CONST || $4.Type != obj.TYPE_CONST {
yyerror("arguments to PCDATA must be integer constants")
}
outcode($1, Always, &$2, 0, &$4);
if($2.type != D_CONST || $4.type != D_CONST)
yyerror("arguments to PCDATA must be integer constants");
outcode($1, Always, &$2, NREG, &$4);
}
/*
* FUNCDATA
*/
| LTYPEF gen ',' gen
{
if $2.Type != obj.TYPE_CONST {
yyerror("index for FUNCDATA must be integer constant")
}
if $4.Type != obj.NAME_EXTERN && $4.Type != obj.NAME_STATIC && $4.Type != obj.TYPE_MEM {
yyerror("value for FUNCDATA must be symbol reference")
}
outcode($1, Always, &$2, 0, &$4);
if($2.type != D_CONST)
yyerror("index for FUNCDATA must be integer constant");
if($4.type != D_EXTERN && $4.type != D_STATIC && $4.type != D_OREG)
yyerror("value for FUNCDATA must be symbol reference");
outcode($1, Always, &$2, NREG, &$4);
}
/*
* END
*/
| LTYPEE comma
{
outcode($1, Always, &nullgen, 0, &nullgen);
}
textsize:
LCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = int64($1)
$$.U.Argsize = obj.ArgsSizeUnknown;
}
| '-' LCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = -int64($2)
$$.U.Argsize = obj.ArgsSizeUnknown;
}
| LCONST '-' LCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = int64($1)
$$.U.Argsize = int32($3);
}
| '-' LCONST '-' LCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = -int64($2)
$$.U.Argsize = int32($4);
outcode($1, Always, &nullgen, NREG, &nullgen);
}
cond:
@@ -406,7 +354,7 @@ cond:
}
| cond LCOND
{
$$ = ($1 & ^ C_SCOND) | $2;
$$ = ($1 & ~C_SCOND) | $2;
}
| cond LS
{
@@ -420,36 +368,45 @@ rel:
con '(' LPC ')'
{
$$ = nullgen;
$$.Type = obj.TYPE_BRANCH;
$$.Offset = int64($1) + int64(asm.PC);
$$.type = D_BRANCH;
$$.offset = $1 + pc;
}
| LNAME offset
{
$1 = asm.LabelLookup($1);
$$ = nullgen;
if asm.Pass == 2 && $1.Type != LLAB {
yyerror("undefined label: %s", $1.Labelname)
}
$$.Type = obj.TYPE_BRANCH;
$$.Offset = $1.Value + int64($2);
if(pass == 2)
yyerror("undefined label: %s", $1->name);
$$.type = D_BRANCH;
$$.offset = $2;
}
| LLAB offset
{
$$ = nullgen;
$$.type = D_BRANCH;
$$.offset = $1->value + $2;
}
ximm: '$' con
{
$$ = nullgen;
$$.Type = obj.TYPE_CONST;
$$.Offset = int64($2);
$$.type = D_CONST;
$$.offset = $2;
}
| '$' oreg
{
$$ = $2;
$$.Type = obj.TYPE_ADDR;
$$.type = D_CONST;
}
| '$' '*' '$' oreg
{
$$ = $4;
$$.type = D_OCONST;
}
| '$' LSCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_SCONST;
$$.U.Sval = $2
$$.type = D_SCONST;
memcpy($$.u.sval, $2, sizeof($$.u.sval));
}
| fcon
@@ -457,34 +414,33 @@ fcon:
'$' LFCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_FCONST;
$$.U.Dval = $2;
$$.type = D_FCONST;
$$.u.dval = $2;
}
| '$' '-' LFCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_FCONST;
$$.U.Dval = -$3;
$$.type = D_FCONST;
$$.u.dval = -$3;
}
reglist:
spreg
{
$$ = 1 << uint($1&15);
$$ = 1 << $1;
}
| spreg '-' spreg
{
int i;
$$=0;
for i:=$1; i<=$3; i++ {
$$ |= 1<<uint(i&15)
}
for i:=$3; i<=$1; i++ {
$$ |= 1<<uint(i&15)
}
for(i=$1; i<=$3; i++)
$$ |= 1<<i;
for(i=$3; i<=$1; i++)
$$ |= 1<<i;
}
| spreg comma reglist
{
$$ = (1<<uint($1&15)) | $3;
$$ = (1<<$1) | $3;
}
gen:
@@ -494,25 +450,25 @@ gen:
| shift '(' spreg ')'
{
$$ = $1;
$$.Reg = int16($3);
$$.reg = $3;
}
| LPSR
{
$$ = nullgen;
$$.Type = obj.TYPE_REG
$$.Reg = int16($1);
$$.type = D_PSR;
$$.reg = $1;
}
| LFCR
{
$$ = nullgen;
$$.Type = obj.TYPE_REG
$$.Reg = int16($1);
$$.type = D_FPCR;
$$.reg = $1;
}
| con
{
$$ = nullgen;
$$.Type = obj.TYPE_MEM;
$$.Offset = int64($1);
$$.type = D_OREG;
$$.offset = $1;
}
| oreg
| freg
@@ -522,7 +478,7 @@ nireg:
| name
{
$$ = $1;
if($1.Name != obj.NAME_EXTERN && $1.Name != obj.NAME_STATIC) {
if($1.name != D_EXTERN && $1.name != D_STATIC) {
}
}
@@ -530,9 +486,9 @@ ireg:
'(' spreg ')'
{
$$ = nullgen;
$$.Type = obj.TYPE_MEM;
$$.Reg = int16($2);
$$.Offset = 0;
$$.type = D_OREG;
$$.reg = $2;
$$.offset = 0;
}
ioreg:
@@ -540,9 +496,9 @@ ioreg:
| con '(' sreg ')'
{
$$ = nullgen;
$$.Type = obj.TYPE_MEM;
$$.Reg = int16($3);
$$.Offset = int64($1);
$$.type = D_OREG;
$$.reg = $3;
$$.offset = $1;
}
oreg:
@@ -550,8 +506,8 @@ oreg:
| name '(' sreg ')'
{
$$ = $1;
$$.Type = obj.TYPE_MEM;
$$.Reg = int16($3);
$$.type = D_OREG;
$$.reg = $3;
}
| ioreg
@@ -563,66 +519,64 @@ imsr:
imm: '$' con
{
$$ = nullgen;
$$.Type = obj.TYPE_CONST;
$$.Offset = int64($2);
$$.type = D_CONST;
$$.offset = $2;
}
reg:
spreg
{
$$ = nullgen;
$$.Type = obj.TYPE_REG;
$$.Reg = int16($1);
$$.type = D_REG;
$$.reg = $1;
}
regreg:
'(' spreg ',' spreg ')'
{
$$ = nullgen;
$$.Type = obj.TYPE_REGREG;
$$.Reg = int16($2);
$$.Offset = int64($4);
$$.type = D_REGREG;
$$.reg = $2;
$$.offset = $4;
}
shift:
spreg '<' '<' rcon
{
$$ = nullgen;
$$.Type = obj.TYPE_SHIFT;
$$.Offset = int64($1&15) | int64($4) | (0 << 5);
$$.type = D_SHIFT;
$$.offset = $1 | $4 | (0 << 5);
}
| spreg '>' '>' rcon
{
$$ = nullgen;
$$.Type = obj.TYPE_SHIFT;
$$.Offset = int64($1&15) | int64($4) | (1 << 5);
$$.type = D_SHIFT;
$$.offset = $1 | $4 | (1 << 5);
}
| spreg '-' '>' rcon
{
$$ = nullgen;
$$.Type = obj.TYPE_SHIFT;
$$.Offset = int64($1&15) | int64($4) | (2 << 5);
$$.type = D_SHIFT;
$$.offset = $1 | $4 | (2 << 5);
}
| spreg LAT '>' rcon
{
$$ = nullgen;
$$.Type = obj.TYPE_SHIFT;
$$.Offset = int64($1&15) | int64($4) | (3 << 5);
$$.type = D_SHIFT;
$$.offset = $1 | $4 | (3 << 5);
}
rcon:
spreg
{
if $$ < REG_R0 || $$ > REG_R15 {
print("register value out of range\n")
}
if($$ < 0 || $$ >= 16)
print("register value out of range\n");
$$ = (($1&15) << 8) | (1 << 4);
}
| con
{
if $$ < 0 || $$ >= 32 {
print("shift value out of range\n")
}
if($$ < 0 || $$ >= 32)
print("shift value out of range\n");
$$ = ($1&31) << 7;
}
@@ -634,10 +588,9 @@ sreg:
}
| LR '(' expr ')'
{
if $3 < 0 || $3 >= NREG {
print("register value out of range\n")
}
$$ = REG_R0 + $3;
if($3 < 0 || $3 >= NREG)
print("register value out of range\n");
$$ = $3;
}
spreg:
@@ -651,10 +604,9 @@ creg:
LCREG
| LC '(' expr ')'
{
if $3 < 0 || $3 >= NREG {
print("register value out of range\n")
}
$$ = $3; // TODO(rsc): REG_C0+$3
if($3 < 0 || $3 >= NREG)
print("register value out of range\n");
$$ = $3;
}
frcon:
@@ -665,40 +617,40 @@ freg:
LFREG
{
$$ = nullgen;
$$.Type = obj.TYPE_REG;
$$.Reg = int16($1);
$$.type = D_FREG;
$$.reg = $1;
}
| LF '(' con ')'
{
$$ = nullgen;
$$.Type = obj.TYPE_REG;
$$.Reg = int16(REG_F0 + $3);
$$.type = D_FREG;
$$.reg = $3;
}
name:
con '(' pointer ')'
{
$$ = nullgen;
$$.Type = obj.TYPE_MEM;
$$.Name = int8($3);
$$.Sym = nil;
$$.Offset = int64($1);
$$.type = D_OREG;
$$.name = $3;
$$.sym = nil;
$$.offset = $1;
}
| LNAME offset '(' pointer ')'
{
$$ = nullgen;
$$.Type = obj.TYPE_MEM;
$$.Name = int8($4);
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
$$.Offset = int64($2);
$$.type = D_OREG;
$$.name = $4;
$$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2;
}
| LNAME '<' '>' offset '(' LSB ')'
{
$$ = nullgen;
$$.Type = obj.TYPE_MEM;
$$.Name = obj.NAME_STATIC;
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
$$.Offset = int64($4);
$$.type = D_OREG;
$$.name = D_STATIC;
$$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4;
}
offset:
@@ -723,7 +675,7 @@ con:
LCONST
| LVAR
{
$$ = int32($1.Value);
$$ = $1->value;
}
| '-' con
{
@@ -735,7 +687,7 @@ con:
}
| '~' con
{
$$ = ^$2;
$$ = ~$2;
}
| '(' expr ')'
{
@@ -775,11 +727,11 @@ expr:
}
| expr '<' '<' expr
{
$$ = $1 << uint($4);
$$ = $1 << $4;
}
| expr '>' '>' expr
{
$$ = $1 >> uint($4);
$$ = $1 >> $4;
}
| expr '&' expr
{

20
src/cmd/5a/doc.go Normal file
View File

@@ -0,0 +1,20 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
/*
5a is a version of the Plan 9 assembler. The original is documented at
http://plan9.bell-labs.com/magic/man2html/1/8a
Go-specific considerations are documented at
http://golang.org/doc/asm
Its target architecture is the ARM, referred to by these tools as arm.
*/
package main

538
src/cmd/5a/lex.c Normal file
View File

@@ -0,0 +1,538 @@
// Inferno utils/5a/lex.c
// http://code.google.com/p/inferno-os/source/browse/utils/5a/lex.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#define EXTERN
#include <u.h>
#include <libc.h>
#include "a.h"
#include "y.tab.h"
enum
{
Plan9 = 1<<0,
Unix = 1<<1,
Windows = 1<<2,
};
int
systemtype(int sys)
{
#ifdef _WIN32
return sys&Windows;
#else
return sys&Plan9;
#endif
}
int
Lconv(Fmt *fp)
{
return linklinefmt(ctxt, fp);
}
void
dodef(char *p)
{
if(nDlist%8 == 0)
Dlist = allocn(Dlist, nDlist*sizeof(char *),
8*sizeof(char *));
Dlist[nDlist++] = p;
}
void
usage(void)
{
print("usage: %ca [options] file.c...\n", thechar);
flagprint(1);
errorexit();
}
void
main(int argc, char *argv[])
{
char *p;
thechar = '5';
thestring = "arm";
ctxt = linknew(&linkarm);
ctxt->diag = yyerror;
ctxt->bso = &bstdout;
ctxt->enforce_data_order = 1;
Binit(&bstdout, 1, OWRITE);
listinit5();
fmtinstall('L', Lconv);
// Allow GOARCH=thestring or GOARCH=thestringsuffix,
// but not other values.
p = getgoarch();
if(strncmp(p, thestring, strlen(thestring)) != 0)
sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
cinit();
outfile = 0;
setinclude(".");
flagfn1("D", "name[=value]: add #define", dodef);
flagfn1("I", "dir: add dir to include path", setinclude);
flagcount("S", "print assembly and machine code", &debug['S']);
flagcount("m", "debug preprocessor macros", &debug['m']);
flagstr("o", "file: set output file", &outfile);
flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
flagparse(&argc, &argv, usage);
ctxt->debugasm = debug['S'];
if(argc < 1)
usage();
if(argc > 1){
print("can't assemble multiple files\n");
errorexit();
}
if(assemble(argv[0]))
errorexit();
Bflush(&bstdout);
exits(0);
}
int
assemble(char *file)
{
char *ofile, *p;
int i, of;
ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
strcpy(ofile, file);
p = utfrrune(ofile, '/');
if(p) {
include[0] = ofile;
*p++ = 0;
} else
p = ofile;
if(outfile == 0) {
outfile = p;
if(outfile){
p = utfrrune(outfile, '.');
if(p)
if(p[1] == 's' && p[2] == 0)
p[0] = 0;
p = utfrune(outfile, 0);
p[0] = '.';
p[1] = thechar;
p[2] = 0;
} else
outfile = "/dev/null";
}
of = create(outfile, OWRITE, 0664);
if(of < 0) {
yyerror("%ca: cannot create %s", thechar, outfile);
errorexit();
}
Binit(&obuf, of, OWRITE);
Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
Bprint(&obuf, "!\n");
for(pass = 1; pass <= 2; pass++) {
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
if(nerrors)
return nerrors;
}
writeobj(ctxt, &obuf);
Bflush(&obuf);
return 0;
}
struct
{
char *name;
ushort type;
ushort value;
} itab[] =
{
"SP", LSP, D_AUTO,
"SB", LSB, D_EXTERN,
"FP", LFP, D_PARAM,
"PC", LPC, D_BRANCH,
"R", LR, 0,
"R0", LREG, 0,
"R1", LREG, 1,
"R2", LREG, 2,
"R3", LREG, 3,
"R4", LREG, 4,
"R5", LREG, 5,
"R6", LREG, 6,
"R7", LREG, 7,
"R8", LREG, 8,
"R9", LREG, 9,
"g", LREG, 10, // avoid unintentionally clobber g using R10
"R11", LREG, 11,
"R12", LREG, 12,
"R13", LREG, 13,
"R14", LREG, 14,
"R15", LREG, 15,
"F", LF, 0,
"F0", LFREG, 0,
"F1", LFREG, 1,
"F2", LFREG, 2,
"F3", LFREG, 3,
"F4", LFREG, 4,
"F5", LFREG, 5,
"F6", LFREG, 6,
"F7", LFREG, 7,
"F8", LFREG, 8,
"F9", LFREG, 9,
"F10", LFREG, 10,
"F11", LFREG, 11,
"F12", LFREG, 12,
"F13", LFREG, 13,
"F14", LFREG, 14,
"F15", LFREG, 15,
"C", LC, 0,
"C0", LCREG, 0,
"C1", LCREG, 1,
"C2", LCREG, 2,
"C3", LCREG, 3,
"C4", LCREG, 4,
"C5", LCREG, 5,
"C6", LCREG, 6,
"C7", LCREG, 7,
"C8", LCREG, 8,
"C9", LCREG, 9,
"C10", LCREG, 10,
"C11", LCREG, 11,
"C12", LCREG, 12,
"C13", LCREG, 13,
"C14", LCREG, 14,
"C15", LCREG, 15,
"CPSR", LPSR, 0,
"SPSR", LPSR, 1,
"FPSR", LFCR, 0,
"FPCR", LFCR, 1,
".EQ", LCOND, 0,
".NE", LCOND, 1,
".CS", LCOND, 2,
".HS", LCOND, 2,
".CC", LCOND, 3,
".LO", LCOND, 3,
".MI", LCOND, 4,
".PL", LCOND, 5,
".VS", LCOND, 6,
".VC", LCOND, 7,
".HI", LCOND, 8,
".LS", LCOND, 9,
".GE", LCOND, 10,
".LT", LCOND, 11,
".GT", LCOND, 12,
".LE", LCOND, 13,
".AL", LCOND, Always,
".U", LS, C_UBIT,
".S", LS, C_SBIT,
".W", LS, C_WBIT,
".P", LS, C_PBIT,
".PW", LS, C_WBIT|C_PBIT,
".WP", LS, C_WBIT|C_PBIT,
".F", LS, C_FBIT,
".IBW", LS, C_WBIT|C_PBIT|C_UBIT,
".IAW", LS, C_WBIT|C_UBIT,
".DBW", LS, C_WBIT|C_PBIT,
".DAW", LS, C_WBIT,
".IB", LS, C_PBIT|C_UBIT,
".IA", LS, C_UBIT,
".DB", LS, C_PBIT,
".DA", LS, 0,
"@", LAT, 0,
"AND", LTYPE1, AAND,
"EOR", LTYPE1, AEOR,
"SUB", LTYPE1, ASUB,
"RSB", LTYPE1, ARSB,
"ADD", LTYPE1, AADD,
"ADC", LTYPE1, AADC,
"SBC", LTYPE1, ASBC,
"RSC", LTYPE1, ARSC,
"ORR", LTYPE1, AORR,
"BIC", LTYPE1, ABIC,
"SLL", LTYPE1, ASLL,
"SRL", LTYPE1, ASRL,
"SRA", LTYPE1, ASRA,
"MUL", LTYPE1, AMUL,
"MULA", LTYPEN, AMULA,
"DIV", LTYPE1, ADIV,
"MOD", LTYPE1, AMOD,
"MULL", LTYPEM, AMULL,
"MULAL", LTYPEM, AMULAL,
"MULLU", LTYPEM, AMULLU,
"MULALU", LTYPEM, AMULALU,
"MVN", LTYPE2, AMVN, /* op2 ignored */
"MOVB", LTYPE3, AMOVB,
"MOVBU", LTYPE3, AMOVBU,
"MOVH", LTYPE3, AMOVH,
"MOVHU", LTYPE3, AMOVHU,
"MOVW", LTYPE3, AMOVW,
"MOVD", LTYPE3, AMOVD,
"MOVDF", LTYPE3, AMOVDF,
"MOVDW", LTYPE3, AMOVDW,
"MOVF", LTYPE3, AMOVF,
"MOVFD", LTYPE3, AMOVFD,
"MOVFW", LTYPE3, AMOVFW,
"MOVWD", LTYPE3, AMOVWD,
"MOVWF", LTYPE3, AMOVWF,
"LDREX", LTYPE3, ALDREX,
"LDREXD", LTYPE3, ALDREXD,
"STREX", LTYPE9, ASTREX,
"STREXD", LTYPE9, ASTREXD,
/*
"NEGF", LTYPEI, ANEGF,
"NEGD", LTYPEI, ANEGD,
"SQTF", LTYPEI, ASQTF,
"SQTD", LTYPEI, ASQTD,
"RNDF", LTYPEI, ARNDF,
"RNDD", LTYPEI, ARNDD,
"URDF", LTYPEI, AURDF,
"URDD", LTYPEI, AURDD,
"NRMF", LTYPEI, ANRMF,
"NRMD", LTYPEI, ANRMD,
*/
"ABSF", LTYPEI, AABSF,
"ABSD", LTYPEI, AABSD,
"SQRTF", LTYPEI, ASQRTF,
"SQRTD", LTYPEI, ASQRTD,
"CMPF", LTYPEL, ACMPF,
"CMPD", LTYPEL, ACMPD,
"ADDF", LTYPEK, AADDF,
"ADDD", LTYPEK, AADDD,
"SUBF", LTYPEK, ASUBF,
"SUBD", LTYPEK, ASUBD,
"MULF", LTYPEK, AMULF,
"MULD", LTYPEK, AMULD,
"DIVF", LTYPEK, ADIVF,
"DIVD", LTYPEK, ADIVD,
"B", LTYPE4, AB,
"BL", LTYPE4, ABL,
"BX", LTYPEBX, ABX,
"BEQ", LTYPE5, ABEQ,
"BNE", LTYPE5, ABNE,
"BCS", LTYPE5, ABCS,
"BHS", LTYPE5, ABHS,
"BCC", LTYPE5, ABCC,
"BLO", LTYPE5, ABLO,
"BMI", LTYPE5, ABMI,
"BPL", LTYPE5, ABPL,
"BVS", LTYPE5, ABVS,
"BVC", LTYPE5, ABVC,
"BHI", LTYPE5, ABHI,
"BLS", LTYPE5, ABLS,
"BGE", LTYPE5, ABGE,
"BLT", LTYPE5, ABLT,
"BGT", LTYPE5, ABGT,
"BLE", LTYPE5, ABLE,
"BCASE", LTYPE5, ABCASE,
"SWI", LTYPE6, ASWI,
"CMP", LTYPE7, ACMP,
"TST", LTYPE7, ATST,
"TEQ", LTYPE7, ATEQ,
"CMN", LTYPE7, ACMN,
"MOVM", LTYPE8, AMOVM,
"SWPBU", LTYPE9, ASWPBU,
"SWPW", LTYPE9, ASWPW,
"RET", LTYPEA, ARET,
"RFE", LTYPEA, ARFE,
"TEXT", LTYPEB, ATEXT,
"GLOBL", LTYPEB, AGLOBL,
"DATA", LTYPEC, ADATA,
"CASE", LTYPED, ACASE,
"END", LTYPEE, AEND,
"WORD", LTYPEH, AWORD,
"NOP", LTYPEI, ANOP,
"MCR", LTYPEJ, 0,
"MRC", LTYPEJ, 1,
"PLD", LTYPEPLD, APLD,
"UNDEF", LTYPEE, AUNDEF,
"CLZ", LTYPE2, ACLZ,
"MULWT", LTYPE1, AMULWT,
"MULWB", LTYPE1, AMULWB,
"MULAWT", LTYPEN, AMULAWT,
"MULAWB", LTYPEN, AMULAWB,
"USEFIELD", LTYPEN, AUSEFIELD,
"PCDATA", LTYPEPC, APCDATA,
"FUNCDATA", LTYPEF, AFUNCDATA,
0
};
void
cinit(void)
{
Sym *s;
int i;
nullgen.type = D_NONE;
nullgen.name = D_NONE;
nullgen.reg = NREG;
nerrors = 0;
iostack = I;
iofree = I;
peekc = IGN;
nhunk = 0;
for(i=0; i<NHASH; i++)
hash[i] = S;
for(i=0; itab[i].name; i++) {
s = slookup(itab[i].name);
s->type = itab[i].type;
s->value = itab[i].value;
}
}
void
syminit(Sym *s)
{
s->type = LNAME;
s->value = 0;
}
int
isreg(Addr *g)
{
USED(g);
return 1;
}
void
cclean(void)
{
outcode(AEND, Always, &nullgen, NREG, &nullgen);
}
static int bcode[] =
{
ABEQ,
ABNE,
ABCS,
ABCC,
ABMI,
ABPL,
ABVS,
ABVC,
ABHI,
ABLS,
ABGE,
ABLT,
ABGT,
ABLE,
AB,
ANOP,
};
static Prog *lastpc;
void
outcode(int a, int scond, Addr *g1, int reg, Addr *g2)
{
Prog *p;
Plist *pl;
/* hack to make B.NE etc. work: turn it into the corresponding conditional */
if(a == AB){
a = bcode[scond&0xf];
scond = (scond & ~0xf) | Always;
}
if(pass == 1)
goto out;
p = malloc(sizeof *p);
memset(p, 0, sizeof *p);
p->as = a;
p->lineno = stmtline;
p->scond = scond;
p->from = *g1;
p->reg = reg;
p->to = *g2;
p->pc = pc;
if(lastpc == nil) {
pl = linknewplist(ctxt);
pl->firstpc = p;
} else
lastpc->link = p;
lastpc = p;
out:
if(a != AGLOBL && a != ADATA)
pc++;
}
#include "../cc/lexbody"
#include "../cc/macbody"

View File

@@ -1,371 +0,0 @@
// Inferno utils/5a/lex.c
// http://code.google.com/p/inferno-os/source/browse/utils/5a/lex.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//go:generate go tool yacc a.y
package main
import (
"cmd/internal/asm"
"cmd/internal/obj"
"cmd/internal/obj/arm"
)
var (
yyerror = asm.Yyerror
nullgen obj.Addr
stmtline int32
)
const Always = arm.C_SCOND_NONE
func main() {
cinit()
asm.LSCONST = LSCONST
asm.LCONST = LCONST
asm.LFCONST = LFCONST
asm.LNAME = LNAME
asm.LVAR = LVAR
asm.LLAB = LLAB
asm.Lexinit = lexinit
asm.Cclean = cclean
asm.Yyparse = yyparse
asm.Thechar = '5'
asm.Thestring = "arm"
asm.Thelinkarch = &arm.Linkarm
asm.Main()
}
type yy struct{}
func (yy) Lex(v *yySymType) int {
var av asm.Yylval
tok := asm.Yylex(&av)
v.sym = av.Sym
v.lval = int32(av.Lval)
v.sval = av.Sval
v.dval = av.Dval
return tok
}
func (yy) Error(msg string) {
asm.Yyerror("%s", msg)
}
func yyparse() {
yyParse(yy{})
}
var lexinit = []asm.Lextab{
{"SP", LSP, obj.NAME_AUTO},
{"SB", LSB, obj.NAME_EXTERN},
{"FP", LFP, obj.NAME_PARAM},
{"PC", LPC, obj.TYPE_BRANCH},
{"R", LR, 0},
{"R0", LREG, arm.REG_R0},
{"R1", LREG, arm.REG_R1},
{"R2", LREG, arm.REG_R2},
{"R3", LREG, arm.REG_R3},
{"R4", LREG, arm.REG_R4},
{"R5", LREG, arm.REG_R5},
{"R6", LREG, arm.REG_R6},
{"R7", LREG, arm.REG_R7},
{"R8", LREG, arm.REG_R8},
{"R9", LREG, arm.REG_R9},
{"g", LREG, arm.REG_R10}, // avoid unintentionally clobber g using R10
{"R11", LREG, arm.REG_R11},
{"R12", LREG, arm.REG_R12},
{"R13", LREG, arm.REG_R13},
{"R14", LREG, arm.REG_R14},
{"R15", LREG, arm.REG_R15},
{"F", LF, 0},
{"F0", LFREG, arm.REG_F0},
{"F1", LFREG, arm.REG_F1},
{"F2", LFREG, arm.REG_F2},
{"F3", LFREG, arm.REG_F3},
{"F4", LFREG, arm.REG_F4},
{"F5", LFREG, arm.REG_F5},
{"F6", LFREG, arm.REG_F6},
{"F7", LFREG, arm.REG_F7},
{"F8", LFREG, arm.REG_F8},
{"F9", LFREG, arm.REG_F9},
{"F10", LFREG, arm.REG_F10},
{"F11", LFREG, arm.REG_F11},
{"F12", LFREG, arm.REG_F12},
{"F13", LFREG, arm.REG_F13},
{"F14", LFREG, arm.REG_F14},
{"F15", LFREG, arm.REG_F15},
{"C", LC, 0},
{"C0", LCREG, 0},
{"C1", LCREG, 1},
{"C2", LCREG, 2},
{"C3", LCREG, 3},
{"C4", LCREG, 4},
{"C5", LCREG, 5},
{"C6", LCREG, 6},
{"C7", LCREG, 7},
{"C8", LCREG, 8},
{"C9", LCREG, 9},
{"C10", LCREG, 10},
{"C11", LCREG, 11},
{"C12", LCREG, 12},
{"C13", LCREG, 13},
{"C14", LCREG, 14},
{"C15", LCREG, 15},
{"CPSR", LPSR, arm.REG_CPSR},
{"SPSR", LPSR, arm.REG_SPSR},
{"FPSR", LFCR, arm.REG_FPSR},
{"FPCR", LFCR, arm.REG_FPCR},
{".EQ", LCOND, arm.C_SCOND_EQ},
{".NE", LCOND, arm.C_SCOND_NE},
{".CS", LCOND, arm.C_SCOND_HS},
{".HS", LCOND, arm.C_SCOND_HS},
{".CC", LCOND, arm.C_SCOND_LO},
{".LO", LCOND, arm.C_SCOND_LO},
{".MI", LCOND, arm.C_SCOND_MI},
{".PL", LCOND, arm.C_SCOND_PL},
{".VS", LCOND, arm.C_SCOND_VS},
{".VC", LCOND, arm.C_SCOND_VC},
{".HI", LCOND, arm.C_SCOND_HI},
{".LS", LCOND, arm.C_SCOND_LS},
{".GE", LCOND, arm.C_SCOND_GE},
{".LT", LCOND, arm.C_SCOND_LT},
{".GT", LCOND, arm.C_SCOND_GT},
{".LE", LCOND, arm.C_SCOND_LE},
{".AL", LCOND, arm.C_SCOND_NONE},
{".U", LS, arm.C_UBIT},
{".S", LS, arm.C_SBIT},
{".W", LS, arm.C_WBIT},
{".P", LS, arm.C_PBIT},
{".PW", LS, arm.C_WBIT | arm.C_PBIT},
{".WP", LS, arm.C_WBIT | arm.C_PBIT},
{".F", LS, arm.C_FBIT},
{".IBW", LS, arm.C_WBIT | arm.C_PBIT | arm.C_UBIT},
{".IAW", LS, arm.C_WBIT | arm.C_UBIT},
{".DBW", LS, arm.C_WBIT | arm.C_PBIT},
{".DAW", LS, arm.C_WBIT},
{".IB", LS, arm.C_PBIT | arm.C_UBIT},
{".IA", LS, arm.C_UBIT},
{".DB", LS, arm.C_PBIT},
{".DA", LS, 0},
{"@", LAT, 0},
{"AND", LTYPE1, arm.AAND},
{"EOR", LTYPE1, arm.AEOR},
{"SUB", LTYPE1, arm.ASUB},
{"RSB", LTYPE1, arm.ARSB},
{"ADD", LTYPE1, arm.AADD},
{"ADC", LTYPE1, arm.AADC},
{"SBC", LTYPE1, arm.ASBC},
{"RSC", LTYPE1, arm.ARSC},
{"ORR", LTYPE1, arm.AORR},
{"BIC", LTYPE1, arm.ABIC},
{"SLL", LTYPE1, arm.ASLL},
{"SRL", LTYPE1, arm.ASRL},
{"SRA", LTYPE1, arm.ASRA},
{"MUL", LTYPE1, arm.AMUL},
{"MULA", LTYPEN, arm.AMULA},
{"DIV", LTYPE1, arm.ADIV},
{"MOD", LTYPE1, arm.AMOD},
{"MULL", LTYPEM, arm.AMULL},
{"MULAL", LTYPEM, arm.AMULAL},
{"MULLU", LTYPEM, arm.AMULLU},
{"MULALU", LTYPEM, arm.AMULALU},
{"MVN", LTYPE2, arm.AMVN}, /* op2 ignored */
{"MOVB", LTYPE3, arm.AMOVB},
{"MOVBU", LTYPE3, arm.AMOVBU},
{"MOVH", LTYPE3, arm.AMOVH},
{"MOVHU", LTYPE3, arm.AMOVHU},
{"MOVW", LTYPE3, arm.AMOVW},
{"MOVD", LTYPE3, arm.AMOVD},
{"MOVDF", LTYPE3, arm.AMOVDF},
{"MOVDW", LTYPE3, arm.AMOVDW},
{"MOVF", LTYPE3, arm.AMOVF},
{"MOVFD", LTYPE3, arm.AMOVFD},
{"MOVFW", LTYPE3, arm.AMOVFW},
{"MOVWD", LTYPE3, arm.AMOVWD},
{"MOVWF", LTYPE3, arm.AMOVWF},
{"LDREX", LTYPE3, arm.ALDREX},
{"LDREXD", LTYPE3, arm.ALDREXD},
{"STREX", LTYPE9, arm.ASTREX},
{"STREXD", LTYPE9, arm.ASTREXD},
/*
{"NEGF", LTYPEI, ANEGF},
{"NEGD", LTYPEI, ANEGD},
{"SQTF", LTYPEI, ASQTF},
{"SQTD", LTYPEI, ASQTD},
{"RNDF", LTYPEI, ARNDF},
{"RNDD", LTYPEI, ARNDD},
{"URDF", LTYPEI, AURDF},
{"URDD", LTYPEI, AURDD},
{"NRMF", LTYPEI, ANRMF},
{"NRMD", LTYPEI, ANRMD},
*/
{"ABSF", LTYPEI, arm.AABSF},
{"ABSD", LTYPEI, arm.AABSD},
{"SQRTF", LTYPEI, arm.ASQRTF},
{"SQRTD", LTYPEI, arm.ASQRTD},
{"CMPF", LTYPEL, arm.ACMPF},
{"CMPD", LTYPEL, arm.ACMPD},
{"ADDF", LTYPEK, arm.AADDF},
{"ADDD", LTYPEK, arm.AADDD},
{"SUBF", LTYPEK, arm.ASUBF},
{"SUBD", LTYPEK, arm.ASUBD},
{"MULF", LTYPEK, arm.AMULF},
{"MULD", LTYPEK, arm.AMULD},
{"DIVF", LTYPEK, arm.ADIVF},
{"DIVD", LTYPEK, arm.ADIVD},
{"B", LTYPE4, arm.AB},
{"BL", LTYPE4, arm.ABL},
{"BX", LTYPEBX, arm.ABX},
{"BEQ", LTYPE5, arm.ABEQ},
{"BNE", LTYPE5, arm.ABNE},
{"BCS", LTYPE5, arm.ABCS},
{"BHS", LTYPE5, arm.ABHS},
{"BCC", LTYPE5, arm.ABCC},
{"BLO", LTYPE5, arm.ABLO},
{"BMI", LTYPE5, arm.ABMI},
{"BPL", LTYPE5, arm.ABPL},
{"BVS", LTYPE5, arm.ABVS},
{"BVC", LTYPE5, arm.ABVC},
{"BHI", LTYPE5, arm.ABHI},
{"BLS", LTYPE5, arm.ABLS},
{"BGE", LTYPE5, arm.ABGE},
{"BLT", LTYPE5, arm.ABLT},
{"BGT", LTYPE5, arm.ABGT},
{"BLE", LTYPE5, arm.ABLE},
{"BCASE", LTYPE5, arm.ABCASE},
{"SWI", LTYPE6, arm.ASWI},
{"CMP", LTYPE7, arm.ACMP},
{"TST", LTYPE7, arm.ATST},
{"TEQ", LTYPE7, arm.ATEQ},
{"CMN", LTYPE7, arm.ACMN},
{"MOVM", LTYPE8, arm.AMOVM},
{"SWPBU", LTYPE9, arm.ASWPBU},
{"SWPW", LTYPE9, arm.ASWPW},
{"RET", LTYPEA, obj.ARET},
{"RFE", LTYPEA, arm.ARFE},
{"TEXT", LTYPEB, obj.ATEXT},
{"GLOBL", LGLOBL, obj.AGLOBL},
{"DATA", LTYPEC, obj.ADATA},
{"CASE", LTYPED, arm.ACASE},
{"END", LTYPEE, obj.AEND},
{"WORD", LTYPEH, arm.AWORD},
{"NOP", LTYPEI, obj.ANOP},
{"MCR", LTYPEJ, 0},
{"MRC", LTYPEJ, 1},
{"PLD", LTYPEPLD, arm.APLD},
{"UNDEF", LTYPEE, obj.AUNDEF},
{"CLZ", LTYPE2, arm.ACLZ},
{"MULWT", LTYPE1, arm.AMULWT},
{"MULWB", LTYPE1, arm.AMULWB},
{"MULAWT", LTYPEN, arm.AMULAWT},
{"MULAWB", LTYPEN, arm.AMULAWB},
{"USEFIELD", LTYPEN, obj.AUSEFIELD},
{"PCDATA", LTYPEPC, obj.APCDATA},
{"FUNCDATA", LTYPEF, obj.AFUNCDATA},
}
func cinit() {
}
func isreg(g *obj.Addr) bool {
return true
}
func cclean() {
outcode(obj.AEND, Always, &nullgen, 0, &nullgen)
}
var bcode = []int{
arm.ABEQ,
arm.ABNE,
arm.ABCS,
arm.ABCC,
arm.ABMI,
arm.ABPL,
arm.ABVS,
arm.ABVC,
arm.ABHI,
arm.ABLS,
arm.ABGE,
arm.ABLT,
arm.ABGT,
arm.ABLE,
arm.AB,
obj.ANOP,
}
var lastpc *obj.Prog
func outcode(a, scond int32, g1 *obj.Addr, reg int32, g2 *obj.Addr) {
var p *obj.Prog
var pl *obj.Plist
/* hack to make B.NE etc. work: turn it into the corresponding conditional */
if a == arm.AB {
a = int32(bcode[(scond^arm.C_SCOND_XOR)&0xf])
scond = (scond &^ 0xf) | Always
}
if asm.Pass == 1 {
goto out
}
p = new(obj.Prog)
*p = obj.Prog{}
p.Ctxt = asm.Ctxt
p.As = int16(a)
p.Lineno = stmtline
p.Scond = uint8(scond)
p.From = *g1
p.Reg = int16(reg)
p.To = *g2
p.Pc = int64(asm.PC)
if lastpc == nil {
pl = obj.Linknewplist(asm.Ctxt)
pl.Firstpc = p
} else {
lastpc.Link = p
}
lastpc = p
out:
if a != obj.AGLOBL && a != obj.ADATA {
asm.PC++
}
}

File diff suppressed because it is too large Load Diff

2936
src/cmd/5a/y.tab.c Normal file

File diff suppressed because it is too large Load Diff

188
src/cmd/5a/y.tab.h Normal file
View File

@@ -0,0 +1,188 @@
/* A Bison parser, made by GNU Bison 2.7.12-4996. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef YY_YY_Y_TAB_H_INCLUDED
# define YY_YY_Y_TAB_H_INCLUDED
/* Enabling traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int yydebug;
#endif
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
LTYPE1 = 258,
LTYPE2 = 259,
LTYPE3 = 260,
LTYPE4 = 261,
LTYPE5 = 262,
LTYPE6 = 263,
LTYPE7 = 264,
LTYPE8 = 265,
LTYPE9 = 266,
LTYPEA = 267,
LTYPEB = 268,
LTYPEC = 269,
LTYPED = 270,
LTYPEE = 271,
LTYPEG = 272,
LTYPEH = 273,
LTYPEI = 274,
LTYPEJ = 275,
LTYPEK = 276,
LTYPEL = 277,
LTYPEM = 278,
LTYPEN = 279,
LTYPEBX = 280,
LTYPEPLD = 281,
LCONST = 282,
LSP = 283,
LSB = 284,
LFP = 285,
LPC = 286,
LTYPEX = 287,
LTYPEPC = 288,
LTYPEF = 289,
LR = 290,
LREG = 291,
LF = 292,
LFREG = 293,
LC = 294,
LCREG = 295,
LPSR = 296,
LFCR = 297,
LCOND = 298,
LS = 299,
LAT = 300,
LFCONST = 301,
LSCONST = 302,
LNAME = 303,
LLAB = 304,
LVAR = 305
};
#endif
/* Tokens. */
#define LTYPE1 258
#define LTYPE2 259
#define LTYPE3 260
#define LTYPE4 261
#define LTYPE5 262
#define LTYPE6 263
#define LTYPE7 264
#define LTYPE8 265
#define LTYPE9 266
#define LTYPEA 267
#define LTYPEB 268
#define LTYPEC 269
#define LTYPED 270
#define LTYPEE 271
#define LTYPEG 272
#define LTYPEH 273
#define LTYPEI 274
#define LTYPEJ 275
#define LTYPEK 276
#define LTYPEL 277
#define LTYPEM 278
#define LTYPEN 279
#define LTYPEBX 280
#define LTYPEPLD 281
#define LCONST 282
#define LSP 283
#define LSB 284
#define LFP 285
#define LPC 286
#define LTYPEX 287
#define LTYPEPC 288
#define LTYPEF 289
#define LR 290
#define LREG 291
#define LF 292
#define LFREG 293
#define LC 294
#define LCREG 295
#define LPSR 296
#define LFCR 297
#define LCOND 298
#define LS 299
#define LAT 300
#define LFCONST 301
#define LSCONST 302
#define LNAME 303
#define LLAB 304
#define LVAR 305
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
/* Line 2053 of yacc.c */
#line 39 "a.y"
Sym *sym;
int32 lval;
double dval;
char sval[8];
Addr addr;
/* Line 2053 of yacc.c */
#line 166 "y.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
#else
int yyparse ();
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
int yyparse (void);
#else
int yyparse ();
#endif
#endif /* ! YYPARSE_PARAM */
#endif /* !YY_YY_Y_TAB_H_INCLUDED */

1213
src/cmd/5c/cgen.c Normal file

File diff suppressed because it is too large Load Diff

16
src/cmd/5c/doc.go Normal file
View File

@@ -0,0 +1,16 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
/*
5c is a version of the Plan 9 C compiler. The original is documented at
http://plan9.bell-labs.com/magic/man2html/1/8c
Its target architecture is the ARM, referred to by these tools as arm.
*/
package main

333
src/cmd/5c/gc.h Normal file
View File

@@ -0,0 +1,333 @@
// Inferno utils/5c/gc.h
// http://code.google.com/p/inferno-os/source/browse/utils/5c/gc.h
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <u.h>
#include "../cc/cc.h"
#include "../5l/5.out.h"
/*
* 5c/arm
* Arm 7500
*/
#define SZ_CHAR 1
#define SZ_SHORT 2
#define SZ_INT 4
#define SZ_LONG 4
#define SZ_IND 4
#define SZ_FLOAT 4
#define SZ_VLONG 8
#define SZ_DOUBLE 8
#define FNX 100
typedef struct Case Case;
typedef struct C1 C1;
typedef struct Multab Multab;
typedef struct Hintab Hintab;
typedef struct Reg Reg;
typedef struct Rgn Rgn;
#define R0ISZERO 0
#define A ((Addr*)0)
#define INDEXED 9
#define P ((Prog*)0)
struct Case
{
Case* link;
int32 val;
int32 label;
char def;
char isv;
};
#define C ((Case*)0)
struct C1
{
int32 val;
int32 label;
};
struct Multab
{
int32 val;
char code[20];
};
struct Hintab
{
ushort val;
char hint[10];
};
struct Reg
{
int32 pc;
int32 rpo; /* reverse post ordering */
Bits set;
Bits use1;
Bits use2;
Bits refbehind;
Bits refahead;
Bits calbehind;
Bits calahead;
Bits regdiff;
Bits act;
int32 regu;
int32 loop; /* could be shorter */
Reg* log5;
int32 active;
Reg* p1;
Reg* p2;
Reg* p2link;
Reg* s1;
Reg* s2;
Reg* link;
Prog* prog;
};
#define R ((Reg*)0)
#define NRGN 600
struct Rgn
{
Reg* enter;
short cost;
short varno;
short regno;
};
EXTERN int32 breakpc;
EXTERN int32 nbreak;
EXTERN Case* cases;
EXTERN Node constnode;
EXTERN Node fconstnode;
EXTERN int32 continpc;
EXTERN int32 curarg;
EXTERN int32 cursafe;
EXTERN int32 isbigendian;
EXTERN Prog* lastp;
EXTERN int32 maxargsafe;
EXTERN int mnstring;
EXTERN Multab multab[20];
extern int hintabsize;
EXTERN Node* nodrat;
EXTERN Node* nodret;
EXTERN Node* nodsafe;
EXTERN int32 nrathole;
EXTERN int32 nstring;
EXTERN Prog* p;
EXTERN int32 pc;
EXTERN Node regnode;
EXTERN char string[NSNAME];
EXTERN Sym* symrathole;
EXTERN Node znode;
EXTERN Prog zprog;
EXTERN char reg[NREG+NFREG];
EXTERN int32 exregoffset;
EXTERN int32 exfregoffset;
EXTERN int suppress;
#define BLOAD(r) band(bnot(r->refbehind), r->refahead)
#define BSTORE(r) band(bnot(r->calbehind), r->calahead)
#define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z])
#define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z])
#define bset(a,n) ((a).b[(n)/32]&(1L<<(n)%32))
#define CLOAD 4
#define CREF 5
#define CINF 1000
#define LOOP 3
EXTERN Rgn region[NRGN];
EXTERN Rgn* rgp;
EXTERN int nregion;
EXTERN int nvar;
EXTERN Bits externs;
EXTERN Bits params;
EXTERN Bits consts;
EXTERN Bits addrs;
EXTERN int32 regbits;
EXTERN int32 exregbits;
EXTERN int change;
EXTERN Reg* firstr;
EXTERN Reg* lastr;
EXTERN Reg zreg;
EXTERN Reg* freer;
EXTERN int32* idom;
EXTERN Reg** rpo2r;
EXTERN int32 maxnr;
extern char* anames[];
extern Hintab hintab[];
/*
* sgen.c
*/
void codgen(Node*, Node*);
void gen(Node*);
void noretval(int);
void usedset(Node*, int);
void xcom(Node*);
int bcomplex(Node*, Node*);
Prog* gtext(Sym*, int32);
vlong argsize(int);
/*
* cgen.c
*/
void cgen(Node*, Node*);
void reglcgen(Node*, Node*, Node*);
void lcgen(Node*, Node*);
void bcgen(Node*, int);
void boolgen(Node*, int, Node*);
void sugen(Node*, Node*, int32);
void layout(Node*, Node*, int, int, Node*);
void cgenrel(Node*, Node*);
/*
* txt.c
*/
void ginit(void);
void gclean(void);
void nextpc(void);
void gargs(Node*, Node*, Node*);
void garg1(Node*, Node*, Node*, int, Node**);
Node* nodconst(int32);
Node* nod32const(vlong);
Node* nodfconst(double);
void nodreg(Node*, Node*, int);
void regret(Node*, Node*, Type*, int);
int tmpreg(void);
void regalloc(Node*, Node*, Node*);
void regfree(Node*);
void regialloc(Node*, Node*, Node*);
void regsalloc(Node*, Node*);
void regaalloc1(Node*, Node*);
void regaalloc(Node*, Node*);
void regind(Node*, Node*);
void gprep(Node*, Node*);
void raddr(Node*, Prog*);
void naddr(Node*, Addr*);
void gmovm(Node*, Node*, int);
void gmove(Node*, Node*);
void gmover(Node*, Node*);
void gins(int a, Node*, Node*);
void gopcode(int, Node*, Node*, Node*);
int samaddr(Node*, Node*);
void gbranch(int);
void patch(Prog*, int32);
int sconst(Node*);
int sval(int32);
void gpseudo(int, Sym*, Node*);
void gprefetch(Node*);
void gpcdata(int, int);
/*
* swt.c
*/
int swcmp(const void*, const void*);
void doswit(Node*);
void swit1(C1*, int, int32, Node*);
void swit2(C1*, int, int32, Node*);
void newcase(void);
void bitload(Node*, Node*, Node*, Node*, Node*);
void bitstore(Node*, Node*, Node*, Node*, Node*);
int mulcon(Node*, Node*);
Multab* mulcon0(int32);
void nullwarn(Node*, Node*);
void outcode(void);
/*
* list
*/
void listinit(void);
/*
* reg.c
*/
Reg* rega(void);
int rcmp(const void*, const void*);
void regopt(Prog*);
void addmove(Reg*, int, int, int);
Bits mkvar(Addr*, int);
void prop(Reg*, Bits, Bits);
void loopit(Reg*, int32);
void synch(Reg*, Bits);
uint32 allreg(uint32, Rgn*);
void paint1(Reg*, int);
uint32 paint2(Reg*, int);
void paint3(Reg*, int, int32, int);
void addreg(Addr*, int);
/*
* peep.c
*/
void peep(void);
void excise(Reg*);
Reg* uniqp(Reg*);
Reg* uniqs(Reg*);
int regtyp(Addr*);
int regzer(Addr*);
int anyvar(Addr*);
int subprop(Reg*);
int copyprop(Reg*);
int shiftprop(Reg*);
void constprop(Addr*, Addr*, Reg*);
int copy1(Addr*, Addr*, Reg*, int);
int copyu(Prog*, Addr*, Addr*);
int copyas(Addr*, Addr*);
int copyau(Addr*, Addr*);
int copyau1(Prog*, Addr*);
int copysub(Addr*, Addr*, Addr*, int);
int copysub1(Prog*, Addr*, Addr*, int);
int32 RtoB(int);
int32 FtoB(int);
int BtoR(int32);
int BtoF(int32);
void predicate(void);
int isbranch(Prog *);
int predicable(Prog *p);
int modifiescpsr(Prog *p);

View File

@@ -1,5 +1,5 @@
// Inferno utils/5l/list.h
// http://code.google.com/p/inferno-os/source/browse/utils/5l/list.c
// Inferno utils/5c/list.c
// http://code.google.com/p/inferno-os/source/browse/utils/5c/list.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
@@ -28,13 +28,12 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// Printing.
#include "l.h"
#include "../ld/lib.h"
#define EXTERN
#include "gc.h"
void
listinit(void)
{
listinit9();
listinit5();
}

640
src/cmd/5c/mul.c Normal file
View File

@@ -0,0 +1,640 @@
// Inferno utils/5c/mul.c
// http://code.google.com/p/inferno-os/source/browse/utils/5c/mul.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "gc.h"
/*
* code sequences for multiply by constant.
* [a-l][0-3]
* lsl $(A-'a'),r0,r1
* [+][0-7]
* add r0,r1,r2
* [-][0-7]
* sub r0,r1,r2
*/
static int maxmulops = 3; /* max # of ops to replace mul with */
static int multabp;
static int32 mulval;
static char* mulcp;
static int32 valmax;
static int shmax;
static int docode(char *hp, char *cp, int r0, int r1);
static int gen1(int len);
static int gen2(int len, int32 r1);
static int gen3(int len, int32 r0, int32 r1, int flag);
enum
{
SR1 = 1<<0, /* r1 has been shifted */
SR0 = 1<<1, /* r0 has been shifted */
UR1 = 1<<2, /* r1 has not been used */
UR0 = 1<<3, /* r0 has not been used */
};
Multab*
mulcon0(int32 v)
{
int a1, a2, g;
Multab *m, *m1;
char hint[10];
if(v < 0)
v = -v;
/*
* look in cache
*/
m = multab;
for(g=0; g<nelem(multab); g++) {
if(m->val == v) {
if(m->code[0] == 0)
return 0;
return m;
}
m++;
}
/*
* select a spot in cache to overwrite
*/
multabp++;
if(multabp < 0 || multabp >= nelem(multab))
multabp = 0;
m = multab+multabp;
m->val = v;
mulval = v;
/*
* look in execption hint table
*/
a1 = 0;
a2 = hintabsize;
for(;;) {
if(a1 >= a2)
goto no;
g = (a2 + a1)/2;
if(v < hintab[g].val) {
a2 = g;
continue;
}
if(v > hintab[g].val) {
a1 = g+1;
continue;
}
break;
}
if(docode(hintab[g].hint, m->code, 1, 0))
return m;
print("multiply table failure %d\n", v);
m->code[0] = 0;
return 0;
no:
/*
* try to search
*/
hint[0] = 0;
for(g=1; g<=maxmulops; g++) {
if(g >= maxmulops && v >= 65535)
break;
mulcp = hint+g;
*mulcp = 0;
if(gen1(g)) {
if(docode(hint, m->code, 1, 0))
return m;
print("multiply table failure %d\n", v);
break;
}
}
/*
* try a recur followed by a shift
*/
g = 0;
while(!(v & 1)) {
g++;
v >>= 1;
}
if(g) {
m1 = mulcon0(v);
if(m1) {
strcpy(m->code, m1->code);
sprint(strchr(m->code, 0), "%c0", g+'a');
return m;
}
}
m->code[0] = 0;
return 0;
}
static int
docode(char *hp, char *cp, int r0, int r1)
{
int c, i;
c = *hp++;
*cp = c;
cp += 2;
switch(c) {
default:
c -= 'a';
if(c < 1 || c >= 30)
break;
for(i=0; i<4; i++) {
switch(i) {
case 0:
if(docode(hp, cp, r0<<c, r1))
goto out;
break;
case 1:
if(docode(hp, cp, r1<<c, r1))
goto out;
break;
case 2:
if(docode(hp, cp, r0, r0<<c))
goto out;
break;
case 3:
if(docode(hp, cp, r0, r1<<c))
goto out;
break;
}
}
break;
case '+':
for(i=0; i<8; i++) {
cp[-1] = i+'0';
switch(i) {
case 1:
if(docode(hp, cp, r0+r1, r1))
goto out;
break;
case 5:
if(docode(hp, cp, r0, r0+r1))
goto out;
break;
}
}
break;
case '-':
for(i=0; i<8; i++) {
cp[-1] = i+'0';
switch(i) {
case 1:
if(docode(hp, cp, r0-r1, r1))
goto out;
break;
case 2:
if(docode(hp, cp, r1-r0, r1))
goto out;
break;
case 5:
if(docode(hp, cp, r0, r0-r1))
goto out;
break;
case 6:
if(docode(hp, cp, r0, r1-r0))
goto out;
break;
}
}
break;
case 0:
if(r0 == mulval)
return 1;
}
return 0;
out:
cp[-1] = i+'0';
return 1;
}
static int
gen1(int len)
{
int i;
for(shmax=1; shmax<30; shmax++) {
valmax = 1<<shmax;
if(valmax >= mulval)
break;
}
if(mulval == 1)
return 1;
len--;
for(i=1; i<=shmax; i++)
if(gen2(len, 1<<i)) {
*--mulcp = 'a'+i;
return 1;
}
return 0;
}
static int
gen2(int len, int32 r1)
{
int i;
if(len <= 0) {
if(r1 == mulval)
return 1;
return 0;
}
len--;
if(len == 0)
goto calcr0;
if(gen3(len, r1, r1+1, UR1)) {
i = '+';
goto out;
}
if(gen3(len, r1-1, r1, UR0)) {
i = '-';
goto out;
}
if(gen3(len, 1, r1+1, UR1)) {
i = '+';
goto out;
}
if(gen3(len, 1, r1-1, UR1)) {
i = '-';
goto out;
}
return 0;
calcr0:
if(mulval == r1+1) {
i = '+';
goto out;
}
if(mulval == r1-1) {
i = '-';
goto out;
}
return 0;
out:
*--mulcp = i;
return 1;
}
static int
gen3(int len, int32 r0, int32 r1, int flag)
{
int i, f1, f2;
int32 x;
if(r0 <= 0 ||
r0 >= r1 ||
r1 > valmax)
return 0;
len--;
if(len == 0)
goto calcr0;
if(!(flag & UR1)) {
f1 = UR1|SR1;
for(i=1; i<=shmax; i++) {
x = r0<<i;
if(x > valmax)
break;
if(gen3(len, r0, x, f1)) {
i += 'a';
goto out;
}
}
}
if(!(flag & UR0)) {
f1 = UR1|SR1;
for(i=1; i<=shmax; i++) {
x = r1<<i;
if(x > valmax)
break;
if(gen3(len, r1, x, f1)) {
i += 'a';
goto out;
}
}
}
if(!(flag & SR1)) {
f1 = UR1|SR1|(flag&UR0);
for(i=1; i<=shmax; i++) {
x = r1<<i;
if(x > valmax)
break;
if(gen3(len, r0, x, f1)) {
i += 'a';
goto out;
}
}
}
if(!(flag & SR0)) {
f1 = UR0|SR0|(flag&(SR1|UR1));
f2 = UR1|SR1;
if(flag & UR1)
f2 |= UR0;
if(flag & SR1)
f2 |= SR0;
for(i=1; i<=shmax; i++) {
x = r0<<i;
if(x > valmax)
break;
if(x > r1) {
if(gen3(len, r1, x, f2)) {
i += 'a';
goto out;
}
} else
if(gen3(len, x, r1, f1)) {
i += 'a';
goto out;
}
}
}
x = r1+r0;
if(gen3(len, r0, x, UR1)) {
i = '+';
goto out;
}
if(gen3(len, r1, x, UR1)) {
i = '+';
goto out;
}
x = r1-r0;
if(gen3(len, x, r1, UR0)) {
i = '-';
goto out;
}
if(x > r0) {
if(gen3(len, r0, x, UR1)) {
i = '-';
goto out;
}
} else
if(gen3(len, x, r0, UR0)) {
i = '-';
goto out;
}
return 0;
calcr0:
f1 = flag & (UR0|UR1);
if(f1 == UR1) {
for(i=1; i<=shmax; i++) {
x = r1<<i;
if(x >= mulval) {
if(x == mulval) {
i += 'a';
goto out;
}
break;
}
}
}
if(mulval == r1+r0) {
i = '+';
goto out;
}
if(mulval == r1-r0) {
i = '-';
goto out;
}
return 0;
out:
*--mulcp = i;
return 1;
}
/*
* hint table has numbers that
* the search algorithm fails on.
* <1000:
* all numbers
* <5000:
* ÷ by 5
* <10000:
* ÷ by 50
* <65536:
* ÷ by 250
*/
Hintab hintab[] =
{
683, "b++d+e+",
687, "b+e++e-",
691, "b++d+e+",
731, "b++d+e+",
811, "b++d+i+",
821, "b++e+e+",
843, "b+d++e+",
851, "b+f-+e-",
853, "b++e+e+",
877, "c++++g-",
933, "b+c++g-",
981, "c-+e-d+",
1375, "b+c+b+h-",
1675, "d+b++h+",
2425, "c++f-e+",
2675, "c+d++f-",
2750, "b+d-b+h-",
2775, "c-+g-e-",
3125, "b++e+g+",
3275, "b+c+g+e+",
3350, "c++++i+",
3475, "c-+e-f-",
3525, "c-+d+g-",
3625, "c-+e-j+",
3675, "b+d+d+e+",
3725, "b+d-+h+",
3925, "b+d+f-d-",
4275, "b+g++e+",
4325, "b+h-+d+",
4425, "b+b+g-j-",
4525, "b+d-d+f+",
4675, "c++d-g+",
4775, "b+d+b+g-",
4825, "c+c-+i-",
4850, "c++++i-",
4925, "b++e-g-",
4975, "c+f++e-",
5500, "b+g-c+d+",
6700, "d+b++i+",
9700, "d++++j-",
11000, "b+f-c-h-",
11750, "b+d+g+j-",
12500, "b+c+e-k+",
13250, "b+d+e-f+",
13750, "b+h-c-d+",
14250, "b+g-c+e-",
14500, "c+f+j-d-",
14750, "d-g--f+",
16750, "b+e-d-n+",
17750, "c+h-b+e+",
18250, "d+b+h-d+",
18750, "b+g-++f+",
19250, "b+e+b+h+",
19750, "b++h--f-",
20250, "b+e-l-c+",
20750, "c++bi+e-",
21250, "b+i+l+c+",
22000, "b+e+d-g-",
22250, "b+d-h+k-",
22750, "b+d-e-g+",
23250, "b+c+h+e-",
23500, "b+g-c-g-",
23750, "b+g-b+h-",
24250, "c++g+m-",
24750, "b+e+e+j-",
25000, "b++dh+g+",
25250, "b+e+d-g-",
25750, "b+e+b+j+",
26250, "b+h+c+e+",
26500, "b+h+c+g+",
26750, "b+d+e+g-",
27250, "b+e+e+f+",
27500, "c-i-c-d+",
27750, "b+bd++j+",
28250, "d-d-++i-",
28500, "c+c-h-e-",
29000, "b+g-d-f+",
29500, "c+h+++e-",
29750, "b+g+f-c+",
30250, "b+f-g-c+",
33500, "c-f-d-n+",
33750, "b+d-b+j-",
34250, "c+e+++i+",
35250, "e+b+d+k+",
35500, "c+e+d-g-",
35750, "c+i-++e+",
36250, "b+bh-d+e+",
36500, "c+c-h-e-",
36750, "d+e--i+",
37250, "b+g+g+b+",
37500, "b+h-b+f+",
37750, "c+be++j-",
38500, "b+e+b+i+",
38750, "d+i-b+d+",
39250, "b+g-l-+d+",
39500, "b+g-c+g-",
39750, "b+bh-c+f-",
40250, "b+bf+d+g-",
40500, "b+g-c+g+",
40750, "c+b+i-e+",
41250, "d++bf+h+",
41500, "b+j+c+d-",
41750, "c+f+b+h-",
42500, "c+h++g+",
42750, "b+g+d-f-",
43250, "b+l-e+d-",
43750, "c+bd+h+f-",
44000, "b+f+g-d-",
44250, "b+d-g--f+",
44500, "c+e+c+h+",
44750, "b+e+d-h-",
45250, "b++g+j-g+",
45500, "c+d+e-g+",
45750, "b+d-h-e-",
46250, "c+bd++j+",
46500, "b+d-c-j-",
46750, "e-e-b+g-",
47000, "b+c+d-j-",
47250, "b+e+e-g-",
47500, "b+g-c-h-",
47750, "b+f-c+h-",
48250, "d--h+n-",
48500, "b+c-g+m-",
48750, "b+e+e-g+",
49500, "c-f+e+j-",
49750, "c+c+g++f-",
50000, "b+e+e+k+",
50250, "b++i++g+",
50500, "c+g+f-i+",
50750, "b+e+d+k-",
51500, "b+i+c-f+",
51750, "b+bd+g-e-",
52250, "b+d+g-j+",
52500, "c+c+f+g+",
52750, "b+c+e+i+",
53000, "b+i+c+g+",
53500, "c+g+g-n+",
53750, "b+j+d-c+",
54250, "b+d-g-j-",
54500, "c-f+e+f+",
54750, "b+f-+c+g+",
55000, "b+g-d-g-",
55250, "b+e+e+g+",
55500, "b+cd++j+",
55750, "b+bh-d-f-",
56250, "c+d-b+j-",
56500, "c+d+c+i+",
56750, "b+e+d++h-",
57000, "b+d+g-f+",
57250, "b+f-m+d-",
57750, "b+i+c+e-",
58000, "b+e+d+h+",
58250, "c+b+g+g+",
58750, "d-e-j--e+",
59000, "d-i-+e+",
59250, "e--h-m+",
59500, "c+c-h+f-",
59750, "b+bh-e+i-",
60250, "b+bh-e-e-",
60500, "c+c-g-g-",
60750, "b+e-l-e-",
61250, "b+g-g-c+",
61750, "b+g-c+g+",
62250, "f--+c-i-",
62750, "e+f--+g+",
64750, "b+f+d+p-",
};
int hintabsize = nelem(hintab);

1478
src/cmd/5c/peep.c Normal file

File diff suppressed because it is too large Load Diff

1210
src/cmd/5c/reg.c Normal file

File diff suppressed because it is too large Load Diff

265
src/cmd/5c/sgen.c Normal file
View File

@@ -0,0 +1,265 @@
// Inferno utils/5c/sgen.c
// http://code.google.com/p/inferno-os/source/browse/utils/5c/sgen.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "gc.h"
Prog*
gtext(Sym *s, int32 stkoff)
{
int32 a;
a = argsize(1);
if((textflag & NOSPLIT) != 0 && stkoff >= 128)
yyerror("stack frame too large for NOSPLIT function");
gpseudo(ATEXT, s, nodconst(stkoff));
p->to.type = D_CONST2;
p->to.offset2 = a;
return p;
}
void
noretval(int n)
{
if(n & 1) {
gins(ANOP, Z, Z);
p->to.type = D_REG;
p->to.reg = REGRET;
}
if(n & 2) {
gins(ANOP, Z, Z);
p->to.type = D_FREG;
p->to.reg = FREGRET;
}
}
/*
* calculate addressability as follows
* CONST ==> 20 $value
* NAME ==> 10 name
* REGISTER ==> 11 register
* INDREG ==> 12 *[(reg)+offset]
* &10 ==> 2 $name
* ADD(2, 20) ==> 2 $name+offset
* ADD(3, 20) ==> 3 $(reg)+offset
* &12 ==> 3 $(reg)+offset
* *11 ==> 11 ??
* *2 ==> 10 name
* *3 ==> 12 *(reg)+offset
* calculate complexity (number of registers)
*/
void
xcom(Node *n)
{
Node *l, *r;
int t;
if(n == Z)
return;
l = n->left;
r = n->right;
n->addable = 0;
n->complex = 0;
switch(n->op) {
case OCONST:
n->addable = 20;
return;
case OREGISTER:
n->addable = 11;
return;
case OINDREG:
n->addable = 12;
return;
case ONAME:
n->addable = 10;
return;
case OADDR:
xcom(l);
if(l->addable == 10)
n->addable = 2;
if(l->addable == 12)
n->addable = 3;
break;
case OIND:
xcom(l);
if(l->addable == 11)
n->addable = 12;
if(l->addable == 3)
n->addable = 12;
if(l->addable == 2)
n->addable = 10;
break;
case OADD:
xcom(l);
xcom(r);
if(l->addable == 20) {
if(r->addable == 2)
n->addable = 2;
if(r->addable == 3)
n->addable = 3;
}
if(r->addable == 20) {
if(l->addable == 2)
n->addable = 2;
if(l->addable == 3)
n->addable = 3;
}
break;
case OASLMUL:
case OASMUL:
xcom(l);
xcom(r);
t = vlog(r);
if(t >= 0) {
n->op = OASASHL;
r->vconst = t;
r->type = types[TINT];
}
break;
case OMUL:
case OLMUL:
xcom(l);
xcom(r);
t = vlog(r);
if(t >= 0) {
n->op = OASHL;
r->vconst = t;
r->type = types[TINT];
}
t = vlog(l);
if(t >= 0) {
n->op = OASHL;
n->left = r;
n->right = l;
r = l;
l = n->left;
r->vconst = t;
r->type = types[TINT];
}
break;
case OASLDIV:
xcom(l);
xcom(r);
t = vlog(r);
if(t >= 0) {
n->op = OASLSHR;
r->vconst = t;
r->type = types[TINT];
}
break;
case OLDIV:
xcom(l);
xcom(r);
t = vlog(r);
if(t >= 0) {
n->op = OLSHR;
r->vconst = t;
r->type = types[TINT];
}
break;
case OASLMOD:
xcom(l);
xcom(r);
t = vlog(r);
if(t >= 0) {
n->op = OASAND;
r->vconst--;
}
break;
case OLMOD:
xcom(l);
xcom(r);
t = vlog(r);
if(t >= 0) {
n->op = OAND;
r->vconst--;
}
break;
default:
if(l != Z)
xcom(l);
if(r != Z)
xcom(r);
break;
}
if(n->addable >= 10)
return;
if(l != Z)
n->complex = l->complex;
if(r != Z) {
if(r->complex == n->complex)
n->complex = r->complex+1;
else
if(r->complex > n->complex)
n->complex = r->complex;
}
if(n->complex == 0)
n->complex++;
if(com64(n))
return;
switch(n->op) {
case OFUNC:
n->complex = FNX;
break;
case OADD:
case OXOR:
case OAND:
case OOR:
case OEQ:
case ONE:
/*
* immediate operators, make const on right
*/
if(l->op == OCONST) {
n->left = r;
n->right = l;
}
break;
}
}

461
src/cmd/5c/swt.c Normal file
View File

@@ -0,0 +1,461 @@
// Inferno utils/5c/swt.c
// http://code.google.com/p/inferno-os/source/browse/utils/5c/swt.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "gc.h"
void
swit1(C1 *q, int nc, int32 def, Node *n)
{
Node nreg;
if(typev[n->type->etype]) {
regsalloc(&nreg, n);
nreg.type = types[TVLONG];
cgen(n, &nreg);
swit2(q, nc, def, &nreg);
return;
}
regalloc(&nreg, n, Z);
nreg.type = types[TLONG];
cgen(n, &nreg);
swit2(q, nc, def, &nreg);
regfree(&nreg);
}
void
swit2(C1 *q, int nc, int32 def, Node *n)
{
C1 *r;
int i;
int32 v;
Prog *sp;
if(nc >= 3) {
i = (q+nc-1)->val - (q+0)->val;
if(!nacl && i > 0 && i < nc*2)
goto direct;
}
if(nc < 5) {
for(i=0; i<nc; i++) {
if(debug['W'])
print("case = %.8ux\n", q->val);
gopcode(OEQ, nodconst(q->val), n, Z);
patch(p, q->label);
q++;
}
gbranch(OGOTO);
patch(p, def);
return;
}
i = nc / 2;
r = q+i;
if(debug['W'])
print("case > %.8ux\n", r->val);
gopcode(OGT, nodconst(r->val), n, Z);
sp = p;
gopcode(OEQ, nodconst(r->val), n, Z); /* just gen the B.EQ */
patch(p, r->label);
swit2(q, i, def, n);
if(debug['W'])
print("case < %.8ux\n", r->val);
patch(sp, pc);
swit2(r+1, nc-i-1, def, n);
return;
direct:
v = q->val;
if(v != 0)
gopcode(OSUB, nodconst(v), Z, n);
gopcode(OCASE, nodconst((q+nc-1)->val - v), n, Z);
patch(p, def);
for(i=0; i<nc; i++) {
if(debug['W'])
print("case = %.8ux\n", q->val);
while(q->val != v) {
nextpc();
p->as = ABCASE;
patch(p, def);
v++;
}
nextpc();
p->as = ABCASE;
patch(p, q->label);
q++;
v++;
}
gbranch(OGOTO); /* so that regopt() won't be confused */
patch(p, def);
}
void
bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
{
int sh;
int32 v;
Node *l;
/*
* n1 gets adjusted/masked value
* n2 gets address of cell
* n3 gets contents of cell
*/
l = b->left;
if(n2 != Z) {
regalloc(n1, l, nn);
reglcgen(n2, l, Z);
regalloc(n3, l, Z);
gopcode(OAS, n2, Z, n3);
gopcode(OAS, n3, Z, n1);
} else {
regalloc(n1, l, nn);
cgen(l, n1);
}
if(b->type->shift == 0 && typeu[b->type->etype]) {
v = ~0 + (1L << b->type->nbits);
gopcode(OAND, nodconst(v), Z, n1);
} else {
sh = 32 - b->type->shift - b->type->nbits;
if(sh > 0)
gopcode(OASHL, nodconst(sh), Z, n1);
sh += b->type->shift;
if(sh > 0)
if(typeu[b->type->etype])
gopcode(OLSHR, nodconst(sh), Z, n1);
else
gopcode(OASHR, nodconst(sh), Z, n1);
}
}
void
bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
{
int32 v;
Node nod, *l;
int sh;
/*
* n1 has adjusted/masked value
* n2 has address of cell
* n3 has contents of cell
*/
l = b->left;
regalloc(&nod, l, Z);
v = ~0 + (1L << b->type->nbits);
gopcode(OAND, nodconst(v), Z, n1);
gopcode(OAS, n1, Z, &nod);
if(nn != Z)
gopcode(OAS, n1, Z, nn);
sh = b->type->shift;
if(sh > 0)
gopcode(OASHL, nodconst(sh), Z, &nod);
v <<= sh;
gopcode(OAND, nodconst(~v), Z, n3);
gopcode(OOR, n3, Z, &nod);
gopcode(OAS, &nod, Z, n2);
regfree(&nod);
regfree(n1);
regfree(n2);
regfree(n3);
}
int32
outstring(char *s, int32 n)
{
int32 r;
if(suppress)
return nstring;
r = nstring;
while(n) {
string[mnstring] = *s++;
mnstring++;
nstring++;
if(mnstring >= NSNAME) {
gpseudo(ADATA, symstring, nodconst(0L));
p->from.offset += nstring - NSNAME;
p->reg = NSNAME;
p->to.type = D_SCONST;
memmove(p->to.u.sval, string, NSNAME);
mnstring = 0;
}
n--;
}
return r;
}
int
mulcon(Node *n, Node *nn)
{
Node *l, *r, nod1, nod2;
Multab *m;
int32 v, vs;
int o;
char code[sizeof(m->code)+2], *p;
if(typefd[n->type->etype])
return 0;
l = n->left;
r = n->right;
if(l->op == OCONST) {
l = r;
r = n->left;
}
if(r->op != OCONST)
return 0;
v = convvtox(r->vconst, n->type->etype);
if(v != r->vconst) {
if(debug['M'])
print("%L multiply conv: %lld\n", n->lineno, r->vconst);
return 0;
}
m = mulcon0(v);
if(!m) {
if(debug['M'])
print("%L multiply table: %lld\n", n->lineno, r->vconst);
return 0;
}
if(debug['M'] && debug['v'])
print("%L multiply: %d\n", n->lineno, v);
memmove(code, m->code, sizeof(m->code));
code[sizeof(m->code)] = 0;
p = code;
if(p[1] == 'i')
p += 2;
regalloc(&nod1, n, nn);
cgen(l, &nod1);
vs = v;
regalloc(&nod2, n, Z);
loop:
switch(*p) {
case 0:
regfree(&nod2);
if(vs < 0) {
gopcode(OAS, &nod1, Z, &nod1);
gopcode(OSUB, &nod1, nodconst(0), nn);
} else
gopcode(OAS, &nod1, Z, nn);
regfree(&nod1);
return 1;
case '+':
o = OADD;
goto addsub;
case '-':
o = OSUB;
addsub: /* number is r,n,l */
v = p[1] - '0';
r = &nod1;
if(v&4)
r = &nod2;
n = &nod1;
if(v&2)
n = &nod2;
l = &nod1;
if(v&1)
l = &nod2;
gopcode(o, l, n, r);
break;
default: /* op is shiftcount, number is r,l */
v = p[1] - '0';
r = &nod1;
if(v&2)
r = &nod2;
l = &nod1;
if(v&1)
l = &nod2;
v = *p - 'a';
if(v < 0 || v >= 32) {
diag(n, "mulcon unknown op: %c%c", p[0], p[1]);
break;
}
gopcode(OASHL, nodconst(v), l, r);
break;
}
p += 2;
goto loop;
}
void
sextern(Sym *s, Node *a, int32 o, int32 w)
{
int32 e, lw;
for(e=0; e<w; e+=NSNAME) {
lw = NSNAME;
if(w-e < lw)
lw = w-e;
gpseudo(ADATA, s, nodconst(0));
p->from.offset += o+e;
p->reg = lw;
p->to.type = D_SCONST;
memmove(p->to.u.sval, a->cstring+e, lw);
}
}
void
gextern(Sym *s, Node *a, int32 o, int32 w)
{
if(a->op == OCONST && typev[a->type->etype]) {
if(isbigendian)
gpseudo(ADATA, s, nod32const(a->vconst>>32));
else
gpseudo(ADATA, s, nod32const(a->vconst));
p->from.offset += o;
p->reg = 4;
if(isbigendian)
gpseudo(ADATA, s, nod32const(a->vconst));
else
gpseudo(ADATA, s, nod32const(a->vconst>>32));
p->from.offset += o + 4;
p->reg = 4;
return;
}
gpseudo(ADATA, s, a);
p->from.offset += o;
p->reg = w;
if(p->to.type == D_OREG)
p->to.type = D_CONST;
}
void
outcode(void)
{
Bprint(&outbuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
if(pragcgobuf.to > pragcgobuf.start) {
Bprint(&outbuf, "\n");
Bprint(&outbuf, "$$ // exports\n\n");
Bprint(&outbuf, "$$ // local types\n\n");
Bprint(&outbuf, "$$ // cgo\n");
Bprint(&outbuf, "%s", fmtstrflush(&pragcgobuf));
Bprint(&outbuf, "\n$$\n\n");
}
Bprint(&outbuf, "!\n");
writeobj(ctxt, &outbuf);
lastp = P;
}
int32
align(int32 i, Type *t, int op, int32 *maxalign)
{
int32 o;
Type *v;
int w, packw;
o = i;
w = 1;
packw = 0;
switch(op) {
default:
diag(Z, "unknown align opcode %d", op);
break;
case Asu2: /* padding at end of a struct */
w = *maxalign;
if(w < 1)
w = 1;
if(packflg)
packw = packflg;
break;
case Ael1: /* initial align of struct element */
for(v=t; v->etype==TARRAY; v=v->link)
;
if(v->etype == TSTRUCT || v->etype == TUNION)
w = v->align;
else {
w = ewidth[v->etype];
if(w == 8)
w = 4;
}
if(w < 1 || w > SZ_LONG)
fatal(Z, "align");
if(packflg)
packw = packflg;
break;
case Ael2: /* width of a struct element */
o += t->width;
break;
case Aarg0: /* initial passbyptr argument in arg list */
if(typesuv[t->etype]) {
o = align(o, types[TIND], Aarg1, nil);
o = align(o, types[TIND], Aarg2, nil);
}
break;
case Aarg1: /* initial align of parameter */
w = ewidth[t->etype];
if(w <= 0 || w >= SZ_LONG) {
w = SZ_LONG;
break;
}
w = 1; /* little endian no adjustment */
break;
case Aarg2: /* width of a parameter */
o += t->width;
w = t->width;
if(w > SZ_LONG)
w = SZ_LONG;
break;
case Aaut3: /* total align of automatic */
o = align(o, t, Ael2, nil);
o = align(o, t, Ael1, nil);
w = SZ_LONG; /* because of a pun in cc/dcl.c:contig() */
break;
}
if(packw != 0 && xround(o, w) != xround(o, packw))
diag(Z, "#pragma pack changes offset of %T", t);
o = xround(o, w);
if(maxalign != nil && *maxalign < w)
*maxalign = w;
if(debug['A'])
print("align %s %d %T = %d\n", bnames[op], i, t, o);
return o;
}
int32
maxround(int32 max, int32 v)
{
v = xround(v, SZ_LONG);
if(v > max)
return v;
return max;
}

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