1
0
mirror of https://github.com/golang/go synced 2024-11-23 02:30:02 -07:00

remove nacl

The recent linker changes broke NaCl support
a month ago, and there are no known users of it.

The NaCl code can always be recovered from the
repository history.

R=adg, r
CC=golang-dev
https://golang.org/cl/3671042
This commit is contained in:
Russ Cox 2010-12-15 11:49:23 -05:00
parent 85f5bb8216
commit 0c54225b51
93 changed files with 22 additions and 13668 deletions

View File

@ -89,8 +89,6 @@ Safe compilation mode: generate code that is guaranteed not to obtain an invalid
<li>
Gccgo: garbage collection.
<li>
Native Client (NaCl) support.
<li>
SWIG support.
<li>
Simpler semicolon rules.

View File

@ -62,7 +62,7 @@ support for segmented stacks, and a strong goroutine implementation.
</p>
<p>
The compilers can target the FreeBSD, Linux, Native Client,
The compilers can target the FreeBSD, Linux,
and OS X (a.k.a. Darwin) operating systems.
(A port to Microsoft Windows is in progress but incomplete. See the
<a href="http://code.google.com/p/go/wiki/WindowsPort">Windows Port</a>
@ -340,7 +340,6 @@ to override the defaults.
Choices for <code>$GOOS</code> are <code>linux</code>,
<code>freebsd</code>,
<code>darwin</code> (Mac OS X 10.5 or 10.6),
<code>nacl</code> (Native Client, an incomplete port),
and <code>windows</code> (Windows, an incomplete port).
Choices for <code>$GOARCH</code> are <code>amd64</code> (64-bit x86, the most mature port),
<code>386</code> (32-bit x86), and
@ -372,9 +371,6 @@ to override the defaults.
<td></td><td><code>linux</code></td> <td><code>arm</code></td> <td><i>incomplete</i></td>
</tr>
<tr>
<td></td><td><code>nacl</code></td> <td><code>386</code></td>
</tr>
<tr>
<td></td><td><code>windows</code></td> <td><code>386</code></td> <td><i>incomplete</i></td>
</tr>
</table>

View File

@ -32,12 +32,11 @@ endif
ifeq ($(GOOS),darwin)
else ifeq ($(GOOS),freebsd)
else ifeq ($(GOOS),linux)
else ifeq ($(GOOS),nacl)
else ifeq ($(GOOS),tiny)
else ifeq ($(GOOS),plan9)
else ifeq ($(GOOS),windows)
else
$(error Invalid $$GOOS '$(GOOS)'; must be darwin, freebsd, linux, nacl, tiny, plan9, or windows)
$(error Invalid $$GOOS '$(GOOS)'; must be darwin, freebsd, linux, plan9, tiny, or windows)
endif
ifeq ($(GOHOSTARCH),)

View File

@ -1,48 +0,0 @@
#!/usr/bin/env bash
# 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.
# TODO(rsc): delete in favor of all.bash once nacl support is complete
export GOARCH=386
export GOOS=nacl
export GORUN=${GORUN:-$GOROOT/misc/nacl/naclrun}
set -e
bash make.bash
xcd() {
echo
echo --- cd $1
builtin cd $1
}
(xcd pkg
make install
make test
) || exit $?
(xcd pkg/exp/nacl/srpc
make clean
make install
) || exit $?
(xcd pkg/exp/nacl/av
make clean
make install
) || exit $?
(xcd pkg/exp/4s
make clean
make
) || exit $?
(xcd pkg/exp/spacewar
make clean
make
) || exit $?
(xcd ../test
./run
) || exit $?

View File

@ -535,8 +535,6 @@ asmb(void)
for(sect=segtext.sect; sect!=nil; sect=sect->next)
elfshbits(sect);
for(sect=segrodata.sect; sect!=nil; sect=sect->next)
elfshbits(sect);
for(sect=segdata.sect; sect!=nil; sect=sect->next)
elfshbits(sect);

View File

@ -415,7 +415,7 @@ addpltsym(Sym *s)
static void
addgotsym(Sym *s)
{
Sym *got, *rela, *indir;
Sym *got, *rela;
if(s->got >= 0)
return;
@ -976,8 +976,6 @@ asmb(void)
diag("elftextsh = %d, want %d", elftextsh, eh->shnum);
for(sect=segtext.sect; sect!=nil; sect=sect->next)
elfshbits(sect);
for(sect=segrodata.sect; sect!=nil; sect=sect->next)
elfshbits(sect);
for(sect=segdata.sect; sect!=nil; sect=sect->next)
elfshbits(sect);

View File

@ -8,7 +8,6 @@
#include "opt.h"
static Prog *pret;
static Node *naclnop;
void
compile(Node *fn)
@ -24,7 +23,6 @@ compile(Node *fn)
newproc = sysfunc("newproc");
deferproc = sysfunc("deferproc");
deferreturn = sysfunc("deferreturn");
naclnop = sysfunc("naclnop");
panicindex = sysfunc("panicindex");
panicslice = sysfunc("panicslice");
throwreturn = sysfunc("throwreturn");
@ -96,16 +94,8 @@ compile(Node *fn)
if(pret)
patch(pret, pc);
ginit();
if(hasdefer) {
// On Native client, insert call to no-op function
// to force alignment immediately before call to deferreturn,
// so that when jmpdefer subtracts 5 from the second CALL's
// return address and then the return masks off the low bits,
// we'll back up to the NOPs immediately after the dummy CALL.
if(strcmp(getgoos(), "nacl") == 0)
ginscall(naclnop, 0);
if(hasdefer)
ginscall(deferreturn, 0);
}
if(curfn->exit)
genlist(curfn->exit);
gclean();

View File

@ -539,8 +539,6 @@ doelf(void)
elfstr[ElfStrData] = addstring(shstrtab, ".data");
elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
addstring(shstrtab, ".elfdata");
if(HEADTYPE == 8)
addstring(shstrtab, ".closure");
addstring(shstrtab, ".rodata");
if(!debug['s']) {
elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
@ -674,8 +672,6 @@ asmb(void)
sect = segtext.sect;
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
codeblk(sect->vaddr, sect->len);
// TODO: NaCl: pad with HLT
/* output read-only data in text segment */
sect = segtext.sect->next;
@ -889,7 +885,7 @@ asmb(void)
Elfput:
/* elf 386 */
if(HEADTYPE == 8 || HEADTYPE == 11)
if(HEADTYPE == 11)
debug['d'] = 1;
eh = getElfEhdr();
@ -901,17 +897,14 @@ asmb(void)
/* This null SHdr must appear before all others */
sh = newElfShdr(elfstr[ElfStrEmpty]);
/* program header info - but not on native client */
pph = nil;
if(HEADTYPE != 8) {
pph = newElfPhdr();
pph->type = PT_PHDR;
pph->flags = PF_R + PF_X;
pph->off = eh->ehsize;
pph->vaddr = INITTEXT - HEADR + pph->off;
pph->paddr = INITTEXT - HEADR + pph->off;
pph->align = INITRND;
}
/* program header info */
pph = newElfPhdr();
pph->type = PT_PHDR;
pph->flags = PF_R + PF_X;
pph->off = eh->ehsize;
pph->vaddr = INITTEXT - HEADR + pph->off;
pph->paddr = INITTEXT - HEADR + pph->off;
pph->align = INITRND;
if(!debug['d']) {
/* interpreter */
@ -935,8 +928,6 @@ asmb(void)
}
elfphload(&segtext);
if(segrodata.len > 0)
elfphload(&segrodata);
elfphload(&segdata);
/* Dynamic linking sections */
@ -1038,8 +1029,6 @@ asmb(void)
diag("elftextsh = %d, want %d", elftextsh, eh->shnum);
for(sect=segtext.sect; sect!=nil; sect=sect->next)
elfshbits(sect);
for(sect=segrodata.sect; sect!=nil; sect=sect->next)
elfshbits(sect);
for(sect=segdata.sect; sect!=nil; sect=sect->next)
elfshbits(sect);
@ -1073,11 +1062,6 @@ asmb(void)
eh->ident[EI_DATA] = ELFDATA2LSB;
eh->ident[EI_VERSION] = EV_CURRENT;
switch(HEADTYPE) {
case 8:
eh->ident[EI_OSABI] = ELFOSABI_NACL;
eh->ident[EI_ABIVERSION] = 7;
eh->flags = 0x200000; // aligned mod 32
break;
case 9:
eh->ident[EI_OSABI] = 9;
break;

View File

@ -321,7 +321,6 @@ EXTERN int32 spsize;
EXTERN Sym* symlist;
EXTERN int32 symsize;
EXTERN Sym* textp;
EXTERN int32 textpad;
EXTERN int32 textsize;
EXTERN int version;
EXTERN Prog zprg;

View File

@ -55,8 +55,10 @@ char *thestring = "386";
* -H4 -Tx -Rx is fake MS-DOS .EXE
* -H6 -Tx -Rx is Apple Mach-O
* -H7 -Tx -Rx is Linux ELF32
* -H8 -Tx -Rx is Google Native Client
* -H8 -Tx -Rx was Google Native Client
* -H9 -Tx -Rx is FreeBSD ELF32
* -H10 -Tx -Rx is MS Windows PE
* -H11 -Tx -Rx is tiny (os image)
*/
void
@ -133,9 +135,6 @@ main(int argc, char *argv[])
if(strcmp(goos, "darwin") == 0)
HEADTYPE = 6;
else
if(strcmp(goos, "nacl") == 0)
HEADTYPE = 8;
else
if(strcmp(goos, "freebsd") == 0)
HEADTYPE = 9;
else
@ -248,21 +247,6 @@ main(int argc, char *argv[])
if(INITRND == -1)
INITRND = 4096;
break;
case 8: /* native client elf32 executable */
elfinit();
HEADR = 4096;
if(INITTEXT == -1)
INITTEXT = 0x20000;
if(INITDAT == -1)
INITDAT = 0;
if(INITRND == -1)
INITRND = 65536;
// 512 kB of address space for closures.
// (Doesn't take any space in the binary file.)
// Closures are 64 bytes each, so this is 8,192 closures.
textpad = 512*1024;
break;
case 10: /* PE executable */
peinit();
HEADR = PEFILEHEADR;

View File

@ -822,22 +822,6 @@ subreg(Prog *p, int from, int to)
print("%P\n", p);
}
// nacl RET:
// POPL BX
// ANDL BX, $~31
// JMP BX
uchar naclret[] = { 0x5b, 0x83, 0xe3, ~31, 0xff, 0xe3 };
// nacl JMP BX:
// ANDL BX, $~31
// JMP BX
uchar nacljmpbx[] = { 0x83, 0xe3, ~31, 0xff, 0xe3 };
// nacl CALL BX:
// ANDL BX, $~31
// CALL BX
uchar naclcallbx[] = { 0x83, 0xe3, ~31, 0xff, 0xd3 };
void
doasm(Prog *p)
{
@ -906,12 +890,6 @@ found:
break;
case Zlit:
if(HEADTYPE == 8 && p->as == ARET) {
// native client return.
for(z=0; z<sizeof(naclret); z++)
*andptr++ = naclret[z];
break;
}
for(; op = o->op[z]; z++)
*andptr++ = op;
break;
@ -945,42 +923,6 @@ found:
break;
case Zo_m:
if(HEADTYPE == 8) {
Adr a;
switch(p->as) {
case AJMP:
if(p->to.type < D_AX || p->to.type > D_DI)
diag("indirect jmp must use register in native client");
// ANDL $~31, REG
*andptr++ = 0x83;
asmand(&p->to, 04);
*andptr++ = ~31;
// JMP REG
*andptr++ = 0xFF;
asmand(&p->to, 04);
return;
case ACALL:
a = p->to;
// native client indirect call
if(a.type < D_AX || a.type > D_DI) {
// MOVL target into BX
*andptr++ = 0x8b;
asmand(&p->to, reg[D_BX]);
memset(&a, 0, sizeof a);
a.type = D_BX;
}
// ANDL $~31, REG
*andptr++ = 0x83;
asmand(&a, 04);
*andptr++ = ~31;
// CALL REG
*andptr++ = 0xFF;
asmand(&a, 02);
return;
}
}
*andptr++ = op;
asmand(&p->to, o->op[z+1]);
break;
@ -1004,12 +946,6 @@ found:
else
a = &p->to;
v = vaddr(a, nil);
if(HEADTYPE == 8 && p->as == AINT && v == 3) {
// native client disallows all INT instructions.
// translate INT $3 to HLT.
*andptr++ = 0xf4;
break;
}
*andptr++ = op;
*andptr++ = v;
break;
@ -1380,51 +1316,8 @@ mfound:
void
asmins(Prog *p)
{
if(HEADTYPE == 8) {
ulong npc;
static Prog *prefix;
// TODO: adjust relocations, like 6l does for rex prefix
// native client
// - pad indirect jump targets (aka ATEXT) to 32-byte boundary
// - instructions cannot cross 32-byte boundary
// - end of call (return address) must be on 32-byte boundary
if(p->as == ATEXT)
p->pc += 31 & -p->pc;
if(p->as == ACALL) {
// must end on 32-byte boundary.
// doasm to find out how long the CALL encoding is.
andptr = and;
doasm(p);
npc = p->pc + (andptr - and);
p->pc += 31 & -npc;
}
if(p->as == AREP || p->as == AREPN) {
// save prefix for next instruction,
// so that inserted NOPs do not split (e.g.) REP / MOVSL sequence.
prefix = p;
andptr = and;
return;
}
andptr = and;
if(prefix)
doasm(prefix);
doasm(p);
npc = p->pc + (andptr - and);
if(andptr > and && (p->pc&~31) != ((npc-1)&~31)) {
// crossed 32-byte boundary; pad to boundary and try again
p->pc += 31 & -p->pc;
andptr = and;
if(prefix)
doasm(prefix);
doasm(p);
}
prefix = nil;
} else {
andptr = and;
doasm(p);
}
andptr = and;
doasm(p);
if(andptr > and+sizeof and) {
print("and[] is too short - %d byte instruction\n", andptr - and);
errorexit();

View File

@ -400,6 +400,7 @@ dpcheck(Node *n)
i = l->param;
b = n->right;
a = Z;
while(i > 0) {
b = nextarg(b, &a);
i--;

View File

@ -95,7 +95,6 @@ EXTERN char* thestring;
EXTERN Segment segtext;
EXTERN Segment segdata;
EXTERN Segment segrodata; // NaCl only
EXTERN Segment segsym;
void addlib(char *src, char *obj);

View File

@ -186,27 +186,6 @@ ifeq ($(DISABLE_NET_TESTS),1)
NOTEST+=http net
endif
# Disable tests that NaCl cannot run yet.
ifeq ($(GOOS),nacl)
NOTEST+=archive/tar # no pipe
NOTEST+=archive/zip # no pread
NOTEST+=debug/dwarf # no pread
NOTEST+=debug/macho # no pread
NOTEST+=debug/elf # no pread
NOTEST+=exec # no pipe
NOTEST+=http # no network
NOTEST+=log # no runtime.Caller
NOTEST+=net # no network
NOTEST+=netchan # no network
NOTEST+=os # many things unimplemented
NOTEST+=os/signal # no signals
NOTEST+=path # tree walking does not work
NOTEST+=rpc # no network
NOTEST+=syslog # no network
NOTEST+=time # no syscall.Kill, syscall.SIGCHLD for sleep tests
NOTEST+=websocket # no network
endif
# Disable tests that windows cannot run yet.
ifeq ($(GOOS),windows)
NOTEST+=os/signal # no signals

View File

@ -18,9 +18,6 @@ GOFILES_darwin=\
GOFILES_linux=\
rand_unix.go\
GOFILES_nacl=\
rand_unix.go\
GOFILES_windows=\
rand_windows.go\

View File

@ -1,20 +0,0 @@
// 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.
package proc
import (
"os"
"syscall"
)
// Process tracing is not supported on Native Client.
func Attach(pid int) (Process, os.Error) {
return nil, os.NewSyscallError("ptrace", syscall.ENACL)
}
func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []*os.File) (Process, os.Error) {
return nil, os.NewSyscallError("fork/exec", syscall.ENACL)
}

View File

@ -1,5 +0,0 @@
// 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.
package proc

View File

@ -17,9 +17,6 @@ GOFILES_darwin=\
GOFILES_linux=\
lp_unix.go\
GOFILES_nacl=\
lp_unix.go\
GOFILES_windows=\
lp_windows.go\

View File

@ -1,77 +0,0 @@
// 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.
// This is a simple demo of Go running under Native Client.
// It is a tetris clone built on top of the exp/nacl/av and exp/draw
// packages.
//
// See ../nacl/README for how to run it.
package main
import (
"exp/nacl/av"
"exp/nacl/srpc"
"log"
"runtime"
"os"
)
var sndc chan []uint16
func main() {
// Native Client requires that some calls are issued
// consistently by the same OS thread.
runtime.LockOSThread()
if srpc.Enabled() {
go srpc.ServeRuntime()
}
args := os.Args
p := pieces4
if len(args) > 1 && args[1] == "-5" {
p = pieces5
}
dx, dy := 500, 500
w, err := av.Init(av.SubsystemVideo|av.SubsystemAudio, dx, dy)
if err != nil {
log.Exit(err)
}
sndc = make(chan []uint16, 10)
go audioServer()
Play(p, w)
}
func audioServer() {
// Native Client requires that all audio calls
// original from a single OS thread.
runtime.LockOSThread()
n, err := av.AudioStream(nil)
if err != nil {
log.Exit(err)
}
for {
b := <-sndc
for len(b)*2 >= n {
var a []uint16
a, b = b[0:n/2], b[n/2:]
n, err = av.AudioStream(a)
if err != nil {
log.Exit(err)
}
println(n, len(b)*2)
}
a := make([]uint16, n/2)
copy(a, b)
n, err = av.AudioStream(a)
}
}
func PlaySound(b []uint16) { sndc <- b }
var whoosh = []uint16{
// Insert your favorite sound samples here.
}

View File

@ -1,26 +0,0 @@
<h1>games/4s</h1>
<table><tr><td valign=top>
<embed name="nacl_module" id="pluginobj" src="8.out" type="application/x-nacl-srpc" width=400 height=600>
<td valign=top>
This is a simple block stacking game, a port of Plan 9's
<a href="http://plan9.bell-labs.com/magic/man2html/1/games">games/4s</a>
<br><br>
To play using the keyboard:
as the blocks fall, the <i>a</i>, <i>s</i>, <i>d</i>, and <i>f</i> keys
move the block left, rotate the block left, rotate the block right,
anad move the block right, respectively.
To drop a block, type the space key.
<b>You may need to click on the game window to
focus the keyboard on it.</b>
<br><br>
To play using the mouse:
as the blocks fall, moving the mouse horizontally positions
the block; left or right clicks rotate the block left or right.
A middle click drops the block.
(Unfortunately, some environments seem to intercept
the middle click before it gets to Native Client.)
<br><br>
To pause the game, type <i>z</i>, <i>p</i>, or the escape key.
</table>

View File

@ -1,9 +0,0 @@
// 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.
// Hack to produce a binary that defaults to 5s.
package main
func init() { pieces4 = pieces5 }

View File

@ -1,26 +0,0 @@
<h1>games/5s</h1>
<table><tr><td valign=top>
<embed name="nacl_module" id="pluginobj" src="8.5s" type="application/x-nacl-srpc" width=400 height=600>
<td valign=top>
This is a simple block stacking game, a port of Plan 9's
<a href="http://plan9.bell-labs.com/magic/man2html/1/games">games/5s</a>
<br><br>
To play using the keyboard:
as the blocks fall, the <i>a</i>, <i>s</i>, <i>d</i>, and <i>f</i> keys
move the block left, rotate the block left, rotate the block right,
anad move the block right, respectively.
To drop a block, type the space key.
<b>You may need to click on the game window to
focus the keyboard on it.</b>
<br><br>
To play using the mouse:
as the blocks fall, moving the mouse horizontally positions
the block; left or right clicks rotate the block left or right.
A middle click drops the block.
(Unfortunately, some environments seem to intercept
the middle click before it gets to Native Client.)
<br><br>
To pause the game, type <i>z</i>, <i>p</i>, or the escape key.
</table>

View File

@ -1,20 +0,0 @@
# 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.
all: 8.out 8.5s
4s.8: 4s.go data.go xs.go
8g 4s.go data.go xs.go
5s.8: 5s.go 4s.go data.go xs.go
8g 5s.go 4s.go data.go xs.go
8.out: 4s.8
8l 4s.8
8.5s: 5s.8
8l -o 8.5s 5s.8
clean:
rm -f *.8 8.out

View File

@ -1,142 +0,0 @@
// games/4s - a tetris clone
//
// Derived from Plan 9's /sys/src/games/xs.c
// http://plan9.bell-labs.com/sources/plan9/sys/src/games/xs.c
//
// Copyright (C) 2003, Lucent Technologies Inc. and others. All Rights Reserved.
// Portions Copyright 2009 The Go Authors. All Rights Reserved.
// Distributed under the terms of the Lucent Public License Version 1.02
// See http://plan9.bell-labs.com/plan9/license.html
package main
import . "image"
var pieces4 = []Piece{
{0, 0, Point{4, 1}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
{1, 0, Point{1, 4}, []Point{{0, 0}, {0, 1}, {0, 1}, {0, 1}}, nil, nil},
{2, 0, Point{4, 1}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
{3, 0, Point{1, 4}, []Point{{0, 0}, {0, 1}, {0, 1}, {0, 1}}, nil, nil},
{0, 3, Point{2, 2}, []Point{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}, nil, nil},
{1, 3, Point{2, 2}, []Point{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}, nil, nil},
{2, 3, Point{2, 2}, []Point{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}, nil, nil},
{3, 3, Point{2, 2}, []Point{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}, nil, nil},
{0, 1, Point{3, 2}, []Point{{0, 0}, {1, 0}, {1, 0}, {0, 1}}, nil, nil},
{1, 1, Point{2, 3}, []Point{{1, 0}, {0, 1}, {0, 1}, {-1, 0}}, nil, nil},
{2, 1, Point{3, 2}, []Point{{0, 0}, {0, 1}, {1, 0}, {1, 0}}, nil, nil},
{3, 1, Point{2, 3}, []Point{{0, 0}, {1, 0}, {-1, 1}, {0, 1}}, nil, nil},
{0, 2, Point{3, 2}, []Point{{0, 1}, {1, 0}, {1, 0}, {0, -1}}, nil, nil},
{1, 2, Point{2, 3}, []Point{{0, 0}, {0, 1}, {0, 1}, {1, 0}}, nil, nil},
{2, 2, Point{3, 2}, []Point{{0, 0}, {1, 0}, {1, 0}, {-2, 1}}, nil, nil},
{3, 2, Point{2, 3}, []Point{{0, 0}, {1, 0}, {0, 1}, {0, 1}}, nil, nil},
{0, 4, Point{3, 2}, []Point{{0, 0}, {1, 0}, {1, 0}, {-1, 1}}, nil, nil},
{1, 4, Point{2, 3}, []Point{{1, 0}, {-1, 1}, {1, 0}, {0, 1}}, nil, nil},
{2, 4, Point{3, 2}, []Point{{1, 0}, {-1, 1}, {1, 0}, {1, 0}}, nil, nil},
{3, 4, Point{2, 3}, []Point{{0, 0}, {0, 1}, {0, 1}, {1, -1}}, nil, nil},
{0, 5, Point{3, 2}, []Point{{0, 0}, {1, 0}, {0, 1}, {1, 0}}, nil, nil},
{1, 5, Point{2, 3}, []Point{{1, 0}, {0, 1}, {-1, 0}, {0, 1}}, nil, nil},
{2, 5, Point{3, 2}, []Point{{0, 0}, {1, 0}, {0, 1}, {1, 0}}, nil, nil},
{3, 5, Point{2, 3}, []Point{{1, 0}, {0, 1}, {-1, 0}, {0, 1}}, nil, nil},
{0, 6, Point{3, 2}, []Point{{0, 1}, {1, 0}, {0, -1}, {1, 0}}, nil, nil},
{1, 6, Point{2, 3}, []Point{{0, 0}, {0, 1}, {1, 0}, {0, 1}}, nil, nil},
{2, 6, Point{3, 2}, []Point{{0, 1}, {1, 0}, {0, -1}, {1, 0}}, nil, nil},
{3, 6, Point{2, 3}, []Point{{0, 0}, {0, 1}, {1, 0}, {0, 1}}, nil, nil},
}
var pieces5 = []Piece{
{0, 1, Point{5, 1}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
{1, 1, Point{1, 5}, []Point{{0, 0}, {0, 1}, {0, 1}, {0, 1}, {0, 1}}, nil, nil},
{2, 1, Point{5, 1}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
{3, 1, Point{1, 5}, []Point{{0, 0}, {0, 1}, {0, 1}, {0, 1}, {0, 1}}, nil, nil},
{0, 0, Point{4, 2}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}, {0, 1}}, nil, nil},
{1, 0, Point{2, 4}, []Point{{1, 0}, {0, 1}, {0, 1}, {0, 1}, {-1, 0}}, nil, nil},
{2, 0, Point{4, 2}, []Point{{0, 0}, {0, 1}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
{3, 0, Point{2, 4}, []Point{{0, 0}, {1, 0}, {-1, 1}, {0, 1}, {0, 1}}, nil, nil},
{0, 2, Point{4, 2}, []Point{{0, 0}, {0, 1}, {1, -1}, {1, 0}, {1, 0}}, nil, nil},
{1, 2, Point{2, 4}, []Point{{0, 0}, {1, 0}, {0, 1}, {0, 1}, {0, 1}}, nil, nil},
{2, 2, Point{4, 2}, []Point{{0, 1}, {1, 0}, {1, 0}, {1, 0}, {0, -1}}, nil, nil},
{3, 2, Point{2, 4}, []Point{{0, 0}, {0, 1}, {0, 1}, {0, 1}, {1, 0}}, nil, nil},
{0, 7, Point{3, 3}, []Point{{0, 0}, {1, 0}, {1, 0}, {0, 1}, {0, 1}}, nil, nil},
{1, 7, Point{3, 3}, []Point{{0, 2}, {1, 0}, {1, 0}, {0, -1}, {0, -1}}, nil, nil},
{2, 7, Point{3, 3}, []Point{{0, 0}, {0, 1}, {0, 1}, {1, 0}, {1, 0}}, nil, nil},
{3, 7, Point{3, 3}, []Point{{0, 2}, {0, -1}, {0, -1}, {1, 0}, {1, 0}}, nil, nil},
{0, 3, Point{3, 2}, []Point{{0, 0}, {1, 0}, {1, 0}, {-2, 1}, {1, 0}}, nil, nil},
{1, 3, Point{2, 3}, []Point{{0, 0}, {1, 0}, {-1, 1}, {1, 0}, {0, 1}}, nil, nil},
{2, 3, Point{3, 2}, []Point{{1, 0}, {1, 0}, {-2, 1}, {1, 0}, {1, 0}}, nil, nil},
{3, 3, Point{2, 3}, []Point{{0, 0}, {0, 1}, {1, 0}, {-1, 1}, {1, 0}}, nil, nil},
{0, 4, Point{3, 2}, []Point{{0, 0}, {1, 0}, {1, 0}, {-1, 1}, {1, 0}}, nil, nil},
{1, 4, Point{2, 3}, []Point{{1, 0}, {-1, 1}, {1, 0}, {-1, 1}, {1, 0}}, nil, nil},
{2, 4, Point{3, 2}, []Point{{0, 0}, {1, 0}, {-1, 1}, {1, 0}, {1, 0}}, nil, nil},
{3, 4, Point{2, 3}, []Point{{0, 0}, {1, 0}, {-1, 1}, {1, 0}, {-1, 1}}, nil, nil},
{0, 7, Point{3, 2}, []Point{{0, 0}, {2, 0}, {-2, 1}, {1, 0}, {1, 0}}, nil, nil},
{1, 7, Point{2, 3}, []Point{{0, 0}, {1, 0}, {-1, 1}, {0, 1}, {1, 0}}, nil, nil},
{2, 7, Point{3, 2}, []Point{{0, 0}, {1, 0}, {1, 0}, {-2, 1}, {2, 0}}, nil, nil},
{3, 7, Point{2, 3}, []Point{{0, 0}, {1, 0}, {0, 1}, {-1, 1}, {1, 0}}, nil, nil},
{0, 5, Point{3, 3}, []Point{{0, 0}, {1, 0}, {0, 1}, {1, 0}, {-1, 1}}, nil, nil},
{1, 5, Point{3, 3}, []Point{{2, 0}, {-2, 1}, {1, 0}, {1, 0}, {-1, 1}}, nil, nil},
{2, 5, Point{3, 3}, []Point{{1, 0}, {-1, 1}, {1, 0}, {0, 1}, {1, 0}}, nil, nil},
{3, 5, Point{3, 3}, []Point{{1, 0}, {-1, 1}, {1, 0}, {1, 0}, {-2, 1}}, nil, nil},
{0, 6, Point{3, 3}, []Point{{1, 0}, {1, 0}, {-2, 1}, {1, 0}, {0, 1}}, nil, nil},
{1, 6, Point{3, 3}, []Point{{1, 0}, {-1, 1}, {1, 0}, {1, 0}, {0, 1}}, nil, nil},
{2, 6, Point{3, 3}, []Point{{1, 0}, {0, 1}, {1, 0}, {-2, 1}, {1, 0}}, nil, nil},
{3, 6, Point{3, 3}, []Point{{0, 0}, {0, 1}, {1, 0}, {1, 0}, {-1, 1}}, nil, nil},
{0, 0, Point{4, 2}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}, {-2, 1}}, nil, nil},
{1, 0, Point{2, 4}, []Point{{1, 0}, {-1, 1}, {1, 0}, {0, 1}, {0, 1}}, nil, nil},
{2, 0, Point{4, 2}, []Point{{2, 0}, {-2, 1}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
{3, 0, Point{2, 4}, []Point{{0, 0}, {0, 1}, {0, 1}, {1, 0}, {-1, 1}}, nil, nil},
{0, 2, Point{4, 2}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}, {-1, 1}}, nil, nil},
{1, 2, Point{2, 4}, []Point{{1, 0}, {0, 1}, {-1, 1}, {1, 0}, {0, 1}}, nil, nil},
{2, 2, Point{4, 2}, []Point{{1, 0}, {-1, 1}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
{3, 2, Point{2, 4}, []Point{{0, 0}, {0, 1}, {1, 0}, {-1, 1}, {0, 1}}, nil, nil},
{0, 1, Point{3, 3}, []Point{{0, 0}, {1, 0}, {0, 1}, {1, 0}, {0, 1}}, nil, nil},
{1, 1, Point{3, 3}, []Point{{2, 0}, {-1, 1}, {1, 0}, {-2, 1}, {1, 0}}, nil, nil},
{2, 1, Point{3, 3}, []Point{{0, 0}, {0, 1}, {1, 0}, {0, 1}, {1, 0}}, nil, nil},
{3, 1, Point{3, 3}, []Point{{1, 0}, {1, 0}, {-2, 1}, {1, 0}, {-1, 1}}, nil, nil},
{0, 3, Point{3, 3}, []Point{{0, 0}, {1, 0}, {1, 0}, {-1, 1}, {0, 1}}, nil, nil},
{1, 3, Point{3, 3}, []Point{{2, 0}, {-2, 1}, {1, 0}, {1, 0}, {0, 1}}, nil, nil},
{2, 3, Point{3, 3}, []Point{{1, 0}, {0, 1}, {-1, 1}, {1, 0}, {1, 0}}, nil, nil},
{3, 3, Point{3, 3}, []Point{{0, 0}, {0, 1}, {1, 0}, {1, 0}, {-2, 1}}, nil, nil},
{0, 4, Point{3, 3}, []Point{{1, 0}, {-1, 1}, {1, 0}, {1, 0}, {-1, 1}}, nil, nil},
{1, 4, Point{3, 3}, []Point{{1, 0}, {-1, 1}, {1, 0}, {1, 0}, {-1, 1}}, nil, nil},
{2, 4, Point{3, 3}, []Point{{1, 0}, {-1, 1}, {1, 0}, {1, 0}, {-1, 1}}, nil, nil},
{3, 4, Point{3, 3}, []Point{{1, 0}, {-1, 1}, {1, 0}, {1, 0}, {-1, 1}}, nil, nil},
{0, 8, Point{4, 2}, []Point{{0, 0}, {1, 0}, {0, 1}, {1, 0}, {1, 0}}, nil, nil},
{1, 8, Point{2, 4}, []Point{{1, 0}, {-1, 1}, {1, 0}, {-1, 1}, {0, 1}}, nil, nil},
{2, 8, Point{4, 2}, []Point{{0, 0}, {1, 0}, {1, 0}, {0, 1}, {1, 0}}, nil, nil},
{3, 8, Point{2, 4}, []Point{{1, 0}, {0, 1}, {-1, 1}, {1, 0}, {-1, 1}}, nil, nil},
{0, 9, Point{4, 2}, []Point{{2, 0}, {1, 0}, {-3, 1}, {1, 0}, {1, 0}}, nil, nil},
{1, 9, Point{2, 4}, []Point{{0, 0}, {0, 1}, {0, 1}, {1, 0}, {0, 1}}, nil, nil},
{2, 9, Point{4, 2}, []Point{{1, 0}, {1, 0}, {1, 0}, {-3, 1}, {1, 0}}, nil, nil},
{3, 9, Point{2, 4}, []Point{{0, 0}, {0, 1}, {1, 0}, {0, 1}, {0, 1}}, nil, nil},
{0, 5, Point{3, 3}, []Point{{0, 0}, {0, 1}, {1, 0}, {1, 0}, {0, 1}}, nil, nil},
{1, 5, Point{3, 3}, []Point{{1, 0}, {1, 0}, {-1, 1}, {-1, 1}, {1, 0}}, nil, nil},
{2, 5, Point{3, 3}, []Point{{0, 0}, {0, 1}, {1, 0}, {1, 0}, {0, 1}}, nil, nil},
{3, 5, Point{3, 3}, []Point{{1, 0}, {1, 0}, {-1, 1}, {-1, 1}, {1, 0}}, nil, nil},
{0, 6, Point{3, 3}, []Point{{2, 0}, {-2, 1}, {1, 0}, {1, 0}, {-2, 1}}, nil, nil},
{1, 6, Point{3, 3}, []Point{{0, 0}, {1, 0}, {0, 1}, {0, 1}, {1, 0}}, nil, nil},
{2, 6, Point{3, 3}, []Point{{2, 0}, {-2, 1}, {1, 0}, {1, 0}, {-2, 1}}, nil, nil},
{3, 6, Point{3, 3}, []Point{{0, 0}, {1, 0}, {0, 1}, {0, 1}, {1, 0}}, nil, nil},
}

View File

@ -1,750 +0,0 @@
// games/4s - a tetris clone
//
// Derived from Plan 9's /sys/src/games/xs.c
// http://plan9.bell-labs.com/sources/plan9/sys/src/games/xs.c
//
// Copyright (C) 2003, Lucent Technologies Inc. and others. All Rights Reserved.
// Portions Copyright 2009 The Go Authors. All Rights Reserved.
// Distributed under the terms of the Lucent Public License Version 1.02
// See http://plan9.bell-labs.com/plan9/license.html
/*
* engine for 4s, 5s, etc
*/
package main
import (
"exp/draw"
"image"
"log"
"os"
"rand"
"time"
)
/*
Cursor whitearrow = {
{0, 0},
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC,
0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF8, 0xFF, 0xFC,
0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC,
0xF3, 0xF8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, },
{0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0xC0, 0x1C,
0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x38, 0xC0, 0x1C,
0xC0, 0x0E, 0xC0, 0x07, 0xCE, 0x0E, 0xDF, 0x1C,
0xD3, 0xB8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, }
};
*/
const (
CNone = 0
CBounds = 1
CPiece = 2
NX = 10
NY = 20
NCOL = 10
MAXN = 5
)
var (
N int
display draw.Window
screen draw.Image
screenr image.Rectangle
board [NY][NX]byte
rboard image.Rectangle
pscore image.Point
scoresz image.Point
pcsz = 32
pos image.Point
bbr, bb2r image.Rectangle
bb, bbmask, bb2, bb2mask *image.RGBA
whitemask image.Image
br, br2 image.Rectangle
points int
dt int
DY int
DMOUSE int
lastmx int
mouse draw.MouseEvent
newscreen bool
timerc <-chan int64
suspc chan bool
mousec chan draw.MouseEvent
resizec chan bool
kbdc chan int
suspended bool
tsleep int
piece *Piece
pieces []Piece
)
type Piece struct {
rot int
tx int
sz image.Point
d []image.Point
left *Piece
right *Piece
}
var txbits = [NCOL][32]byte{
{0xDD, 0xDD, 0xFF, 0xFF, 0x77, 0x77, 0xFF, 0xFF,
0xDD, 0xDD, 0xFF, 0xFF, 0x77, 0x77, 0xFF, 0xFF,
0xDD, 0xDD, 0xFF, 0xFF, 0x77, 0x77, 0xFF, 0xFF,
0xDD, 0xDD, 0xFF, 0xFF, 0x77, 0x77, 0xFF, 0xFF,
},
{0xDD, 0xDD, 0x77, 0x77, 0xDD, 0xDD, 0x77, 0x77,
0xDD, 0xDD, 0x77, 0x77, 0xDD, 0xDD, 0x77, 0x77,
0xDD, 0xDD, 0x77, 0x77, 0xDD, 0xDD, 0x77, 0x77,
0xDD, 0xDD, 0x77, 0x77, 0xDD, 0xDD, 0x77, 0x77,
},
{0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
},
{0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
},
{0x22, 0x22, 0x88, 0x88, 0x22, 0x22, 0x88, 0x88,
0x22, 0x22, 0x88, 0x88, 0x22, 0x22, 0x88, 0x88,
0x22, 0x22, 0x88, 0x88, 0x22, 0x22, 0x88, 0x88,
0x22, 0x22, 0x88, 0x88, 0x22, 0x22, 0x88, 0x88,
},
{0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
},
{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
},
{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
},
{0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
},
{0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
},
}
var txpix = [NCOL]image.Image{
image.NewColorImage(image.RGBAColor{0xFF, 0xFF, 0x00, 0xFF}), /* yellow */
image.NewColorImage(image.RGBAColor{0x00, 0xFF, 0xFF, 0xFF}), /* cyan */
image.NewColorImage(image.RGBAColor{0x00, 0xFF, 0x00, 0xFF}), /* lime green */
image.NewColorImage(image.RGBAColor{0x00, 0x5D, 0xBB, 0xFF}), /* slate */
image.NewColorImage(image.RGBAColor{0xFF, 0x00, 0x00, 0xFF}), /* red */
image.NewColorImage(image.RGBAColor{0x55, 0xAA, 0xAA, 0xFF}), /* olive green */
image.NewColorImage(image.RGBAColor{0x00, 0x00, 0xFF, 0xFF}), /* blue */
image.NewColorImage(image.RGBAColor{0xFF, 0x55, 0xAA, 0xFF}), /* pink */
image.NewColorImage(image.RGBAColor{0xFF, 0xAA, 0xFF, 0xFF}), /* lavender */
image.NewColorImage(image.RGBAColor{0xBB, 0x00, 0x5D, 0xFF}), /* maroon */
}
func movemouse() int {
//mouse.image.Point = image.Pt(rboard.Min.X + rboard.Dx()/2, rboard.Min.Y + rboard.Dy()/2);
//moveto(mousectl, mouse.Xy);
return mouse.Loc.X
}
func warp(p image.Point, x int) int {
if !suspended && piece != nil {
x = pos.X + piece.sz.X*pcsz/2
if p.Y < rboard.Min.Y {
p.Y = rboard.Min.Y
}
if p.Y >= rboard.Max.Y {
p.Y = rboard.Max.Y - 1
}
//moveto(mousectl, image.Pt(x, p.Y));
}
return x
}
func initPieces() {
for i := range pieces {
p := &pieces[i]
if p.rot == 3 {
p.right = &pieces[i-3]
} else {
p.right = &pieces[i+1]
}
if p.rot == 0 {
p.left = &pieces[i+3]
} else {
p.left = &pieces[i-1]
}
}
}
func collide(pt image.Point, p *Piece) bool {
pt.X = (pt.X - rboard.Min.X) / pcsz
pt.Y = (pt.Y - rboard.Min.Y) / pcsz
for _, q := range p.d {
pt.X += q.X
pt.Y += q.Y
if pt.X < 0 || pt.X >= NX || pt.Y < 0 || pt.Y >= NY {
return true
continue
}
if board[pt.Y][pt.X] != 0 {
return true
}
}
return false
}
func collider(pt, pmax image.Point) bool {
pi := (pt.X - rboard.Min.X) / pcsz
pj := (pt.Y - rboard.Min.Y) / pcsz
n := pmax.X / pcsz
m := pmax.Y/pcsz + 1
for i := pi; i < pi+n && i < NX; i++ {
for j := pj; j < pj+m && j < NY; j++ {
if board[j][i] != 0 {
return true
}
}
}
return false
}
func setpiece(p *Piece) {
draw.Draw(bb, bbr, image.White, image.ZP)
draw.Draw(bbmask, bbr, image.Transparent, image.ZP)
br = image.Rect(0, 0, 0, 0)
br2 = br
piece = p
if p == nil {
return
}
var op image.Point
var r image.Rectangle
r.Min = bbr.Min
for i, pt := range p.d {
r.Min.X += pt.X * pcsz
r.Min.Y += pt.Y * pcsz
r.Max.X = r.Min.X + pcsz
r.Max.Y = r.Min.Y + pcsz
if i == 0 {
draw.Draw(bb, r, image.Black, image.ZP)
draw.Draw(bb, r.Inset(1), txpix[piece.tx], image.ZP)
draw.Draw(bbmask, r, image.Opaque, image.ZP)
op = r.Min
} else {
draw.Draw(bb, r, bb, op)
draw.Draw(bbmask, r, bbmask, op)
}
if br.Max.X < r.Max.X {
br.Max.X = r.Max.X
}
if br.Max.Y < r.Max.Y {
br.Max.Y = r.Max.Y
}
}
br.Max = br.Max.Sub(bbr.Min)
delta := image.Pt(0, DY)
br2.Max = br.Max.Add(delta)
r = br.Add(bb2r.Min)
r2 := br2.Add(bb2r.Min)
draw.Draw(bb2, r2, image.White, image.ZP)
draw.Draw(bb2, r.Add(delta), bb, bbr.Min)
draw.Draw(bb2mask, r2, image.Transparent, image.ZP)
draw.DrawMask(bb2mask, r, image.Opaque, bbr.Min, bbmask, image.ZP, draw.Over)
draw.DrawMask(bb2mask, r.Add(delta), image.Opaque, bbr.Min, bbmask, image.ZP, draw.Over)
}
func drawpiece() {
draw.DrawMask(screen, br.Add(pos), bb, bbr.Min, bbmask, image.ZP, draw.Over)
if suspended {
draw.DrawMask(screen, br.Add(pos), image.White, image.ZP, whitemask, image.ZP, draw.Over)
}
}
func undrawpiece() {
var mask image.Image
if collider(pos, br.Max) {
mask = bbmask
}
draw.DrawMask(screen, br.Add(pos), image.White, bbr.Min, mask, bbr.Min, draw.Over)
}
func rest() {
pt := pos.Sub(rboard.Min)
pt.X /= pcsz
pt.Y /= pcsz
for _, p := range piece.d {
pt.X += p.X
pt.Y += p.Y
board[pt.Y][pt.X] = byte(piece.tx + 16)
}
}
func canfit(p *Piece) bool {
var dx = [...]int{0, -1, 1, -2, 2, -3, 3, 4, -4}
j := N + 1
if j >= 4 {
j = p.sz.X
if j < p.sz.Y {
j = p.sz.Y
}
j = 2*j - 1
}
for i := 0; i < j; i++ {
var z image.Point
z.X = pos.X + dx[i]*pcsz
z.Y = pos.Y
if !collide(z, p) {
z.Y = pos.Y + pcsz - 1
if !collide(z, p) {
undrawpiece()
pos.X = z.X
return true
}
}
}
return false
}
func score(p int) {
points += p
// snprint(buf, sizeof(buf), "%.6ld", points);
// draw.Draw(screen, draw.Rpt(pscore, pscore.Add(scoresz)), image.White, image.ZP);
// string(screen, pscore, image.Black, image.ZP, font, buf);
}
func drawsq(b draw.Image, p image.Point, ptx int) {
var r image.Rectangle
r.Min = p
r.Max.X = r.Min.X + pcsz
r.Max.Y = r.Min.Y + pcsz
draw.Draw(b, r, image.Black, image.ZP)
draw.Draw(b, r.Inset(1), txpix[ptx], image.ZP)
}
func drawboard() {
draw.Border(screen, rboard.Inset(-2), 2, image.Black, image.ZP)
draw.Draw(screen, image.Rect(rboard.Min.X, rboard.Min.Y-2, rboard.Max.X, rboard.Min.Y),
image.White, image.ZP)
for i := 0; i < NY; i++ {
for j := 0; j < NX; j++ {
if board[i][j] != 0 {
drawsq(screen, image.Pt(rboard.Min.X+j*pcsz, rboard.Min.Y+i*pcsz), int(board[i][j]-16))
}
}
}
score(0)
if suspended {
draw.DrawMask(screen, screenr, image.White, image.ZP, whitemask, image.ZP, draw.Over)
}
}
func choosepiece() {
for {
i := rand.Intn(len(pieces))
setpiece(&pieces[i])
pos = rboard.Min
pos.X += rand.Intn(NX) * pcsz
if !collide(image.Pt(pos.X, pos.Y+pcsz-DY), piece) {
break
}
}
drawpiece()
display.FlushImage()
}
func movepiece() bool {
var mask image.Image
if collide(image.Pt(pos.X, pos.Y+pcsz), piece) {
return false
}
if collider(pos, br2.Max) {
mask = bb2mask
}
draw.DrawMask(screen, br2.Add(pos), bb2, bb2r.Min, mask, bb2r.Min, draw.Over)
pos.Y += DY
display.FlushImage()
return true
}
func suspend(s bool) {
suspended = s
/*
if suspended {
setcursor(mousectl, &whitearrow);
} else {
setcursor(mousectl, nil);
}
*/
if !suspended {
drawpiece()
}
drawboard()
display.FlushImage()
}
func pause(t int) {
display.FlushImage()
for {
select {
case s := <-suspc:
if !suspended && s {
suspend(true)
} else if suspended && !s {
suspend(false)
lastmx = warp(mouse.Loc, lastmx)
}
case <-timerc:
if suspended {
break
}
t -= tsleep
if t < 0 {
return
}
case <-resizec:
//redraw(true);
case mouse = <-mousec:
case <-kbdc:
}
}
}
func horiz() bool {
var lev [MAXN]int
h := 0
for i := 0; i < NY; i++ {
for j := 0; board[i][j] != 0; j++ {
if j == NX-1 {
lev[h] = i
h++
break
}
}
}
if h == 0 {
return false
}
r := rboard
newscreen = false
for j := 0; j < h; j++ {
r.Min.Y = rboard.Min.Y + lev[j]*pcsz
r.Max.Y = r.Min.Y + pcsz
draw.DrawMask(screen, r, image.White, image.ZP, whitemask, image.ZP, draw.Over)
display.FlushImage()
}
PlaySound(whoosh)
for i := 0; i < 3; i++ {
pause(250)
if newscreen {
drawboard()
break
}
for j := 0; j < h; j++ {
r.Min.Y = rboard.Min.Y + lev[j]*pcsz
r.Max.Y = r.Min.Y + pcsz
draw.DrawMask(screen, r, image.White, image.ZP, whitemask, image.ZP, draw.Over)
}
display.FlushImage()
}
r = rboard
for j := 0; j < h; j++ {
i := NY - lev[j] - 1
score(250 + 10*i*i)
r.Min.Y = rboard.Min.Y
r.Max.Y = rboard.Min.Y + lev[j]*pcsz
draw.Draw(screen, r.Add(image.Pt(0, pcsz)), screen, r.Min)
r.Max.Y = rboard.Min.Y + pcsz
draw.Draw(screen, r, image.White, image.ZP)
for k := lev[j] - 1; k >= 0; k-- {
board[k+1] = board[k]
}
board[0] = [NX]byte{}
}
display.FlushImage()
return true
}
func mright() {
if !collide(image.Pt(pos.X+pcsz, pos.Y), piece) &&
!collide(image.Pt(pos.X+pcsz, pos.Y+pcsz-DY), piece) {
undrawpiece()
pos.X += pcsz
drawpiece()
display.FlushImage()
}
}
func mleft() {
if !collide(image.Pt(pos.X-pcsz, pos.Y), piece) &&
!collide(image.Pt(pos.X-pcsz, pos.Y+pcsz-DY), piece) {
undrawpiece()
pos.X -= pcsz
drawpiece()
display.FlushImage()
}
}
func rright() {
if canfit(piece.right) {
setpiece(piece.right)
drawpiece()
display.FlushImage()
}
}
func rleft() {
if canfit(piece.left) {
setpiece(piece.left)
drawpiece()
display.FlushImage()
}
}
var fusst = 0
func drop(f bool) bool {
if f {
score(5 * (rboard.Max.Y - pos.Y) / pcsz)
for movepiece() {
}
}
fusst = 0
rest()
if pos.Y == rboard.Min.Y && !horiz() {
return true
}
horiz()
setpiece(nil)
pause(1500)
choosepiece()
lastmx = warp(mouse.Loc, lastmx)
return false
}
func play() {
var om draw.MouseEvent
dt = 64
lastmx = -1
lastmx = movemouse()
choosepiece()
lastmx = warp(mouse.Loc, lastmx)
for {
select {
case mouse = <-mousec:
if suspended {
om = mouse
break
}
if lastmx < 0 {
lastmx = mouse.Loc.X
}
if mouse.Loc.X > lastmx+DMOUSE {
mright()
lastmx = mouse.Loc.X
}
if mouse.Loc.X < lastmx-DMOUSE {
mleft()
lastmx = mouse.Loc.X
}
if mouse.Buttons&^om.Buttons&1 == 1 {
rleft()
}
if mouse.Buttons&^om.Buttons&2 == 2 {
if drop(true) {
return
}
}
if mouse.Buttons&^om.Buttons&4 == 4 {
rright()
}
om = mouse
case s := <-suspc:
if !suspended && s {
suspend(true)
} else if suspended && !s {
suspend(false)
lastmx = warp(mouse.Loc, lastmx)
}
case <-resizec:
//redraw(true);
case r := <-kbdc:
if suspended {
break
}
switch r {
case 'f', ';':
mright()
case 'a', 'j':
mleft()
case 'd', 'l':
rright()
case 's', 'k':
rleft()
case ' ':
if drop(true) {
return
}
}
case <-timerc:
if suspended {
break
}
dt -= tsleep
if dt < 0 {
i := 1
dt = 16 * (points + rand.Intn(10000) - 5000) / 10000
if dt >= 32 {
i += (dt - 32) / 16
dt = 32
}
dt = 52 - dt
for ; i > 0; i-- {
if movepiece() {
continue
}
fusst++
if fusst == 40 {
if drop(false) {
return
}
break
}
}
}
}
}
}
func suspproc() {
s := false
for {
select {
case mouse = <-mousec:
mousec <- mouse
case r := <-kbdc:
switch r {
case 'q', 'Q', 0x04, 0x7F:
os.Exit(0)
default:
if s {
s = false
suspc <- s
break
}
switch r {
case 'z', 'Z', 'p', 'P', 0x1B:
s = true
suspc <- s
default:
kbdc <- r
}
}
}
}
}
func redraw(new bool) {
// if new && getwindow(display, Refmesg) < 0 {
// sysfatal("can't reattach to window");
// }
r := screen.Bounds()
pos.X = (pos.X - rboard.Min.X) / pcsz
pos.Y = (pos.Y - rboard.Min.Y) / pcsz
dx := r.Max.X - r.Min.X
dy := r.Max.Y - r.Min.Y - 2*32
DY = dx / NX
if DY > dy/NY {
DY = dy / NY
}
DY /= 8
if DY > 4 {
DY = 4
}
pcsz = DY * 8
DMOUSE = pcsz / 3
if pcsz < 8 {
log.Exitf("screen too small: %d", pcsz)
}
rboard = screenr
rboard.Min.X += (dx - pcsz*NX) / 2
rboard.Min.Y += (dy-pcsz*NY)/2 + 32
rboard.Max.X = rboard.Min.X + NX*pcsz
rboard.Max.Y = rboard.Min.Y + NY*pcsz
pscore.X = rboard.Min.X + 8
pscore.Y = rboard.Min.Y - 32
// scoresz = stringsize(font, "000000");
pos.X = pos.X*pcsz + rboard.Min.X
pos.Y = pos.Y*pcsz + rboard.Min.Y
bbr = image.Rect(0, 0, N*pcsz, N*pcsz)
bb = image.NewRGBA(bbr.Max.X, bbr.Max.Y)
bbmask = image.NewRGBA(bbr.Max.X, bbr.Max.Y) // actually just a bitmap
bb2r = image.Rect(0, 0, N*pcsz, N*pcsz+DY)
bb2 = image.NewRGBA(bb2r.Dx(), bb2r.Dy())
bb2mask = image.NewRGBA(bb2r.Dx(), bb2r.Dy()) // actually just a bitmap
draw.Draw(screen, screenr, image.White, image.ZP)
drawboard()
setpiece(piece)
if piece != nil {
drawpiece()
}
lastmx = movemouse()
newscreen = true
display.FlushImage()
}
func demuxEvents(w draw.Window) {
for event := range w.EventChan() {
switch e := event.(type) {
case draw.MouseEvent:
mousec <- e
case draw.ConfigEvent:
resizec <- true
case draw.KeyEvent:
kbdc <- e.Key
}
}
os.Exit(0)
}
func Play(pp []Piece, ctxt draw.Window) {
display = ctxt
screen = ctxt.Screen()
screenr = screen.Bounds()
pieces = pp
N = len(pieces[0].d)
initPieces()
rand.Seed(int64(time.Nanoseconds() % (1e9 - 1)))
whitemask = image.NewColorImage(image.AlphaColor{0x7F})
tsleep = 50
timerc = time.Tick(int64(tsleep/2) * 1e6)
suspc = make(chan bool)
mousec = make(chan draw.MouseEvent)
resizec = make(chan bool)
kbdc = make(chan int)
go demuxEvents(ctxt)
go suspproc()
points = 0
redraw(false)
play()
}

View File

@ -1,36 +0,0 @@
To try Native Client by running 4s (tetris) or 5s or Spacewar:
1. Build the Go distribution for your native system.
2. Download the Native Client SDK and install it.
http://code.google.com/p/nativeclient-sdk/wiki/HowTo_GetStarted
* You only need to do steps 1 and 2.
3. Copy "./native_client*/toolchain/*/bin/sel_ldr"
from the Native Client distribution somewhere in your path as "nacl".
This will let you run binaries using "nacl -M 8.out".
The -M flag enables multithreaded access to the video library.
4. Build the Go distribution again, this time for Native Client:
cd $GOROOT/src
./all-nacl.bash
* If you didn't do step 3, the tests at the end will fail, but that's okay.
* If you are on a Mac, your dock will flicker as the "nacl" binary
starts and stops while the tests run. You can stop the tests at any time.
5. Run the programs by using
nacl -M $GOROOT/src/pkg/exp/4s/8.out
nacl -M $GOROOT/src/pkg/exp/4s/8.5s
nacl -M $GOROOT/src/pkg/exp/spacewar/8.out
6. If you have an old copy of the Native Client plugin, you may be
able to run the programs in your browser, by running
"godoc --http=:5103" and then visiting
* http://localhost:5103/src/pkg/exp/4s/4s.html
* http://localhost:5103/src/pkg/exp/4s/5s.html [sic]
* http://localhost:5103/src/pkg/exp/spacewar/spacewar.html
This usage is deprecated in favor of newere APIs in recent
releases of Native Client. More work will be necessary to support
interactive graphics when using those releases.

View File

@ -1,13 +0,0 @@
# 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.
include ../../../../Make.inc
TARG=exp/nacl/av
GOFILES=\
av.go\
event.go\
image.go\
include ../../../../Make.pkg

View File

@ -1,289 +0,0 @@
// 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.
// Native Client audio/video
// Package av implements audio and video access for Native Client
// binaries running standalone or embedded in a web browser window.
//
// The C version of the API is documented at
// http://nativeclient.googlecode.com/svn/data/docs_tarball/nacl/googleclient/native_client/scons-out/doc/html/group__audio__video.html
package av
import (
"exp/draw"
"exp/nacl/srpc"
"log"
"os"
"syscall"
"unsafe"
)
var srpcEnabled = srpc.Enabled()
// native_client/src/trusted/service_runtime/include/sys/audio_video.h
// Subsystem values for Init.
const (
SubsystemVideo = 1 << iota
SubsystemAudio
SubsystemEmbed
)
// SubsystemRawEvents;
// Audio formats.
const (
AudioFormatStereo44K = iota
AudioFormatStereo48K
)
// A Window represents a connection to the Native Client window.
// It implements draw.Context.
type Window struct {
Embedded bool // running as part of a web page?
*Image // screen image
eventc chan interface{}
}
// *Window implements draw.Window.
var _ draw.Window = (*Window)(nil)
func (w *Window) EventChan() <-chan interface{} { return w.eventc }
func (w *Window) Close() os.Error {
// TODO(nigeltao): implement.
return nil
}
func (w *Window) Screen() draw.Image { return w.Image }
// Init initializes the Native Client subsystems specified by subsys.
// Init must be called before using any of the other functions
// in this package, and it must be called only once.
//
// If the SubsystemVideo flag is set, Init requests a window of size dx×dy.
// When embedded in a web page, the web page's window specification
// overrides the parameters to Init, so the returned Window may have
// a different size than requested.
//
// If the SubsystemAudio flag is set, Init requests a connection to the
// audio device carrying 44 kHz 16-bit stereo PCM audio samples.
func Init(subsys int, dx, dy int) (*Window, os.Error) {
xsubsys := subsys
if srpcEnabled {
waitBridge()
xsubsys &^= SubsystemVideo | SubsystemEmbed
}
if xsubsys&SubsystemEmbed != 0 {
return nil, os.NewError("not embedded")
}
w := new(Window)
err := multimediaInit(xsubsys)
if err != nil {
return nil, err
}
if subsys&SubsystemVideo != 0 {
if dx, dy, err = videoInit(dx, dy); err != nil {
return nil, err
}
w.Image = newImage(dx, dy, bridge.pixel)
w.eventc = make(chan interface{}, 64)
}
if subsys&SubsystemAudio != 0 {
var n int
if n, err = audioInit(AudioFormatStereo44K, 2048); err != nil {
return nil, err
}
println("audio", n)
}
if subsys&SubsystemVideo != 0 {
go w.readEvents()
}
return w, nil
}
func (w *Window) FlushImage() {
if w.Image == nil {
return
}
videoUpdate(w.Image.Linear)
}
func multimediaInit(subsys int) (err os.Error) {
return os.NewSyscallError("multimedia_init", syscall.MultimediaInit(subsys))
}
func videoInit(dx, dy int) (ndx, ndy int, err os.Error) {
if srpcEnabled {
bridge.share.ready = 1
return int(bridge.share.width), int(bridge.share.height), nil
}
if e := syscall.VideoInit(dx, dy); e != 0 {
return 0, 0, os.NewSyscallError("video_init", int(e))
}
return dx, dy, nil
}
func videoUpdate(data []Color) (err os.Error) {
if srpcEnabled {
bridge.flushRPC.Call("upcall", nil)
return
}
return os.NewSyscallError("video_update", syscall.VideoUpdate((*uint32)(&data[0])))
}
var noEvents = os.NewError("no events")
func videoPollEvent(ev []byte) (err os.Error) {
if srpcEnabled {
r := bridge.share.eq.ri
if r == bridge.share.eq.wi {
return noEvents
}
copy(ev, bridge.share.eq.event[r][0:])
bridge.share.eq.ri = (r + 1) % eqsize
return nil
}
return os.NewSyscallError("video_poll_event", syscall.VideoPollEvent(&ev[0]))
}
func audioInit(fmt int, want int) (got int, err os.Error) {
var x int
e := syscall.AudioInit(fmt, want, &x)
if e == 0 {
return x, nil
}
return 0, os.NewSyscallError("audio_init", e)
}
var audioSize uintptr
// AudioStream provides access to the audio device.
// Each call to AudioStream writes the given data,
// which should be a slice of 16-bit stereo PCM audio samples,
// and returns the number of samples required by the next
// call to AudioStream.
//
// To find out the initial number of samples to write, call AudioStream(nil).
//
func AudioStream(data []uint16) (nextSize int, err os.Error) {
if audioSize == 0 {
e := os.NewSyscallError("audio_stream", syscall.AudioStream(nil, &audioSize))
return int(audioSize), e
}
if data == nil {
return int(audioSize), nil
}
if uintptr(len(data))*2 != audioSize {
log.Printf("invalid audio size want %d got %d", audioSize, len(data))
}
e := os.NewSyscallError("audio_stream", syscall.AudioStream(&data[0], &audioSize))
return int(audioSize), e
}
// Synchronization structure to wait for bridge to become ready.
var bridge struct {
c chan bool
displayFd int
rpcFd int
share *videoShare
pixel []Color
client *srpc.Client
flushRPC *srpc.RPC
}
// Wait for bridge to become ready.
// When chan is first created, there is nothing in it,
// so this blocks. Once the bridge is ready, multimediaBridge.Run
// will drop a value into the channel. Then any calls
// to waitBridge will finish, taking the value out and immediately putting it back.
func waitBridge() { bridge.c <- <-bridge.c }
const eqsize = 64
// Data structure shared with host via mmap.
type videoShare struct {
revision int32 // definition below is rev 100 unless noted
mapSize int32
// event queue
eq struct {
ri uint32 // read index [0,eqsize)
wi uint32 // write index [0,eqsize)
eof int32
event [eqsize][64]byte
}
// now unused
_, _, _, _ int32
// video backing store information
width, height, _, size int32
ready int32 // rev 0x101
}
// The frame buffer data is videoShareSize bytes after
// the videoShare begins.
const videoShareSize = 16 * 1024
type multimediaBridge struct{}
// If using SRPC, the runtime will call this method to pass in two file descriptors,
// one to mmap to get the display memory, and another to use for SRPCs back
// to the main process.
func (multimediaBridge) Run(arg, ret []interface{}, size []int) srpc.Errno {
bridge.displayFd = arg[0].(int)
bridge.rpcFd = arg[1].(int)
var st syscall.Stat_t
if errno := syscall.Fstat(bridge.displayFd, &st); errno != 0 {
log.Exitf("mmbridge stat display: %s", os.Errno(errno))
}
addr, _, errno := syscall.Syscall6(syscall.SYS_MMAP,
0,
uintptr(st.Size),
syscall.PROT_READ|syscall.PROT_WRITE,
syscall.MAP_SHARED,
uintptr(bridge.displayFd),
0)
if errno != 0 {
log.Exitf("mmap display: %s", os.Errno(errno))
}
bridge.share = (*videoShare)(unsafe.Pointer(addr))
// Overestimate frame buffer size
// (must use a compile-time constant)
// and then reslice. 256 megapixels (1 GB) should be enough.
fb := (*[256 * 1024 * 1024]Color)(unsafe.Pointer(addr + videoShareSize))
bridge.pixel = fb[0 : (st.Size-videoShareSize)/4]
// Configure RPC connection back to client.
var err os.Error
bridge.client, err = srpc.NewClient(bridge.rpcFd)
if err != nil {
log.Exitf("NewClient: %s", err)
}
bridge.flushRPC = bridge.client.NewRPC(nil)
// Notify waiters that the bridge is ready.
println("bridged", bridge.share.revision)
bridge.c <- true
return srpc.OK
}
func init() {
bridge.c = make(chan bool, 1)
if srpcEnabled {
srpc.Add("nacl_multimedia_bridge", "hh:", multimediaBridge{})
}
}

View File

@ -1,473 +0,0 @@
// 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.
// NaCl GUI events.
// Clients do not have raw access to the event stream
// (only filtered through the lens of package draw)
// but perhaps they will.
package av
import (
"encoding/binary"
"exp/draw"
"image"
"log"
"os"
"time"
)
// An eventType identifies the type of a Native Client Event.
type eventType uint8
const (
eventActive = 1 + iota
eventExpose
eventKeyDown
eventKeyUp
eventMouseMotion
eventMouseButtonDown
eventMouseButtonUp
eventQuit
eventUnsupported
)
// A key represents a key on a keyboard.
type key uint16
const (
keyUnknown = 0
keyFirst = 0
keyBackspace = 8
keyTab = 9
keyClear = 12
keyReturn = 13
keyPause = 19
keyEscape = 27
keySpace = 32
keyExclaim = 33
keyQuotedbl = 34
keyHash = 35
keyDollar = 36
keyAmpersand = 38
keyQuote = 39
keyLeftparen = 40
keyRightparen = 41
keyAsterisk = 42
keyPlus = 43
keyComma = 44
keyMinus = 45
keyPeriod = 46
keySlash = 47
key0 = 48
key1 = 49
key2 = 50
key3 = 51
key4 = 52
key5 = 53
key6 = 54
key7 = 55
key8 = 56
key9 = 57
keyColon = 58
keySemicolon = 59
keyLess = 60
keyEquals = 61
keyGreater = 62
keyQuestion = 63
keyAt = 64
keyLeftbracket = 91
keyBackslash = 92
keyRightbracket = 93
keyCaret = 94
keyUnderscore = 95
keyBackquote = 96
keyA = 97
keyB = 98
keyC = 99
keyD = 100
keyE = 101
keyF = 102
keyG = 103
keyH = 104
keyI = 105
keyJ = 106
keyK = 107
keyL = 108
keyM = 109
keyN = 110
keyO = 111
keyP = 112
keyQ = 113
keyR = 114
keyS = 115
keyT = 116
keyU = 117
keyV = 118
keyW = 119
keyX = 120
keyY = 121
keyZ = 122
keyDelete = 127
keyWorld0 = 160
keyWorld1 = 161
keyWorld2 = 162
keyWorld3 = 163
keyWorld4 = 164
keyWorld5 = 165
keyWorld6 = 166
keyWorld7 = 167
keyWorld8 = 168
keyWorld9 = 169
keyWorld10 = 170
keyWorld11 = 171
keyWorld12 = 172
keyWorld13 = 173
keyWorld14 = 174
keyWorld15 = 175
keyWorld16 = 176
keyWorld17 = 177
keyWorld18 = 178
keyWorld19 = 179
keyWorld20 = 180
keyWorld21 = 181
keyWorld22 = 182
keyWorld23 = 183
keyWorld24 = 184
keyWorld25 = 185
keyWorld26 = 186
keyWorld27 = 187
keyWorld28 = 188
keyWorld29 = 189
keyWorld30 = 190
keyWorld31 = 191
keyWorld32 = 192
keyWorld33 = 193
keyWorld34 = 194
keyWorld35 = 195
keyWorld36 = 196
keyWorld37 = 197
keyWorld38 = 198
keyWorld39 = 199
keyWorld40 = 200
keyWorld41 = 201
keyWorld42 = 202
keyWorld43 = 203
keyWorld44 = 204
keyWorld45 = 205
keyWorld46 = 206
keyWorld47 = 207
keyWorld48 = 208
keyWorld49 = 209
keyWorld50 = 210
keyWorld51 = 211
keyWorld52 = 212
keyWorld53 = 213
keyWorld54 = 214
keyWorld55 = 215
keyWorld56 = 216
keyWorld57 = 217
keyWorld58 = 218
keyWorld59 = 219
keyWorld60 = 220
keyWorld61 = 221
keyWorld62 = 222
keyWorld63 = 223
keyWorld64 = 224
keyWorld65 = 225
keyWorld66 = 226
keyWorld67 = 227
keyWorld68 = 228
keyWorld69 = 229
keyWorld70 = 230
keyWorld71 = 231
keyWorld72 = 232
keyWorld73 = 233
keyWorld74 = 234
keyWorld75 = 235
keyWorld76 = 236
keyWorld77 = 237
keyWorld78 = 238
keyWorld79 = 239
keyWorld80 = 240
keyWorld81 = 241
keyWorld82 = 242
keyWorld83 = 243
keyWorld84 = 244
keyWorld85 = 245
keyWorld86 = 246
keyWorld87 = 247
keyWorld88 = 248
keyWorld89 = 249
keyWorld90 = 250
keyWorld91 = 251
keyWorld92 = 252
keyWorld93 = 253
keyWorld94 = 254
keyWorld95 = 255
// Numeric keypad
keyKp0 = 256
keyKp1 = 257
keyKp2 = 258
keyKp3 = 259
keyKp4 = 260
keyKp5 = 261
keyKp6 = 262
keyKp7 = 263
keyKp8 = 264
keyKp9 = 265
keyKpPeriod = 266
keyKpDivide = 267
keyKpMultiply = 268
keyKpMinus = 269
keyKpPlus = 270
keyKpEnter = 271
keyKpEquals = 272
// Arrow & insert/delete pad
keyUp = 273
keyDown = 274
keyRight = 275
keyLeft = 276
keyInsert = 277
keyHome = 278
keyEnd = 279
keyPageup = 280
keyPagedown = 281
// Function keys
keyF1 = 282
keyF2 = 283
keyF3 = 284
keyF4 = 285
keyF5 = 286
keyF6 = 287
keyF7 = 288
keyF8 = 289
keyF9 = 290
keyF10 = 291
keyF11 = 292
keyF12 = 293
keyF13 = 294
keyF14 = 295
keyF15 = 296
// Modifier keys
keyNumlock = 300
keyCapslock = 301
keyScrollock = 302
keyRshift = 303
keyLshift = 304
keyRctrl = 305
keyLctrl = 306
keyRalt = 307
keyLalt = 308
keyRmeta = 309
keyLmeta = 310
keyLsuper = 311
keyRsuper = 312
keyMode = 313
keyCompose = 314
// Misc keys
keyHelp = 315
keyPrint = 316
keySysreq = 317
keyBreak = 318
keyMenu = 319
keyPower = 320
keyEuro = 321
keyUndo = 322
// Add any other keys here
keyLast
)
// A keymod is a set of bit flags
type keymod uint16
const (
keymodNone = 0x0000
keymodLshift = 0x0001
keymodRshift = 0x0002
keymodLctrl = 0x0040
keymodRctrl = 0x0080
keymodLalt = 0x0100
keymodRalt = 0x0200
keymodLmeta = 0x0400
keymodRmeta = 0x0800
keymodNum = 0x1000
keymodCaps = 0x2000
keymodMode = 0x4000
keymodReserved = 0x8000
)
const (
mouseButtonLeft = 1
mouseButtonMiddle = 2
mouseButtonRight = 3
mouseScrollUp = 4
mouseScrollDown = 5
)
const (
mouseStateLeftButtonPressed = 1
mouseStateMiddleButtonPressed = 2
mouseStateRightButtonPressed = 4
)
const (
activeMouse = 1 // mouse leaving/entering
activeInputFocus = 2 // input focus lost/restored
activeApplication = 4 // application minimized/restored
)
const maxEventBytes = 64
type activeEvent struct {
EventType eventType
Gain uint8
State uint8
}
type exposeEvent struct {
EventType eventType
}
type keyboardEvent struct {
EventType eventType
Device uint8
State uint8
Pad uint8
ScanCode uint8
Pad1 uint8
Key key
Mod keymod
Unicode uint16
}
type mouseMotionEvent struct {
EventType eventType
Device uint8
Buttons uint8
Pad uint8
X uint16
Y uint16
Xrel int16
Yrel int16
}
type mouseButtonEvent struct {
EventType eventType
Device uint8
Button uint8
State uint8
X uint16
Y uint16
}
type quitEvent struct {
EventType eventType
}
type syncEvent struct{}
type event interface{}
type reader []byte
func (r *reader) Read(p []byte) (n int, err os.Error) {
b := *r
if len(b) == 0 && len(p) > 0 {
return 0, os.EOF
}
n = copy(p, b)
*r = b[n:]
return
}
func (w *Window) readEvents() {
buf := make([]byte, maxEventBytes)
clean := false
var (
ea *activeEvent
ee *exposeEvent
ke *keyboardEvent
mme *mouseMotionEvent
mbe *mouseButtonEvent
qe *quitEvent
)
var m draw.MouseEvent
for {
if err := videoPollEvent(buf); err != nil {
if !clean {
clean = w.eventc <- draw.ConfigEvent{image.Config{ColorModel, w.Image.Bounds().Dx(), w.Image.Bounds().Dy()}}
}
time.Sleep(10e6) // 10ms
continue
}
clean = false
var e event
switch buf[0] {
default:
log.Print("unsupported event type", buf[0])
continue
case eventActive:
ea = new(activeEvent)
e = ea
case eventExpose:
ee = new(exposeEvent)
e = ee
case eventKeyDown, eventKeyUp:
ke = new(keyboardEvent)
e = ke
case eventMouseMotion:
mme = new(mouseMotionEvent)
e = mme
case eventMouseButtonDown, eventMouseButtonUp:
mbe = new(mouseButtonEvent)
e = mbe
case eventQuit:
qe = new(quitEvent)
e = qe
}
r := reader(buf)
if err := binary.Read(&r, binary.LittleEndian, e); err != nil {
log.Printf("unpacking %T event: %s", e, err)
continue
}
// log.Printf("%#v\n", e);
switch buf[0] {
case eventExpose:
w.eventc <- draw.ConfigEvent{image.Config{ColorModel, w.Image.Bounds().Dx(), w.Image.Bounds().Dy()}}
case eventKeyDown:
w.eventc <- draw.KeyEvent{int(ke.Key)}
case eventKeyUp:
w.eventc <- draw.KeyEvent{-int(ke.Key)}
case eventMouseMotion:
m.Loc.X = int(mme.X)
m.Loc.Y = int(mme.Y)
m.Buttons = int(mme.Buttons)
m.Nsec = time.Nanoseconds()
_ = w.eventc <- m
case eventMouseButtonDown:
m.Loc.X = int(mbe.X)
m.Loc.Y = int(mbe.Y)
// TODO(rsc): Remove uint cast once 8g bug is fixed.
m.Buttons |= 1 << uint(mbe.Button-1)
m.Nsec = time.Nanoseconds()
_ = w.eventc <- m
case eventMouseButtonUp:
m.Loc.X = int(mbe.X)
m.Loc.Y = int(mbe.Y)
// TODO(rsc): Remove uint cast once 8g bug is fixed.
m.Buttons &^= 1 << uint(mbe.Button-1)
m.Nsec = time.Nanoseconds()
_ = w.eventc <- m
case eventQuit:
close(w.eventc)
}
}
}

View File

@ -1,84 +0,0 @@
// 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.
package av
import (
"image"
)
// Native Client image format:
// a single linear array of 32-bit ARGB as packed uint32s.
// An Image represents a Native Client frame buffer.
// The pixels in the image can be accessed as a single
// linear slice or as a two-dimensional slice of slices.
// Image implements image.Image.
type Image struct {
Linear []Color
Pixel [][]Color
}
var _ image.Image = (*Image)(nil)
func (m *Image) ColorModel() image.ColorModel { return ColorModel }
func (m *Image) Bounds() image.Rectangle {
if len(m.Pixel) == 0 {
return image.ZR
}
return image.Rectangle{image.ZP, image.Point{len(m.Pixel[0]), len(m.Pixel)}}
}
func (m *Image) At(x, y int) image.Color { return m.Pixel[y][x] }
func (m *Image) Set(x, y int, color image.Color) {
if c, ok := color.(Color); ok {
m.Pixel[y][x] = c
return
}
m.Pixel[y][x] = makeColor(color.RGBA())
}
func newImage(dx, dy int, linear []Color) *Image {
if linear == nil {
linear = make([]Color, dx*dy)
}
pix := make([][]Color, dy)
for i := range pix {
pix[i] = linear[dx*i : dx*(i+1)]
}
return &Image{linear, pix}
}
// A Color represents a Native Client color value,
// a 32-bit R, G, B, A value packed as 0xAARRGGBB.
type Color uint32
func (p Color) RGBA() (r, g, b, a uint32) {
x := uint32(p)
a = x >> 24
a |= a << 8
r = (x >> 16) & 0xFF
r |= r << 8
g = (x >> 8) & 0xFF
g |= g << 8
b = x & 0xFF
b |= b << 8
return
}
func makeColor(r, g, b, a uint32) Color {
return Color(a>>8<<24 | r>>8<<16 | g>>8<<8 | b>>8)
}
func toColor(color image.Color) image.Color {
if c, ok := color.(Color); ok {
return c
}
return makeColor(color.RGBA())
}
// ColorModel is the color model corresponding to the Native Client Color.
var ColorModel = image.ColorModelFunc(toColor)

View File

@ -1,13 +0,0 @@
# 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.
include ../../../../Make.inc
TARG=exp/nacl/srpc
GOFILES=\
client.go\
msg.go\
server.go\
include ../../../../Make.pkg

View File

@ -1,210 +0,0 @@
// 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.
// This package implements Native Client's simple RPC (SRPC).
package srpc
import (
"bytes"
"log"
"os"
"sync"
)
// A Client represents the client side of an SRPC connection.
type Client struct {
fd int // fd to server
r msgReceiver
s msgSender
service map[string]srv // services by name
out chan *msg // send to out to write to connection
mu sync.Mutex // protects pending, idGen
pending map[uint64]*RPC
idGen uint64 // generator for request IDs
}
// A srv is a single method that the server offers.
type srv struct {
num uint32 // method number
fmt string // argument format
}
// An RPC represents a single RPC issued by a client.
type RPC struct {
Ret []interface{} // Return values
Done chan *RPC // Channel where notification of done arrives
Errno Errno // Status code
c *Client
id uint64 // request id
}
// NewClient allocates a new client using the file descriptor fd.
func NewClient(fd int) (c *Client, err os.Error) {
c = new(Client)
c.fd = fd
c.r.fd = fd
c.s.fd = fd
c.service = make(map[string]srv)
c.pending = make(map[uint64]*RPC)
// service discovery request
m := &msg{
protocol: protocol,
isReq: true,
Ret: []interface{}{[]byte(nil)},
Size: []int{4000},
}
m.packRequest()
c.s.send(m)
m, err = c.r.recv()
if err != nil {
return nil, err
}
m.unpackResponse()
if m.status != OK {
log.Printf("NewClient service_discovery: %s", m.status)
return nil, m.status
}
for n, line := range bytes.Split(m.Ret[0].([]byte), []byte{'\n'}, -1) {
i := bytes.Index(line, []byte{':'})
if i < 0 {
continue
}
c.service[string(line[0:i])] = srv{uint32(n), string(line[i+1:])}
}
c.out = make(chan *msg)
go c.input()
go c.output()
return c, nil
}
func (c *Client) input() {
for {
m, err := c.r.recv()
if err != nil {
log.Exitf("client recv: %s", err)
}
if m.unpackResponse(); m.status != OK {
log.Printf("invalid message: %s", m.status)
continue
}
c.mu.Lock()
rpc, ok := c.pending[m.requestId]
if ok {
c.pending[m.requestId] = nil, false
}
c.mu.Unlock()
if !ok {
log.Print("unexpected response")
continue
}
rpc.Ret = m.Ret
rpc.Done <- rpc
}
}
func (c *Client) output() {
for m := range c.out {
c.s.send(m)
}
}
// NewRPC creates a new RPC on the client connection.
func (c *Client) NewRPC(done chan *RPC) *RPC {
if done == nil {
done = make(chan *RPC)
}
c.mu.Lock()
id := c.idGen
c.idGen++
c.mu.Unlock()
return &RPC{nil, done, OK, c, id}
}
// Start issues an RPC request for method name with the given arguments.
// The RPC r must not be in use for another pending request.
// To wait for the RPC to finish, receive from r.Done and then
// inspect r.Ret and r.Errno.
func (r *RPC) Start(name string, arg []interface{}) {
var m msg
r.Errno = OK
r.c.mu.Lock()
srv, ok := r.c.service[name]
if !ok {
r.c.mu.Unlock()
r.Errno = ErrBadRPCNumber
r.Done <- r
return
}
r.c.pending[r.id] = r
r.c.mu.Unlock()
m.protocol = protocol
m.requestId = r.id
m.isReq = true
m.rpcNumber = srv.num
m.Arg = arg
// Fill in the return values and sizes to generate
// the right type chars. We'll take most any size.
// Skip over input arguments.
// We could check them against arg, but the server
// will do that anyway.
i := 0
for srv.fmt[i] != ':' {
i++
}
fmt := srv.fmt[i+1:]
// Now the return prototypes.
m.Ret = make([]interface{}, len(fmt)-i)
m.Size = make([]int, len(fmt)-i)
for i := 0; i < len(fmt); i++ {
switch fmt[i] {
default:
log.Exitf("unexpected service type %c", fmt[i])
case 'b':
m.Ret[i] = false
case 'C':
m.Ret[i] = []byte(nil)
m.Size[i] = 1 << 30
case 'd':
m.Ret[i] = float64(0)
case 'D':
m.Ret[i] = []float64(nil)
m.Size[i] = 1 << 30
case 'h':
m.Ret[i] = int(-1)
case 'i':
m.Ret[i] = int32(0)
case 'I':
m.Ret[i] = []int32(nil)
m.Size[i] = 1 << 30
case 's':
m.Ret[i] = ""
m.Size[i] = 1 << 30
}
}
m.packRequest()
r.c.out <- &m
}
// Call is a convenient wrapper that starts the RPC request,
// waits for it to finish, and then returns the results.
// Its implementation is:
//
// r.Start(name, arg)
// <-r.Done
// return r.Ret, r.Errno
//
func (r *RPC) Call(name string, arg []interface{}) (ret []interface{}, err Errno) {
r.Start(name, arg)
<-r.Done
return r.Ret, r.Errno
}

View File

@ -1,522 +0,0 @@
// 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.
// SRPC constants, data structures, and parsing.
package srpc
import (
"math"
"os"
"strconv"
"syscall"
"unsafe"
)
// An Errno is an SRPC status code.
type Errno uint32
const (
OK Errno = 256 + iota
ErrBreak
ErrMessageTruncated
ErrNoMemory
ErrProtocolMismatch
ErrBadRPCNumber
ErrBadArgType
ErrTooFewArgs
ErrTooManyArgs
ErrInArgTypeMismatch
ErrOutArgTypeMismatch
ErrInternalError
ErrAppError
)
var errstr = [...]string{
OK - OK: "ok",
ErrBreak - OK: "break",
ErrMessageTruncated - OK: "message truncated",
ErrNoMemory - OK: "out of memory",
ErrProtocolMismatch - OK: "protocol mismatch",
ErrBadRPCNumber - OK: "invalid RPC method number",
ErrBadArgType - OK: "unexpected argument type",
ErrTooFewArgs - OK: "too few arguments",
ErrTooManyArgs - OK: "too many arguments",
ErrInArgTypeMismatch - OK: "input argument type mismatch",
ErrOutArgTypeMismatch - OK: "output argument type mismatch",
ErrInternalError - OK: "internal error",
ErrAppError - OK: "application error",
}
func (e Errno) String() string {
if e < OK || int(e-OK) >= len(errstr) {
return "Errno(" + strconv.Itoa64(int64(e)) + ")"
}
return errstr[e-OK]
}
// A *msgHdr is the data argument to the imc_recvmsg
// and imc_sendmsg system calls. Because it contains unchecked
// counts trusted by the system calls, the data structure is unsafe
// to expose to package clients.
type msgHdr struct {
iov *iov
niov int32
desc *int32
ndesc int32
flags uint32
}
// A single region for I/O. Just as unsafe as msgHdr.
type iov struct {
base *byte
len int32
}
// A msg is the Go representation of a message.
type msg struct {
rdata []byte // data being consumed during message parsing
rdesc []int32 // file descriptors being consumed during message parsing
wdata []byte // data being generated when replying
// parsed version of message
protocol uint32
requestId uint64
isReq bool
rpcNumber uint32
gotHeader bool
status Errno // error code sent in response
Arg []interface{} // method arguments
Ret []interface{} // method results
Size []int // max sizes for arrays in method results
fmt string // accumulated format string of arg+":"+ret
}
// A msgReceiver receives messages from a file descriptor.
type msgReceiver struct {
fd int
data [128 * 1024]byte
desc [8]int32
hdr msgHdr
iov iov
}
func (r *msgReceiver) recv() (*msg, os.Error) {
// Init pointers to buffers where syscall recvmsg can write.
r.iov.base = &r.data[0]
r.iov.len = int32(len(r.data))
r.hdr.iov = &r.iov
r.hdr.niov = 1
r.hdr.desc = &r.desc[0]
r.hdr.ndesc = int32(len(r.desc))
n, _, e := syscall.Syscall(syscall.SYS_IMC_RECVMSG, uintptr(r.fd), uintptr(unsafe.Pointer(&r.hdr)), 0)
if e != 0 {
return nil, os.NewSyscallError("imc_recvmsg", int(e))
}
// Make a copy of the data so that the next recvmsg doesn't
// smash it. The system call did not update r.iov.len. Instead it
// returned the total byte count as n.
m := new(msg)
m.rdata = make([]byte, n)
copy(m.rdata, r.data[0:])
// Make a copy of the desc too.
// The system call *did* update r.hdr.ndesc.
if r.hdr.ndesc > 0 {
m.rdesc = make([]int32, r.hdr.ndesc)
copy(m.rdesc, r.desc)
}
return m, nil
}
// A msgSender sends messages on a file descriptor.
type msgSender struct {
fd int
hdr msgHdr
iov iov
}
func (s *msgSender) send(m *msg) os.Error {
if len(m.wdata) > 0 {
s.iov.base = &m.wdata[0]
}
s.iov.len = int32(len(m.wdata))
s.hdr.iov = &s.iov
s.hdr.niov = 1
s.hdr.desc = nil
s.hdr.ndesc = 0
_, _, e := syscall.Syscall(syscall.SYS_IMC_SENDMSG, uintptr(s.fd), uintptr(unsafe.Pointer(&s.hdr)), 0)
if e != 0 {
return os.NewSyscallError("imc_sendmsg", int(e))
}
return nil
}
// Reading from msg.rdata.
func (m *msg) uint8() uint8 {
if m.status != OK {
return 0
}
if len(m.rdata) < 1 {
m.status = ErrMessageTruncated
return 0
}
x := m.rdata[0]
m.rdata = m.rdata[1:]
return x
}
func (m *msg) uint32() uint32 {
if m.status != OK {
return 0
}
if len(m.rdata) < 4 {
m.status = ErrMessageTruncated
return 0
}
b := m.rdata[0:4]
x := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
m.rdata = m.rdata[4:]
return x
}
func (m *msg) uint64() uint64 {
if m.status != OK {
return 0
}
if len(m.rdata) < 8 {
m.status = ErrMessageTruncated
return 0
}
b := m.rdata[0:8]
x := uint64(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
x |= uint64(uint32(b[4])|uint32(b[5])<<8|uint32(b[6])<<16|uint32(b[7])<<24) << 32
m.rdata = m.rdata[8:]
return x
}
func (m *msg) bytes(n int) []byte {
if m.status != OK {
return nil
}
if len(m.rdata) < n {
m.status = ErrMessageTruncated
return nil
}
x := m.rdata[0:n]
m.rdata = m.rdata[n:]
return x
}
// Writing to msg.wdata.
func (m *msg) grow(n int) []byte {
i := len(m.wdata)
if i+n > cap(m.wdata) {
a := make([]byte, i, (i+n)*2)
copy(a, m.wdata)
m.wdata = a
}
m.wdata = m.wdata[0 : i+n]
return m.wdata[i : i+n]
}
func (m *msg) wuint8(x uint8) { m.grow(1)[0] = x }
func (m *msg) wuint32(x uint32) {
b := m.grow(4)
b[0] = byte(x)
b[1] = byte(x >> 8)
b[2] = byte(x >> 16)
b[3] = byte(x >> 24)
}
func (m *msg) wuint64(x uint64) {
b := m.grow(8)
lo := uint32(x)
b[0] = byte(lo)
b[1] = byte(lo >> 8)
b[2] = byte(lo >> 16)
b[3] = byte(lo >> 24)
hi := uint32(x >> 32)
b[4] = byte(hi)
b[5] = byte(hi >> 8)
b[6] = byte(hi >> 16)
b[7] = byte(hi >> 24)
}
func (m *msg) wbytes(p []byte) { copy(m.grow(len(p)), p) }
func (m *msg) wstring(s string) {
b := m.grow(len(s))
copy(b, s)
}
// Parsing of RPC header and arguments.
//
// The header format is:
// protocol uint32;
// requestId uint64;
// isReq bool;
// rpcNumber uint32;
// status uint32; // only for response
//
// Then a sequence of values follow, preceded by the length:
// nvalue uint32;
//
// Each value begins with a one-byte type followed by
// type-specific data.
//
// type uint8;
// 'b': x bool;
// 'C': len uint32; x [len]byte;
// 'd': x float64;
// 'D': len uint32; x [len]float64;
// 'h': x int; // handle aka file descriptor
// 'i': x int32;
// 'I': len uint32; x [len]int32;
// 's': len uint32; x [len]byte;
//
// If this is a request, a sequence of pseudo-values follows,
// preceded by its length (nvalue uint32).
//
// Each pseudo-value is a one-byte type as above,
// followed by a maximum length (len uint32)
// for the 'C', 'D', 'I', and 's' types.
//
// In the Go msg, we represent each argument by
// an empty interface containing the type of x in the
// corresponding case.
// The current protocol number.
const protocol = 0xc0da0002
func (m *msg) unpackHeader() {
m.protocol = m.uint32()
m.requestId = m.uint64()
m.isReq = m.uint8() != 0
m.rpcNumber = m.uint32()
m.gotHeader = m.status == OK // signal that header parsed successfully
if m.gotHeader && !m.isReq {
status := Errno(m.uint32())
m.gotHeader = m.status == OK // still ok?
if m.gotHeader {
m.status = status
}
}
}
func (m *msg) packHeader() {
m.wuint32(m.protocol)
m.wuint64(m.requestId)
if m.isReq {
m.wuint8(1)
} else {
m.wuint8(0)
}
m.wuint32(m.rpcNumber)
if !m.isReq {
m.wuint32(uint32(m.status))
}
}
func (m *msg) unpackValues(v []interface{}) {
for i := range v {
t := m.uint8()
m.fmt += string(t)
switch t {
default:
if m.status == OK {
m.status = ErrBadArgType
}
return
case 'b': // bool[1]
v[i] = m.uint8() > 0
case 'C': // char array
v[i] = m.bytes(int(m.uint32()))
case 'd': // double
v[i] = math.Float64frombits(m.uint64())
case 'D': // double array
a := make([]float64, int(m.uint32()))
for j := range a {
a[j] = math.Float64frombits(m.uint64())
}
v[i] = a
case 'h': // file descriptor (handle)
if len(m.rdesc) == 0 {
if m.status == OK {
m.status = ErrBadArgType
}
return
}
v[i] = int(m.rdesc[0])
m.rdesc = m.rdesc[1:]
case 'i': // int
v[i] = int32(m.uint32())
case 'I': // int array
a := make([]int32, int(m.uint32()))
for j := range a {
a[j] = int32(m.uint32())
}
v[i] = a
case 's': // string
v[i] = string(m.bytes(int(m.uint32())))
}
}
}
func (m *msg) packValues(v []interface{}) {
for i := range v {
switch x := v[i].(type) {
default:
if m.status == OK {
m.status = ErrInternalError
}
return
case bool:
m.wuint8('b')
if x {
m.wuint8(1)
} else {
m.wuint8(0)
}
case []byte:
m.wuint8('C')
m.wuint32(uint32(len(x)))
m.wbytes(x)
case float64:
m.wuint8('d')
m.wuint64(math.Float64bits(x))
case []float64:
m.wuint8('D')
m.wuint32(uint32(len(x)))
for _, f := range x {
m.wuint64(math.Float64bits(f))
}
case int32:
m.wuint8('i')
m.wuint32(uint32(x))
case []int32:
m.wuint8('I')
m.wuint32(uint32(len(x)))
for _, i := range x {
m.wuint32(uint32(i))
}
case string:
m.wuint8('s')
m.wuint32(uint32(len(x)))
m.wstring(x)
}
}
}
func (m *msg) unpackRequest() {
m.status = OK
if m.unpackHeader(); m.status != OK {
return
}
if m.protocol != protocol || !m.isReq {
m.status = ErrProtocolMismatch
return
}
// type-tagged argument values
m.Arg = make([]interface{}, m.uint32())
m.unpackValues(m.Arg)
if m.status != OK {
return
}
// type-tagged expected return sizes.
// fill in zero values for each return value
// and save sizes.
m.fmt += ":"
m.Ret = make([]interface{}, m.uint32())
m.Size = make([]int, len(m.Ret))
for i := range m.Ret {
t := m.uint8()
m.fmt += string(t)
switch t {
default:
if m.status == OK {
m.status = ErrBadArgType
}
return
case 'b': // bool[1]
m.Ret[i] = false
case 'C': // char array
m.Size[i] = int(m.uint32())
m.Ret[i] = []byte(nil)
case 'd': // double
m.Ret[i] = float64(0)
case 'D': // double array
m.Size[i] = int(m.uint32())
m.Ret[i] = []float64(nil)
case 'h': // file descriptor (handle)
m.Ret[i] = int(-1)
case 'i': // int
m.Ret[i] = int32(0)
case 'I': // int array
m.Size[i] = int(m.uint32())
m.Ret[i] = []int32(nil)
case 's': // string
m.Size[i] = int(m.uint32())
m.Ret[i] = ""
}
}
}
func (m *msg) packRequest() {
m.packHeader()
m.wuint32(uint32(len(m.Arg)))
m.packValues(m.Arg)
m.wuint32(uint32(len(m.Ret)))
for i, v := range m.Ret {
switch x := v.(type) {
case bool:
m.wuint8('b')
case []byte:
m.wuint8('C')
m.wuint32(uint32(m.Size[i]))
case float64:
m.wuint8('d')
case []float64:
m.wuint8('D')
m.wuint32(uint32(m.Size[i]))
case int:
m.wuint8('h')
case int32:
m.wuint8('i')
case []int32:
m.wuint8('I')
m.wuint32(uint32(m.Size[i]))
case string:
m.wuint8('s')
m.wuint32(uint32(m.Size[i]))
}
}
}
func (m *msg) unpackResponse() {
m.status = OK
if m.unpackHeader(); m.status != OK {
return
}
if m.protocol != protocol || m.isReq {
m.status = ErrProtocolMismatch
return
}
// type-tagged return values
m.fmt = ""
m.Ret = make([]interface{}, m.uint32())
m.unpackValues(m.Ret)
}
func (m *msg) packResponse() {
m.packHeader()
m.wuint32(uint32(len(m.Ret)))
m.packValues(m.Ret)
}

View File

@ -1,192 +0,0 @@
// 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.
// SRPC server
package srpc
import (
"bytes"
"log"
"os"
"syscall"
)
// TODO(rsc): I'd prefer to make this
// type Handler func(m *msg) Errno
// but NaCl can't use closures.
// The explicit interface is a way to attach state.
// A Handler is a handler for an SRPC method.
// It reads arguments from arg, checks size for array limits,
// writes return values to ret, and returns an Errno status code.
type Handler interface {
Run(arg, ret []interface{}, size []int) Errno
}
type method struct {
name string
fmt string
handler Handler
}
var rpcMethod []method
// BUG(rsc): Add's format string should be replaced by analyzing the
// type of an arbitrary func passed in an interface{} using reflection.
// Add registers a handler for the named method.
// Fmt is a Native Client format string, a sequence of
// alphabetic characters representing the types of the parameter values,
// a colon, and then a sequence of alphabetic characters
// representing the types of the returned values.
// The format characters and corresponding dynamic types are:
//
// b bool
// C []byte
// d float64
// D []float64
// h int // a file descriptor (aka handle)
// i int32
// I []int32
// s string
//
func Add(name, fmt string, handler Handler) {
rpcMethod = append(rpcMethod, method{name, fmt, handler})
}
// Serve accepts new SRPC connections from the file descriptor fd
// and answers RPCs issued on those connections.
// It closes fd and returns an error if the imc_accept system call fails.
func Serve(fd int) os.Error {
defer syscall.Close(fd)
for {
cfd, _, e := syscall.Syscall(syscall.SYS_IMC_ACCEPT, uintptr(fd), 0, 0)
if e != 0 {
return os.NewSyscallError("imc_accept", int(e))
}
go serveLoop(int(cfd))
}
panic("unreachable")
}
func serveLoop(fd int) {
c := make(chan *msg)
go sendLoop(fd, c)
var r msgReceiver
r.fd = fd
for {
m, err := r.recv()
if err != nil {
break
}
m.unpackRequest()
if !m.gotHeader {
log.Printf("cannot unpack header: %s", m.status)
continue
}
// log.Printf("<- %#v", m);
m.isReq = false // set up for response
go serveMsg(m, c)
}
close(c)
}
func sendLoop(fd int, c <-chan *msg) {
var s msgSender
s.fd = fd
for m := range c {
// log.Printf("-> %#v", m);
m.packResponse()
s.send(m)
}
syscall.Close(fd)
}
func serveMsg(m *msg, c chan<- *msg) {
if m.status != OK {
c <- m
return
}
if m.rpcNumber >= uint32(len(rpcMethod)) {
m.status = ErrBadRPCNumber
c <- m
return
}
meth := &rpcMethod[m.rpcNumber]
if meth.fmt != m.fmt {
switch {
case len(m.fmt) < len(meth.fmt):
m.status = ErrTooFewArgs
case len(m.fmt) > len(meth.fmt):
m.status = ErrTooManyArgs
default:
// There's a type mismatch.
// It's an in-arg mismatch if the mismatch happens
// before the colon; otherwise it's an out-arg mismatch.
m.status = ErrInArgTypeMismatch
for i := 0; i < len(m.fmt) && m.fmt[i] == meth.fmt[i]; i++ {
if m.fmt[i] == ':' {
m.status = ErrOutArgTypeMismatch
break
}
}
}
c <- m
return
}
m.status = meth.handler.Run(m.Arg, m.Ret, m.Size)
c <- m
}
// ServeRuntime serves RPCs issued by the Native Client embedded runtime.
// This should be called by main once all methods have been registered using Add.
func ServeRuntime() os.Error {
// Call getFd to check that we are running embedded.
if _, err := getFd(); err != nil {
return err
}
// We are running embedded.
// The fd returned by getFd is a red herring.
// Accept connections on magic fd 3.
return Serve(3)
}
// getFd runs the srpc_get_fd system call.
func getFd() (fd int, err os.Error) {
r1, _, e := syscall.Syscall(syscall.SYS_SRPC_GET_FD, 0, 0, 0)
return int(r1), os.NewSyscallError("srpc_get_fd", int(e))
}
// Enabled returns true if SRPC is enabled in the Native Client runtime.
func Enabled() bool {
_, err := getFd()
return err == nil
}
// Service #0, service_discovery, returns a list of the other services
// and their argument formats.
type serviceDiscovery struct{}
func (serviceDiscovery) Run(arg, ret []interface{}, size []int) Errno {
var b bytes.Buffer
for _, m := range rpcMethod {
b.WriteString(m.name)
b.WriteByte(':')
b.WriteString(m.fmt)
b.WriteByte('\n')
}
if b.Len() > size[0] {
return ErrNoMemory
}
ret[0] = b.Bytes()
return OK
}
func init() { Add("service_discovery", ":C", serviceDiscovery{}) }

View File

@ -1,18 +0,0 @@
# 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.
all: 8.out
pdp1.8: pdp1.go
8g pdp1.go
spacewar.8: spacewar.go code.go pdp1.8
8g spacewar.go code.go
8.out: spacewar.8
8l spacewar.8
clean:
rm -f *.8 8.out

File diff suppressed because it is too large Load Diff

View File

@ -1,389 +0,0 @@
// Copyright (c) 1996 Barry Silverman, Brian Silverman, Vadim Gerasimov.
// Portions Copyright (c) 2009 The Go Authors.
//
// 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.
// This package and spacewar.go implement a simple PDP-1 emulator
// complete enough to run the original PDP-1 video game Spacewar!
// See ../../nacl/README for details on running them.
//
// They are a translation of the Java emulator pdp1.java in
// http://spacewar.oversigma.com/sources/sources.zip.
//
// See also the PDP-1 handbook at http://www.dbit.com/~greeng3/pdp1/pdp1.html
//
// http://spacewar.oversigma.com/readme.html reads:
//
// Spacewar! was conceived in 1961 by Martin Graetz, Stephen Russell,
// and Wayne Wiitanen. It was first realized on the PDP-1 in 1962 by
// Stephen Russell, Peter Samson, Dan Edwards, and Martin Graetz,
// together with Alan Kotok, Steve Piner, and Robert A Saunders.
// Spacewar! is in the public domain, but this credit paragraph must
// accompany all distributed versions of the program.
//
// This is the original version! Martin Graetz provided us with a
// printed version of the source. We typed in in again - it was about
// 40 pages long - and re-assembled it with a PDP-1 assembler written
// in PERL. The resulting binary runs on a PDP-1 emulator written as
// a Java applet. The code is extremely faithful to the original. There
// are only two changes. 1)The spaceships have been made bigger and
// 2) The overall timing has been special cased to deal with varying
// machine speeds.
//
// The "a", "s", "d", "f" keys control one of the spaceships. The "k",
// "l", ";", "'" keys control the other. The controls are spin one
// way, spin the other, thrust, and fire.
//
// Barry Silverman
// Brian Silverman
// Vadim Gerasimov
//
package pdp1
import (
"bufio"
"fmt"
"os"
"io"
)
type Word uint32
const mask = 0777777
const sign = 0400000
const (
_ = iota // 00
opAND
opIOR
opXOR
opXCT
_
_
opCALJDA
opLAC // 10
opLIO
opDAC
opDAP
_
opDIO
opDZM
_
opADD // 20
opSUB
opIDX
opISP
opSAD
opSAS
opMUS
opDIS
opJMP // 30
opJSP
opSKP
opSFT
opLAW
opIOT
_
opOPR
)
// A Trapper represents an object with a Trap method.
// The machine calls the Trap method to implement the
// PDP-1 IOT instruction.
type Trapper interface {
Trap(y Word)
}
// An M represents the machine state of a PDP-1.
// Clients can set Display to install an output device.
type M struct {
AC, IO, PC, OV Word
Mem [010000]Word
Flag [7]bool
Sense [7]bool
Halt bool
}
// Step runs a single machine instruction.
func (m *M) Step(t Trapper) os.Error {
inst := m.Mem[m.PC]
m.PC++
return m.run(inst, t)
}
// Normalize actual 32-bit integer i to 18-bit ones-complement integer.
// Interpret mod 0777777, because 0777777 == -0 == +0 == 0000000.
func norm(i Word) Word {
i += i >> 18
i &= mask
if i == mask {
i = 0
}
return i
}
type UnknownInstrError struct {
Inst Word
PC Word
}
func (e UnknownInstrError) String() string {
return fmt.Sprintf("unknown instruction %06o at %06o", e.Inst, e.PC)
}
type HaltError Word
func (e HaltError) String() string {
return fmt.Sprintf("executed HLT instruction at %06o", e)
}
type LoopError Word
func (e LoopError) String() string { return fmt.Sprintf("indirect load looping at %06o", e) }
func (m *M) run(inst Word, t Trapper) os.Error {
ib, y := (inst>>12)&1, inst&07777
op := inst >> 13
if op < opSKP && op != opCALJDA {
for n := 0; ib != 0; n++ {
if n > 07777 {
return LoopError(m.PC - 1)
}
ib = (m.Mem[y] >> 12) & 1
y = m.Mem[y] & 07777
}
}
switch op {
case opAND:
m.AC &= m.Mem[y]
case opIOR:
m.AC |= m.Mem[y]
case opXOR:
m.AC ^= m.Mem[y]
case opXCT:
m.run(m.Mem[y], t)
case opCALJDA:
a := y
if ib == 0 {
a = 64
}
m.Mem[a] = m.AC
m.AC = (m.OV << 17) + m.PC
m.PC = a + 1
case opLAC:
m.AC = m.Mem[y]
case opLIO:
m.IO = m.Mem[y]
case opDAC:
m.Mem[y] = m.AC
case opDAP:
m.Mem[y] = m.Mem[y]&0770000 | m.AC&07777
case opDIO:
m.Mem[y] = m.IO
case opDZM:
m.Mem[y] = 0
case opADD:
m.AC += m.Mem[y]
m.OV = m.AC >> 18
m.AC = norm(m.AC)
case opSUB:
diffSigns := (m.AC^m.Mem[y])>>17 == 1
m.AC += m.Mem[y] ^ mask
m.AC = norm(m.AC)
if diffSigns && m.Mem[y]>>17 == m.AC>>17 {
m.OV = 1
}
case opIDX:
m.AC = norm(m.Mem[y] + 1)
m.Mem[y] = m.AC
case opISP:
m.AC = norm(m.Mem[y] + 1)
m.Mem[y] = m.AC
if m.AC&sign == 0 {
m.PC++
}
case opSAD:
if m.AC != m.Mem[y] {
m.PC++
}
case opSAS:
if m.AC == m.Mem[y] {
m.PC++
}
case opMUS:
if m.IO&1 == 1 {
m.AC += m.Mem[y]
m.AC = norm(m.AC)
}
m.IO = (m.IO>>1 | m.AC<<17) & mask
m.AC >>= 1
case opDIS:
m.AC, m.IO = (m.AC<<1|m.IO>>17)&mask,
((m.IO<<1|m.AC>>17)&mask)^1
if m.IO&1 == 1 {
m.AC = m.AC + (m.Mem[y] ^ mask)
} else {
m.AC = m.AC + 1 + m.Mem[y]
}
m.AC = norm(m.AC)
case opJMP:
m.PC = y
case opJSP:
m.AC = (m.OV << 17) + m.PC
m.PC = y
case opSKP:
cond := y&0100 == 0100 && m.AC == 0 ||
y&0200 == 0200 && m.AC>>17 == 0 ||
y&0400 == 0400 && m.AC>>17 == 1 ||
y&01000 == 01000 && m.OV == 0 ||
y&02000 == 02000 && m.IO>>17 == 0 ||
y&7 != 0 && !m.Flag[y&7] ||
y&070 != 0 && !m.Sense[(y&070)>>3] ||
y&070 == 010
if (ib == 0) == cond {
m.PC++
}
if y&01000 == 01000 {
m.OV = 0
}
case opSFT:
for count := inst & 0777; count != 0; count >>= 1 {
if count&1 == 0 {
continue
}
switch (inst >> 9) & 017 {
case 001: // rotate AC left
m.AC = (m.AC<<1 | m.AC>>17) & mask
case 002: // rotate IO left
m.IO = (m.IO<<1 | m.IO>>17) & mask
case 003: // rotate AC and IO left.
w := uint64(m.AC)<<18 | uint64(m.IO)
w = w<<1 | w>>35
m.AC = Word(w>>18) & mask
m.IO = Word(w) & mask
case 005: // shift AC left (excluding sign bit)
m.AC = (m.AC<<1|m.AC>>17)&mask&^sign | m.AC&sign
case 006: // shift IO left (excluding sign bit)
m.IO = (m.IO<<1|m.IO>>17)&mask&^sign | m.IO&sign
case 007: // shift AC and IO left (excluding AC's sign bit)
w := uint64(m.AC)<<18 | uint64(m.IO)
w = w<<1 | w>>35
m.AC = Word(w>>18)&mask&^sign | m.AC&sign
m.IO = Word(w)&mask&^sign | m.AC&sign
case 011: // rotate AC right
m.AC = (m.AC>>1 | m.AC<<17) & mask
case 012: // rotate IO right
m.IO = (m.IO>>1 | m.IO<<17) & mask
case 013: // rotate AC and IO right
w := uint64(m.AC)<<18 | uint64(m.IO)
w = w>>1 | w<<35
m.AC = Word(w>>18) & mask
m.IO = Word(w) & mask
case 015: // shift AC right (excluding sign bit)
m.AC = m.AC>>1 | m.AC&sign
case 016: // shift IO right (excluding sign bit)
m.IO = m.IO>>1 | m.IO&sign
case 017: // shift AC and IO right (excluding AC's sign bit)
w := uint64(m.AC)<<18 | uint64(m.IO)
w = w >> 1
m.AC = Word(w>>18) | m.AC&sign
m.IO = Word(w) & mask
default:
goto Unknown
}
}
case opLAW:
if ib == 0 {
m.AC = y
} else {
m.AC = y ^ mask
}
case opIOT:
t.Trap(y)
case opOPR:
if y&0200 == 0200 {
m.AC = 0
}
if y&04000 == 04000 {
m.IO = 0
}
if y&01000 == 01000 {
m.AC ^= mask
}
if y&0400 == 0400 {
m.PC--
return HaltError(m.PC)
}
switch i, f := y&7, y&010 == 010; {
case i == 7:
for i := 2; i < 7; i++ {
m.Flag[i] = f
}
case i >= 2:
m.Flag[i] = f
}
default:
Unknown:
return UnknownInstrError{inst, m.PC - 1}
}
return nil
}
// Load loads the machine's memory from a text input file
// listing octal address-value pairs, one per line, matching the
// regular expression ^[ +]([0-7]+)\t([0-7]+).
func (m *M) Load(r io.Reader) os.Error {
b := bufio.NewReader(r)
for {
line, err := b.ReadString('\n')
if err != nil {
if err != os.EOF {
return err
}
break
}
// look for ^[ +]([0-9]+)\t([0-9]+)
if line[0] != ' ' && line[0] != '+' {
continue
}
i := 1
a := Word(0)
for ; i < len(line) && '0' <= line[i] && line[i] <= '7'; i++ {
a = a*8 + Word(line[i]-'0')
}
if i >= len(line) || line[i] != '\t' || i == 1 {
continue
}
v := Word(0)
j := i
for i++; i < len(line) && '0' <= line[i] && line[i] <= '7'; i++ {
v = v*8 + Word(line[i]-'0')
}
if i == j {
continue
}
m.Mem[a] = v
}
return nil
}

View File

@ -1,202 +0,0 @@
// Copyright (c) 1996 Barry Silverman, Brian Silverman, Vadim Gerasimov.
// Portions Copyright (c) 2009 The Go Authors.
//
// 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.
// See ../../nacl/README.
package main
import (
"bytes"
"exp/draw"
"exp/nacl/av"
"exp/nacl/srpc"
"image"
"log"
"os"
"runtime"
"time"
"./pdp1"
)
func main() {
runtime.LockOSThread()
if srpc.Enabled() {
go srpc.ServeRuntime()
}
w, err := av.Init(av.SubsystemVideo, 512, 512)
if err != nil {
log.Exitf("av.Init: %s", err)
}
kc := make(chan int)
go demuxEvents(w, kc)
var m SpacewarPDP1
m.Init(w, kc)
m.PC = 4
f := bytes.NewBuffer([]byte(spacewarCode))
if err = m.Load(f); err != nil {
log.Exitf("loading %s: %s", "spacewar.lst", err)
}
for err == nil {
//fmt.Printf("step PC=%06o ", m.PC);
//fmt.Printf("inst=%06o AC=%06o IO=%06o OV=%o\n",
// m.Mem[m.PC], m.AC, m.IO, m.OV);
err = m.Step()
}
log.Exitf("step: %s", err)
}
func demuxEvents(w draw.Window, kc chan int) {
for event := range w.EventChan() {
switch e := event.(type) {
case draw.KeyEvent:
kc <- e.Key
}
}
os.Exit(0)
}
// A SpacewarPDP1 is a PDP-1 machine configured to run Spacewar!
// It responds to traps by drawing on the display, and it flushes the
// display and pauses every second time the program counter reaches
// instruction 02051.
type SpacewarPDP1 struct {
pdp1.M
nframe int
frameTime int64
ctxt draw.Window
dx, dy int
screen draw.Image
ctl pdp1.Word
kc <-chan int
colorModel image.ColorModel
cmap []image.Color
pix [][]uint8
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func (m *SpacewarPDP1) Init(ctxt draw.Window, kc chan int) {
m.ctxt = ctxt
m.kc = kc
m.screen = ctxt.Screen()
m.dx = m.screen.Bounds().Dx()
m.dy = m.screen.Bounds().Dy()
m.colorModel = m.screen.ColorModel()
m.pix = make([][]uint8, m.dy)
for i := range m.pix {
m.pix[i] = make([]uint8, m.dx)
}
m.cmap = make([]image.Color, 256)
for i := range m.cmap {
var r, g, b uint8
r = uint8(min(0, 255))
g = uint8(min(i*2, 255))
b = uint8(min(0, 255))
m.cmap[i] = m.colorModel.Convert(image.RGBAColor{r, g, b, 0xff})
}
}
const (
frameDelay = 56 * 1e6 // 56 ms
)
var ctlBits = [...]pdp1.Word{
'f': 0000001,
'd': 0000002,
'a': 0000004,
's': 0000010,
'\'': 0040000,
';': 0100000,
'k': 0200000,
'l': 0400000,
}
func (m *SpacewarPDP1) Step() os.Error {
if m.PC == 02051 {
m.pollInput()
m.nframe++
if m.nframe&1 == 0 {
m.flush()
t := time.Nanoseconds()
if t >= m.frameTime+3*frameDelay {
m.frameTime = t
} else {
m.frameTime += frameDelay
for t < m.frameTime {
time.Sleep(m.frameTime - t)
t = time.Nanoseconds()
}
}
}
}
return m.M.Step(m)
}
func (m *SpacewarPDP1) Trap(y pdp1.Word) {
switch y & 077 {
case 7:
x := int(m.AC+0400000) & 0777777
y := int(m.IO+0400000) & 0777777
x = x * m.dx / 0777777
y = y * m.dy / 0777777
if 0 <= x && x < m.dx && 0 <= y && y < m.dy {
n := uint8(min(int(m.pix[y][x])+128, 255))
m.pix[y][x] = n
}
case 011:
m.IO = m.ctl
}
}
func (m *SpacewarPDP1) flush() {
// Update screen image; simulate phosphor decay.
for y := 0; y < m.dy; y++ {
for x := 0; x < m.dx; x++ {
m.screen.Set(x, y, m.cmap[m.pix[y][x]])
m.pix[y][x] >>= 1
}
}
m.ctxt.FlushImage()
}
func (m *SpacewarPDP1) pollInput() {
for {
select {
case ch := <-m.kc:
if 0 <= ch && ch < len(ctlBits) {
m.ctl |= ctlBits[ch]
}
if 0 <= -ch && -ch < len(ctlBits) {
m.ctl &^= ctlBits[-ch]
}
default:
return
}
}
}

View File

@ -1,21 +0,0 @@
<h1>Spacewar</h1>
<table>
<tr><td valign=top>
<embed name="nacl_module" id="pluginobj" src="8.out" type="application/x-nacl-srpc" width=512 height=512>
<td valign=top>
This is a Go translation of the Java emulator pdp1.java in
<a href="http://spacewar.oversigma.com/sources/sources.zip">http://spacewar.oversigma.com/sources/sources.zip</a>.
See <a href="pdp1.go">pdp1.go</a>, <a href="spacewar.go">spacewar.go</a>,
and
<a href="http://spacewar.oversigma.com/readme.html">http://spacewar.oversigma.com/readme.html</a>.
<br><br>
The <i>a</i>, <i>s</i>, <i>d</i>, <i>f</i> keys control one of the spaceships. The <i>k</i>,
<i>l</i>, <i>;</i>, <i>'</i> keys control the other. The controls are spin one
way, spin the other, thrust, and fire.
<br>
<br>
<b>You may need to click on the game window to
focus the keyboard on it.</b>
</table>

View File

@ -41,13 +41,6 @@ GOFILES_linux=\
dnsconfig.go\
dnsclient.go\
port.go\
GOFILES_nacl=\
newpollserver.go\
fd.go\
dnsconfig.go\
dnsclient.go\
port.go\
GOFILES_windows=\
resolv_windows.go\

View File

@ -1,33 +0,0 @@
// 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.
package net
import (
"os"
"syscall"
)
type pollster struct{}
func newpollster() (p *pollster, err os.Error) {
return nil, os.NewSyscallError("networking", syscall.ENACL)
}
func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
_, err := newpollster()
return err
}
func (p *pollster) StopWaiting(fd int, bits uint) {
}
func (p *pollster) DelFD(fd int, mode int) {}
func (p *pollster) WaitFD(nsec int64) (fd int, mode int, err os.Error) {
_, err = newpollster()
return
}
func (p *pollster) Close() os.Error { return nil }

View File

@ -33,11 +33,6 @@ GOFILES_linux=\
file_unix.go\
sys_linux.go\
GOFILES_nacl=\
env_unix.go\
file_unix.go\
sys_nacl.go\
GOFILES_windows=\
env_windows.go\
file_windows.go\

View File

@ -1,69 +0,0 @@
// 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.
package os
import (
"syscall"
"unsafe"
)
const (
blockSize = 4096 // TODO(r): use statfs
)
func clen(n []byte) int {
for i := 0; i < len(n); i++ {
if n[i] == 0 {
return i
}
}
return len(n)
}
func (file *File) Readdirnames(count int) (names []string, err Error) {
// If this file has no dirinfo, create one.
if file.dirinfo == nil {
file.dirinfo = new(dirInfo)
// The buffer must be at least a block long.
// TODO(r): use fstatfs to find fs block size.
file.dirinfo.buf = make([]byte, blockSize)
}
d := file.dirinfo
size := count
if size < 0 {
size = 100
}
names = make([]string, 0, size) // Empty with room to grow.
for count != 0 {
// Refill the buffer if necessary
if d.bufp >= d.nbuf {
var errno int
d.nbuf, errno = syscall.Getdents(file.fd, d.buf)
if errno != 0 {
return names, NewSyscallError("getdents", errno)
}
if d.nbuf <= 0 {
break // EOF
}
d.bufp = 0
}
// Drain the buffer
for count != 0 && d.bufp < d.nbuf {
dirent := (*syscall.Dirent)(unsafe.Pointer(&d.buf[d.bufp]))
d.bufp += int(dirent.Reclen)
if dirent.Ino == 0 { // File absent in directory.
continue
}
bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
var name = string(bytes[0:clen(bytes[0:])])
if name == "." || name == ".." { // Useless names
continue
}
count--
names = append(names, name)
}
}
return names, nil
}

View File

@ -1,38 +0,0 @@
// 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.
package os
import "syscall"
func isSymlink(stat *syscall.Stat_t) bool {
return stat.Mode&syscall.S_IFMT == syscall.S_IFLNK
}
func fileInfoFromStat(name string, fi *FileInfo, lstat, stat *syscall.Stat_t) *FileInfo {
fi.Dev = uint64(stat.Dev)
fi.Ino = uint64(stat.Ino)
fi.Nlink = uint64(stat.Nlink)
fi.Mode = stat.Mode
fi.Uid = int(stat.Uid)
fi.Gid = int(stat.Gid)
fi.Rdev = uint64(stat.Rdev)
fi.Size = int64(stat.Size)
fi.Blksize = int64(stat.Blksize)
fi.Blocks = int64(stat.Blocks)
fi.Atime_ns = int64(stat.Atime) * 1e9
fi.Mtime_ns = int64(stat.Mtime) * 1e9
fi.Ctime_ns = int64(stat.Ctime) * 1e9
for i := len(name) - 1; i >= 0; i-- {
if name[i] == '/' {
name = name[i+1:]
break
}
}
fi.Name = name
if isSymlink(lstat) && !isSymlink(stat) {
fi.FollowedSymlink = true
}
return fi
}

View File

@ -1,7 +0,0 @@
// 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.
package os
func Hostname() (name string, err Error) { return "nacl", nil }

View File

@ -18,9 +18,6 @@ GOFILES_darwin=\
GOFILES_linux=\
path_unix.go
GOFILES_nacl=\
path_unix.go
GOFILES_windows=\
path_windows.go

View File

@ -15,9 +15,6 @@ runtime·closure(int32 siz, byte *fn, byte *arg0)
int32 i, n;
int32 pcrel;
if(runtime·goos != nil && runtime·strcmp((uint8*)runtime·goos, (uint8*)"nacl") == 0)
runtime·throw("no closures in native client yet");
if(siz < 0 || siz%4 != 0)
runtime·throw("bad closure size");

View File

@ -165,9 +165,3 @@ ifeq ($(GOARCH),386)
traceback.$O: amd64/traceback.c
$(CC) $(CFLAGS) $<
endif
# NaCl closure is special.
ifeq ($(GOOS),nacl)
closure.$O: nacl/$(GOARCH)/closure.c
$(CC) $(CFLAGS) $<
endif

View File

@ -327,10 +327,6 @@ struct MHeap
byte *min;
byte *max;
// range of addresses we might see in a Native Client closure
byte *closure_min;
byte *closure_max;
// central free lists for small size classes.
// the union makes sure that the MCentrals are
// spaced 64 bytes apart, so that each MCentral.Lock

View File

@ -76,22 +76,6 @@ scanblock(byte *b, int64 n)
obj = vp[i];
if(obj == nil)
continue;
if(runtime·mheap.closure_min != nil && runtime·mheap.closure_min <= (byte*)obj && (byte*)obj < runtime·mheap.closure_max) {
if((((uintptr)obj) & 63) != 0)
continue;
// Looks like a Native Client closure.
// Actual pointer is pointed at by address in first instruction.
// Embedded pointer starts at byte 2.
// If it is f4f4f4f4 then that space hasn't been
// used for a closure yet (f4 is the HLT instruction).
// See nacl/386/closure.c for more.
void **pp;
pp = *(void***)((byte*)obj+2);
if(pp == (void**)0xf4f4f4f4) // HLT... - not a closure after all
continue;
obj = *pp;
}
if(runtime·mheap.min <= (byte*)obj && (byte*)obj < runtime·mheap.max) {
if(runtime·mlookup(obj, &obj, &size, nil, &refp)) {
ref = *refp;

View File

@ -165,7 +165,7 @@ MHeap_Grow(MHeap *h, uintptr npage)
// Ask for a big chunk, to reduce the number of mappings
// the operating system needs to track; also amortizes
// the overhead of an operating system mapping.
// For Native Client, allocate a multiple of 64kB (16 pages).
// Allocate a multiple of 64kB (16 pages).
npage = (npage+15)&~15;
ask = npage<<PageShift;
if(ask < HeapAllocChunk)

View File

@ -1,249 +0,0 @@
// 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.
/*
* Closure implementation for Native Client.
* Native Client imposes some interesting restrictions.
*
* First, we can only add new code to the code segment
* through a special system call, and we have to pick the
* maximum amount of code we're going to add that way
* at link time (8l reserves 512 kB for us).
*
* Second, once we've added the code we can't ever
* change it or delete it. If we want to garbage collect
* the memory and then reuse it for another closure,
* we have to do so without editing the code.
*
* To address both of these, we fill the code segment pieces
* with very stylized closures. Each has the form given below
* in the comments on the closasm array, with ** replaced by
* a pointer to a single word of memory. The garbage collector
* treats a pointer to such a closure as equivalent to the value
* held in **. This tiled run of closures is called the closure array.
*
* The ptr points at a ClosureData structure, defined below,
* which gives the function, arguments, and size for the
* closuretramp function. The ClosureData structure has
* in it a pointer to a ClosureFreeList structure holding the index
* of the closure in the closure array (but not a pointer to it).
* That structure has a finalizer: when the garbage collector
* notices that the ClosureFreeList structure is not referenced
* anymore, that means the closure is not referenced, so it
* can be reused. To do that, the ClosureFreeList entry is put
* onto an actual free list.
*/
#include "runtime.h"
#include "malloc.h"
// NaCl system call to copy data into text segment.
extern int32 runtime·dyncode_copy(void*, void*, int32);
enum{
// Allocate chunks of 4096 bytes worth of closures:
// at 64 bytes each, that's 64 closures.
ClosureChunk = 4096,
ClosureSize = 64,
};
typedef struct ClosureFreeList ClosureFreeList;
struct ClosureFreeList
{
ClosureFreeList *next;
int32 index; // into closure array
};
// Known to closasm
typedef struct ClosureData ClosureData;
struct ClosureData
{
ClosureFreeList *free;
byte *fn;
int32 siz;
// then args
};
// List of the closure data pointer blocks we've allocated
// and hard-coded in the closure text segments.
// The list keeps the pointer blocks from getting collected.
typedef struct ClosureDataList ClosureDataList;
struct ClosureDataList
{
ClosureData **block;
ClosureDataList *next;
};
static struct {
Lock;
byte *code;
byte *ecode;
ClosureFreeList *free;
ClosureDataList *datalist;
byte buf[ClosureChunk];
} clos;
static byte closasm[64] = {
0x8b, 0x1d, 0, 0, 0, 0, // MOVL **, BX
0x8b, 0x4b, 8, // MOVL 8(BX), CX
0x8d, 0x73, 12, // LEAL 12(BX), SI
0x29, 0xcc, // SUBL CX, SP
0x89, 0xe7, // MOVL SP, DI
0xc1, 0xe9, 2, // SHRL $2, CX
0xf3, 0xa5, // REP MOVSL
0x8b, 0x5b, 4, // MOVL 4(BX), BX
0x90, 0x90, 0x90, // NOP...
0x83, 0xe3, ~31, // ANDL $~31, BX
0xff, 0xd3, // CALL *BX
// --- 32-byte boundary
0x8b, 0x1d, 0, 0, 0, 0, // MOVL **, BX
0x03, 0x63, 8, // ADDL 8(BX), SP
0x5b, // POPL BX
0x83, 0xe3, ~31, // ANDL $~31, BX
0xff, 0xe3, // JMP *BX
0xf4, // HLT...
0xf4, 0xf4, 0xf4, 0xf4,
0xf4, 0xf4, 0xf4, 0xf4,
0xf4, 0xf4, 0xf4, 0xf4,
0xf4, 0xf4, 0xf4, 0xf4,
// --- 32-byte boundary
};
// Returns immediate pointer from closure code block.
// Triple pointer:
// p is the instruction stream
// p+2 is the location of the immediate value
// *(p+2) is the immediate value, a word in the pointer block
// permanently associated with this closure.
// **(p+2) is the ClosureData* pointer temporarily associated
// with this closure.
//
#define codeptr(p) *(ClosureData***)((byte*)(p)+2)
void
runtime·finclosure(void *v)
{
byte *p;
ClosureFreeList *f;
f = v;
p = clos.code + f->index*ClosureSize;
*codeptr(p) = nil;
runtime·lock(&clos);
f->next = clos.free;
clos.free = f;
runtime·unlock(&clos);
}
#pragma textflag 7
// func closure(siz int32,
// fn func(arg0, arg1, arg2 *ptr, callerpc uintptr, xxx) yyy,
// arg0, arg1, arg2 *ptr) (func(xxx) yyy)
void
runtime·closure(int32 siz, byte *fn, byte *arg0)
{
byte *p, **ret;
int32 e, i, n, off;
extern byte rodata[], etext[];
ClosureData *d, **block;
ClosureDataList *l;
ClosureFreeList *f;
if(siz < 0 || siz%4 != 0)
runtime·throw("bad closure size");
ret = (byte**)((byte*)&arg0 + siz);
if(siz > 100) {
// TODO(rsc): implement stack growth preamble?
runtime·throw("closure too big");
}
runtime·lock(&clos);
if(clos.free == nil) {
// Allocate more closures.
if(clos.code == nil) {
// First time: find closure space, between end of text
// segment and beginning of data.
clos.code = (byte*)(((uintptr)etext + 65535) & ~65535);
clos.ecode = clos.code;
runtime·mheap.closure_min = clos.code;
runtime·mheap.closure_max = rodata;
}
if(clos.ecode+ClosureChunk > rodata) {
// Last ditch effort: garbage collect and hope.
runtime·unlock(&clos);
runtime·gc(1);
runtime·lock(&clos);
if(clos.free != nil)
goto alloc;
runtime·throw("ran out of room for closures in text segment");
}
n = ClosureChunk/ClosureSize;
// Allocate the pointer block as opaque to the
// garbage collector. Finalizers will clean up.
block = runtime·mallocgc(n*sizeof block[0], RefNoPointers, 1, 1);
// Pointers into the pointer block are getting added
// to the text segment; keep a pointer here in the data
// segment so that the garbage collector doesn't free
// the block itself.
l = runtime·mal(sizeof *l);
l->block = block;
l->next = clos.datalist;
clos.datalist = l;
p = clos.buf;
off = (clos.ecode - clos.code)/ClosureSize;
for(i=0; i<n; i++) {
f = runtime·mal(sizeof *f);
f->index = off++;
f->next = clos.free;
clos.free = f;
// There are two hard-coded immediate values in
// the assembly that need to be pp+i, one 2 bytes in
// and one 2 bytes after the 32-byte boundary.
runtime·mcpy(p, closasm, ClosureSize);
*(ClosureData***)(p+2) = block+i;
*(ClosureData***)(p+32+2) = block+i;
p += ClosureSize;
}
if(p != clos.buf+sizeof clos.buf)
runtime·throw("bad buf math in closure");
e = runtime·dyncode_copy(clos.ecode, clos.buf, ClosureChunk);
if(e != 0) {
runtime·fd = 2;
if(e == -22)
runtime·throw("NaCl running with dyncode_copy disabled; export NACLDYNCODE=1 in your environment");
runtime·printf("dyncode_copy: error %d\n", e);
runtime·throw("dyncode_copy");
}
clos.ecode += ClosureChunk;
}
alloc:
// Grab a free closure and save the data pointer in its indirect pointer.
f = clos.free;
clos.free = f->next;
f->next = nil;
p = clos.code + f->index*ClosureSize;
d = runtime·mal(sizeof(*d)+siz);
d->free = f;
d->fn = fn;
d->siz = siz;
runtime·mcpy((byte*)(d+1), (byte*)&arg0, siz);
*codeptr(p) = d;
runtime·addfinalizer(f, runtime·finclosure, 0);
runtime·unlock(&clos);
*ret = p;
}

View File

@ -1,17 +0,0 @@
// godefs -f-m32 -f-I/home/rsc/pub/nacl/native_client/src/third_party/nacl_sdk/linux/sdk/nacl-sdk/nacl/include -f-I/home/rsc/pub/nacl/native_client defs.c
// MACHINE GENERATED - DO NOT EDIT.
// Constants
enum {
PROT_NONE = 0,
PROT_READ = 0x1,
PROT_WRITE = 0x2,
PROT_EXEC = 0x4,
MAP_ANON = 0x20,
MAP_PRIVATE = 0x2,
};
// Types
#pragma pack on
#pragma pack off

View File

@ -1,8 +0,0 @@
// 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.
// Native Client and Linux use the same linkage to main
TEXT _rt0_386_nacl(SB),7,$0
JMP _rt0_386(SB)

View File

@ -1,14 +0,0 @@
// 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.
#include "runtime.h"
#include "defs.h"
#include "signals.h"
#include "os.h"
void
runtime·initsig(int32 queue)
{
}

View File

@ -1,142 +0,0 @@
// 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.
//
// System calls and other sys.stuff for 386, Linux
//
#include "386/asm.h"
// http://code.google.com/p/nativeclient/source/browse/trunk/src/native_client/src/trusted/service_runtime/include/bits/nacl_syscalls.h
#define SYS_exit 30
#define SYS_mmap 21
#define SYS_munmap 22
#define SYS_thread_create 80
#define SYS_thread_exit 81
#define SYS_tls_init 82
#define SYS_write 13
#define SYS_close 11
#define SYS_mutex_create 70
#define SYS_mutex_lock 71
#define SYS_mutex_unlock 73
#define SYS_gettimeofday 40
#define SYS_dyncode_copy 104
#define SYSCALL(x) $(0x10000+SYS_/**/x * 32)
TEXT runtime·exit(SB),7,$4
MOVL code+0(FP), AX
MOVL AX, 0(SP)
CALL SYSCALL(exit)
INT $3 // not reached
RET
TEXT runtime·exit1(SB),7,$4
MOVL code+0(FP), AX
MOVL AX, 0(SP)
CALL SYSCALL(thread_exit)
INT $3 // not reached
RET
TEXT runtime·write(SB),7,$0
JMP SYSCALL(write)
TEXT runtime·close(SB),7,$0
JMP SYSCALL(close)
TEXT runtime·mutex_create(SB),7,$0
JMP SYSCALL(mutex_create)
TEXT runtime·mutex_lock(SB),7,$0
JMP SYSCALL(mutex_lock)
TEXT runtime·mutex_unlock(SB),7,$0
JMP SYSCALL(mutex_unlock)
TEXT runtime·thread_create(SB),7,$0
JMP SYSCALL(thread_create)
TEXT runtime·dyncode_copy(SB),7,$0
JMP SYSCALL(dyncode_copy)
// For Native Client: a simple no-op function.
// Inserting a call to this no-op is a simple way
// to trigger an alignment.
TEXT runtime·naclnop(SB),7,$0
RET
TEXT runtime·mmap(SB),7,$24
MOVL a1+0(FP), BX
MOVL a2+4(FP), CX // round up to 64 kB boundary; silences nacl warning
ADDL $(64*1024-1), CX
ANDL $~(64*1024-1), CX
MOVL a3+8(FP), DX
MOVL a4+12(FP), SI
MOVL a5+16(FP), DI
MOVL a6+20(FP), BP
MOVL BX, 0(SP)
MOVL CX, 4(SP)
MOVL DX, 8(SP)
MOVL SI, 12(SP)
MOVL DI, 16(SP)
MOVL BP, 20(SP)
CALL SYSCALL(mmap)
CMPL AX, $0xfffff001
JLS 6(PC)
MOVL $1, 0(SP)
MOVL $runtime·mmap_failed(SB), 4(SP)
MOVL $12, 8(SP) // "mmap failed\n"
CALL SYSCALL(write)
INT $3
RET
TEXT runtime·munmap(SB),7,$0
JMP SYSCALL(munmap)
TEXT runtime·gettime(SB),7,$32
LEAL 8(SP), BX
MOVL BX, 0(SP)
MOVL $0, 4(SP)
CALL SYSCALL(gettimeofday)
MOVL 8(SP), BX // sec
MOVL sec+0(FP), DI
MOVL BX, (DI)
MOVL $0, 4(DI) // zero extend 32 -> 64 bits
MOVL 12(SP), BX // usec
MOVL usec+4(FP), DI
MOVL BX, (DI)
RET
// setldt(int entry, int address, int limit)
TEXT runtime·setldt(SB),7,$32
// entry is ignored - nacl tells us the
// segment selector to use and stores it in GS.
MOVL address+4(FP), BX
MOVL limit+8(FP), CX
MOVL BX, 0(SP)
MOVL CX, 4(SP)
CALL SYSCALL(tls_init)
CMPL AX, $0xfffff001
JLS 6(PC)
MOVL $1, 0(SP)
MOVL $runtime·tls_init_failed(SB), 4(SP)
MOVL $16, 8(SP) // "tls_init failed\n"
CALL SYSCALL(write)
INT $3
RET
// There's no good way (yet?) to get stack traces out of a
// broken NaCl process, so if something goes wrong,
// print an error string before dying.
DATA runtime·mmap_failed(SB)/8, $"mmap fai"
DATA mmap_failed+8(SB)/4, $"led\n"
GLOBL runtime·mmap_failed(SB), $12
DATA runtime·tls_init_failed(SB)/8, $"tls_init"
DATA tls_init_failed+8(SB)/8, $" failed\n"
GLOBL runtime·tls_init_failed(SB), $16

View File

@ -1,27 +0,0 @@
// 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.
/*
Input to godefs.
godefs -f-m32 -f-I/home/rsc/pub/nacl/native_client/src/third_party/nacl_sdk/linux/sdk/nacl-sdk/nacl/include -f-I/home/rsc/pub/nacl/native_client defs.c >386/defs.h
*/
#define __native_client__ 1
#define suseconds_t nacl_suseconds_t_1
#include <sys/types.h>
#undef suseconds_t
#include <sys/mman.h>
enum {
$PROT_NONE = PROT_NONE,
$PROT_READ = PROT_READ,
$PROT_WRITE = PROT_WRITE,
$PROT_EXEC = PROT_EXEC,
$MAP_ANON = MAP_ANONYMOUS,
$MAP_PRIVATE = MAP_PRIVATE,
};

View File

@ -1,37 +0,0 @@
#include "runtime.h"
#include "defs.h"
#include "os.h"
#include "malloc.h"
enum {
NaclPage = 0x10000
};
void*
runtime·SysAlloc(uintptr n)
{
mstats.sys += n;
return runtime·mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0);
}
void
runtime·SysUnused(void *v, uintptr n)
{
USED(v);
USED(n);
// TODO(rsc): call madvise MADV_DONTNEED
}
void
runtime·SysFree(void *v, uintptr n)
{
// round to page size or else nacl prints annoying log messages
mstats.sys -= n;
n = (n+NaclPage-1) & ~(NaclPage-1);
runtime·munmap(v, n);
}
void
runtime·SysMemInit(void)
{
}

View File

@ -1,9 +0,0 @@
// 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.
int32 runtime·thread_create(void(*fn)(void), void *stk, void *tls, int32 tlssize);
void runtime·close(int32);
int32 runtime·mutex_create(void);
int32 runtime·mutex_lock(int32);
int32 runtime·mutex_unlock(int32);

View File

@ -1,14 +0,0 @@
// Copyright 2010 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.
// OS-Specific Go definitions of internal structures. Master is runtime.h
package runtime
type lock struct {
key uint32
sema uint32
}
type note lock

View File

@ -1,164 +0,0 @@
// 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.
#include "runtime.h"
#include "defs.h"
#include "os.h"
int8 *goos = "nacl";
// Thread-safe allocation of a mutex.
// (The name sema is left over from the Darwin implementation.
// Native Client implements semaphores too, but it is just a shim
// over the host implementation, which on some hosts imposes a very
// low limit on how many semaphores can be created.)
//
// Psema points at a mutex descriptor.
// It starts out zero, meaning no mutex.
// Fill it in, being careful of others calling initsema
// simultaneously.
static void
initsema(uint32 *psema)
{
uint32 sema;
if(*psema != 0) // already have one
return;
sema = runtime·mutex_create();
if((int32)sema < 0) {
runtime·printf("mutex_create failed\n");
runtime·breakpoint();
}
// mutex_create returns a file descriptor;
// shift it up and add the 1 bit so that can
// distinguish unintialized from fd 0.
sema = (sema<<1) | 1;
if(!cas(psema, 0, sema)){
// Someone else filled it in. Use theirs.
runtime·close(sema);
return;
}
}
// Lock and unlock.
// Defer entirely to Native Client.
// The expense of a call into Native Client is more like
// a function call than a system call, so as long as the
// Native Client lock implementation is good, we can't
// do better ourselves.
static void
xlock(int32 fd)
{
if(mutex_lock(fd) < 0) {
runtime·printf("mutex_lock failed\n");
runtime·breakpoint();
}
}
static void
xunlock(int32 fd)
{
if(mutex_unlock(fd) < 0) {
runtime·printf("mutex_lock failed\n");
runtime·breakpoint();
}
}
void
runtime·lock(Lock *l)
{
if(m->locks < 0)
runtime·throw("lock count");
m->locks++;
if(l->sema == 0)
runtime·initsema(&l->sema);
runtime·xlock(l->sema>>1);
}
void
runtime·unlock(Lock *l)
{
m->locks--;
if(m->locks < 0)
runtime·throw("lock count");
runtime·xunlock(l->sema>>1);
}
void
runtime·destroylock(Lock*)
{
}
// One-time notifications.
//
// Since the lock/unlock implementation already
// takes care of sleeping in the kernel, we just reuse it.
// (But it's a weird use, so it gets its own interface.)
//
// We use a lock to represent the event:
// unlocked == event has happened.
// Thus the lock starts out locked, and to wait for the
// event you try to lock the lock. To signal the event,
// you unlock the lock.
//
// Native Client does not require that the thread acquiring
// a lock be the thread that releases the lock, so this is safe.
void
runtime·noteclear(Note *n)
{
if(n->lock.sema == 0)
runtime·initsema(&n->lock.sema);
runtime·xlock(n->lock.sema>>1);
}
void
runtime·notewakeup(Note *n)
{
if(n->lock.sema == 0) {
runtime·printf("notewakeup without noteclear");
runtime·breakpoint();
}
runtime·xunlock(n->lock.sema>>1);
}
void
runtime·notesleep(Note *n)
{
if(n->lock.sema == 0) {
runtime·printf("notesleep without noteclear");
runtime·breakpoint();
}
runtime·xlock(n->lock.sema>>1);
runtime·xunlock(n->lock.sema>>1); // Let other sleepers find out too.
}
void
runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
{
void **vstk;
// I wish every OS made thread creation this easy.
m->tls[0] = (uint32)g;
m->tls[1] = (uint32)m;
vstk = stk;
*--vstk = nil;
if(thread_create(fn, vstk, m->tls, sizeof m->tls) < 0) {
runtime·printf("thread_create failed\n");
runtime·breakpoint();
}
}
void
runtime·osinit(void)
{
}
// Called to initialize a new m (including the bootstrap m).
void
runtime·minit(void)
{
}

View File

@ -30,10 +30,6 @@ GOFILES_linux=\
syscall_unix.go\
exec_unix.go\
GOFILES_nacl=\
syscall_unix.go\
exec_unix.go\
GOFILES_windows=\
exec_windows.go

View File

@ -1,119 +0,0 @@
// 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.
//
// System calls for 386, Native Client
//
#define SYSCALL(x) $(0x10000+x * 32)
// func Syscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
// Trap # in AX, args in BX CX DX SI DI, return in AX
TEXT ·Syscall(SB),7,$20
CALL runtime·entersyscall(SB)
MOVL trap+0(FP), AX // syscall entry
MOVL a1+4(FP), BX
MOVL a2+8(FP), CX
MOVL a3+12(FP), DX
MOVL $0, SI
MOVL $0, DI
MOVL BX, 0(SP)
MOVL CX, 4(SP)
MOVL DX, 8(SP)
MOVL SI, 12(SP)
MOVL DI, 16(SP)
// Call $(0x10000+32*AX)
SHLL $5, AX
ADDL $0x10000, AX
CALL AX
CMPL AX, $0xfffff001
JLS ok
MOVL $-1, r1+16(FP)
MOVL $0, r2+20(FP)
NEGL AX
MOVL AX, errno+24(FP)
CALL runtime·exitsyscall(SB)
RET
ok:
MOVL AX, r1+16(FP)
MOVL DX, r2+20(FP)
MOVL $0, errno+24(FP)
CALL runtime·exitsyscall(SB)
RET
// func Syscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
TEXT ·Syscall6(SB),7,$24
CALL runtime·entersyscall(SB)
MOVL a1+4(FP), BX
MOVL a2+8(FP), CX
MOVL a3+12(FP), DX
MOVL a4+16(FP), SI
MOVL a5+20(FP), DI
MOVL a6+24(FP), AX
MOVL BX, 0(SP)
MOVL CX, 4(SP)
MOVL DX, 8(SP)
MOVL SI, 12(SP)
MOVL DI, 16(SP)
MOVL AX, 20(SP)
// Call $(0x10000+32*trap)
MOVL trap+0(FP), AX // syscall entry
SHLL $5, AX
ADDL $0x10000, AX
CALL AX
CMPL AX, $0xfffff001
JLS ok6
MOVL $-1, r1+28(FP)
MOVL $0, r2+32(FP)
NEGL AX
MOVL AX, errno+36(FP)
CALL runtime·exitsyscall(SB)
RET
ok6:
MOVL AX, r1+28(FP)
MOVL DX, r2+32(FP)
MOVL $0, errno+36(FP)
CALL runtime·exitsyscall(SB)
RET
// func RawSyscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
TEXT ·RawSyscall(SB),7,$20
MOVL trap+0(FP), AX // syscall entry
MOVL a1+4(FP), BX
MOVL a2+8(FP), CX
MOVL a3+12(FP), DX
MOVL $0, SI
MOVL $0, DI
MOVL BX, 0(SP)
MOVL CX, 4(SP)
MOVL DX, 8(SP)
MOVL SI, 12(SP)
MOVL DI, 16(SP)
// Call $(0x10000+32*AX)
SHLL $5, AX
ADDL $0x10000, AX
CALL AX
CMPL AX, $0xfffff001
JLS ok1
MOVL $-1, r1+16(FP)
MOVL $0, r2+20(FP)
NEGL AX
MOVL AX, errno+24(FP)
RET
ok1:
MOVL AX, r1+16(FP)
MOVL DX, r2+20(FP)
MOVL $0, errno+24(FP)
RET

View File

@ -1,41 +0,0 @@
#!/bin/sh
# 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.
# Generate Go code listing error values (ENAMETOOLONG etc)
# for Native Client.
echo '// mkerrors_nacl.sh' "$@"
echo '// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT'
echo
echo 'package syscall'
echo
echo 'const ('
perl -n -e '
if(/#define\s+NACL_ABI_(\S*)\s+([0-9]+)/) {
print "\t$1 = $2;\n"
}
' $1
echo ' ENACL = 99; /* otherwise unused */'
echo ')'
echo
echo
echo '// Error table'
echo 'var errors = [...]string {'
perl -n -e '
if(/#define\s+NACL_ABI_(\S*)\s+([0-9]+)\s+\/\* (.*) \*\//) {
$err = $1;
$text = $3;
if($text =~ /^[A-Z][a-z]/) {
# lowercase first letter: Bad -> bad, but STREAM -> STREAM.
$l = substr($text, 0, 1);
$rest = substr($text, 1);
$l =~ y/A-Z/a-z/;
$text = $l . $rest;
}
print "\t$err: \"$text\",\n";
}
' $1
echo ' ENACL: "not supported by native client",'
echo '}'

View File

@ -1,29 +0,0 @@
#!/usr/bin/perl
# 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.
my $command = "mksysnum_nacl.sh ". join(' ', @ARGV);
print <<EOF;
// $command
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
package syscall
const(
EOF
while(<>){
if(/^#define NACL_sys_(\w+)\s+([0-9]+)/){
my $name = "SYS_$1";
my $num = $2;
$name =~ y/a-z/A-Z/;
print " $name = $num;\n";
}
}
print <<EOF;
)
EOF

View File

@ -1,357 +0,0 @@
// 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.
// Native Client system calls.
package syscall
const OS = "nacl"
var _zero [1]byte // pointer used for zero-length writes
// Auto-generated
//sys Chmod(path string, mode uint32) (errno int)
//sys Clock() (clock int)
//sys Close(fd int) (errno int)
//sys Exit(code int)
//sys Fstat(fd int, stat *Stat_t) (errno int)
//sys Getdents(fd int, buf []byte) (n int, errno int)
//sys Getpid() (pid int)
//sys Gettimeofday(tv *Timeval) (errno int)
//sys Open(path string, mode int, perm uint32) (fd int, errno int)
//sys Read(fd int, p []byte) (n int, errno int)
//sys read(fd int, buf *byte, nbuf int) (n int, errno int)
//sys Stat(path string, stat *Stat_t) (errno int)
//sys Write(fd int, p []byte) (n int, errno int)
//sys MultimediaInit(subsys int) (errno int)
//sys MultimediaShutdown() (errno int)
//sys CondCreate() (cv int, errno int)
//sys CondWait(cv int, mutex int) (errno int)
//sys CondSignal(cv int) (errno int)
//sys CondBroadcast(cv int) (errno int)
//sys CondTimedWaitAbs(cv int, mutex int, abstime *Timespec) (errno int)
//sys MutexCreate() (mutex int, errno int)
//sys MutexLock(mutex int) (errno int)
//sys MutexUnlock(mutex int) (errno int)
//sys MutexTryLock(mutex int) (errno int) = SYS_MUTEX_TRYLOCK
//sys SemCreate() (sema int, errno int)
//sys SemWait(sema int) (errno int)
//sys SemPost(sema int) (errno int)
//sys VideoInit(dx int, dy int) (errno int)
//sys VideoUpdate(data *uint32) (errno int)
//sys VideoPollEvent(ev *byte) (errno int)
//sys VideoShutdown() (errno int)
//sys AudioInit(fmt int, nreq int, data *int) (errno int)
//sys AudioShutdown() (errno int)
//sys AudioStream(data *uint16, size *uintptr) (errno int)
// Hand-written
func Seek(fd int, offset int64, whence int) (newoffset int64, errno int) {
// Offset passed to system call is 32 bits. Failure of vision by NaCl.
if int64(int32(offset)) != offset {
return 0, ERANGE
}
o, _, e := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
return int64(o), int(e)
}
// Sleep by waiting on a condition variable that will never be signaled.
// TODO(rsc): Replace when NaCl adds a proper sleep system call.
var tcv, tmu int
func init() {
tmu, _ = MutexCreate()
tcv, _ = CondCreate()
}
func Sleep(ns int64) (errno int) {
ts := NsecToTimespec(ns)
var tv Timeval
if errno = Gettimeofday(&tv); errno != 0 {
return
}
ts.Sec += tv.Sec
ts.Nsec += tv.Usec * 1000
switch {
case ts.Nsec >= 1e9:
ts.Nsec -= 1e9
ts.Sec++
case ts.Nsec <= -1e9:
ts.Nsec += 1e9
ts.Sec--
}
if errno = MutexLock(tmu); errno != 0 {
return
}
errno = CondTimedWaitAbs(tcv, tmu, &ts)
if e := MutexUnlock(tmu); e != 0 && errno == 0 {
errno = e
}
return
}
// Implemented in NaCl but not here; maybe later:
// SYS_IOCTL
// SYS_IMC_*
// SYS_MMAP ???
// SYS_SRPC_*
// SYS_SYSCONF
// Implemented in NaCl but not here; used by runtime instead:
// SYS_SYSBRK
// SYS_MMAP
// SYS_MUNMAP
// SYS_THREAD_*
// SYS_TLS_*
// SYS_SCHED_YIELD
// #define'd in NaCl but not picked up by mkerrors_nacl.sh.
const EWOULDBLOCK = EAGAIN
// Not implemented in NaCl but needed to compile other packages.
const (
SIGTRAP = 5
)
func Pipe(p []int) (errno int) { return ENACL }
func fcntl(fd, cmd, arg int) (val int, errno int) {
return 0, ENACL
}
func Pread(fd int, p []byte, offset int64) (n int, errno int) {
return 0, ENACL
}
func Pwrite(fd int, p []byte, offset int64) (n int, errno int) {
return 0, ENACL
}
func Mkdir(path string, mode uint32) (errno int) { return ENACL }
func Lstat(path string, stat *Stat_t) (errno int) {
return Stat(path, stat)
}
func Chdir(path string) (errno int) { return ENACL }
func Fchdir(fd int) (errno int) { return ENACL }
func Unlink(path string) (errno int) { return ENACL }
func Rmdir(path string) (errno int) { return ENACL }
func Link(oldpath, newpath string) (errno int) {
return ENACL
}
func Symlink(path, link string) (errno int) { return ENACL }
func Readlink(path string, buf []byte) (n int, errno int) {
return 0, ENACL
}
func Rename(oldpath, newpath string) (errno int) {
return ENACL
}
func Fchmod(fd int, mode uint32) (errno int) { return ENACL }
func Chown(path string, uid int, gid int) (errno int) {
return ENACL
}
func Lchown(path string, uid int, gid int) (errno int) {
return ENACL
}
func Fchown(fd int, uid int, gid int) (errno int) {
return ENACL
}
func Utimes(path string, tv []Timeval) (errno int) {
return ENACL
}
func Futimes(fd int, tv []Timeval) (errno int) {
return ENACL
}
func Truncate(name string, size int64) (errno int) {
return ENACL
}
func Ftruncate(fd int, length int64) (errno int) {
return ENACL
}
// NaCL doesn't actually implement Getwd, but it also
// don't implement Chdir, so the fallback algorithm
// fails worse than calling Getwd does.
const ImplementsGetwd = true
func Getwd() (wd string, errno int) { return "", ENACL }
func Getuid() (uid int) { return -1 }
func Geteuid() (euid int) { return -1 }
func Getgid() (gid int) { return -1 }
func Getegid() (egid int) { return -1 }
func Getppid() (ppid int) { return -1 }
func Getgroups() (gids []int, errno int) { return nil, ENACL }
type Sockaddr interface {
sockaddr()
}
type SockaddrInet4 struct {
Port int
Addr [4]byte
}
func (*SockaddrInet4) sockaddr() {}
type SockaddrInet6 struct {
Port int
Addr [16]byte
}
func (*SockaddrInet6) sockaddr() {}
type SockaddrUnix struct {
Name string
}
func (*SockaddrUnix) sockaddr() {}
const (
AF_INET = 1 + iota
AF_INET6
AF_UNIX
IPPROTO_TCP
SOCK_DGRAM
SOCK_STREAM
SOCK_RAW
SOL_SOCKET
SOMAXCONN
SO_DONTROUTE
SO_KEEPALIVE
SO_LINGER
SO_RCVBUF
SO_REUSEADDR
SO_SNDBUF
IPPROTO_IPV6
IPV6_V6ONLY
TCP_NODELAY
WNOHANG
WSTOPPED
PTRACE_TRACEME
SO_BROADCAST = 0
SHUT_RDWR = 0
)
func Accept(fd int) (nfd int, sa Sockaddr, errno int) {
return 0, nil, ENACL
}
func Getsockname(fd int) (sa Sockaddr, errno int) {
return nil, ENACL
}
func Getpeername(fd int) (sa Sockaddr, errno int) {
return nil, ENACL
}
func Bind(fd int, sa Sockaddr) (errno int) { return ENACL }
func BindToDevice(fd int, device string) (errno int) { return ENACL }
func Connect(fd int, sa Sockaddr) (errno int) { return ENACL }
func Socket(domain, typ, proto int) (fd, errno int) {
return 0, ENACL
}
func SetsockoptInt(fd, level, opt int, value int) (errno int) {
return ENACL
}
func Shutdown(fd, how int) (errno int) { return ENACL }
func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, errno int) {
return 0, nil, ENACL
}
func Sendto(fd int, p []byte, flags int, to Sockaddr) (errno int) {
return ENACL
}
func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (errno int) {
return ENACL
}
type Linger struct {
Onoff int32
Linger int32
}
func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) {
return ENACL
}
func Listen(s int, n int) (errno int) { return ENACL }
type Rusage struct {
Utime Timeval
Stime Timeval
Maxrss int32
Ixrss int32
Idrss int32
Isrss int32
Minflt int32
Majflt int32
Nswap int32
Inblock int32
Oublock int32
Msgsnd int32
Msgrcv int32
Nsignals int32
Nvcsw int32
Nivcsw int32
}
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, errno int) {
return 0, ENACL
}
type WaitStatus uint32
func (WaitStatus) Exited() bool { return false }
func (WaitStatus) ExitStatus() int { return -1 }
func (WaitStatus) Signal() int { return -1 }
func (WaitStatus) CoreDump() bool { return false }
func (WaitStatus) Stopped() bool { return false }
func (WaitStatus) Continued() bool { return false }
func (WaitStatus) StopSignal() int { return -1 }
func (WaitStatus) Signaled() bool { return false }
func (WaitStatus) TrapCause() int { return -1 }

View File

@ -1,19 +0,0 @@
// 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.
package syscall
func Getpagesize() int { return 4096 }
func NsecToTimeval(nsec int64) (tv Timeval) {
tv.Sec = int32(nsec / 1e9)
tv.Usec = int32(nsec % 1e9 / 1e3)
return
}
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = int32(nsec / 1e9)
ts.Nsec = int32(nsec % 1e9)
return
}

View File

@ -1,123 +0,0 @@
// 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.
/*
Input to godefs. See also mkerrors.sh and mkall.sh
*/
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#define _GNU_SOURCE
#define __native_client__ 1
#define suseconds_t nacl_suseconds_t_1
#include <sys/types.h>
#undef suseconds_t
#include <sys/dirent.h>
#include <sys/mman.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/unistd.h>
#include <sys/mman.h>
// Machine characteristics; for internal use.
enum
{
$sizeofPtr = sizeof(void*),
$sizeofShort = sizeof(short),
$sizeofInt = sizeof(int),
$sizeofLong = sizeof(long),
$sizeofLongLong = sizeof(long long),
};
// Mmap constants
enum {
$PROT_READ = PROT_READ,
$PROT_WRITE = PROT_WRITE,
$MAP_SHARED = MAP_SHARED,
};
// Unimplemented system calls
enum {
$SYS_FORK = 0,
$SYS_PTRACE = 0,
$SYS_CHDIR = 0,
$SYS_DUP2 = 0,
$SYS_FCNTL = 0,
$SYS_EXECVE = 0,
};
// Basic types
typedef short $_C_short;
typedef int $_C_int;
typedef long $_C_long;
typedef long long $_C_long_long;
typedef off_t $_C_off_t;
// Time
typedef struct timespec $Timespec;
typedef struct timeval $Timeval;
typedef time_t $Time_t;
// Processes
//typedef struct rusage $Rusage;
//typedef struct rlimit $Rlimit;
typedef gid_t $_Gid_t;
// Files
enum
{
$O_RDONLY = O_RDONLY,
$O_WRONLY = O_WRONLY,
$O_RDWR = O_RDWR,
$O_APPEND = O_APPEND,
$O_ASYNC = O_ASYNC,
$O_CREAT = O_CREAT,
$O_NOCTTY = 0, // not supported
$O_NONBLOCK = O_NONBLOCK,
$O_SYNC = O_SYNC,
$O_TRUNC = O_TRUNC,
$O_EXCL = O_EXCL,
$O_CLOEXEC = 0, // not supported
$F_GETFD = F_GETFD,
$F_SETFD = F_SETFD,
$F_GETFL = F_GETFL,
$F_SETFL = F_SETFL,
$FD_CLOEXEC = 0, // not supported
};
enum
{ // Directory mode bits
$S_IFMT = S_IFMT,
$S_IFIFO = S_IFIFO,
$S_IFCHR = S_IFCHR,
$S_IFDIR = S_IFDIR,
$S_IFBLK = S_IFBLK,
$S_IFREG = S_IFREG,
$S_IFLNK = S_IFLNK,
$S_IFSOCK = S_IFSOCK,
$S_ISUID = S_ISUID,
$S_ISGID = S_ISGID,
$S_ISVTX = S_ISVTX,
$S_IRUSR = S_IRUSR,
$S_IWUSR = S_IWUSR,
$S_IXUSR = S_IXUSR,
};
typedef struct stat $Stat_t;
typedef struct dirent $Dirent;

View File

@ -1,246 +0,0 @@
// mkerrors_nacl.sh /home/rsc/pub/nacl/native_client/src/trusted/service_runtime/include/sys/errno.h
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
package syscall
const (
EPERM = 1
ENOENT = 2
ESRCH = 3
EINTR = 4
EIO = 5
ENXIO = 6
E2BIG = 7
ENOEXEC = 8
EBADF = 9
ECHILD = 10
EAGAIN = 11
ENOMEM = 12
EACCES = 13
EFAULT = 14
EBUSY = 16
EEXIST = 17
EXDEV = 18
ENODEV = 19
ENOTDIR = 20
EISDIR = 21
EINVAL = 22
ENFILE = 23
EMFILE = 24
ENOTTY = 25
EFBIG = 27
ENOSPC = 28
ESPIPE = 29
EROFS = 30
EMLINK = 31
EPIPE = 32
ENAMETOOLONG = 36
ENOSYS = 38
EDQUOT = 122
EDOM = 33
ERANGE = 34
ENOMSG = 35
ECHRNG = 37
EL3HLT = 39
EL3RST = 40
ELNRNG = 41
EUNATCH = 42
ENOCSI = 43
EL2HLT = 44
EDEADLK = 45
ENOLCK = 46
EBADE = 50
EBADR = 51
EXFULL = 52
ENOANO = 53
EBADRQC = 54
EBADSLT = 55
EBFONT = 57
ENOSTR = 60
ENODATA = 61
ETIME = 62
ENOSR = 63
ENONET = 64
ENOPKG = 65
EREMOTE = 66
ENOLINK = 67
EADV = 68
ESRMNT = 69
ECOMM = 70
EPROTO = 71
EMULTIHOP = 74
ELBIN = 75
EDOTDOT = 76
EBADMSG = 77
EFTYPE = 79
ENOTUNIQ = 80
EBADFD = 81
EREMCHG = 82
ELIBACC = 83
ELIBBAD = 84
ELIBSCN = 85
ELIBMAX = 86
ELIBEXEC = 87
ENMFILE = 89
ENOTEMPTY = 90
ELOOP = 92
EOPNOTSUPP = 95
EPFNOSUPPORT = 96
ECONNRESET = 104
ENOBUFS = 105
EAFNOSUPPORT = 106
EPROTOTYPE = 107
ENOTSOCK = 108
ENOPROTOOPT = 109
ESHUTDOWN = 110
ECONNREFUSED = 111
EADDRINUSE = 112
ECONNABORTED = 113
ENETUNREACH = 114
ENETDOWN = 115
ETIMEDOUT = 116
EHOSTDOWN = 117
EHOSTUNREACH = 118
EINPROGRESS = 119
EALREADY = 120
EDESTADDRREQ = 121
EPROTONOSUPPORT = 123
ESOCKTNOSUPPORT = 124
EADDRNOTAVAIL = 125
ENETRESET = 126
EISCONN = 127
ENOTCONN = 128
ETOOMANYREFS = 129
EPROCLIM = 130
EUSERS = 131
ESTALE = 133
ENOMEDIUM = 135
ENOSHARE = 136
ECASECLASH = 137
EILSEQ = 138
EOVERFLOW = 139
ECANCELED = 140
EL2NSYNC = 88
EIDRM = 91
EMSGSIZE = 132
ENACL = 99 /* otherwise unused */
)
// Error table
var errors = [...]string{
EPERM: "operation not permitted",
ENOENT: "no such file or directory",
ESRCH: "no such process",
EINTR: "interrupted system call",
EIO: "I/O error",
ENXIO: "no such device or address",
E2BIG: "argument list too long",
ENOEXEC: "exec format error",
EBADF: "bad file number",
ECHILD: "no child processes",
EAGAIN: "try again",
ENOMEM: "out of memory",
EACCES: "permission denied",
EFAULT: "bad address",
EBUSY: "device or resource busy",
EEXIST: "file exists",
EXDEV: "cross-device link",
ENODEV: "no such device",
ENOTDIR: "not a directory",
EISDIR: "is a directory",
EINVAL: "invalid argument",
ENFILE: "file table overflow",
EMFILE: "too many open files",
ENOTTY: "not a typewriter",
EFBIG: "file too large",
ENOSPC: "no space left on device",
ESPIPE: "illegal seek",
EROFS: "read-only file system",
EMLINK: "too many links",
EPIPE: "broken pipe",
ENAMETOOLONG: "file name too long",
ENOSYS: "function not implemented",
EDQUOT: "quota exceeded",
EDOM: "math arg out of domain of func",
ERANGE: "math result not representable",
ENOMSG: "no message of desired type",
ECHRNG: "channel number out of range",
EL3HLT: "level 3 halted",
EL3RST: "level 3 reset",
ELNRNG: "link number out of range",
EUNATCH: "protocol driver not attached",
ENOCSI: "no CSI structure available",
EL2HLT: "level 2 halted",
EDEADLK: "deadlock condition",
ENOLCK: "no record locks available",
EBADE: "invalid exchange",
EBADR: "invalid request descriptor",
EXFULL: "exchange full",
ENOANO: "no anode",
EBADRQC: "invalid request code",
EBADSLT: "invalid slot",
EBFONT: "bad font file fmt",
ENOSTR: "device not a stream",
ENODATA: "no data (for no delay io)",
ETIME: "timer expired",
ENOSR: "out of streams resources",
ENONET: "machine is not on the network",
ENOPKG: "package not installed",
EREMOTE: "the object is remote",
ENOLINK: "the link has been severed",
EADV: "advertise error",
ESRMNT: "srmount error",
ECOMM: "communication error on send",
EPROTO: "protocol error",
EMULTIHOP: "multihop attempted",
ELBIN: "inode is remote (not really error)",
EDOTDOT: "cross mount point (not really error)",
EBADMSG: "trying to read unreadable message",
EFTYPE: "inappropriate file type or format",
ENOTUNIQ: "given log. name not unique",
EBADFD: "f.d. invalid for this operation",
EREMCHG: "remote address changed",
ELIBACC: "can't access a needed shared lib",
ELIBBAD: "accessing a corrupted shared lib",
ELIBSCN: ".lib section in a.out corrupted",
ELIBMAX: "attempting to link in too many libs",
ELIBEXEC: "attempting to exec a shared library",
ENMFILE: "no more files",
ENOTEMPTY: "directory not empty",
ELOOP: "too many symbolic links",
EOPNOTSUPP: "operation not supported on transport endpoint",
EPFNOSUPPORT: "protocol family not supported",
ECONNRESET: "connection reset by peer",
ENOBUFS: "no buffer space available",
EAFNOSUPPORT: "address family not supported by protocol family",
EPROTOTYPE: "protocol wrong type for socket",
ENOTSOCK: "socket operation on non-socket",
ENOPROTOOPT: "protocol not available",
ESHUTDOWN: "can't send after socket shutdown",
ECONNREFUSED: "connection refused",
EADDRINUSE: "address already in use",
ECONNABORTED: "connection aborted",
ENETUNREACH: "network is unreachable",
ENETDOWN: "network interface is not configured",
ETIMEDOUT: "connection timed out",
EHOSTDOWN: "host is down",
EHOSTUNREACH: "host is unreachable",
EINPROGRESS: "connection already in progress",
EALREADY: "socket already connected",
EDESTADDRREQ: "destination address required",
EPROTONOSUPPORT: "unknown protocol",
ESOCKTNOSUPPORT: "socket type not supported",
EADDRNOTAVAIL: "address not available",
EISCONN: "socket is already connected",
ENOTCONN: "socket is not connected",
ENOMEDIUM: "no medium (in tape drive)",
ENOSHARE: "no such host or network path",
ECASECLASH: "filename exists with different case",
EOVERFLOW: "value too large for defined data type",
ECANCELED: "operation canceled.",
EL2NSYNC: "level 2 not synchronized",
EIDRM: "identifier removed",
EMSGSIZE: "message too long",
ENACL: "not supported by native client",
}

View File

@ -1,303 +0,0 @@
// mksyscall.sh -l32 -nacl syscall_nacl.go syscall_nacl_386.go
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
package syscall
import "unsafe"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Chmod(path string, mode uint32) (errno int) {
_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Clock() (clock int) {
r0, _, _ := Syscall(SYS_CLOCK, 0, 0, 0)
clock = int(r0)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Close(fd int) (errno int) {
_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Exit(code int) {
Syscall(SYS_EXIT, uintptr(code), 0, 0)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fstat(fd int, stat *Stat_t) (errno int) {
_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getdents(fd int, buf []byte) (n int, errno int) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero[0])
}
r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
n = int(r0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getpid() (pid int) {
r0, _, _ := Syscall(SYS_GETPID, 0, 0, 0)
pid = int(r0)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Gettimeofday(tv *Timeval) (errno int) {
_, _, e1 := Syscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Open(path string, mode int, perm uint32) (fd int, errno int) {
r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), uintptr(perm))
fd = int(r0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Read(fd int, p []byte) (n int, errno int) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
} else {
_p0 = unsafe.Pointer(&_zero[0])
}
r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
n = int(r0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func read(fd int, buf *byte, nbuf int) (n int, errno int) {
r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
n = int(r0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Stat(path string, stat *Stat_t) (errno int) {
_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(stat)), 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Write(fd int, p []byte) (n int, errno int) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
} else {
_p0 = unsafe.Pointer(&_zero[0])
}
r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
n = int(r0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func MultimediaInit(subsys int) (errno int) {
_, _, e1 := Syscall(SYS_MULTIMEDIA_INIT, uintptr(subsys), 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func MultimediaShutdown() (errno int) {
_, _, e1 := Syscall(SYS_MULTIMEDIA_SHUTDOWN, 0, 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func CondCreate() (cv int, errno int) {
r0, _, e1 := Syscall(SYS_COND_CREATE, 0, 0, 0)
cv = int(r0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func CondWait(cv int, mutex int) (errno int) {
_, _, e1 := Syscall(SYS_COND_WAIT, uintptr(cv), uintptr(mutex), 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func CondSignal(cv int) (errno int) {
_, _, e1 := Syscall(SYS_COND_SIGNAL, uintptr(cv), 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func CondBroadcast(cv int) (errno int) {
_, _, e1 := Syscall(SYS_COND_BROADCAST, uintptr(cv), 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func CondTimedWaitAbs(cv int, mutex int, abstime *Timespec) (errno int) {
_, _, e1 := Syscall(SYS_COND_TIMED_WAIT_ABS, uintptr(cv), uintptr(mutex), uintptr(unsafe.Pointer(abstime)))
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func MutexCreate() (mutex int, errno int) {
r0, _, e1 := Syscall(SYS_MUTEX_CREATE, 0, 0, 0)
mutex = int(r0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func MutexLock(mutex int) (errno int) {
_, _, e1 := Syscall(SYS_MUTEX_LOCK, uintptr(mutex), 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func MutexUnlock(mutex int) (errno int) {
_, _, e1 := Syscall(SYS_MUTEX_UNLOCK, uintptr(mutex), 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func MutexTryLock(mutex int) (errno int) {
_, _, e1 := Syscall(SYS_MUTEX_TRYLOCK, uintptr(mutex), 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func SemCreate() (sema int, errno int) {
r0, _, e1 := Syscall(SYS_SEM_CREATE, 0, 0, 0)
sema = int(r0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func SemWait(sema int) (errno int) {
_, _, e1 := Syscall(SYS_SEM_WAIT, uintptr(sema), 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func SemPost(sema int) (errno int) {
_, _, e1 := Syscall(SYS_SEM_POST, uintptr(sema), 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func VideoInit(dx int, dy int) (errno int) {
_, _, e1 := Syscall(SYS_VIDEO_INIT, uintptr(dx), uintptr(dy), 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func VideoUpdate(data *uint32) (errno int) {
_, _, e1 := Syscall(SYS_VIDEO_UPDATE, uintptr(unsafe.Pointer(data)), 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func VideoPollEvent(ev *byte) (errno int) {
_, _, e1 := Syscall(SYS_VIDEO_POLL_EVENT, uintptr(unsafe.Pointer(ev)), 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func VideoShutdown() (errno int) {
_, _, e1 := Syscall(SYS_VIDEO_SHUTDOWN, 0, 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func AudioInit(fmt int, nreq int, data *int) (errno int) {
_, _, e1 := Syscall(SYS_AUDIO_INIT, uintptr(fmt), uintptr(nreq), uintptr(unsafe.Pointer(data)))
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func AudioShutdown() (errno int) {
_, _, e1 := Syscall(SYS_AUDIO_SHUTDOWN, 0, 0, 0)
errno = int(e1)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func AudioStream(data *uint16, size *uintptr) (errno int) {
_, _, e1 := Syscall(SYS_AUDIO_STREAM, uintptr(unsafe.Pointer(data)), uintptr(unsafe.Pointer(size)), 0)
errno = int(e1)
return
}

View File

@ -1,64 +0,0 @@
// mksysnum_nacl.sh /home/rsc/pub/nacl/native_client/src/trusted/service_runtime/include/bits/nacl_syscalls.h
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
package syscall
const (
SYS_NULL = 1
SYS_OPEN = 10
SYS_CLOSE = 11
SYS_READ = 12
SYS_WRITE = 13
SYS_LSEEK = 14
SYS_IOCTL = 15
SYS_STAT = 16
SYS_FSTAT = 17
SYS_CHMOD = 18
SYS_SYSBRK = 20
SYS_MMAP = 21
SYS_MUNMAP = 22
SYS_GETDENTS = 23
SYS_EXIT = 30
SYS_GETPID = 31
SYS_SCHED_YIELD = 32
SYS_SYSCONF = 33
SYS_GETTIMEOFDAY = 40
SYS_CLOCK = 41
SYS_NANOSLEEP = 42
SYS_MULTIMEDIA_INIT = 50
SYS_MULTIMEDIA_SHUTDOWN = 51
SYS_VIDEO_INIT = 52
SYS_VIDEO_SHUTDOWN = 53
SYS_VIDEO_UPDATE = 54
SYS_VIDEO_POLL_EVENT = 55
SYS_AUDIO_INIT = 56
SYS_AUDIO_SHUTDOWN = 57
SYS_AUDIO_STREAM = 58
SYS_IMC_MAKEBOUNDSOCK = 60
SYS_IMC_ACCEPT = 61
SYS_IMC_CONNECT = 62
SYS_IMC_SENDMSG = 63
SYS_IMC_RECVMSG = 64
SYS_IMC_MEM_OBJ_CREATE = 65
SYS_IMC_SOCKETPAIR = 66
SYS_MUTEX_CREATE = 70
SYS_MUTEX_LOCK = 71
SYS_MUTEX_TRYLOCK = 72
SYS_MUTEX_UNLOCK = 73
SYS_COND_CREATE = 74
SYS_COND_WAIT = 75
SYS_COND_SIGNAL = 76
SYS_COND_BROADCAST = 77
SYS_COND_TIMED_WAIT_ABS = 79
SYS_THREAD_CREATE = 80
SYS_THREAD_EXIT = 81
SYS_TLS_INIT = 82
SYS_THREAD_NICE = 83
SYS_TLS_GET = 84
SYS_SRPC_GET_FD = 90
SYS_SEM_CREATE = 100
SYS_SEM_WAIT = 101
SYS_SEM_POST = 102
SYS_SEM_GET_VALUE = 103
SYS_DYNCODE_COPY = 104
)

View File

@ -1,4 +1,3 @@
// mksysnum_nacl.sh /home/rsc/pub/nacl/native_client/src/trusted/service_runtime/include/bits/nacl_syscalls.h
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
// nothing to see here
package syscall

View File

@ -1,9 +0,0 @@
// godefs -gsyscall -f-m32 -f-I/home/rsc/pub/nacl/native_client/src/third_party/nacl_sdk/linux/sdk/nacl-sdk/nacl/include -f-I/home/rsc/pub/nacl/native_client/src/trusted/service_runtime/include types_nacl.c
// MACHINE GENERATED - DO NOT EDIT.
package syscall
// Constants
// Types

View File

@ -1,105 +0,0 @@
// godefs -gsyscall -f-m32 -f-I/home/rsc/pub/nacl/native_client/src/third_party/nacl_sdk/linux/sdk/nacl-sdk/nacl/include -f-I/home/rsc/pub/nacl/native_client types_nacl.c
// MACHINE GENERATED - DO NOT EDIT.
package syscall
// Constants
const (
sizeofPtr = 0x4
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x4
sizeofLongLong = 0x8
PROT_READ = 0x1
PROT_WRITE = 0x2
MAP_SHARED = 0x1
SYS_FORK = 0
SYS_PTRACE = 0
SYS_CHDIR = 0
SYS_DUP2 = 0
SYS_FCNTL = 0
SYS_EXECVE = 0
O_RDONLY = 0
O_WRONLY = 0x1
O_RDWR = 0x2
O_APPEND = 0x400
O_ASYNC = 0x2000
O_CREAT = 0x40
O_NOCTTY = 0
O_NONBLOCK = 0x800
O_SYNC = 0x1000
O_TRUNC = 0x200
O_EXCL = 0x80
O_CLOEXEC = 0
F_GETFD = 0x1
F_SETFD = 0x2
F_GETFL = 0x3
F_SETFL = 0x4
FD_CLOEXEC = 0
S_IFMT = 0x1f000
S_IFIFO = 0x1000
S_IFCHR = 0x2000
S_IFDIR = 0x4000
S_IFBLK = 0x6000
S_IFREG = 0x8000
S_IFLNK = 0xa000
S_IFSOCK = 0xc000
S_ISUID = 0x800
S_ISGID = 0x400
S_ISVTX = 0x200
S_IRUSR = 0x100
S_IWUSR = 0x80
S_IXUSR = 0x40
)
// Types
type _C_short int16
type _C_int int32
type _C_long int32
type _C_long_long int64
type _C_off_t int32
type Timespec struct {
Sec int32
Nsec int32
}
type Timeval struct {
Sec int32
Usec int32
}
type Time_t int32
type _Gid_t uint32
type Stat_t struct {
Dev int64
Ino uint32
Mode uint32
Nlink uint32
Uid uint32
Gid uint32
X__padding int32
Rdev int64
Size int32
Blksize int32
Blocks int32
Atime int32
Mtime int32
Ctime int32
}
type Dirent struct {
Ino uint32
Off int32
Reclen uint16
Name [256]int8
Pad0 [2]byte
}

View File

@ -20,9 +20,6 @@ GOFILES_darwin=\
GOFILES_linux=\
zoneinfo_unix.go\
GOFILES_nacl=\
zoneinfo_unix.go\
GOFILES_windows=\
zoneinfo_windows.go\

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # NaCl runner does not expose environment
// $G $F.go && $L $F.$A && ./$A.out
// Copyright 2009 The Go Authors. All rights reserved.

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # no network
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2010 The Go Authors. All rights reserved.

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # do not bother on NaCl
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # do not bother on NaCl
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # do not bother on NaCl
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # do not bother on NaCl
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # do not bother on NaCl
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # do not bother on NaCl
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # do not bother on NaCl
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # do not bother on NaCl
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # do not bother on NaCl
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # do not bother on NaCl
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # NaCl runner elides NUL in output
// [ "$GORUN" == "" ] || exit 0 # Android runner gets confused by the NUL output
// $G $D/$F.go && $L $F.$A && ./$A.out >tmp.go &&
// errchk $G -e tmp.go

View File

@ -7,7 +7,6 @@
// Test of recover for run-time errors.
// TODO(rsc):
// integer divide by zero?
// null pointer accesses
package main
@ -15,7 +14,6 @@ package main
import (
"os"
"strings"
"syscall"
)
var x = make([]byte, 10)
@ -83,10 +81,6 @@ func test6() {
}
func test7() {
if syscall.OS == "nacl" {
// NaCl cannot handle traps
return
}
defer mustRecover("divide by zero")
var x, y int
println(x / y)

View File

@ -1,4 +1,3 @@
// [ $GOOS != nacl ] || exit 0 # NaCl cannot recover from signals
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2010 The Go Authors. All rights reserved.

View File

@ -1,4 +1,3 @@
// if [ $GOOS == nacl ]; then echo survived SIGCHLD; exit 0; fi # NaCl has no signals.
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 The Go Authors. All rights reserved.

View File

@ -10,7 +10,6 @@ import (
"fmt"
"math"
"strings"
"syscall"
)
type Error interface {
@ -163,7 +162,7 @@ func alike(a, b float64) bool {
func main() {
bad := false
for _, t := range errorTests {
if t.err != "" && syscall.OS == "nacl" {
if t.err != "" {
continue
}
err := error(t.fn)