Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 11832] ファイルの概要

このコミットは、Go言語のランタイムとunsafeパッケージにおける型情報の扱いを大幅に変更し、reflectパッケージへの一元化を進めるものです。具体的には、runtimeパッケージ内のType型とその関連実装、およびunsafeパッケージ内のTypeofReflectUnreflectNewNewArrayといった関数が削除され、これらがreflectパッケージの機能に置き換えられました。

コミット

commit 6a75ece01c99164d04752f26d58fdfec268d9139
Author: Russ Cox <rsc@golang.org>
Date:   Sun Feb 12 23:26:20 2012 -0500

    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

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/6a75ece01c99164d04752f26d58d9139

元コミット内容

Go言語のランタイムとunsafeパッケージにおける型情報の扱いをreflectパッケージに統合するため、以下の変更が行われました。

  • runtimeパッケージからType型およびその関連実装を削除し、reflectパッケージの機能を使用するように変更。
  • unsafeパッケージからTypeofReflectUnreflectNewNewArray関数を削除。

この変更は、Go言語のIssue 2955と2968の一部として実施されました。

変更の背景

このコミットの主な背景には、Go言語の型システムとリフレクションメカニズムの設計思想の進化があります。初期のGo言語では、型情報はruntimeパッケージ内で直接管理され、unsafeパッケージを通じて低レベルな型操作が可能でした。しかし、これはいくつかの問題を引き起こしていました。

  1. 機能の重複と複雑性: runtimeパッケージとreflectパッケージの両方に型情報に関する機能が分散しており、コードベースの複雑性を増していました。特に、unsafeパッケージの関数はreflectパッケージが提供する機能と重複しており、より安全で堅牢なreflectパッケージの存在意義を薄めていました。
  2. 安全性と堅牢性: unsafeパッケージは、その名の通り「安全でない」操作を可能にするものであり、誤用するとプログラムのクラッシュや未定義の動作を引き起こす可能性がありました。型情報のような重要な要素をunsafeパッケージで直接操作できることは、Go言語が目指す安全性と堅牢性とは相容れない側面がありました。
  3. ブートストラップとパッケージ依存関係の簡素化: コミットメッセージにもあるように、reflectパッケージがすべてのバイナリに自動的にリンクされる必要がないようにすることで、ブートストラッププロセスとパッケージ依存関係を簡素化する狙いがありました。runtimeパッケージが型情報を直接持つことで、reflectパッケージがruntimeパッケージの内部構造に依存するという循環的な依存関係が生じる可能性がありました。

これらの問題を解決し、Go言語の型システムをより一貫性があり、安全で、保守しやすいものにするために、型情報の管理をreflectパッケージに一元化する決定がなされました。これにより、runtimeパッケージはより低レベルなランタイムの責務に集中し、型情報の検査と操作はreflectパッケージを通じて安全に行われるようになります。

前提知識の解説

このコミットを理解するためには、Go言語のリフレクション、unsafeパッケージ、およびGoの型システムに関する基本的な知識が必要です。

Go言語のリフレクション (reflectパッケージ)

Go言語のreflectパッケージは、実行時にプログラムの構造を検査し、操作するための機能を提供します。これにより、型情報(reflect.Type)や値(reflect.Value)を動的に取得・変更することが可能になります。

  • reflect.Type: Goの型を表すインターフェースです。型の名前、カテゴリ(Kind)、メソッド、フィールドなどの情報を取得できます。reflect.TypeOf(i interface{})関数で取得します。
  • reflect.Value: Goの値を表す構造体です。値の取得、設定、メソッドの呼び出しなど、値に対する操作が可能です。reflect.ValueOf(i interface{})関数で取得します。
  • reflect.Kind: 型の基本的なカテゴリ(例: int, string, struct, slice, map, ptrなど)を表す列挙型です。reflect.Typereflect.ValueからKind()メソッドで取得できます。

リフレクションは、汎用的なデータシリアライゼーション(例: JSONエンコーディング/デコーディング)、ORM、テストフレームワークなど、コンパイル時に型が確定しない状況で非常に強力なツールとなります。

unsafeパッケージ

unsafeパッケージは、Go言語の型安全性をバイパスし、低レベルなメモリ操作を可能にするためのパッケージです。ポインタ演算や、異なる型間のポインタ変換など、通常では許可されない操作を行うことができます。

  • unsafe.Pointer: 任意の型のポインタを保持できる特殊なポインタ型です。C言語のvoid*に似ていますが、Goのガベージコレクタと連携して動作します。
  • unsafe.Sizeof: 型または変数のメモリサイズをバイト単位で返します。
  • unsafe.Alignof: 型または変数のアライメントをバイト単位で返します。
  • unsafe.Offsetof: 構造体内のフィールドのオフセットをバイト単位で返します。

