2010-03-31 15:55:10 -07:00
|
|
|
// 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.
|
|
|
|
|
|
|
|
|
|
package runtime
|
|
|
|
|
|
|
|
|
|
// The Error interface identifies a run time error.
|
|
|
|
|
type Error interface {
|
2011-11-01 21:48:27 -04:00
|
|
|
error
|
2010-04-01 22:31:27 -07:00
|
|
|
|
|
|
|
|
// RuntimeError is a no-op function but
|
|
|
|
|
// serves to distinguish types that are runtime
|
2011-11-01 22:58:09 -04:00
|
|
|
// errors from ordinary errors: a type is a
|
2010-04-01 22:31:27 -07:00
|
|
|
// runtime error if it has a RuntimeError method.
|
|
|
|
|
RuntimeError()
|
2010-03-31 15:55:10 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A TypeAssertionError explains a failed type assertion.
|
|
|
|
|
type TypeAssertionError struct {
|
|
|
|
|
interfaceString string
|
|
|
|
|
concreteString string
|
|
|
|
|
assertedString string
|
|
|
|
|
missingMethod string // one method needed by Interface, missing from Concrete
|
|
|
|
|
}
|
|
|
|
|
|
2010-04-01 22:31:27 -07:00
|
|
|
func (*TypeAssertionError) RuntimeError() {}
|
|
|
|
|
|
2011-11-01 21:48:27 -04:00
|
|
|
func (e *TypeAssertionError) Error() string {
|
2010-03-31 15:55:10 -07:00
|
|
|
inter := e.interfaceString
|
|
|
|
|
if inter == "" {
|
|
|
|
|
inter = "interface"
|
|
|
|
|
}
|
2012-02-12 23:26:20 -05:00
|
|
|
if e.concreteString == "" {
|
2010-03-31 15:55:10 -07:00
|
|
|
return "interface conversion: " + inter + " is nil, not " + e.assertedString
|
|
|
|
|
}
|
|
|
|
|
if e.missingMethod == "" {
|
|
|
|
|
return "interface conversion: " + inter + " is " + e.concreteString +
|
|
|
|
|
", not " + e.assertedString
|
|
|
|
|
}
|
|
|
|
|
return "interface conversion: " + e.concreteString + " is not " + e.assertedString +
|
|
|
|
|
": missing method " + e.missingMethod
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For calling from C.
|
2012-02-12 23:26:20 -05:00
|
|
|
func newTypeAssertionError(ps1, ps2, ps3 *string, pmeth *string, ret *interface{}) {
|
2010-03-31 15:55:10 -07:00
|
|
|
var s1, s2, s3, meth string
|
|
|
|
|
|
|
|
|
|
if ps1 != nil {
|
|
|
|
|
s1 = *ps1
|
|
|
|
|
}
|
|
|
|
|
if ps2 != nil {
|
|
|
|
|
s2 = *ps2
|
|
|
|
|
}
|
|
|
|
|
if ps3 != nil {
|
|
|
|
|
s3 = *ps3
|
|
|
|
|
}
|
|
|
|
|
if pmeth != nil {
|
|
|
|
|
meth = *pmeth
|
|
|
|
|
}
|
2012-02-12 23:26:20 -05:00
|
|
|
*ret = &TypeAssertionError{s1, s2, s3, meth}
|
2010-03-31 15:55:10 -07:00
|
|
|
}
|
|
|
|
|
|
2010-04-01 22:31:27 -07:00
|
|
|
// An errorString represents a runtime error described by a single string.
|
|
|
|
|
type errorString string
|
|
|
|
|
|
|
|
|
|
func (e errorString) RuntimeError() {}
|
|
|
|
|
|
2011-11-01 21:48:27 -04:00
|
|
|
func (e errorString) Error() string {
|
2010-04-01 22:31:27 -07:00
|
|
|
return "runtime error: " + string(e)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For calling from C.
|
|
|
|
|
func newErrorString(s string, ret *interface{}) {
|
|
|
|
|
*ret = errorString(s)
|
|
|
|
|
}
|
|
|
|
|
|
runtime: avoid allocation of internal panic values
If a fault happens in malloc, inevitably the next thing that happens
is a deadlock trying to allocate the panic value that says the fault
happened. Stop doing that, two ways.
First, reject panic in malloc just as we reject panic in garbage collection.
Second, runtime.panicstring was using an error implementation
backed by a Go string, so the interface held an allocated *string.
Since the actual errors are C strings, define a new error
implementation backed by a C char*, which needs no indirection
and therefore no allocation.
This second fix will avoid allocation for errors like nil panic derefs
or division by zero, so it is worth doing even though the first fix
should take care of faults during malloc.
Update #6419
R=golang-dev, dvyukov, dave
CC=golang-dev
https://golang.org/cl/13774043
2013-09-20 15:15:25 -04:00
|
|
|
// An errorCString represents a runtime error described by a single C string.
|
2014-01-08 21:40:33 -08:00
|
|
|
// Not "type errorCString uintptr" because of http://golang.org/issue/7084.
|
|
|
|
|
type errorCString struct{ cstr uintptr }
|
runtime: avoid allocation of internal panic values
If a fault happens in malloc, inevitably the next thing that happens
is a deadlock trying to allocate the panic value that says the fault
happened. Stop doing that, two ways.
First, reject panic in malloc just as we reject panic in garbage collection.
Second, runtime.panicstring was using an error implementation
backed by a Go string, so the interface held an allocated *string.
Since the actual errors are C strings, define a new error
implementation backed by a C char*, which needs no indirection
and therefore no allocation.
This second fix will avoid allocation for errors like nil panic derefs
or division by zero, so it is worth doing even though the first fix
should take care of faults during malloc.
Update #6419
R=golang-dev, dvyukov, dave
CC=golang-dev
https://golang.org/cl/13774043
2013-09-20 15:15:25 -04:00
|
|
|
|
|
|
|
|
func (e errorCString) RuntimeError() {}
|
|
|
|
|
|
|
|
|
|
func (e errorCString) Error() string {
|
2014-01-08 21:40:33 -08:00
|
|
|
return "runtime error: " + cstringToGo(e.cstr)
|
runtime: avoid allocation of internal panic values
If a fault happens in malloc, inevitably the next thing that happens
is a deadlock trying to allocate the panic value that says the fault
happened. Stop doing that, two ways.
First, reject panic in malloc just as we reject panic in garbage collection.
Second, runtime.panicstring was using an error implementation
backed by a Go string, so the interface held an allocated *string.
Since the actual errors are C strings, define a new error
implementation backed by a C char*, which needs no indirection
and therefore no allocation.
This second fix will avoid allocation for errors like nil panic derefs
or division by zero, so it is worth doing even though the first fix
should take care of faults during malloc.
Update #6419
R=golang-dev, dvyukov, dave
CC=golang-dev
https://golang.org/cl/13774043
2013-09-20 15:15:25 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For calling from C.
|
|
|
|
|
func newErrorCString(s uintptr, ret *interface{}) {
|
2014-01-08 21:40:33 -08:00
|
|
|
*ret = errorCString{s}
|
runtime: avoid allocation of internal panic values
If a fault happens in malloc, inevitably the next thing that happens
is a deadlock trying to allocate the panic value that says the fault
happened. Stop doing that, two ways.
First, reject panic in malloc just as we reject panic in garbage collection.
Second, runtime.panicstring was using an error implementation
backed by a Go string, so the interface held an allocated *string.
Since the actual errors are C strings, define a new error
implementation backed by a C char*, which needs no indirection
and therefore no allocation.
This second fix will avoid allocation for errors like nil panic derefs
or division by zero, so it is worth doing even though the first fix
should take care of faults during malloc.
Update #6419
R=golang-dev, dvyukov, dave
CC=golang-dev
https://golang.org/cl/13774043
2013-09-20 15:15:25 -04:00
|
|
|
}
|
|
|
|
|
|
2010-03-31 15:55:10 -07:00
|
|
|
type stringer interface {
|
|
|
|
|
String() string
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-22 17:04:32 -04:00
|
|
|
func typestring(interface{}) string
|
|
|
|
|
|
2010-03-31 15:55:10 -07:00
|
|
|
// For calling from C.
|
2010-04-01 22:31:27 -07:00
|
|
|
// Prints an argument passed to panic.
|
2010-03-31 15:55:10 -07:00
|
|
|
// 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{}) {
|
|
|
|
|
switch v := i.(type) {
|
|
|
|
|
case nil:
|
|
|
|
|
print("nil")
|
|
|
|
|
case stringer:
|
|
|
|
|
print(v.String())
|
2011-11-01 21:48:27 -04:00
|
|
|
case error:
|
|
|
|
|
print(v.Error())
|
2010-03-31 15:55:10 -07:00
|
|
|
case int:
|
|
|
|
|
print(v)
|
|
|
|
|
case string:
|
|
|
|
|
print(v)
|
|
|
|
|
default:
|
2010-10-22 17:04:32 -04:00
|
|
|
print("(", typestring(i), ") ", i)
|
2010-03-31 15:55:10 -07:00
|
|
|
}
|
|
|
|
|
}
|
2011-06-17 15:23:27 -04:00
|
|
|
|
|
|
|
|
// called from generated code
|
|
|
|
|
func panicwrap(pkg, typ, meth string) {
|
|
|
|
|
panic("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer")
|
|
|
|
|
}
|