runtime: delete Type and implementations (use reflect instead)
unsafe: delete Typeof, Reflect, Unreflect, New, NewArray
Part of issue 2955 and issue 2968.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5650069
diff --git a/src/pkg/runtime/error.go b/src/pkg/runtime/error.go
index 4b0ee49..b6b520c 100644
--- a/src/pkg/runtime/error.go
+++ b/src/pkg/runtime/error.go
@@ -17,9 +17,6 @@
// A TypeAssertionError explains a failed type assertion.
type TypeAssertionError struct {
- interfaceType Type // interface had this type
- concreteType Type // concrete value had this type
- assertedType Type // asserted type
interfaceString string
concreteString string
assertedString string
@@ -33,7 +30,7 @@
if inter == "" {
inter = "interface"
}
- if e.concreteType == nil {
+ if e.concreteString == "" {
return "interface conversion: " + inter + " is nil, not " + e.assertedString
}
if e.missingMethod == "" {
@@ -44,40 +41,10 @@
": missing method " + e.missingMethod
}
-// Concrete returns the type of the concrete value in the failed type assertion.
-// If the interface value was nil, Concrete returns nil.
-func (e *TypeAssertionError) Concrete() Type {
- return e.concreteType
-}
-
-// Asserted returns the type incorrectly asserted by the type assertion.
-func (e *TypeAssertionError) Asserted() Type {
- return e.assertedType
-}
-
-// If the type assertion is to an interface type, MissingMethod returns the
-// name of a method needed to satisfy that interface type but not implemented
-// by Concrete. If there are multiple such methods,
-// MissingMethod returns one; which one is unspecified.
-// If the type assertion is not to an interface type, MissingMethod returns an empty string.
-func (e *TypeAssertionError) MissingMethod() string {
- return e.missingMethod
-}
-
// For calling from C.
-func newTypeAssertionError(pt1, pt2, pt3 *Type, ps1, ps2, ps3 *string, pmeth *string, ret *interface{}) {
- var t1, t2, t3 Type
+func newTypeAssertionError(ps1, ps2, ps3 *string, pmeth *string, ret *interface{}) {
var s1, s2, s3, meth string
- if pt1 != nil {
- t1 = *pt1
- }
- if pt2 != nil {
- t2 = *pt2
- }
- if pt3 != nil {
- t3 = *pt3
- }
if ps1 != nil {
s1 = *ps1
}
@@ -90,7 +57,7 @@
if pmeth != nil {
meth = *pmeth
}
- *ret = &TypeAssertionError{t1, t2, t3, s1, s2, s3, meth}
+ *ret = &TypeAssertionError{s1, s2, s3, meth}
}
// An errorString represents a runtime error described by a single string.
diff --git a/src/pkg/runtime/iface.c b/src/pkg/runtime/iface.c
index 9f70935..2b60c4f 100644
--- a/src/pkg/runtime/iface.c
+++ b/src/pkg/runtime/iface.c
@@ -7,14 +7,6 @@
#include "type.h"
#include "malloc.h"
-enum
-{
- // If an empty interface has these bits set in its type
- // pointer, it was copied from a reflect.Value and is
- // not a valid empty interface.
- reflectFlags = 3,
-};
-
void
runtime·printiface(Iface i)
{
@@ -127,7 +119,7 @@
if(!canfail) {
throw:
// didn't find method
- runtime·newTypeAssertionError(nil, type, inter,
+ runtime·newTypeAssertionError(
nil, type->string, inter->string,
iname, &err);
if(locked)
@@ -243,13 +235,13 @@
tab = i.tab;
if(tab == nil) {
- runtime·newTypeAssertionError(nil, nil, t,
+ runtime·newTypeAssertionError(
nil, nil, t->string,
nil, &err);
runtime·panic(err);
}
if(tab->type != t) {
- runtime·newTypeAssertionError(tab->inter, tab->type, t,
+ runtime·newTypeAssertionError(
tab->inter->string, tab->type->string, t->string,
nil, &err);
runtime·panic(err);
@@ -289,8 +281,6 @@
{
byte *ret;
- if(((uintptr)e.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
ret = (byte*)(&e+1);
assertE2Tret(t, e, ret);
}
@@ -300,16 +290,14 @@
{
Eface err;
- if(((uintptr)e.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
if(e.type == nil) {
- runtime·newTypeAssertionError(nil, nil, t,
+ runtime·newTypeAssertionError(
nil, nil, t->string,
nil, &err);
runtime·panic(err);
}
if(e.type != t) {
- runtime·newTypeAssertionError(nil, e.type, t,
+ runtime·newTypeAssertionError(
nil, e.type->string, t->string,
nil, &err);
runtime·panic(err);
@@ -326,8 +314,6 @@
bool *ok;
int32 wid;
- if(((uintptr)e.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
ret = (byte*)(&e+1);
wid = t->size;
ok = (bool*)(ret + wid);
@@ -366,7 +352,7 @@
tab = i.tab;
if(tab == nil) {
// explicit conversions require non-nil interface value.
- runtime·newTypeAssertionError(nil, nil, inter,
+ runtime·newTypeAssertionError(
nil, nil, inter->string,
nil, &err);
runtime·panic(err);
@@ -421,7 +407,7 @@
tab = i.tab;
if(tab == nil) {
// explicit conversions require non-nil interface value.
- runtime·newTypeAssertionError(nil, nil, inter,
+ runtime·newTypeAssertionError(
nil, nil, inter->string,
nil, &err);
runtime·panic(err);
@@ -463,12 +449,10 @@
Type *t;
Eface err;
- if(((uintptr)e.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
t = e.type;
if(t == nil) {
// explicit conversions require non-nil interface value.
- runtime·newTypeAssertionError(nil, nil, inter,
+ runtime·newTypeAssertionError(
nil, nil, inter->string,
nil, &err);
runtime·panic(err);
@@ -496,8 +480,6 @@
void
runtime·assertE2I2(InterfaceType *inter, Eface e, Iface ret, bool ok)
{
- if(((uintptr)e.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
if(e.type == nil) {
ok = 0;
ret.data = nil;
@@ -520,12 +502,10 @@
Type *t;
Eface err;
- if(((uintptr)e.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
t = e.type;
if(t == nil) {
// explicit conversions require non-nil interface value.
- runtime·newTypeAssertionError(nil, nil, inter,
+ runtime·newTypeAssertionError(
nil, nil, inter->string,
nil, &err);
runtime·panic(err);
@@ -538,8 +518,6 @@
void
runtime·assertE2E2(InterfaceType* inter, Eface e, Eface ret, bool ok)
{
- if(((uintptr)e.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
USED(inter);
ret = e;
ok = e.type != nil;
@@ -626,10 +604,6 @@
bool
runtime·efaceeq_c(Eface e1, Eface e2)
{
- if(((uintptr)e1.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
- if(((uintptr)e2.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
if(e1.type != e2.type)
return false;
if(e1.type == nil)
@@ -672,8 +646,6 @@
{
Type *t;
- if(((uintptr)e1.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
ret = 0;
t = e1.type;
if(t != nil)
@@ -682,10 +654,8 @@
}
void
-unsafe·Typeof(Eface e, Eface ret)
+reflect·unsafe_Typeof(Eface e, Eface ret)
{
- if(((uintptr)e.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
if(e.type == nil) {
ret.type = nil;
ret.data = nil;
@@ -696,73 +666,10 @@
}
void
-unsafe·Reflect(Eface e, Eface rettype, void *retaddr)
-{
- uintptr *p;
- uintptr x;
-
- if(((uintptr)e.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
- if(e.type == nil) {
- rettype.type = nil;
- rettype.data = nil;
- retaddr = 0;
- } else {
- rettype = *(Eface*)e.type;
- if(e.type->size <= sizeof(uintptr)) {
- // Copy data into x ...
- x = 0;
- e.type->alg->copy(e.type->size, &x, &e.data);
-
- // but then build pointer to x so that Reflect
- // always returns pointer to data.
- p = runtime·mal(sizeof(uintptr));
- *p = x;
- } else {
- // Already a pointer, but still make a copy,
- // to preserve value semantics for interface data.
- p = runtime·mal(e.type->size);
- e.type->alg->copy(e.type->size, p, e.data);
- }
- retaddr = p;
- }
- FLUSH(&rettype);
- FLUSH(&retaddr);
-}
-
-void
-unsafe·Unreflect(Eface typ, void *addr, Eface e)
-{
- if(((uintptr)typ.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
-
- // Reflect library has reinterpreted typ
- // as its own kind of type structure.
- // We know that the pointer to the original
- // type structure sits before the data pointer.
- e.type = (Type*)((Eface*)typ.data-1);
-
- // Interface holds either pointer to data
- // or copy of original data.
- if(e.type->size <= sizeof(uintptr))
- e.type->alg->copy(e.type->size, &e.data, addr);
- else {
- // Easier: already a pointer to data.
- // TODO(rsc): Should this make a copy?
- e.data = addr;
- }
-
- FLUSH(&e);
-}
-
-void
-unsafe·New(Eface typ, void *ret)
+reflect·unsafe_New(Eface typ, void *ret)
{
Type *t;
- if(((uintptr)typ.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
-
// Reflect library has reinterpreted typ
// as its own kind of type structure.
// We know that the pointer to the original
@@ -777,14 +684,11 @@
}
void
-unsafe·NewArray(Eface typ, uint32 n, void *ret)
+reflect·unsafe_NewArray(Eface typ, uint32 n, void *ret)
{
uint64 size;
Type *t;
- if(((uintptr)typ.type&reflectFlags) != 0)
- runtime·throw("invalid interface value");
-
// Reflect library has reinterpreted typ
// as its own kind of type structure.
// We know that the pointer to the original
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h
index 3134dcf..b29487e 100644
--- a/src/pkg/runtime/runtime.h
+++ b/src/pkg/runtime/runtime.h
@@ -674,7 +674,7 @@
*/
void runtime·newError(String, Eface*);
void runtime·printany(Eface);
-void runtime·newTypeAssertionError(Type*, Type*, Type*, String*, String*, String*, String*, Eface*);
+void runtime·newTypeAssertionError(String*, String*, String*, String*, Eface*);
void runtime·newErrorString(String, Eface*);
void runtime·fadd64c(uint64, uint64, uint64*);
void runtime·fsub64c(uint64, uint64, uint64*);
diff --git a/src/pkg/runtime/type.go b/src/pkg/runtime/type.go
index 1e0d723..6af6b23 100644
--- a/src/pkg/runtime/type.go
+++ b/src/pkg/runtime/type.go
@@ -4,206 +4,51 @@
/*
* Runtime type representation.
- *
- * The following files know the exact layout of these
- * data structures and must be kept in sync with this file:
- *
- * ../../cmd/gc/reflect.c
- * ../../cmd/ld/dwarf.c decodetype_*
- * ../reflect/type.go
- * type.h
+ * This file exists only to provide types that 6l can turn into
+ * DWARF information for use by gdb. Nothing else uses these.
+ * They should match the same types in ../reflect/type.go.
+ * For comments see ../reflect/type.go.
*/
package runtime
import "unsafe"
-// The compiler can only construct empty interface values at
-// compile time; non-empty interface values get created
-// during initialization. Type is an empty interface
-// so that the compiler can lay out references as data.
-type Type interface{}
-
-// All types begin with a few common fields needed for
-// the interface runtime.
type commonType struct {
- size uintptr // size in bytes
- hash uint32 // hash of type; avoids computation in hash tables
- _ uint8 // unused
- align uint8 // alignment of variable with this type
- fieldAlign uint8 // alignment of struct field with this type
- kind uint8 // enumeration for C
- alg *uintptr // algorithm table (../runtime/runtime.h:/Alg)
- string *string // string form; unnecessary but undeniably useful
- *uncommonType // (relatively) uncommon fields
- ptrToThis *Type // pointer to this type, if used in binary or has methods
+ size uintptr
+ hash uint32
+ _ uint8
+ align uint8
+ fieldAlign uint8
+ kind uint8
+ alg *uintptr
+ string *string
+ *uncommonType
+ ptrToThis *interface{}
}
-// Values for commonType.kind.
-const (
- kindBool = 1 + iota
- kindInt
- kindInt8
- kindInt16
- kindInt32
- kindInt64
- kindUint
- kindUint8
- kindUint16
- kindUint32
- kindUint64
- kindUintptr
- kindFloat32
- kindFloat64
- kindComplex64
- kindComplex128
- kindArray
- kindChan
- kindFunc
- kindInterface
- kindMap
- kindPtr
- kindSlice
- kindString
- kindStruct
- kindUnsafePointer
-
- kindNoPointers = 1 << 7 // OR'ed into kind
-)
-
-// Method on non-interface type
-type _method struct { // underscore is to avoid collision with C
- name *string // name of method
- pkgPath *string // nil for exported Names; otherwise import path
- mtyp *Type // method type (without receiver)
- typ *Type // .(*FuncType) underneath (with receiver)
- ifn unsafe.Pointer // fn used in interface call (one-word receiver)
- tfn unsafe.Pointer // fn used for normal method call
+type _method struct {
+ name *string
+ pkgPath *string
+ mtyp *interface{}
+ typ *interface{}
+ ifn unsafe.Pointer
+ tfn unsafe.Pointer
}
-// uncommonType is present only for types with names or methods
-// (if T is a named type, the uncommonTypes for T and *T have methods).
-// Using a pointer to this struct reduces the overall size required
-// to describe an unnamed type with no methods.
type uncommonType struct {
- name *string // name of type
- pkgPath *string // import path; nil for built-in types like int, string
- methods []_method // methods associated with type
+ name *string
+ pkgPath *string
+ methods []_method
}
-// BoolType represents a boolean type.
-type BoolType commonType
+type _imethod struct {
+ name *string
+ pkgPath *string
+ typ *interface{}
+}
-// FloatType represents a float type.
-type FloatType commonType
-
-// ComplexType represents a complex type.
-type ComplexType commonType
-
-// IntType represents an int type.
-type IntType commonType
-
-// UintType represents a uint type.
-type UintType commonType
-
-// StringType represents a string type.
-type StringType commonType
-
-// UintptrType represents a uintptr type.
-type UintptrType commonType
-
-// UnsafePointerType represents an unsafe.Pointer type.
-type UnsafePointerType commonType
-
-// ArrayType represents a fixed array type.
-type ArrayType struct {
+type interfaceType struct {
commonType
- elem *Type // array element type
- slice *Type // slice type
- len uintptr
-}
-
-// SliceType represents a slice type.
-type SliceType struct {
- commonType
- elem *Type // slice element type
-}
-
-// ChanDir represents a channel type's direction.
-type ChanDir int
-
-const (
- RecvDir ChanDir = 1 << iota // <-chan
- SendDir // chan<-
- BothDir = RecvDir | SendDir // chan
-)
-
-// ChanType represents a channel type.
-type ChanType struct {
- commonType
- elem *Type // channel element type
- dir uintptr // channel direction (ChanDir)
-}
-
-// FuncType represents a function type.
-type FuncType struct {
- commonType
- dotdotdot bool // last input parameter is ...
- in []*Type // input parameter types
- out []*Type // output parameter types
-}
-
-// Method on interface type
-type _imethod struct { // underscore is to avoid collision with C
- name *string // name of method
- pkgPath *string // nil for exported Names; otherwise import path
- typ *Type // .(*FuncType) underneath
-}
-
-// InterfaceType represents an interface type.
-type InterfaceType struct {
- commonType
- methods []_imethod // sorted by hash
-}
-
-// MapType represents a map type.
-type MapType struct {
- commonType
- key *Type // map key type
- elem *Type // map element (value) type
-}
-
-// PtrType represents a pointer type.
-type PtrType struct {
- commonType
- elem *Type // pointer element (pointed at) type
-}
-
-// Struct field
-type structField struct {
- name *string // nil for embedded fields
- pkgPath *string // nil for exported Names; otherwise import path
- typ *Type // type of field
- tag *string // nil if no tag
- offset uintptr // byte offset of field within struct
-}
-
-// StructType represents a struct type.
-type StructType struct {
- commonType
- fields []structField // sorted by offset
-}
-
-/*
- * Must match iface.c:/Itab and compilers.
- * NOTE: this is the version used by the reflection code, there is another
- * one in iface_defs.go that is closer to the original C version.
- */
-type Itable struct {
- Itype *Type // (*tab.inter).(*InterfaceType) is the interface type
- Type *Type
- link *Itable
- bad int32
- unused int32
- Fn [100000]uintptr // bigger than we'll ever see
+ methods []_imethod
}