diff options
Diffstat (limited to 'src/pkg/runtime')
| -rw-r--r-- | src/pkg/runtime/complex.c | 2 | ||||
| -rw-r--r-- | src/pkg/runtime/error.go | 27 | ||||
| -rw-r--r-- | src/pkg/runtime/hashmap.c | 4 | ||||
| -rw-r--r-- | src/pkg/runtime/iface.c | 18 | ||||
| -rw-r--r-- | src/pkg/runtime/runtime.c | 45 | ||||
| -rw-r--r-- | src/pkg/runtime/runtime.h | 8 | ||||
| -rw-r--r-- | src/pkg/runtime/slice.c | 19 | ||||
| -rw-r--r-- | src/pkg/runtime/string.cgo | 47 |
8 files changed, 76 insertions, 94 deletions
diff --git a/src/pkg/runtime/complex.c b/src/pkg/runtime/complex.c index 72c65467d..ca6ed79ba 100644 --- a/src/pkg/runtime/complex.c +++ b/src/pkg/runtime/complex.c @@ -20,7 +20,7 @@ void b = -b; if(a <= b) { if(b == 0) - throw("complex divide"); + panicstring("complex divide by zero"); ratio = denreal/denimag; denom = denreal*ratio + denimag; quoreal = (numreal*ratio + numimag) / denom; diff --git a/src/pkg/runtime/error.go b/src/pkg/runtime/error.go index a7d3bedb9..673e77b2c 100644 --- a/src/pkg/runtime/error.go +++ b/src/pkg/runtime/error.go @@ -7,7 +7,12 @@ package runtime // The Error interface identifies a run time error. type Error interface { String() string - RuntimeError() // no-op that uniquely identifies runtime.Error + + // RuntimeError is a no-op function but + // serves to distinguish types that are runtime + // errors from ordinary os.Errors: a type is a + // runtime error if it has a RuntimeError method. + RuntimeError() } // A TypeAssertionError explains a failed type assertion. @@ -21,6 +26,8 @@ type TypeAssertionError struct { missingMethod string // one method needed by Interface, missing from Concrete } +func (*TypeAssertionError) RuntimeError() {} + func (e *TypeAssertionError) String() string { inter := e.interfaceString if inter == "" { @@ -57,8 +64,6 @@ func (e *TypeAssertionError) MissingMethod() string { return e.missingMethod } -func (*TypeAssertionError) RuntimeError() {} - // For calling from C. func newTypeAssertionError(pt1, pt2, pt3 *Type, ps1, ps2, ps3 *string, pmeth *string, ret *interface{}) { var t1, t2, t3 Type @@ -88,12 +93,26 @@ func newTypeAssertionError(pt1, pt2, pt3 *Type, ps1, ps2, ps3 *string, pmeth *st *ret = &TypeAssertionError{t1, t2, t3, s1, s2, s3, meth} } +// An errorString represents a runtime error described by a single string. +type errorString string + +func (e errorString) RuntimeError() {} + +func (e errorString) String() string { + return "runtime error: " + string(e) +} + +// For calling from C. +func newErrorString(s string, ret *interface{}) { + *ret = errorString(s) +} + type stringer interface { String() string } // For calling from C. -// Prints an argument to panic. +// Prints an argument passed to panic. // There's room for arbitrary complexity here, but we keep it // simple and handle just a few important cases: int, string, and Stringer. func printany(i interface{}) { diff --git a/src/pkg/runtime/hashmap.c b/src/pkg/runtime/hashmap.c index ccb5cfdb5..f27264b68 100644 --- a/src/pkg/runtime/hashmap.c +++ b/src/pkg/runtime/hashmap.c @@ -770,10 +770,6 @@ void mapaccess(h, ak, av, &pres); -// new spec -- all elements have "zero" value -// if(!pres) -// throw("runtime.mapaccess1: key not in map"); - if(debug) { prints("runtime.mapaccess1: map="); ·printpointer(h); diff --git a/src/pkg/runtime/iface.c b/src/pkg/runtime/iface.c index 1af7ca7f5..28e3edeee 100644 --- a/src/pkg/runtime/iface.c +++ b/src/pkg/runtime/iface.c @@ -457,6 +457,7 @@ static uintptr ifacehash1(void *data, Type *t) { int32 alg, wid; + Eface err; if(t == nil) return 0; @@ -464,12 +465,10 @@ ifacehash1(void *data, Type *t) alg = t->alg; wid = t->size; if(algarray[alg].hash == nohash) { - // calling nohash will throw too, + // calling nohash will panic too, // but we can print a better error. - printf("hash of unhashable type %S\n", *t->string); - if(alg == AFAKE) - throw("fake interface hash"); - throw("interface hash"); + ·newErrorString(catstring(gostring((byte*)"hash of unhashable type "), *t->string), &err); + ·panic(err); } if(wid <= sizeof(data)) return algarray[alg].hash(wid, &data); @@ -494,17 +493,16 @@ static bool ifaceeq1(void *data1, void *data2, Type *t) { int32 alg, wid; + Eface err; alg = t->alg; wid = t->size; if(algarray[alg].equal == noequal) { - // calling noequal will throw too, + // calling noequal will panic too, // but we can print a better error. - printf("comparing uncomparable type %S\n", *t->string); - if(alg == AFAKE) - throw("fake interface compare"); - throw("interface compare"); + ·newErrorString(catstring(gostring((byte*)"comparing uncomparable type "), *t->string), &err); + ·panic(err); } if(wid <= sizeof(data1)) diff --git a/src/pkg/runtime/runtime.c b/src/pkg/runtime/runtime.c index 02509deb6..27c59218c 100644 --- a/src/pkg/runtime/runtime.c +++ b/src/pkg/runtime/runtime.c @@ -42,27 +42,29 @@ panic(int32 unused) } void -·throwindex(void) +·panicindex(void) { - throw("index out of range"); + panicstring("index out of range"); } void -·throwslice(void) +·panicslice(void) { - throw("slice out of range"); + panicstring("slice bounds out of range"); } void ·throwreturn(void) { - throw("no return at end of a typed function"); + // can only happen if compiler is broken + throw("no return at end of a typed function - compiler is broken"); } void ·throwinit(void) { - throw("recursive call during initialization"); + // can only happen with linker skew + throw("recursive call during initialization - linker skew"); } void @@ -76,6 +78,15 @@ throw(int8 *s) } void +panicstring(int8 *s) +{ + Eface err; + + ·newErrorString(gostring((byte*)s), &err); + ·panic(err); +} + +void mcpy(byte *t, byte *f, uint32 n) { while(n > 0) { @@ -421,7 +432,7 @@ nohash(uint32 s, void *a) { USED(s); USED(a); - throw("hash of unhashable type"); + panicstring("hash of unhashable type"); return 0; } @@ -431,27 +442,10 @@ noequal(uint32 s, void *a, void *b) USED(s); USED(a); USED(b); - throw("comparing uncomparable types"); + panicstring("comparing uncomparable types"); return 0; } -static void -noprint(uint32 s, void *a) -{ - USED(s); - USED(a); - throw("print of unprintable type"); -} - -static void -nocopy(uint32 s, void *a, void *b) -{ - USED(s); - USED(a); - USED(b); - throw("copy of uncopyable type"); -} - Alg algarray[] = { @@ -460,7 +454,6 @@ algarray[] = [ASTRING] { strhash, strequal, strprint, memcopy }, [AINTER] { interhash, interequal, interprint, memcopy }, [ANILINTER] { nilinterhash, nilinterequal, nilinterprint, memcopy }, -[AFAKE] { nohash, noequal, noprint, nocopy }, }; #pragma textflag 7 diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index b4011b758..415dddb86 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -300,7 +300,6 @@ enum ASTRING, AINTER, ANILINTER, - AFAKE, Amax }; @@ -369,6 +368,7 @@ void goargs(void); void FLUSH(void*); void* getu(void); void throw(int8*); +void panicstring(int8*); uint32 rnd(uint32, uint32); void prints(int8*); void printf(int8*, ...); @@ -379,6 +379,7 @@ void memmove(void*, void*, uint32); void* mal(uintptr); void* malx(uintptr size, int32 skip_delta); uint32 cmpstring(String, String); +String catstring(String, String); String gostring(byte*); String gostringw(uint16*); void initsig(void); @@ -416,6 +417,7 @@ void free(void *v); void addfinalizer(void*, void(*fn)(void*), int32); void walkfintab(void (*fn)(void*)); void runpanic(Panic*); +void* getcallersp(void*); void exit(int32); void breakpoint(void); @@ -531,13 +533,15 @@ void runtime_printslice(Slice); void runtime_printcomplex(Complex128); void reflect·call(byte*, byte*, uint32); void ·panic(Eface); - +void ·panicindex(void); +void ·panicslice(void); /* * runtime c-called (but written in Go) */ void ·newError(String, Eface*); void ·printany(Eface); void ·newTypeAssertionError(Type*, Type*, Type*, String*, String*, String*, String*, Eface*); +void ·newErrorString(String, Eface*); /* * wrapped for go users diff --git a/src/pkg/runtime/slice.c b/src/pkg/runtime/slice.c index 03572e822..ca2585c79 100644 --- a/src/pkg/runtime/slice.c +++ b/src/pkg/runtime/slice.c @@ -36,19 +36,6 @@ void } } -static void -throwslice(uint32 lb, uint32 hb, uint32 n) -{ - prints("slice["); - ·printint(lb); - prints(":"); - ·printint(hb); - prints("] of ["); - ·printint(n); - prints("] array\n"); - throw("array slice"); -} - // sliceslice(old []any, lb int, hb int, width int) (ary []any); void ·sliceslice(Slice old, uint32 lb, uint32 hb, uint32 width, Slice ret) @@ -71,7 +58,7 @@ void ·printint(old.cap); prints("\n"); } - throwslice(lb, hb, old.cap); + ·panicslice(); } // new array is inside old array @@ -116,7 +103,7 @@ void ·printint(old.cap); prints("\n"); } - throwslice(lb, old.len, old.cap); + ·panicslice(); } // new array is inside old array @@ -165,7 +152,7 @@ void ·printint(width); prints("\n"); } - throwslice(lb, hb, nel); + ·panicslice(); } // new array is inside old array diff --git a/src/pkg/runtime/string.cgo b/src/pkg/runtime/string.cgo index 4a96b83ec..005b0ffc8 100644 --- a/src/pkg/runtime/string.cgo +++ b/src/pkg/runtime/string.cgo @@ -78,34 +78,25 @@ gostringw(uint16 *str) return s; } -func catstring(s1 String, s2 String) (s3 String) { - if(s1.len == 0) { - s3 = s2; - goto out; - } - if(s2.len == 0) { - s3 = s1; - goto out; - } +String +catstring(String s1, String s2) +{ + String s3; + + if(s1.len == 0) + return s2; + if(s2.len == 0) + return s1; s3 = gostringsize(s1.len + s2.len); mcpy(s3.str, s1.str, s1.len); mcpy(s3.str+s1.len, s2.str, s2.len); -out: + return s3; } -static void -prbounds(int8* s, int32 a, int32 b, int32 c) -{ - prints(s); - prints(" "); - ·printint(a); - prints("<"); - ·printint(b); - prints(">"); - ·printint(c); - prints("\n"); - throw("string bounds"); + +func catstring(s1 String, s2 String) (s3 String) { + s3 = catstring(s1, s2); } uint32 @@ -159,9 +150,7 @@ func slicestring(si String, lindex int32, hindex int32) (so String) { if(lindex < 0 || lindex > si.len || hindex < lindex || hindex > si.len) { - ·printpc(&si); - prints(" "); - prbounds("slice", lindex, si.len, hindex); + ·panicslice(); } l = hindex-lindex; @@ -177,9 +166,7 @@ func slicestring1(si String, lindex int32) (so String) { int32 l; if(lindex < 0 || lindex > si.len) { - ·printpc(&si); - prints(" "); - prbounds("slice", lindex, si.len, si.len); + ·panicslice(); } l = si.len-lindex; @@ -193,9 +180,7 @@ func slicestring1(si String, lindex int32) (so String) { func indexstring(s String, i int32) (b byte) { if(i < 0 || i >= s.len) { - ·printpc(&s); - prints(" "); - prbounds("index", 0, i, s.len); + ·panicindex(); } b = s.str[i]; |
