[インデックス 1562] ファイルの概要
このコミットは、Goコンパイラ(gc
)の内部処理に関するバグ修正を含んでいます。具体的には、パッケージのインポート処理とシンボル解決のロジックが変更されています。また、関連するテストファイルがtest/bugs
からtest/fixedbugs
に移動されています。
変更されたファイルは以下の通りです。
src/cmd/gc/dcl.c
: 宣言処理に関するC言語のソースファイル。src/cmd/gc/go.h
: Goコンパイラのヘッダーファイル。src/cmd/gc/go.y
: Go言語の文法定義ファイル(Yacc/Bison形式)。test/{bugs => fixedbugs}/bug133.dir/bug0.go
: テストファイル(リネーム)。test/{bugs => fixedbugs}/bug133.dir/bug1.go
: テストファイル(リネーム)。test/{bugs => fixedbugs}/bug133.dir/bug2.go
: テストファイル(リネーム)。test/{bugs => fixedbugs}/bug133.go
: テストファイル(リネーム)。test/golden.out
: テストの期待出力ファイル。
コミット
commit 4efad58d0a0a6d96d83ccfa39e27308c85be96a9
Author: Russ Cox <rsc@golang.org>
Date: Mon Jan 26 16:57:24 2009 -0800
bug133
R=ken
OCL=23528
CL=23528
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/4efad58d0a0a6d96d83ccfa39e27308c85be96a9
元コミット内容
bug133
R=ken
OCL=23528
CL=23528
変更の背景
このコミットは、コミットメッセージにある「bug133」という特定のバグを修正するために行われました。Go言語の初期段階におけるコンパイラのバグであり、特にパッケージのインポートとシンボル解決のメカニズムに関連する問題であったと推測されます。
test/bugs
ディレクトリからtest/fixedbugs
ディレクトリへのテストファイルの移動は、このバグが修正され、その修正が将来のリグレッションテストで確実に検証されるようにするための標準的なプラクティスです。golden.out
の変更は、テストの期待される出力がバグ修正によって変化したことを示しています。
Web検索の結果からも、「bug133」はGoプロジェクト自身のテストスイート内に存在する特定の歴史的なバグを指しており、Go言語自体の特定の問題に対する修正を実証し、検証するために使用されたことが示唆されています。
前提知識の解説
このコミットを理解するためには、以下のGoコンパイラ(gc
)に関する基本的な知識が必要です。
- Goコンパイラ (
gc
): Go言語の公式コンパイラであり、Goソースコードを機械語に変換します。src/cmd/gc
ディレクトリにそのソースコードが存在します。 - Yacc/Bison (
.y
ファイル):go.y
ファイルは、Go言語の文法を定義するYacc(Yet Another Compiler Compiler)またはBisonの入力ファイルです。Yacc/Bisonは、文法定義からパーサー(構文解析器)を生成するツールです。パーサーは、ソースコードが文法的に正しいかをチェックし、抽象構文木(AST)を構築します。 - シンボルテーブルとシンボル解決: コンパイラは、変数、関数、型などの識別子(シンボル)に関する情報をシンボルテーブルに格納します。シンボル解決は、ソースコード中の識別子がどのシンボルテーブルのエントリに対応するかを決定するプロセスです。特に、異なるパッケージからインポートされたシンボルを正しく解決することが重要です。
- パッケージインポート: Go言語では、
import
ステートメントを使用して他のパッケージの機能を利用します。コンパイラは、インポートされたパッケージのシンボルを現在のスコープで利用できるように処理する必要があります。 dcl.c
:gc
における宣言(declaration)処理を担当するC言語のソースファイルです。変数、関数、型の宣言がどのように処理され、シンボルテーブルに登録されるかを定義します。go.h
:gc
全体で共有されるグローバル変数、構造体、関数のプロトタイプなどが定義されているヘッダーファイルです。
技術的詳細
このコミットの技術的な核心は、Goコンパイラがパッケージのインポートされたシンボルをどのように解決するか、特にその「コンテキスト」をどのように管理するかという点にあります。
変更点を見ると、src/cmd/gc/dcl.c
ではpkgimportname
という変数がpkgcontext
という変数に置き換えられています。
pkgimportname
: これは、おそらく特定のインポートされたパッケージの名前を保持していた変数です。しかし、シンボル解決の際には、単にインポートされたパッケージの名前だけでなく、そのシンボルがどのパッケージのコンテキストで定義されたものなのか、というより広範な情報が必要になる場合があります。pkgcontext
: この新しい変数は、より一般的な「パッケージコンテキスト」を指すと考えられます。これは、現在処理しているシンボルが属するパッケージの情報を保持し、シンボル解決の際にそのコンテキストを利用して正しいシンボルを特定するために使用されます。
src/cmd/gc/go.y
の変更は、このpkgcontext
の導入と密接に関連しています。
%type <node> hidden_funres ohidden_funres hidden_importsym
が%type <node> hidden_funres ohidden_funres hidden_importsym hidden_pkg_importsym
に変更されています。これは、Yaccの型定義にhidden_pkg_importsym
という新しい型が追加されたことを意味します。hidden_import
ルールの変更では、LVAR
,LCONST
,LTYPE
,LFUNC
といったキーワードに続くシンボルが、これまでのhidden_importsym
からhidden_pkg_importsym
に変わっています。これは、インポートされた変数、定数、型、関数のシンボルを解析する際に、より詳細なパッケージコンテキスト情報を持つhidden_pkg_importsym
を使用するように文法が変更されたことを示しています。- 新しく追加された
hidden_pkg_importsym
ルールは、hidden_importsym
を解析した後、そのシンボルのpsym->name
(おそらくパッケージシンボルの名前)をグローバル変数pkgcontext
に設定しています。これにより、パーサーがインポートされたシンボルを処理する際に、そのシンボルがどのパッケージに属しているかというコンテキスト情報がpkgcontext
を通じて利用可能になります。
この変更は、Goコンパイラがインポートされたシンボルを曖昧さなく解決するために、より堅牢なメカニズムを導入したことを示唆しています。特に、異なるパッケージで同じ名前のシンボルが存在する場合や、複雑なインポートパスを持つ場合に、正しいシンボルを特定するためのコンテキスト情報が不可欠になります。
コアとなるコードの変更箇所
src/cmd/gc/dcl.c
--- a/src/cmd/gc/dcl.c
+++ b/src/cmd/gc/dcl.c
@@ -517,7 +517,7 @@ loop:
f->embedded = n->embedded;
f->sym = f->nname->sym;
if(pkgimportname != S && !exportname(f->sym->name))
- f->sym = pkglookup(f->sym->name, pkgimportname->name);
+ f->sym = pkglookup(f->sym->name, pkgcontext);
}
*t = f;
src/cmd/gc/go.h
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -504,6 +504,7 @@ EXTERN Node* fskel;
EXTERN Node* addtop;
EXTERN char* context;
+EXTERN char* pkgcontext;
EXTERN int thechar;
EXTERN char* thestring;
EXTERN char* hunk;
src/cmd/gc/go.y
--- a/src/cmd/gc/go.y
+++ b/src/cmd/gc/go.y
@@ -80,7 +80,7 @@
%type <node> hidden_interfacedcl_list ohidden_interfacedcl_list hidden_interfacedcl_list_r
%type <node> hidden_interfacedcl
%type <node> hidden_funarg_list ohidden_funarg_list hidden_funarg_list_r
-%type <node> hidden_funres ohidden_funres hidden_importsym
+%type <node> hidden_funres ohidden_funres hidden_importsym hidden_pkg_importsym
%left LOROR
%left LANDAND
@@ -1730,23 +1730,23 @@ oliteral:
hidden_import:
LPACKAGE sym1
/* variables */
-|\tLVAR hidden_importsym hidden_type
+|\tLVAR hidden_pkg_importsym hidden_type
{
importvar($2, $3);
}
-|\tLCONST hidden_importsym '=' hidden_constant
+|\tLCONST hidden_pkg_importsym '=' hidden_constant
{
importconst($2, T, &$4);
}
-|\tLCONST hidden_importsym hidden_type '=' hidden_constant
+|\tLCONST hidden_pkg_importsym hidden_type '=' hidden_constant
{
importconst($2, $3, &$5);
}
-|\tLTYPE hidden_importsym hidden_type
+|\tLTYPE hidden_pkg_importsym hidden_type
{
importtype($2, $3);
}
-|\tLFUNC hidden_importsym '(' ohidden_funarg_list ')' ohidden_funres
+|\tLFUNC hidden_pkg_importsym '(' ohidden_funarg_list ')' ohidden_funres
{
importvar($2, functype(N, $4, $6));
}
@@ -1920,6 +1920,14 @@ hidden_importsym:
$$->sym = $3;
}
+hidden_pkg_importsym:
+\thidden_importsym
+\t{
+\t\t$$ = $1;
+\t\tpkgcontext = $$->psym->name;
+\t}\n
+\n
/*
* helpful error messages.
* THIS SECTION MUST BE AT THE END OF THE FILE.
コアとなるコードの解説
src/cmd/gc/dcl.c
の変更
- f->sym = pkglookup(f->sym->name, pkgimportname->name);
+ f->sym = pkglookup(f->sym->name, pkgcontext);
この変更は、シンボルf->sym
をルックアップする際に、これまでのpkgimportname->name
(インポートされたパッケージの名前)の代わりに、新しく導入されたグローバル変数pkgcontext
を使用するように修正しています。pkglookup
関数は、指定された名前とパッケージコンテキストに基づいてシンボルテーブルからシンボルを検索します。この変更により、シンボル解決の際に、より正確なパッケージのコンテキスト情報が利用されるようになります。
src/cmd/gc/go.h
の変更
+EXTERN char* pkgcontext;
go.h
にpkgcontext
というchar*
型のグローバル変数が追加されました。EXTERN
キーワードは、この変数が他のファイルで定義されていることを示し、このファイルでは宣言のみを行うことを意味します。これにより、コンパイラの複数の部分でpkgcontext
が共有され、現在のパッケージコンテキストを追跡できるようになります。
src/cmd/gc/go.y
の変更
-
型定義の追加:
-%type <node> hidden_funres ohidden_funres hidden_importsym +%type <node> hidden_funres ohidden_funres hidden_importsym hidden_pkg_importsym
Yaccの型定義に
hidden_pkg_importsym
が追加されました。これは、パーサーがhidden_pkg_importsym
という新しい種類のノードを扱うことを可能にします。 -
hidden_import
ルールの変更:-|\tLVAR hidden_importsym hidden_type +|\tLVAR hidden_pkg_importsym hidden_type // ... (同様の変更がLCONST, LTYPE, LFUNCにも適用)
hidden_import
ルール内で、LVAR
(変数)、LCONST
(定数)、LTYPE
(型)、LFUNC
(関数)といったインポートされた要素のシンボルを解析する際に、これまでのhidden_importsym
の代わりにhidden_pkg_importsym
を使用するように変更されました。これは、インポートされたシンボルを解析する際に、そのシンボルが属するパッケージのコンテキストをより明示的に取得するための準備です。 -
hidden_pkg_importsym
ルールの追加:+hidden_pkg_importsym: +\thidden_importsym +\t{ +\t\t$$ = $1; +\t\tpkgcontext = $$->psym->name; +\t}\n
この新しいルールは、まず
hidden_importsym
を解析します。その後、アクションブロック内で、解析されたシンボルノード($1
)を現在のノード($$
)に代入し、さらにそのシンボルが持つパッケージシンボル(psym
)の名前をグローバル変数pkgcontext
に設定しています。これにより、パーサーがインポートされたシンボルを認識した時点で、そのシンボルが属するパッケージの名前がpkgcontext
に格納され、後続のシンボル解決処理で利用できるようになります。
これらの変更は全体として、Goコンパイラがインポートされたシンボルを処理する際に、より正確で堅牢なパッケージコンテキスト情報を利用できるようにするためのものです。これにより、シンボル解決の曖昧さが解消され、コンパイラの正確性が向上したと考えられます。
関連リンク
- Go言語の公式ドキュメント: https://go.dev/
- Goのソースコードリポジトリ: https://go.googlesource.com/go
参考にした情報源リンク
- Web検索結果: "Go bug133 golang"
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFApsu6dtx2K9aQ7oIBThMU5N4tmkit1rpb8ZmZjqvN1kytdIFv7_cBuztRo0932CLq3fnsqjQVbMI4P5vT4fPZ2C_jnPjrYF9-wUIjUPb0fEJp1wPjppCOkXvmTnZyyfedCIdDjjKZlNEy80EjvMK3NClBuWuLwo_GfX2Q2jFm61TyeNRJtxY=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEFpYpvQyrwiFO0hzPQFqdu-yzaSsX56Z8bBmNMKcGfXqnNDm9D5EvbpWHH6SihU5ErOMzG9sjXJWoXEXqs9oCq-qs5a1BEvMJ63fW8rxWog7UAkE88NIyaWdMXkcM3NgL-aUgo
- コミット情報:
/home/orange/Project/comemo/commit_data/1562.txt
- GitHubコミットページ: https://github.com/golang/go/commit/4efad58d0a0a6d96d83ccfa39e27308c85be96a9