diff options
| author | Russ Cox <rsc@golang.org> | 2010-03-30 10:53:16 -0700 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2010-03-30 10:53:16 -0700 |
| commit | 01eaf780a8d09ce0b41526fa2701cfbba80f2b8b (patch) | |
| tree | 8b22d716f9984a7f88845cd2c746c175c911fbcf /src/pkg | |
| parent | c7122a3c5888df468a96edd0cb071801030794e6 (diff) | |
| download | go-01eaf780a8d09ce0b41526fa2701cfbba80f2b8b.tar.xz | |
gc: add panic and recover (still unimplemented in runtime)
main semantic change is to enforce single argument to panic.
runtime: change to 1-argument panic.
use String method on argument if it has one.
R=ken2, r
CC=golang-dev
https://golang.org/cl/812043
Diffstat (limited to 'src/pkg')
| -rw-r--r-- | src/pkg/runtime/386/asm.s | 27 | ||||
| -rw-r--r-- | src/pkg/runtime/amd64/asm.s | 25 | ||||
| -rw-r--r-- | src/pkg/runtime/arm/asm.s | 15 | ||||
| -rw-r--r-- | src/pkg/runtime/print.c | 68 | ||||
| -rw-r--r-- | src/pkg/runtime/runtime.c | 19 | ||||
| -rw-r--r-- | src/pkg/runtime/runtime.h | 4 |
6 files changed, 138 insertions, 20 deletions
diff --git a/src/pkg/runtime/386/asm.s b/src/pkg/runtime/386/asm.s index c6c8b4a85b..e2eca81a88 100644 --- a/src/pkg/runtime/386/asm.s +++ b/src/pkg/runtime/386/asm.s @@ -360,15 +360,28 @@ TEXT runcgo(SB),7,$16 // check that SP is in range [g->stackbase, g->stackguard) TEXT stackcheck(SB), 7, $0 get_tls(CX) - MOVL g(CX), AX - CMPL g_stackbase(AX), SP - JHI 2(PC) - INT $3 - CMPL SP, g_stackguard(AX) - JHI 2(PC) - INT $3 + MOVL g(CX), AX + CMPL g_stackbase(AX), SP + JHI 2(PC) + INT $3 + CMPL SP, g_stackguard(AX) + JHI 2(PC) + INT $3 RET +// callString(f, arg, out) +// call Go f(arg), which returns a string, and store in out +TEXT callString(SB), 7, $24 + MOVL arg+4(FP), BX + MOVL f+0(FP), CX + MOVL BX, 0(SP) + CALL *CX + MOVL out+8(FP), DI + LEAL 4(SP), SI + MOVSL + MOVSL + MOVSL + RET GLOBL m0(SB), $1024 GLOBL g0(SB), $1024 diff --git a/src/pkg/runtime/amd64/asm.s b/src/pkg/runtime/amd64/asm.s index c8466318c1..fb32be05f9 100644 --- a/src/pkg/runtime/amd64/asm.s +++ b/src/pkg/runtime/amd64/asm.s @@ -303,11 +303,24 @@ TEXT runcgo(SB),7,$32 // check that SP is in range [g->stackbase, g->stackguard) TEXT stackcheck(SB), 7, $0 - CMPQ g_stackbase(g), SP - JHI 2(PC) - INT $3 - CMPQ SP, g_stackguard(g) - JHI 2(PC) - INT $3 + CMPQ g_stackbase(g), SP + JHI 2(PC) + INT $3 + CMPQ SP, g_stackguard(g) + JHI 2(PC) + INT $3 + RET + +// callString(f, arg, out) +// call Go f(arg), which returns a string, and store in out +TEXT callString(SB), 7, $24 + MOVQ arg+8(FP), BX + MOVQ f+0(FP), CX + MOVQ BX, 0(SP) + CALL *CX + MOVQ out+16(FP), DI + LEAQ 8(SP), SI + MOVSQ + MOVSQ RET diff --git a/src/pkg/runtime/arm/asm.s b/src/pkg/runtime/arm/asm.s index 19fa1cc2e3..6be266734d 100644 --- a/src/pkg/runtime/arm/asm.s +++ b/src/pkg/runtime/arm/asm.s @@ -264,3 +264,18 @@ TEXT abort(SB),7,$0 MOVW $0, R0 MOVW (R0), R1 +// callString(f, arg, out) +// call Go f(arg), which returns a string, and store in out +TEXT callString(SB), 7, $24 + MOVW arg+4(FP), R1 + MOVW f+0(FP), R0 + MOVW R1, 0(SP) + BL R0 + MOVW 4(SP), R1 + MOVW 8(SP), R2 + MOVW 12(SP), R3 + MOVW out+8(FP), R0 + MOVW R1, 0(R0) + MOVW R2, 4(R0) + MOVW R3, 8(R0) + RET diff --git a/src/pkg/runtime/print.c b/src/pkg/runtime/print.c index 26b3de785c..5e4f2f5956 100644 --- a/src/pkg/runtime/print.c +++ b/src/pkg/runtime/print.c @@ -3,6 +3,7 @@ // license that can be found in the LICENSE file. #include "runtime.h" +#include "type.h" //static Lock debuglock; @@ -150,7 +151,7 @@ vprintf(int8 *s, byte *arg) ·printhex(*(uint64*)arg); break; case '!': - ·panicl(-1); + panic(-1); } arg = narg; lp = p+1; @@ -347,3 +348,68 @@ void { write(fd, "\n", 1); } + +// print an empty interface, for use by panic. +// this could be arbitrarily complex in general, +// so we pick off only a few important cases: +// int, string, and values with a String() string method. +void +printany(Eface e) +{ + int32 i; + FuncType *ft; + Method *m; + String s; + Type *rt; + UncommonType *x; + + if(e.type == nil) { + write(fd, "nil", 3); + return; + } + + if((x=e.type->x) != nil) { + for(i=0; i<x->mhdr.len; i++) { + // Look for String() string method. + m = &x->m[i]; + if(m->name->len == 6 && + mcmp(m->name->str, (byte*)"String", 6) == 0 && + // Found String; check method signature for func() string. + m->mtyp->kind == KindFunc && + (ft = (FuncType*)m->mtyp)->in.len == 0 && + ft->out.len == 1 && + // Found single output. Is it string? + // Only base types have name != nil but pkgPath == nil. + (rt = *(Type**)ft->out.array)->kind == KindString && + rt->x != nil && + rt->x->name != nil && rt->x->pkgPath == nil) { + // Found the method! + // Have to use assembly to call it + // and save the return value. + callString(m->ifn, e.data, &s); + ·printstring(s); + return; + } + } + } + + switch(e.type->kind & ~KindNoPointers) { + case KindInt: + mcpy((byte*)&i, (byte*)&e.data, sizeof(i)); + ·printint(i); + break; + + case KindString: + ·printstring(*(String*)e.data); + break; + + default: + // Could print the other numeric types, + // but that's overkill: good panics have + // a string method anyway. + ·printstring(*e.type->string); + write(fd, "(???)", 5); + break; + } + +} diff --git a/src/pkg/runtime/runtime.c b/src/pkg/runtime/runtime.c index aa6d82506e..c6655d9ec0 100644 --- a/src/pkg/runtime/runtime.c +++ b/src/pkg/runtime/runtime.c @@ -20,7 +20,7 @@ gotraceback(void) } void -·panicl(int32 lno) +panic(int32 unused) { uint8 *sp; @@ -31,10 +31,10 @@ void } panicking++; - printf("\npanic PC=%X\n", (uint64)(uintptr)&lno); - sp = (uint8*)&lno; + printf("\npanic PC=%X\n", (uint64)(uintptr)&unused); + sp = (uint8*)&unused; if(gotraceback()){ - traceback(·getcallerpc(&lno), sp, g); + traceback(·getcallerpc(&unused), sp, g); tracebackothers(g); } breakpoint(); // so we can grab it in a debugger @@ -42,6 +42,15 @@ void } void +·panic(Eface e) +{ + fd = 2; + printf("panic: "); + printany(e); + panic(0); +} + +void ·throwindex(void) { throw("index out of range"); @@ -70,7 +79,7 @@ throw(int8 *s) { fd = 2; printf("throw: %s\n", s); - ·panicl(-1); + panic(-1); *(int32*)0 = 0; // not reached exit(1); // even more not reached } diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index 2671a05924..a0c0dd7a18 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -344,6 +344,7 @@ int32 charntorune(int32*, uint8*, int32); /* * very low level c-called */ +void callString(void(*fn)(void), void *arg, String *out); void gogo(Gobuf*, uintptr); void gogocall(Gobuf*, void(*)(void)); uintptr gosave(Gobuf*); @@ -354,6 +355,7 @@ void* getu(void); void throw(int8*); uint32 rnd(uint32, uint32); void prints(int8*); +void printany(Eface); void printf(int8*, ...); byte* mchr(byte*, byte, byte*); void mcpy(byte*, byte*, uint32); @@ -510,7 +512,7 @@ void runtime_printuint(uint64); void runtime_printhex(uint64); void runtime_printslice(Slice); void runtime_printcomplex(Complex128); -void ·panicl(int32); +void panic(int32); void reflect·call(byte*, byte*, uint32); /* |