unsafeパッケージは非常に強力ですが、その使用は厳密に制限されるべきです。なぜなら、型安全性を損ない、移植性のないコードやバグの原因となる可能性があるためです。通常、Goの標準ライブラリや、特定のパフォーマンス要件を持つ低レベルなコードでのみ使用されます。

Goの型システムとインターフェースの内部表現

Goのインターフェースは、内部的には2つのワードで表現されます。

  1. 型情報ポインタ (Type Word): インターフェースが保持する具体的な値の型情報へのポインタです。この型情報には、型のサイズ、アライメント、メソッドセットなどが含まれます。
  2. データポインタ (Data Word): インターフェースが保持する具体的な値へのポインタです。値がポインタサイズに収まる場合は直接値が格納されることもあります。

このコミット以前は、runtimeパッケージがこの型情報を直接管理し、unsafeパッケージがその内部構造にアクセスして型操作を行うための関数を提供していました。しかし、この変更により、型情報の管理と操作はreflectパッケージに集約され、より抽象化された安全なAPIを通じて行われるようになります。

技術的詳細

このコミットの技術的な核心は、Goの型システムにおける「真の型情報源」をruntimeパッケージからreflectパッケージへ移行した点にあります。

runtime.Typeの廃止とreflect.Typeへの統一

以前のGoでは、runtimeパッケージ内にTypeという型が存在し、これがGoの型の内部表現を担っていました。しかし、このコミットにより、runtime/type.goからTypeインターフェースおよびcommonType_method_imethodなどの型定義が削除されました。代わりに、reflect/type.goに定義されているreflect.Typeインターフェースと、その基盤となるcommonType構造体が、Goの型情報の唯一の公式な表現となりました。

これにより、runtimeパッケージは型情報の詳細な構造を知る必要がなくなり、reflectパッケージが型情報の定義と操作の責任を完全に負うことになります。これは、Goのモジュール間の責務分離を明確にし、コードベースの凝集度を高める上で重要な変更です。

unsafeパッケージ関数の削除とreflectパッケージへの移行

unsafeパッケージから削除された関数とその代替は以下の通りです。

  • unsafe.Typeof(i interface{}) (typ interface{}):
    • 削除理由: reflect.TypeOf(i interface{}) Typeと機能が重複しており、reflect.TypeOfの方がより安全で、reflect.Typeという適切な型を返すため。
    • 代替: reflect.TypeOf(i)
  • unsafe.Reflect(e Eface, rettype Eface, retaddr unsafe.Pointer):
    • 削除理由: インターフェースの内部表現を直接操作する低レベルな関数であり、reflect.ValueOfreflect.NewAtなどのより抽象化された安全なAPIで代替可能であるため。
    • 代替: reflect.ValueOf(i)や、特定のメモリ位置にreflect.Valueを作成するreflect.NewAt(typ Type, p unsafe.Pointer)
  • unsafe.Unreflect(typ Eface, addr unsafe.Pointer, e Eface):
    • 削除理由: unsafe.Reflectの逆操作であり、同様に低レベルな操作であるため。
    • 代替: reflect.NewAt(typ, p).Elem()など、reflect.Valueを介した操作。
  • unsafe.New(typ Eface, ret unsafe.Pointer):
    • 削除理由: reflect.New(typ Type) Valueと機能が重複しており、reflect.Newの方がreflect.Valueを返すため、よりGoらしいAPIであるため。
    • 代替: reflect.New(typ)
  • unsafe.NewArray(typ Eface, n uint32, ret unsafe.Pointer):
    • 削除理由: reflect.MakeSlice(typ Type, len, cap int) Valueと機能が重複しており、reflect.MakeSliceの方がスライスを直接作成できるため、よりGoらしいAPIであるため。
    • 代替: reflect.MakeSlice(typ, n, n)

これらの変更により、Goの型システムとリフレクションに関する操作は、すべてreflectパッケージの公開APIを通じて行われることが推奨されるようになりました。これにより、Goプログラムの安全性と保守性が向上します。

reflectパッケージの内部構造の調整

reflect/type.goでは、runtime.Typeへの参照が*runtimeTypeinterface{}のエイリアス)に変更され、commonType構造体内のポインタ型も*runtime.Typeから*runtimeTypeに更新されました。これは、reflectパッケージがruntimeパッケージの具体的な型定義に直接依存するのではなく、より抽象的なinterface{}を介して型情報を扱うようにするための変更です。

また、reflectパッケージ内の各種型(arrayType, chanType, funcType, interfaceType, mapType, ptrType, sliceType, structField)の要素型も、*runtime.Typeから*runtimeTypeに変更されています。これにより、reflectパッケージは自身の内部で型情報を完結させ、runtimeパッケージとの結合度を低減しています。

encoding/gobパッケージの変更

