|  | // 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 | 
|  |  | 
|  | import "unsafe" | 
|  |  | 
|  | // The Error interface identifies a run time error. | 
|  | type Error interface { | 
|  | error | 
|  |  | 
|  | // RuntimeError is a no-op function but | 
|  | // serves to distinguish types that are run time | 
|  | // errors from ordinary errors: a type is a | 
|  | // run time error if it has a RuntimeError method. | 
|  | RuntimeError() | 
|  | } | 
|  |  | 
|  | // 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 | 
|  | } | 
|  |  | 
|  | func (*TypeAssertionError) RuntimeError() {} | 
|  |  | 
|  | func (e *TypeAssertionError) Error() string { | 
|  | inter := e.interfaceString | 
|  | if inter == "" { | 
|  | inter = "interface" | 
|  | } | 
|  | if e.concreteString == "" { | 
|  | 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. | 
|  | func NewTypeAssertionError(ps1, ps2, ps3 *string, pmeth *string, ret *interface{}) { | 
|  | 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 | 
|  | } | 
|  |  | 
|  | // For gccgo, strip out quoted strings. | 
|  | s1 = unquote(s1) | 
|  | s2 = unquote(s2) | 
|  | s3 = unquote(s3) | 
|  |  | 
|  | *ret = &TypeAssertionError{s1, s2, s3, meth} | 
|  | } | 
|  |  | 
|  | // Remove quoted strings from gccgo reflection strings. | 
|  | func unquote(s string) string { | 
|  | ls := len(s) | 
|  | var i int | 
|  | for i = 0; i < ls; i++ { | 
|  | if s[i] == '\t' { | 
|  | break | 
|  | } | 
|  | } | 
|  | if i == ls { | 
|  | return s | 
|  | } | 
|  | var q bool | 
|  | r := make([]byte, len(s)) | 
|  | j := 0 | 
|  | for i = 0; i < ls; i++ { | 
|  | if s[i] == '\t' { | 
|  | q = !q | 
|  | } else if !q { | 
|  | r[j] = s[i] | 
|  | j++ | 
|  | } | 
|  | } | 
|  | return string(r[:j]) | 
|  | } | 
|  |  | 
|  | // An errorString represents a runtime error described by a single string. | 
|  | type errorString string | 
|  |  | 
|  | func (e errorString) RuntimeError() {} | 
|  |  | 
|  | func (e errorString) Error() string { | 
|  | return "runtime error: " + string(e) | 
|  | } | 
|  |  | 
|  | // An errorCString represents a runtime error described by a single C string. | 
|  | // Not "type errorCString uintptr" because of http://golang.org/issue/7084. | 
|  | type errorCString struct{ cstr uintptr } | 
|  |  | 
|  | func (e errorCString) RuntimeError() {} | 
|  |  | 
|  | func (e errorCString) Error() string { | 
|  | return "runtime error: " + gostringnocopy((*byte)(unsafe.Pointer(e.cstr))) | 
|  | } | 
|  |  | 
|  | // For calling from C. | 
|  | func NewErrorCString(s uintptr, ret *interface{}) { | 
|  | *ret = errorCString{s} | 
|  | } | 
|  |  | 
|  | // plainError represents a runtime error described a string without | 
|  | // the prefix "runtime error: " after invoking errorString.Error(). | 
|  | // See Issue #14965. | 
|  | type plainError string | 
|  |  | 
|  | func (e plainError) RuntimeError() {} | 
|  |  | 
|  | func (e plainError) Error() string { | 
|  | return string(e) | 
|  | } | 
|  |  | 
|  | type stringer interface { | 
|  | String() string | 
|  | } | 
|  |  | 
|  | func typestring(x interface{}) string { | 
|  | e := efaceOf(&x) | 
|  | return *e._type.string | 
|  | } | 
|  |  | 
|  | // For calling from C. | 
|  | // 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{}) { | 
|  | switch v := i.(type) { | 
|  | case nil: | 
|  | print("nil") | 
|  | case stringer: | 
|  | print(v.String()) | 
|  | case error: | 
|  | print(v.Error()) | 
|  | case int: | 
|  | print(v) | 
|  | case string: | 
|  | print(v) | 
|  | default: | 
|  | print("(", typestring(i), ") ", i) | 
|  | } | 
|  | } | 
|  |  | 
|  | // called from generated code | 
|  | func panicwrap(pkg, typ, meth string) { | 
|  | panic(plainError("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer")) | 
|  | } |