// 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")) }