encoding/gobパッケージは、Goのデータ構造をシリアライズ/デシリアライズするためのパッケージであり、内部でリフレクションを多用しています。このコミットでは、unsafeパッケージの関数が削除されたことに伴い、gob/decode.gogob/encode.go内のunsafe.Newunsafe.NewArrayunsafe.Unreflectの呼び出しが、それぞれreflect.Newreflect.MakeSlicereflect.NewAtなどのreflectパッケージの関数に置き換えられました。

これは、unsafeパッケージの低レベルな操作からreflectパッケージのより安全で抽象化されたAPIへの移行を示す具体的な例です。

runtime/error.goruntime/iface.cの変更

runtime/error.goでは、TypeAssertionError構造体からType型のフィールド(interfaceType, concreteType, assertedType)が削除され、代わりにstring型のフィールド(interfaceString, concreteString, assertedString)が使用されるようになりました。これは、エラー情報が文字列として表現されることで、runtimeパッケージがreflect.Typeの具体的な構造に依存しないようにするための変更です。

runtime/iface.cでは、インターフェースの型アサーションに関連するエラー生成関数runtime·newTypeAssertionErrorの引数からType*型のポインタが削除され、String*型のポインタのみを受け取るように変更されました。また、unsafe.Typeofunsafe.Reflectunsafe.Unreflectunsafe.Newunsafe.NewArrayのC言語実装が削除され、代わりにreflect·unsafe_Typeofなどの新しい関数名が導入されています。これは、これらの関数がreflectパッケージの内部実装として扱われるようになったことを示唆しています。

コアとなるコードの変更箇所

このコミットにおける主要なコード変更は、以下のファイルに集中しています。

  1. src/pkg/reflect/type.go: runtime.Typeへの依存を排除し、reflectパッケージが型情報の主要な定義元となるように変更。commonType構造体や、各種型(arrayTypeなど)の要素型が*runtime.Typeから*runtimeTypeinterface{}のエイリアス)に変更されています。
  2. src/pkg/reflect/value.go: unsafeパッケージの関数呼び出しをreflectパッケージの関数に置き換え。特にMakeSliceNewNewAtなどの関数が追加・修正されています。
  3. src/pkg/runtime/type.go: Typeインターフェースおよび関連する型定義が完全に削除され、このファイルがGoのデバッガ(gdb)のためのDWARF情報を提供する目的のみに特化されました。
  4. src/pkg/runtime/iface.c: インターフェースの型アサーションに関連するC言語コードから、unsafeパッケージの関数呼び出しが削除され、reflectパッケージの内部関数への参照に置き換えられています。
  5. src/pkg/encoding/gob/decode.go & src/pkg/encoding/gob/encode.go: unsafe.Newunsafe.NewArrayunsafe.Unreflectの呼び出しが、reflect.Newreflect.MakeSlicereflect.NewAtなどのreflectパッケージの関数に置き換えられています。
  6. src/pkg/unsafe/unsafe.go: Typeof, Reflect, Unreflect, New, NewArrayの宣言が削除されています。

コアとなるコードの解説

src/pkg/reflect/type.goの変更

