mirror of
https://github.com/golang/go
synced 2024-11-19 13:04:45 -07:00
403ab0f221
Move the IndexByte function from the runtime to a new bytealg package. The new package will eventually hold all the optimized assembly for groveling through byte slices and strings. It seems a better home for this code than randomly keeping it in runtime. Once this is in, the next step is to move the other functions (Compare, Equal, ...). Update #19792 This change seems complicated enough that we might just declare "not worth it" and abandon. Opinions welcome. The core assembly is all unchanged, except minor modifications where the code reads cpu feature bits. The wrapper functions have been cleaned up as they are now actually checked by vet. Change-Id: I9fa75bee5d85db3a65b3fd3b7997e60367523796 Reviewed-on: https://go-review.googlesource.com/98016 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
151 lines
3.5 KiB
Go
151 lines
3.5 KiB
Go
// 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 "internal/bytealg"
|
|
|
|
// 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
|
|
}
|
|
|
|
// 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)
|
|
}
|
|
|
|
// 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()
|
|
}
|
|
|
|
// printany prints an argument passed to panic.
|
|
// If panic is called with a value that has a String or Error method,
|
|
// it has already been converted into a string by preprintpanics.
|
|
func printany(i interface{}) {
|
|
switch v := i.(type) {
|
|
case nil:
|
|
print("nil")
|
|
case bool:
|
|
print(v)
|
|
case int:
|
|
print(v)
|
|
case int8:
|
|
print(v)
|
|
case int16:
|
|
print(v)
|
|
case int32:
|
|
print(v)
|
|
case int64:
|
|
print(v)
|
|
case uint:
|
|
print(v)
|
|
case uint8:
|
|
print(v)
|
|
case uint16:
|
|
print(v)
|
|
case uint32:
|
|
print(v)
|
|
case uint64:
|
|
print(v)
|
|
case uintptr:
|
|
print(v)
|
|
case float32:
|
|
print(v)
|
|
case float64:
|
|
print(v)
|
|
case complex64:
|
|
print(v)
|
|
case complex128:
|
|
print(v)
|
|
case string:
|
|
print(v)
|
|
default:
|
|
print("(", typestring(i), ") ", i)
|
|
}
|
|
}
|
|
|
|
// panicwrap generates a panic for a call to a wrapped value method
|
|
// with a nil pointer receiver.
|
|
//
|
|
// It is called from the generated wrapper code.
|
|
func panicwrap() {
|
|
pc := getcallerpc()
|
|
name := funcname(findfunc(pc))
|
|
// name is something like "main.(*T).F".
|
|
// We want to extract pkg ("main"), typ ("T"), and meth ("F").
|
|
// Do it by finding the parens.
|
|
i := bytealg.IndexByteString(name, '(')
|
|
if i < 0 {
|
|
throw("panicwrap: no ( in " + name)
|
|
}
|
|
pkg := name[:i-1]
|
|
if i+2 >= len(name) || name[i-1:i+2] != ".(*" {
|
|
throw("panicwrap: unexpected string after package name: " + name)
|
|
}
|
|
name = name[i+2:]
|
|
i = bytealg.IndexByteString(name, ')')
|
|
if i < 0 {
|
|
throw("panicwrap: no ) in " + name)
|
|
}
|
|
if i+2 >= len(name) || name[i:i+2] != ")." {
|
|
throw("panicwrap: unexpected string after type name: " + name)
|
|
}
|
|
typ := name[:i]
|
|
meth := name[i+2:]
|
|
panic(plainError("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer"))
|
|
}
|