[インデックス 15370] ファイルの概要
このコミットは、Go言語の実験的なSSA (Static Single Assignment) インタープリタ (exp/ssa/interp
) において、Plan 9オペレーティングシステム向けのビルド問題を修正するものです。具体的には、Plan 9環境でのsyscall.Kill
関数の未実装とsyscall.Write
関数のエミュレーションに関する変更が含まれています。
コミット
commit edc3126e98d5624d6f2a7d47991db0ba5b2b07d3
Author: Anthony Martin <ality@pbrane.org>
Date: Thu Feb 21 20:06:26 2013 -0800
exp/ssa/interp: fix build for Plan 9
R=adonovan, minux.ma, alex.brainman, akumar, rminnich
CC=golang-dev, lucio.dere
https://golang.org/cl/7300078
---
src/pkg/exp/ssa/interp/external_plan9.go | 26 ++++++++++++++++++++++++++
src/pkg/exp/ssa/interp/external_unix.go | 1 -
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/src/pkg/exp/ssa/interp/external_plan9.go b/src/pkg/exp/ssa/interp/external_plan9.go
new file mode 100644
index 0000000000..5f17cacda6
--- /dev/null
+++ b/src/pkg/exp/ssa/interp/external_plan9.go
@@ -0,0 +1,26 @@
+// Copyright 2013 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 interp
+
+import (
+ "exp/ssa"
+ "syscall"
+)
+
+func ext۰syscall۰Kill(fn *ssa.Function, args []value) value {
+ panic("syscall.Kill not yet implemented")
+}
+
+func ext۰syscall۰Write(fn *ssa.Function, args []value) value {
+ // We could emulate syscall.Syscall but it's more effort.
+ p := args[1].([]value)
+ b := make([]byte, 0, len(p))
+ for i := range p {
+ b = append(b, p[i].(byte))
+ }
+ n, _ := syscall.Write(args[0].(int), b)
+ err := iface{} // TODO(adonovan): fix: adapt concrete err to interpreted iface.
+ return tuple{n, err}
+}
diff --git a/src/pkg/exp/ssa/interp/external_unix.go b/src/pkg/exp/ssa/interp/external_unix.go
index e021ff7214..afc874535f 100644
--- a/src/pkg/exp/ssa/interp/external_unix.go
+++ b/src/pkg/exp/ssa/interp/external_unix.go
@@ -28,5 +28,4 @@ func ext۰syscall۰Write(fn *ssa.Function, args []value) value {
n, _ := syscall.Write(args[0].(int), b)
err := iface{} // TODO(adonovan): fix: adapt concrete err to interpreted iface.
return tuple{n, err}
-\n }
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/edc3126e98d5624d6f2a7d47991db0ba5b2b07d3
元コミット内容
exp/ssa/interp: fix build for Plan 9
このコミットは、Go言語の実験的なSSA (Static Single Assignment) インタープリタのビルドがPlan 9オペレーティングシステムで失敗する問題を修正します。
変更の背景
Go言語はクロスプラットフォーム対応を重視しており、様々なオペレーティングシステムで動作するように設計されています。Plan 9は、ベル研究所で開発された分散オペレーティングシステムであり、Go言語の開発者の一部がPlan 9の設計思想に影響を受けていることでも知られています。
exp/ssa/interp
は、Goコンパイラのバックエンドで利用されるSSA形式のコードを解釈・実行するための実験的なインタープリタです。これは、コンパイラの最適化パスのデバッグや、SSA形式のコードの動作検証などに利用されます。
このコミットが作成された2013年2月時点では、Go言語のSSAインタープリタはまだ開発途上にあり、特定のプラットフォーム(この場合はPlan 9)での互換性問題が発生していました。特に、システムコールのようなOS固有の機能の扱いが課題となっていました。syscall.Kill
やsyscall.Write
といったシステムコールは、OSによって実装が異なるため、SSAインタープリタがこれらの関数を正しくエミュレートまたは処理できるようにする必要がありました。
このコミットは、Plan 9環境でSSAインタープリタがビルドエラーを起こす、または正しく動作しない問題を解決するために導入されました。これは、Go言語がサポートするプラットフォームの範囲を広げ、開発者がPlan 9環境でもSSAインタープリタを利用できるようにするための重要なステップでした。
前提知識の解説
Go言語 (Golang)
GoはGoogleによって開発されたオープンソースのプログラミング言語です。静的型付け、コンパイル型言語でありながら、動的型付け言語のような簡潔さを持ち、並行処理に優れています。システムプログラミング、Webサービス、ネットワークプログラミングなどで広く利用されています。
SSA (Static Single Assignment) 形式
SSA形式は、コンパイラの最適化において中間表現として用いられるプログラムの表現形式の一つです。SSA形式では、各変数が一度だけ代入されるという特性を持ちます。これにより、データフロー解析や最適化が容易になります。
例えば、以下のコードを考えます。
x = a + b
y = x + c
x = y + d
これをSSA形式に変換すると、以下のようになります。
x1 = a + b
y1 = x1 + c
x2 = y1 + d
このように、変数の各定義に新しい名前(バージョン)を割り当てることで、変数の値がどこで定義され、どこで使われているかが明確になります。Goコンパイラも内部でSSA形式を利用してコードの最適化を行っています。
インタープリタ (interp
)
インタープリタは、プログラムのソースコードや中間コードを直接解釈し、実行するソフトウェアです。コンパイラがソースコードを機械語に変換して実行するのに対し、インタープリタは逐次的にコードを読み込み、その場で実行します。exp/ssa/interp
は、Goコンパイラが生成するSSA形式のコードを解釈・実行するためのインタープリタです。
Plan 9 from Bell Labs
Plan 9は、ベル研究所で開発された分散オペレーティングシステムです。Unixの設計思想をさらに推し進め、すべてのリソース(ファイル、デバイス、ネットワーク接続など)をファイルとして扱うという「すべてはファイルである」という原則を徹底しています。また、UTF-8をネイティブにサポートし、ネットワーク透過性を重視しています。Go言語の開発者の一部はPlan 9の開発にも携わっており、Go言語の設計にもPlan 9の思想が影響を与えていると言われています。
システムコール (syscall
)
システムコールは、オペレーティングシステムが提供するサービスをプログラムが利用するためのインターフェースです。ファイルI/O、プロセス管理、メモリ管理、ネットワーク通信など、OSのカーネルが提供する低レベルな機能にアクセスするために使用されます。Go言語のsyscall
パッケージは、これらのシステムコールをGoプログラムから呼び出すための機能を提供します。OSによって利用できるシステムコールやその引数、戻り値の形式が異なるため、クロスプラットフォーム対応においては、各OSのシステムコールを適切に抽象化またはエミュレートする必要があります。
技術的詳細
このコミットは、Go言語のSSAインタープリタがPlan 9環境でシステムコールを扱う方法を改善しています。
Go言語のSSAインタープリタは、GoプログラムのSSA形式のコードを解釈して実行します。この際、Goプログラムがsyscall
パッケージを介してシステムコールを呼び出す場合、インタープリタはそのシステムコールをエミュレートするか、ホストOSの実際のシステムコールを呼び出す必要があります。
既存のexternal_unix.go
ファイルは、Unix系システム(Linux, macOSなど)向けのシステムコールエミュレーションを提供していました。しかし、Plan 9はUnixとは異なるシステムコールインターフェースを持つため、external_unix.go
のコードをそのまま利用することはできませんでした。
このコミットでは、external_plan9.go
という新しいファイルが追加され、Plan 9固有のシステムコールエミュレーションが実装されています。
具体的には、以下の2つのシステムコールに焦点を当てています。
syscall.Kill
: プロセスにシグナルを送信するシステムコールです。Plan 9ではUnixとは異なるシグナル処理メカニズムを持つため、この時点ではpanic("syscall.Kill not yet implemented")
として、未実装であることを明示しています。これは、Plan 9環境でsyscall.Kill
が呼び出された場合に、インタープリタが予期せぬ動作をするのを防ぐための暫定的な措置です。syscall.Write
: ファイルディスクリプタにデータを書き込むシステムコールです。external_unix.go
にも同様の処理がありましたが、Plan 9向けに独立した実装が提供されています。この実装では、インタープリタのvalue
型で表現されたバイトスライスを、実際の[]byte
に変換し、syscall.Write
を呼び出しています。
syscall.Write
の実装では、args[1].([]value)
でインタープリタのvalue
型のスライスを取得し、それをGoのネイティブな[]byte
スライスに変換しています。これは、インタープリタ内部のデータ表現と、実際のシステムコールが期待するデータ表現との間の変換処理です。
また、err := iface{} // TODO(adonovan): fix: adapt concrete err to interpreted iface.
というコメントがあります。これは、syscall.Write
が返すエラー値を、インタープリタが理解できるiface{}
型(インターフェース型)に適切に変換する必要があることを示しています。この時点ではまだ完全なエラーハンドリングが実装されておらず、今後の課題として残されています。
この変更により、Plan 9環境でSSAインタープリタをビルドし、基本的なsyscall.Write
を使用するプログラムを実行できるようになります。
コアとなるコードの変更箇所
新規ファイル: src/pkg/exp/ssa/interp/external_plan9.go
このファイルが新規に追加されました。
// Copyright 2013 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 interp
import (
"exp/ssa"
"syscall"
)
func ext۰syscall۰Kill(fn *ssa.Function, args []value) value {
panic("syscall.Kill not yet implemented")
}
func ext۰syscall۰Write(fn *ssa.Function, args []value) value {
// We could emulate syscall.Syscall but it's more effort.
p := args[1].([]value)
b := make([]byte, 0, len(p))
for i := range p {
b = append(b, p[i].(byte))
}
n, _ := syscall.Write(args[0].(int), b)
err := iface{} // TODO(adonovan): fix: adapt concrete err to interpreted iface.
return tuple{n, err}
}
変更ファイル: src/pkg/exp/ssa/interp/external_unix.go
syscall.Write
関数の末尾の空行が削除されました。これは、external_plan9.go
が追加されたことによるコードの整理の一環と考えられます。
--- a/src/pkg/exp/ssa/interp/external_unix.go
+++ b/src/pkg/exp/ssa/interp/external_unix.go
@@ -28,5 +28,4 @@ func ext۰syscall۰Write(fn *ssa.Function, args []value) value {
n, _ := syscall.Write(args[0].(int), b)
err := iface{} // TODO(adonovan): fix: adapt concrete err to interpreted iface.
return tuple{n, err}
-\n }
コアとなるコードの解説
src/pkg/exp/ssa/interp/external_plan9.go
このファイルは、GoのSSAインタープリタがPlan 9環境で外部のシステムコールをどのように扱うかを定義しています。Goのビルドシステムでは、ファイル名に_plan9.go
のようなサフィックスを付けることで、特定のOS向けにコンパイルされるファイルを指定できます。
package interp
: このファイルがinterp
パッケージの一部であることを示します。import ("exp/ssa", "syscall")
:exp/ssa
パッケージはSSA形式の関数や値を扱うために、syscall
パッケージは実際のシステムコールを呼び出すためにインポートされています。func ext۰syscall۰Kill(fn *ssa.Function, args []value) value
:- この関数は、SSAインタープリタが
syscall.Kill
関数を呼び出そうとしたときに実行されます。 panic("syscall.Kill not yet implemented")
という行は、Plan 9環境でのsyscall.Kill
の実装がまだ完了していないことを示しています。これにより、未実装の機能が呼び出された場合に、明確なエラーメッセージとともにプログラムが終了します。これは、開発中のソフトウェアでよく見られる暫定的なエラーハンドリングです。
- この関数は、SSAインタープリタが
func ext۰syscall۰Write(fn *ssa.Function, args []value) value
:- この関数は、SSAインタープリタが
syscall.Write
関数を呼び出そうとしたときに実行されます。 p := args[1].([]value)
:syscall.Write
の第2引数(書き込むデータ)は、インタープリタ内部では[]value
(value
型のスライス)として渡されます。これをp
に代入しています。b := make([]byte, 0, len(p))
とfor i := range p { b = append(b, p[i].(byte)) }
: インタープリタのvalue
型のスライスp
を、Goのネイティブなバイトスライス[]byte
に変換しています。これは、syscall.Write
がネイティブなバイトスライスを期待するためです。n, _ := syscall.Write(args[0].(int), b)
: 実際のPlan 9のsyscall.Write
を呼び出しています。args[0].(int)
はファイルディスクリプタ(第1引数)を、b
は変換されたバイトスライス(第2引数)を渡しています。戻り値のうち、書き込まれたバイト数n
のみを受け取り、エラーは一時的に無視しています(_
)。err := iface{} // TODO(adonovan): fix: adapt concrete err to interpreted iface.
: ここは重要なTODOコメントです。syscall.Write
がエラーを返した場合、そのエラーをSSAインタープリタが理解できるiface{}
型(インターフェース型)に変換して返す必要があります。この時点ではその変換ロジックが未実装であり、今後の課題として残されています。return tuple{n, err}
: 書き込まれたバイト数n
と、未実装のエラー値err
をtuple
型で返しています。tuple
はSSAインタープリタ内部で複数の戻り値を表現するための型です。
- この関数は、SSAインタープリタが
src/pkg/exp/ssa/interp/external_unix.go
このファイルは、Unix系システム向けのシステムコールエミュレーションを提供します。このコミットでは、syscall.Write
関数の定義の末尾にあった不要な空行が削除されています。これは機能的な変更ではなく、コードの整形やクリーンアップの一環です。
関連リンク
- Go言語の公式ウェブサイト: https://golang.org/
- Go言語のSSAパッケージに関するドキュメント (GoDoc): https://pkg.go.dev/golang.org/x/tools/go/ssa (現在のパッケージパスは変更されていますが、概念は同じです)
- Plan 9 from Bell Labs: https://9p.io/plan9/
- Go言語の
syscall
パッケージに関するドキュメント (GoDoc): https://pkg.go.dev/syscall
参考にした情報源リンク
- Go言語のコミット履歴 (GitHub): https://github.com/golang/go/commits/master
- Go言語のコードレビューシステム (Gerrit): https://go-review.googlesource.com/ (コミットメッセージにある
https://golang.org/cl/7300078
は、このGerritの変更リストへのリンクです) - SSA形式に関するWikipedia記事: https://ja.wikipedia.org/wiki/SSA%E5%BD%A2%E5%BC%8F
- Plan 9に関するWikipedia記事: https://ja.wikipedia.org/wiki/Plan_9_from_Bell_Labs
- Go言語のビルドタグに関するドキュメント: https://go.dev/cmd/go/#hdr-Build_constraints (ファイル名によるOS固有のビルドに関する情報)