--- a/src/pkg/reflect/type.go
+++ b/src/pkg/reflect/type.go
@@ -16,7 +16,6 @@
  package reflect
  
  import (
-	"runtime"
  	"strconv"
  	"sync"
  	"unsafe"
@@ -181,7 +180,7 @@ type Type interface {
  	// It panics if i is not in the range [0, NumOut()).
  	Out(i int) Type
  
-	runtimeType() *runtime.Type
+	runtimeType() *runtimeType
  	common() *commonType
  	uncommon() *uncommonType
  }
@@ -221,128 +220,131 @@ const (
  )
  
  /*
- * Copy of data structures from ../runtime/type.go.
- * For comments, see the ones in that file.
- *\
- * These data structures are known to the compiler and the runtime.\
- *\
- * Putting these types in runtime instead of reflect means that
- * reflect doesn\'t need to be autolinked into every binary, which
- * simplifies bootstrapping and package dependencies.
- * Unfortunately, it also means that reflect needs its own
- * copy in order to access the private fields.
+ * These data structures are known to the compiler (../../cmd/gc/reflect.c).
+ * A few are known to ../runtime/type.go to convey to debuggers.
   */
  
+// 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.
+// The underlying type is *reflect.ArrayType and so on.
+type runtimeType interface{}
+
  // commonType is the common implementation of most values.
  // It is embedded in other, public struct types, but always
  // with a unique tag like `reflect:\"array\"` or `reflect:\"ptr\"`
  // so that code cannot convert from, say, *arrayType to *ptrType.
 -
  type commonType struct {
-	size       uintptr
-	hash       uint32
-	_          uint8
-	align      uint8
-	fieldAlign uint8
-	kind       uint8
-	alg        *uintptr
-	string     *string
-	*uncommonType
-	ptrToThis *runtime.Type
+	size          uintptr      // size in bytes
+	hash          uint32       // hash of type; avoids computation in hash tables
+	_             uint8        // unused/padding
+	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     *runtimeType // pointer to this type, if used in binary or has methods
  }
  
+// Method on non-interface type
  type method struct {
-	name    *string
-	pkgPath *string
-	mtyp    *runtime.Type
-	typ     *runtime.Type
-	ifn     unsafe.Pointer
-	tfn     unsafe.Pointer
+	name    *string        // name of method
+	pkgPath *string        // nil for exported Names; otherwise import path
+	mtyp    *runtimeType   // method type (without receiver)
+	typ     *runtimeType   // .(*FuncType) underneath (with receiver)
+	ifn     unsafe.Pointer // fn used in interface call (one-word receiver)
+	tfn     unsafe.Pointer // fn used for normal method call
  }
  
+// 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
-	pkgPath *string
-	methods []method
+	name    *string  // name of type
+	pkgPath *string  // import path; nil for built-in types like int, string
+	methods []method // methods associated with type
  }
  
  // ChanDir represents a channel type\'s direction.
  type ChanDir int
  
  const (
-	RecvDir ChanDir = 1 << iota
-	SendDir
-	BothDir = RecvDir | SendDir
+	RecvDir ChanDir             = 1 << iota // <-chan
+	SendDir                                 // chan<-
+	BothDir = RecvDir | SendDir             // chan
  )
  
  // arrayType represents a fixed array type.
  type arrayType struct {
  	commonType `reflect:\"array\"`
-	elem       *runtime.Type
-	slice      *runtime.Type
+	elem       *runtimeType // array element type
+	slice      *runtimeType // slice type
  	len        uintptr
  }
  
  // chanType represents a channel type.
  type chanType struct {
  	commonType `reflect:\"chan\"`
-	elem       *runtime.Type
-	dir        uintptr
+	elem       *runtimeType // channel element type
+	dir        uintptr      // channel direction (ChanDir)
  }
  
  // funcType represents a function type.
  type funcType struct {
  	commonType `reflect:\"func\"`
-	dotdotdot  bool
-	in         []*runtime.Type
-	out        []*runtime.Type
+	dotdotdot  bool           // last input parameter is ...
+	in         []*runtimeType // input parameter types
+	out        []*runtimeType // output parameter types
  }
  
  // imethod represents a method on an interface type
  type imethod struct {
-	name    *string
-	pkgPath *string
-	typ     *runtime.Type
+	name    *string      // name of method
+	pkgPath *string      // nil for exported Names; otherwise import path
+	typ     *runtimeType // .(*FuncType) underneath
  }
  
  // interfaceType represents an interface type.
  type interfaceType struct {
  	commonType `reflect:\"interface\"`
-	methods    []imethod
+	methods    []imethod // sorted by hash
  }
  
  // mapType represents a map type.
  type mapType struct {
  	commonType `reflect:\"map\"`
-	key        *runtime.Type
-	elem       *runtime.Type
+	key        *runtimeType // map key type
+	elem       *runtimeType // map element (value) type
  }
  
  // ptrType represents a pointer type.
  type ptrType struct {
  	commonType `reflect:\"ptr\"`
-	elem       *runtime.Type
+	elem       *runtimeType // pointer element (pointed at) type
  }
  
  // sliceType represents a slice type.
  type sliceType struct {
  	commonType `reflect:\"slice\"`
-	elem       *runtime.Type
+	elem       *runtimeType // slice element type
  }
  
  // Struct field
  type structField struct {
-	name    *string
-	pkgPath *string
-	typ     *runtime.Type
-	tag     *string
-	offset  uintptr
+	name    *string      // nil for embedded fields
+	pkgPath *string      // nil for exported Names; otherwise import path
+	typ     *runtimeType // 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 `reflect:\"struct\"`
-	fields     []structField
+	fields     []structField // sorted by offset
  }
  
  /*
@@ -909,23 +911,18 @@ func (t *structType) FieldByNameFunc(match func(string) bool) (f StructField, pr\
  }\n \n // Convert runtime type to reflect type.\n-func toCommonType(p *runtime.Type) *commonType {\n+func toCommonType(p *runtimeType) *commonType {\n  	if p == nil {\n  		return nil\n  	}\n-\ttype hdr struct {\n-\t\tx interface{}\n-\t\tt commonType\n-\t}\n-\tx := unsafe.Pointer(p)\n-\treturn &(*hdr)(x).t\n+\treturn (*p).(*commonType)\n  }\n  \n-func toType(p *runtime.Type) Type {\n+func toType(p *runtimeType) Type {\n  	if p == nil {\n  		return nil\n  	}\n-\treturn toCommonType(p).toType()\n+\treturn (*p).(*commonType)\n  }\n  \n  // TypeOf returns the reflection Type of the value in the interface{}.\n@@ -940,14 +937,14 @@ var ptrMap struct {\n  	m map[*commonType]*ptrType\n  }\n  \n-func (t *commonType) runtimeType() *runtime.Type {\n-\t// The runtime.Type always precedes the commonType in memory.\n+func (t *commonType) runtimeType() *runtimeType {\n+\t// The runtimeType always precedes the commonType in memory.\n  	// Adjust pointer to find it.\n  	var rt struct {\n-\t\ti  runtime.Type\n+\t\ti  runtimeType\n  	\tct commonType\n  	}\n-\treturn (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(t)) - unsafe.Offsetof(rt.ct)))\n+\treturn (*runtimeType)(unsafe.Pointer(uintptr(unsafe.Pointer(t)) - unsafe.Offsetof(rt.ct)))\n  }\n  \n  // PtrTo returns the pointer type with element t.\n@@ -986,16 +983,15 @@ func (ct *commonType) ptrTo() *commonType {\n  	}\n  \n  	var rt struct {\n-\t\ti runtime.Type\n+\t\ti runtimeType\n  	\tptrType\n  	}\n-\trt.i = (*runtime.PtrType)(unsafe.Pointer(&rt.ptrType))\n+\trt.i = &rt.commonType\n  \n  	// initialize p using *byte\'s ptrType as a prototype.\n-\t// have to do assignment as ptrType, not runtime.PtrType,\n-\t// in order to write to unexported fields.\n  \tp = &rt.ptrType\n-\tbp := (*ptrType)(unsafe.Pointer(unsafe.Typeof((*byte)(nil)).(*runtime.PtrType)))\n+\tvar ibyte interface{} = (*byte)(nil)\n+\tbp := (*ptrType)(unsafe.Pointer((**(**runtimeType)(unsafe.Pointer(&ibyte))).(*commonType)))\n  \t*p = *bp\n  \n  \ts := \"*\" + *ct.string\n@@ -1010,7 +1006,7 @@ func (ct *commonType) ptrTo() *commonType {\n  \n  \tp.uncommonType = nil\n  \tp.ptrToThis = nil\n-\tp.elem = (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(ct)) - unsafe.Offsetof(rt.ptrType)))\n+\tp.elem = (*runtimeType)(unsafe.Pointer(uintptr(unsafe.Pointer(ct)) - unsafe.Offsetof(rt.ptrType)))\n  \n  \tptrMap.m[ct] = p\n  \tptrMap.Unlock()\n```

-   **`import "runtime"`の削除**: `reflect`パッケージが`runtime`パッケージの具体的な型定義に直接依存しなくなったことを示します。
-   **`runtimeType interface{}`の導入**: `reflect`パッケージ内で、ランタイムの型情報を抽象的に扱うための`interface{}`エイリアスが導入されました。これにより、`reflect`パッケージは`runtime`パッケージの内部実装に直接結合されることなく、型情報を参照できるようになります。
-   **`commonType`および関連構造体のポインタ型の変更**: `commonType`、`method`、`imethod`、`arrayType`、`chanType`、`funcType`、`interfaceType`、`mapType`、`ptrType`、`sliceType`、`structField`内の`*runtime.Type`型のフィールドがすべて`*runtimeType`(`interface{}`のエイリアス)に変更されました。これは、`reflect`パッケージが型情報の定義と操作の主要な責任を負うようになったことを明確に示しています。
-   **`toCommonType`、`toType`、`runtimeType()`メソッドの変更**: これらの関数やメソッドは、`*runtime.Type`から`*runtimeType`への変換ロジックを調整し、`reflect`パッケージが型情報をより適切に扱うように変更されました。特に`toCommonType`は、`unsafe.Pointer`を使った複雑なポインタ操作から、より直接的な型アサーションに簡素化されています。

### `src/pkg/reflect/value.go`の変更

```diff
--- a/src/pkg/reflect/value.go
+++ b/src/pkg/reflect/value.go
@@ -1606,6 +1606,10 @@ func Copy(dst, src Value) int {\n   * constructors\n   */\n  \n+// implemented in package runtime\n+func unsafe_New(Type) unsafe.Pointer
+func unsafe_NewArray(Type, int) unsafe.Pointer
+\n // MakeSlice creates a new zero-initialized slice value\n  // for the specified slice type, length, and capacity.\n  func MakeSlice(typ Type, len, cap int) Value {\n@@ -1618,7 +1618,7 @@ func MakeSlice(typ Type, len, cap int) Value {\n  \n  	// Reinterpret as *SliceHeader to edit.\n  	s := (*SliceHeader)(unsafe.Pointer(&x))\n-\ts.Data = uintptr(unsafe.NewArray(typ.Elem(), cap))\n+\ts.Data = uintptr(unsafe_NewArray(typ.Elem(), cap))\n  \ts.Len = len\n  \ts.Cap = cap\n  \n@@ -1697,7 +1701,7 @@ func Zero(typ Type) Value {\n  	if t.size <= ptrSize {\n  		return Value{t, nil, fl}\n  	}\n-\treturn Value{t, unsafe.New(typ), fl | flagIndir}\n+\treturn Value{t, unsafe_New(typ), fl | flagIndir}\n  }\n  \n  // New returns a Value representing a pointer to a new zero value\n@@ -1706,11 +1710,18 @@ func New(typ Type) Value {\n  	if typ == nil {\n  		panic(\"reflect: New(nil)\")\n  	}\n-\tptr := unsafe.New(typ)\n+\tptr := unsafe_New(typ)\n  \tfl := flag(Ptr) << flagKindShift\n  \treturn Value{typ.common().ptrTo(), ptr, fl}\n  }\n  \n+// NewAt returns a Value representing a pointer to a value of the\n+// specified type, using p as that pointer.\n+func NewAt(typ Type, p unsafe.Pointer) Value {\n+\tfl := flag(Ptr) << flagKindShift\n+\treturn Value{typ.common().ptrTo(), p, fl}\n+}\n+\n  // assignTo returns a value v that can be assigned directly to typ.\n  // It panics if v is not assignable to typ.\n  // For a conversion to an interface type, target is a suggested scratch space to use.\n@@ -1749,20 +1760,20 @@ func (v Value) assignTo(context string, dst *commonType, target *interface{}) Va\n  func chancap(ch iword) int32\n  func chanclose(ch iword)\n  func chanlen(ch iword) int32\n-func chanrecv(t *runtime.Type, ch iword, nb bool) (val iword, selected, received bool)\n-func chansend(t *runtime.Type, ch iword, val iword, nb bool) bool\n-\n-func makechan(typ *runtime.Type, size uint32) (ch iword)\n-func makemap(t *runtime.Type) (m iword)\n-func mapaccess(t *runtime.Type, m iword, key iword) (val iword, ok bool)\n-func mapassign(t *runtime.Type, m iword, key, val iword, ok bool)\n-func mapiterinit(t *runtime.Type, m iword) *byte\n+func chanrecv(t *runtimeType, ch iword, nb bool) (val iword, selected, received bool)\n+func chansend(t *runtimeType, ch iword, val iword, nb bool) bool\n+\n+func makechan(typ *runtimeType, size uint32) (ch iword)\n+func makemap(t *runtimeType) (m iword)\n+func mapaccess(t *runtimeType, m iword, key iword) (val iword, ok bool)\n+func mapassign(t *runtimeType, m iword, key, val iword, ok bool)\n+func mapiterinit(t *runtimeType, m iword) *byte\n  func mapiterkey(it *byte) (key iword, ok bool)\n  func mapiternext(it *byte)\n  func maplen(m iword) int32\n  \n  func call(fn, arg unsafe.Pointer, n uint32)\n-func ifaceE2I(t *runtime.Type, src interface{}, dst unsafe.Pointer)\n+func ifaceE2I(t *runtimeType, src interface{}, dst unsafe.Pointer)\n  \n  // Dummy annotation marking that the value x escapes,\n  // for use in cases where the reflect code is so clever that\n```

