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

[インデックス 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.Killsyscall.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つのシステムコールに焦点を当てています。

  1. syscall.Kill: プロセスにシグナルを送信するシステムコールです。Plan 9ではUnixとは異なるシグナル処理メカニズムを持つため、この時点ではpanic("syscall.Kill not yet implemented")として、未実装であることを明示しています。これは、Plan 9環境でsyscall.Killが呼び出された場合に、インタープリタが予期せぬ動作をするのを防ぐための暫定的な措置です。
  2. 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の実装がまだ完了していないことを示しています。これにより、未実装の機能が呼び出された場合に、明確なエラーメッセージとともにプログラムが終了します。これは、開発中のソフトウェアでよく見られる暫定的なエラーハンドリングです。
  • func ext۰syscall۰Write(fn *ssa.Function, args []value) value:
    • この関数は、SSAインタープリタがsyscall.Write関数を呼び出そうとしたときに実行されます。
    • p := args[1].([]value): syscall.Writeの第2引数(書き込むデータ)は、インタープリタ内部では[]valuevalue型のスライス)として渡されます。これを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と、未実装のエラー値errtuple型で返しています。tupleはSSAインタープリタ内部で複数の戻り値を表現するための型です。

src/pkg/exp/ssa/interp/external_unix.go

このファイルは、Unix系システム向けのシステムコールエミュレーションを提供します。このコミットでは、syscall.Write関数の定義の末尾にあった不要な空行が削除されています。これは機能的な変更ではなく、コードの整形やクリーンアップの一環です。

関連リンク

参考にした情報源リンク