-   **`unsafe_New`と`unsafe_NewArray`の宣言**: `reflect`パッケージ内で、ランタイムが提供する低レベルなメモリ割り当て関数を呼び出すための内部関数として宣言されています。これは、`unsafe`パッケージの公開関数が削除された後も、`reflect`パッケージが内部的にこれらの機能を利用できるようにするためのものです。
-   **`MakeSlice`、`Zero`、`New`関数での`unsafe`関数の置き換え**: `MakeSlice`、`Zero`、`New`といった`reflect`パッケージのコンストラクタ関数内で、以前は`unsafe.NewArray`や`unsafe.New`を直接呼び出していた箇所が、新しく宣言された内部関数`unsafe_NewArray`や`unsafe_New`に置き換えられています。これにより、`reflect`パッケージの外部からは`unsafe`パッケージの直接的な利用が見えなくなります。
-   **`NewAt`関数の追加**: 特定のメモリ位置に`reflect.Value`を作成するための`NewAt`関数が追加されました。これは、以前`unsafe.Unreflect`が提供していた機能の一部を、より安全な形で代替するものです。
-   **ランタイム関数シグネチャの変更**: `chanrecv`、`chansend`、`makechan`、`makemap`、`mapaccess`、`mapassign`、`mapiterinit`、`ifaceE2I`などのランタイム関数の引数型が`*runtime.Type`から`*runtimeType`に変更されています。これは、`reflect`パッケージがランタイムとのインターフェースを`runtimeType`という抽象的な型で統一したことを示しています。

### `src/pkg/runtime/type.go`の変更

```diff
--- 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:\
- *\
- *\t../../cmd/gc/reflect.c\
- *\t../../cmd/ld/dwarf.c decodetype_*\
- *\t../reflect/type.go\
- *\ttype.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 {\n-\tsize          uintptr  // size in bytes\n-\thash          uint32   // hash of type; avoids computation in hash tables\n-\t_             uint8    // unused\n-\talign         uint8    // alignment of variable with this type\n-\tfieldAlign    uint8    // alignment of struct field with this type\n-\tkind          uint8    // enumeration for C\n-\talg           *uintptr // algorithm table (../runtime/runtime.h:/Alg)\n-\tstring        *string  // string form; unnecessary  but undeniably useful\n-\t*uncommonType          // (relatively) uncommon fields\n-\tptrToThis     *Type    // pointer to this type, if used in binary or has methods\n+\tsize       uintptr\n+\thash       uint32\n+\t_          uint8\n+\talign      uint8\n+\tfieldAlign uint8\n+\tkind       uint8\n+\talg        *uintptr\n+\tstring     *string\n+\t*uncommonType\n+\tptrToThis *interface{}\n  }\n  
-// Values for commonType.kind.\n-const (\n-\tkindBool = 1 + iota\n-\tkindInt\n-\tkindInt8\n-\tkindInt16\n-\tkindInt32\n-\tkindInt64\n-\tkindUint\n-\tkindUint8\n-\tkindUint16\n-\tkindUint32\n-\tkindUint64\n-\tkindUintptr\n-\tkindFloat32\n-\tkindFloat64\n-\tkindComplex64\n-\tkindComplex128\n-\tkindArray\n-\tkindChan\n-\tkindFunc\n-\tkindInterface\n-\tkindMap\n-\tkindPtr\n-\tkindSlice\n-\tkindString\n-\tkindStruct\n-\tkindUnsafePointer\n-\n-\tkindNoPointers = 1 << 7 // OR\'ed into kind\n-)\n-\n-// Method on non-interface type\n-type _method struct { // underscore is to avoid collision with C\n-\tname    *string        // name of method\n-\tpkgPath *string        // nil for exported Names; otherwise import path\n-\tmtyp    *Type          // method type (without receiver)\n-\ttyp     *Type          // .(*FuncType) underneath (with receiver)\n-\tifn     unsafe.Pointer // fn used in interface call (one-word receiver)\n-\ttfn     unsafe.Pointer // fn used for normal method call\n+\n+type _method struct {\n+\tname    *string\n+\tpkgPath *string\n+\tmtyp    *interface{}\n+\ttyp     *interface{}\n+\tifn     unsafe.Pointer\n+\ttfn     unsafe.Pointer\n  }\n  
-// uncommonType is present only for types with names or methods\n-// (if T is a named type, the uncommonTypes for T and *T have methods).\n-// Using a pointer to this struct reduces the overall size required\n-// to describe an unnamed type with no methods.\n type uncommonType struct {\n-\tname    *string   // name of type\n-\tpkgPath *string   // import path; nil for built-in types like int, string\n-\tmethods []_method // methods associated with type\n+\tname    *string\n+\tpkgPath *string\n+\tmethods []_method\n  }\n  
-// BoolType represents a boolean type.\n-type BoolType commonType\n-// FloatType represents a float type.\n-type FloatType commonType
-// ComplexType represents a complex type.\n-type ComplexType commonType
-// IntType represents an int type.\n-type IntType commonType
-// UintType represents a uint type.\n-type UintType commonType
-// StringType represents a string type.\n-type StringType commonType
-// UintptrType represents a uintptr type.\n-type UintptrType commonType
-// UnsafePointerType represents an unsafe.Pointer type.\n-type UnsafePointerType commonType
-// ArrayType represents a fixed array type.\n-type ArrayType struct {\n-\tcommonType\n-\telem  *Type // array element type\n-\tslice *Type // slice type\n-\tlen   uintptr\n-}\n-// SliceType represents a slice type.\n-type SliceType struct {\n-\tcommonType\n-\telem *Type // slice element type\n-}\n-// ChanDir represents a channel type\'s direction.\n-type ChanDir int
-// const (\n-//\tRecvDir ChanDir             = 1 << iota // <-chan\n-//\tSendDir                                 // chan<-\n-//\tBothDir = RecvDir | SendDir             // chan\n-//)\n-// ChanType represents a channel type.\n-type ChanType struct {\n-\tcommonType\n-\telem *Type   // channel element type\n-\tdir  uintptr // channel direction (ChanDir)\n-}\n-// FuncType represents a function type.\n-type FuncType struct {\n-\tcommonType\n-\tdotdotdot bool    // last input parameter is ...\n-\tin        []*Type // input parameter types\n-\tout       []*Type // output parameter types\n+\n+type _imethod struct {\n+\tname    *string\n+\tpkgPath *string\n+\ttyp     *interface{}\n  }\n  
-// Method on interface type\n-type _imethod struct { // underscore is to avoid collision with C\n-\tname    *string // name of method\n-\tpkgPath *string // nil for exported Names; otherwise import path\n-\ttyp     *Type   // .(*FuncType) underneath\n+\n+type interfaceType struct {\n+\tcommonType\n+\tmethods []_imethod\n  }\n  
-// InterfaceType represents an interface type.\n-type InterfaceType struct {\n+\n```

-   **大幅な削除**: `Type`インターフェース、`kindBool`から`kindUnsafePointer`までの`kind`定数、`BoolType`から`StructType`までの具体的な型構造体(`ArrayType`, `SliceType`, `ChanType`, `FuncType`, `MapType`, `PtrType`, `StructType`など)がすべて削除されました。
-   **コメントの変更**: ファイルの冒頭のコメントが「このファイルは、gdbが使用するDWARF情報に6lが変換できる型を提供するためにのみ存在する。他には何も使用しない。」と変更されました。これは、`runtime/type.go`がもはやGoの型情報の主要な定義元ではなく、デバッグ情報提供のための補助的な役割に限定されたことを明確に示しています。
-   **残された型定義の簡素化**: 残された`commonType`、`_method`、`uncommonType`、`_imethod`、`interfaceType`の定義も、`reflect`パッケージの対応する型定義と一致するように簡素化され、`*Type`への参照が`*interface{}`に変更されています。

これらの変更は、Goの型システムが`reflect`パッケージを中心に再構築されたことを明確に示しており、`runtime`パッケージはより低レベルなランタイムの責務に特化するようになりました。

## 関連リンク

-   **GitHubコミットページ**: [https://github.com/golang/go/commit/6a75ece01c99164d04752f26d58fdfec268d9139](https://github.com/golang/go/commit/6a75ece01c99164d04752f26d58fdfec268d9139)
-   **Go Issue 2955**: このコミットが解決しようとした問題の一つ。具体的な内容は検索結果からは特定できませんでしたが、型システムとリフレクションの改善に関連するものです。
-   **Go Issue 2968**: このコミットが解決しようとしたもう一つの問題。こちらも具体的な内容は特定できませんでしたが、型システムとリフレクションの改善に関連するものです。

## 参考にした情報源リンク

-   Go reflect package internal structure:
    -   [https://scaler.com/topics/go-reflect-package/](https://scaler.com/topics/go-reflect-package/)
    -   [https://pieces.app/blog/go-reflection-tutorial/](https://pieces.app/blog/go-reflection-tutorial/)
    -   [https://coffeebytes.dev/posts/go-reflection-deep-dive/](https://coffeebytes.dev/posts/go-reflection-deep-dive/)
    -   [https://shichao.io/2013/09/02/go-reflection-deep-dive.html](https://shichao.io/2013/09/02/go-reflection-deep-dive.html)
    -   [https://medium.com/@mlowicki/go-reflection-deep-dive-2-reflect-type-and-reflect-value-100e22222222](https://medium.com/@mlowicki/go-reflection-deep-dive-2-reflect-type-and-reflect-value-100e22222222)
    -   [https://dev.to/ankit01/go-reflection-deep-dive-1-3k9](https://dev.to/ankit01/go-reflection-deep-dive-1-3k9)
    -   [https://go.dev/blog/laws-of-reflection](https://go.dev/blog/laws-of-reflection)
    -   [https://nutanix.dev/2023/08/29/go-reflection-deep-dive/](https://nutanix.dev/2023/08/29/go-reflection-deep-dive/)
    -   [https://josemukorivo.com/go-reflection-deep-dive/](https://josemukorivo.com/go-reflection-deep-dive/)
    -   [https://go.dev/doc/articles/laws_of_reflection.html](https://go.dev/doc/articles/laws_of_reflection.html)
-   Go unsafe package Typeof Reflect Unreflect New NewArray removal:
    -   [https://go.dev/doc/go1#unsafe](https://go.dev/doc/go1#unsafe)
-   Go issue 2955 & 2968:
    -   [https://go.dev/cl/5650069](https://go.dev/cl/5650069) (このコミットのChangeListページ)
    -   [https://youtrack.jetbrains.com/issue/GO-2968](https://youtrack.jetbrains.com/issue/GO-2968) (GoLand IDEのIssueトラッカーのGO-2968)
    -   [https://pkg.go.dev/vuln/GO-2024-2955](https://pkg.go.dev/vuln/GO-2024-2955) (Goの脆弱性レポートGO-2024-2955)
    -   [https://pkg.go.dev/vuln/GO-2024-2968](https://pkg.go.dev/vuln/GO-2024-2968) (Goの脆弱性レポートGO-2024-2968)
    -   [https://github.com/golang/vscode-go/issues/2955](https://github.com/golang/vscode-go/issues/2955) (VS Code Go拡張機能のIssue #2955)
    -   [https://github.com/grpc/grpc-go/issues/2955](https://github.com/grpc/grpc-go/issues/2955) (grpc-goのIssue #2955)
    -   [https://gochanges.org/go.golang.org/x/oauth2/commit/2955](https://gochanges.org/go.golang.org/x/oauth2/commit/2955) (golang.org/x/oauth2のコミット2955)