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

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

このコミットは、Go言語の実験的なSSA(Static Single Assignment)パッケージ exp/ssa における複数のバグ修正と機能改善を目的としています。特に、SSAダンプツール (ssadump) の使いやすさの向上、SSAビルダーのバグ修正、そしてSSAインタープリタ (interp) の外部関数サポートの拡充に焦点を当てています。これにより、exp/ssa パッケージ全体の安定性と実用性が向上し、最終的には ssadump 自身をSSAインタープリタで実行できるようになるという、自己参照的なマイルストーンを達成しています。

コミット

commit 1c5e079600a820bdb9a61d1813ab2a342cc70ce9
Author: Alan Donovan <adonovan@google.com>
Date:   Wed Feb 27 16:43:16 2013 -0500

    exp/ssa: a number of bug fixes.
    
    ssadump:
    - permit naming a package (not just *.go files) on command line.
    - set BuildSerially flag when setting Log* flags
      (Q. should instead the logging functions take a lock?)
    
    Builder:
    - fixed bug when calling variadic function with zero '...'-params.
      Added regression test.
    
    interp:
    - more external functions:
       the 'error' interface
       bytes.{Equal,IndexByte}
       reflect.(Value).{Bool,NumOut,Out}
       syscall.{Close,Fstat,Read,Open,Stat,Lstat,Fstat,
         Getdents,ParseDirents,Getwd}
    - permit comparisons between *Function and *closure.
    
    With this CL, ssadump can now interpret ssadump itself (!),
    loading, parsing, typing, SSA-building, and running
    println("Hello, World!").  While a fmt-based equivalent still
    lacks some external routines, e.g. math/big, I think there are
    diminishing returns in expanding the interpreter (and
    debugging it is starting to feel like "Inception").
    
    I'm pretty confident this package is now good enough for wider use.
    
    R=gri
    CC=golang-dev
    https://golang.org/cl/7392053

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

https://github.com/golang/go/commit/1c5e079600a820bdb9a61d1813ab2a342cc70ce9

元コミット内容

このコミットは、Go言語の exp/ssa パッケージに対する複数のバグ修正と機能拡張を含んでいます。主な内容は以下の通りです。

  • ssadump の改善:
    • コマンドラインで .go ファイルだけでなく、パッケージ名を指定してSSAダンプを実行できるようになりました。
    • ログ関連のフラグ (LogPackages, LogFunctions, LogSource) が設定された際に、BuildSerially フラグも自動的に設定されるようになりました。これは、並行ビルド中にログ出力が混在するのを防ぐための措置と考えられます。
  • Builder のバグ修正:
    • 可変長引数関数 (variadic function) を、可変長引数部分にゼロ個の引数(つまり空のスライス)で呼び出した際のバグが修正されました。これに対する回帰テストも追加されています。
  • interp (SSAインタープリタ) の機能拡張:
    • より多くの外部関数がインタープリタでサポートされるようになりました。これには、error インターフェース、bytes.Equalbytes.IndexBytereflect.ValueBool, NumOut, Out メソッド、そして syscall パッケージの様々な関数(Close, Fstat, Read, Open, Stat, Lstat, Getdents, ParseDirents, Getwd)が含まれます。
    • *ssa.Function*closure の比較が許可されるようになりました。
  • 自己解釈能力の達成: このコミットにより、ssadump ツール自体をSSAインタープリタで実行できるようになりました。これは、SSAインタープリタがGoプログラムのロード、パース、型チェック、SSA構築、そして実行という一連のプロセスを十分にエミュレートできるようになったことを示しています。

コミットメッセージでは、インタープリタの拡張には「収穫逓減の法則」が働き始めている(これ以上の拡張は効率が悪い)と述べられており、現在のパッケージが「より広範な用途に十分対応できる」という自信が示されています。

変更の背景

この変更の背景には、Go言語のコンパイラとツールチェーンの進化があります。exp/ssa パッケージは、GoプログラムのSSA形式(静的単一割り当て形式)表現を生成・操作するための実験的なライブラリです。SSA形式は、コンパイラの最適化や静的解析において非常に重要な中間表現であり、プログラムのデータフローを明確にする利点があります。

このコミットが行われた2013年当時、GoコンパイラはまだSSA形式を本格的に採用していませんでした。exp/ssa は、将来のコンパイラバックエンドや高度なツール開発のための基盤を構築する目的で開発が進められていました。

  • ssadump の改善: ssadump は、GoプログラムのSSA表現をダンプ(表示)するためのツールです。初期のバージョンでは、個々の .go ファイルしか扱えませんでしたが、実際のGoプロジェクトは複数のファイルからなるパッケージで構成されます。そのため、パッケージ全体を対象にSSAダンプを行えるようにすることは、ツールの実用性を高める上で不可欠でした。また、ログ出力時の BuildSerially フラグの設定は、並行処理によるログの乱れを防ぎ、デバッグのしやすさを向上させるための品質改善です。
  • Builder のバグ修正: SSA形式を構築する Builder は、Go言語の複雑なセマンティクス(特に可変長引数関数のような機能)を正確にSSAに変換する必要があります。可変長引数関数を空のスライスで呼び出すというエッジケースでのバグは、SSA構築の正確性を保証するために修正が必要でした。
  • interp の機能拡張: interp は、SSA形式のGoプログラムを直接実行できるインタープリタです。これは、コンパイラを介さずにSSA形式の動作を検証したり、SSAベースの静的解析ツールを開発したりする上で非常に有用です。しかし、Goプログラムは標準ライブラリの多くの関数に依存しており、インタープリタがこれらの外部関数をエミュレートできなければ、実用的なプログラムを実行することはできませんでした。特に、error インターフェース、bytes パッケージの基本的な操作、reflect パッケージの型情報取得、そして syscall パッケージのファイルI/Oやプロセス操作といった低レベルな機能のサポートは、より複雑なGoプログラムをインタープリタで実行するために不可欠でした。ssadump 自身をインタープリタで実行できるようになったことは、interp の機能がGoの基本的なプログラムを実行するのに十分なレベルに達したことを示す重要なマイルストーンでした。

これらの変更は、exp/ssa パッケージをより堅牢で実用的なものにし、Go言語のコンパイラ技術の将来的な発展に貢献するための重要なステップでした。

前提知識の解説

このコミット内容を理解するためには、以下の概念について基本的な知識があると役立ちます。

  1. SSA (Static Single Assignment) 形式:
    • コンパイラの中間表現の一種で、各変数が一度だけ代入されるようにプログラムを変換します。
    • これにより、データフロー解析や最適化が容易になります。例えば、x = a + b; y = x * 2; x = c + d; z = x / 3; というコードは、SSA形式では x1 = a + b; y = x1 * 2; x2 = c + d; z = x2 / 3; のように変換され、各 x の使用がどの定義に対応するかが明確になります。
    • Go言語のコンパイラは、現在SSA形式を内部的に使用して最適化を行っています。
  2. Go言語の exp/ssa パッケージ:
    • Go言語のプログラムをSSA形式に変換し、そのSSAグラフを操作するための実験的なライブラリです。
    • このパッケージは、Goコンパイラの将来のバックエンドや、静的解析ツール、デバッガなどの開発のために設計されました。
  3. ssadump ツール:
    • exp/ssa パッケージに含まれるコマンドラインツールで、GoプログラムのSSA形式をテキスト形式で出力します。
    • コンパイラ開発者やツール開発者が、プログラムのSSA表現を視覚的に確認するために使用します。
  4. SSAインタープリタ (interp):
    • exp/ssa パッケージの一部として開発された、SSA形式のGoプログラムを直接実行できるインタープリタです。
    • 実際のGoコンパイラでコンパイルして実行する代わりに、SSA形式のプログラムをステップ実行したり、デバッグしたり、SSAベースの解析ツールの動作を検証したりするために使用されます。
    • インタープリタは、Goの組み込み関数や標準ライブラリの関数(外部関数)の動作をエミュレートする必要があります。
  5. 可変長引数関数 (Variadic Functions):
    • Go言語の関数で、最後の引数に ... を付けることで、任意の数の引数を受け取ることができます(例: func sum(nums ...int) int)。
    • 関数内部では、可変長引数はスライスとして扱われます。
    • このコミットでは、可変長引数部分に引数が一つも渡されない(つまり空のスライスが渡される)ケースでのバグが修正されました。
  6. reflect パッケージ:
    • Go言語の実行時リフレクション機能を提供するパッケージです。
    • プログラムの実行中に、変数や型の情報を動的に検査・操作することができます。
    • インタープリタがGoプログラムを正確にエミュレートするためには、reflect パッケージの基本的な機能もサポートする必要があります。
  7. syscall パッケージ:
    • オペレーティングシステムのシステムコールにアクセスするためのパッケージです。
    • ファイルI/O、プロセス管理、ネットワーク通信など、低レベルな操作を行うために使用されます。
    • インタープリタがファイルシステムやプロセスとやり取りするGoプログラムを実行するためには、syscall パッケージの主要な関数をエミュレートする必要があります。

技術的詳細

このコミットは、exp/ssa パッケージの主要なコンポーネントである ssadumpBuilderinterp に対して、それぞれ異なる技術的アプローチで改善を加えています。

ssadump の改善

  • パッケージ名のサポート: 以前は ssadump main.go other.go のように個々のGoファイルを指定する必要がありましたが、この変更により ssadump my/package のようにGoのインポートパス形式でパッケージを指定できるようになりました。これは、ssa.GorootLoader を利用してパッケージのソースファイルをロードすることで実現されています。これにより、ユーザーはより自然な形でGoのパッケージ構造を扱えるようになり、ツールの利便性が向上しました。
  • BuildSerially フラグの自動設定: ssadump がSSAグラフを構築する際に、LogPackages, LogFunctions, LogSource といった詳細なログ出力フラグが有効になっている場合、ssa.BuildSerially フラグも自動的に設定されるようになりました。BuildSerially は、SSA構築プロセスを直列に実行することを強制するフラグです。SSA構築は複雑なプロセスであり、特にデバッグや詳細なログ出力が必要な場合には、並行処理によるログの混在やデバッグの困難さを避けるために直列実行が望ましい場合があります。この自動設定は、ユーザーが明示的に BuildSerially を指定しなくても、ログ出力の整合性を保つための配慮です。

Builder のバグ修正

  • 可変長引数関数のゼロ引数呼び出しの修正: src/pkg/exp/ssa/builder.gosetCall 関数において、可変長引数関数が呼び出される際の引数処理ロジックが修正されました。
    • 元のコードでは、可変長引数関数 (typ.IsVariadic) でありながら、可変長引数部分に引数が一つも渡されない(つまり len(args) > np-1 が偽となる)場合に、可変長引数スライス (varargs) が正しく初期化されない可能性がありました。
    • 修正後、if typ.IsVariadic の条件のみで可変長引数スライスを準備するようになり、引数がゼロ個の場合でも varargs が空のスライスとして適切に扱われるようになりました。
    • また、if len(varargs) > 0 の条件が if vt != nil に変更されました。vt は可変長引数の要素型を表す変数であり、可変長引数関数であれば vt は常に nil ではないため、これにより可変長引数スライスの処理がより堅牢になりました。この修正により、fmt.Sprint() のような引数なしの可変長引数関数の呼び出しが正しくSSAに変換されるようになりました。

interp (SSAインタープリタ) の機能拡張

  • 外部関数のエミュレーション: src/pkg/exp/ssa/interp/external.goexternal_plan9.goexternal_unix.goexternal_windows.go にて、Goの標準ライブラリ関数をSSAインタープリタでエミュレートするためのコードが追加されました。
    • インタープリタは、Goプログラムが外部の関数(例えば fmt.Printlnos.Exit など)を呼び出す際に、その実際の動作を模倣する必要があります。これは、GoのソースコードをSSAに変換して実行するだけでは、これらの外部関数がSSAグラフ内に存在しないためです。
    • 追加された関数には、error インターフェースの Error() メソッド、bytes.Equalbytes.IndexBytereflect.ValueBool, NumOut, Out メソッド、そして syscall パッケージのファイルI/Oやプロセス関連の関数が含まれます。
    • 特に syscall パッケージの関数は、OS固有の実装 (external_unix.go, external_plan9.go, external_windows.go) が必要であり、それぞれのOSでシステムコールを模倣するロジックが追加されています。例えば、ext۰syscall۰Read は実際の syscall.Read を呼び出し、その結果をインタープリタの value 型に変換して返します。
    • wrapError ヘルパー関数が導入され、Goの error 型をインタープリタの iface (インターフェース値) に変換する処理が統一されました。
  • *Function*closure の比較許可: src/pkg/exp/ssa/interp/value.goequals 関数において、*ssa.Function*closure 型の比較が許可されるようになりました。これは、関数値やクロージャがSSAインタープリタ内で正しく比較できるようにするための変更です。Go言語では関数は第一級オブジェクトであり、比較可能であるため、インタープリタもそのセマンティクスを模倣する必要があります。
  • reflect.error 型の導入: src/pkg/exp/ssa/interp/reflect.goerrorType という新しい名前付き型が導入されました。これは、インタープリタが生成する組み込みの error インターフェースの実装に使用されます。これにより、インタープリタ内で error インターフェースがより正確に扱えるようになりました。また、interpreter 構造体に errorMethods が追加され、errorType のメソッドセットを管理するようになりました。

これらの技術的詳細は、SSAインタープリタがより多くのGoプログラムを正確に実行できるようにするための、地道ながらも重要な改善を示しています。特に、syscallreflect のような低レベルな機能のエミュレーションは、インタープリタの実用性を大きく向上させます。

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

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

  1. src/pkg/exp/ssa/builder.go:
    • 可変長引数関数の呼び出しに関するバグ修正。特に、引数がゼロ個の場合の処理が改善されました。
  2. src/pkg/exp/ssa/interp/external.go:
    • SSAインタープリタがエミュレートする外部関数のマッピング (externals マップ) に、reflect.Valueerror インターフェース、bytessyscall パッケージの関数が多数追加されました。
    • bytes.Equalbytes.IndexByte のエミュレーション関数が追加されました。
    • wrapError ヘルパー関数が追加され、Goのエラーをインタープリタのエラーインターフェース値に変換する処理が共通化されました。
  3. src/pkg/exp/ssa/interp/external_plan9.go:
    • Plan 9 環境向けの syscall パッケージ関数のエミュレーションが追加されました。多くの関数はまだ panic を発生させるスタブですが、syscall.Write は実装されています。
  4. src/pkg/exp/ssa/interp/external_unix.go:
    • Unix系環境向けの syscall パッケージ関数のエミュレーションが大幅に拡充されました。syscall.Close, syscall.Fstat, syscall.Getdents, syscall.Kill, syscall.Lstat, syscall.Open, syscall.ParseDirent, syscall.Read, syscall.Stat, syscall.Write など、多くのファイルI/Oおよびシステムコール関連の関数が実装されました。
    • valueToBytesfillStat といったヘルパー関数が追加され、インタープリタの内部表現と実際のGoの型との変換を助けています。
  5. src/pkg/exp/ssa/interp/external_windows.go:
    • Windows環境向けの syscall パッケージ関数のエミュレーションが追加されました。Plan 9 と同様に、多くの関数はまだスタブです。
  6. src/pkg/exp/ssa/interp/interp.go:
    • インタープリタの interpreter 構造体に errorMethods フィールドが追加され、error インターフェースのメソッドセットを管理するようになりました。
    • findMethodSet 関数が errorType のメソッドセットも返すように修正されました。
    • Defer 命令の処理において、instr.Pos をローカル変数にコピーする修正が行われました。これは、クロージャ内で instr.Pos が正しくキャプチャされるようにするためのものです。
  7. src/pkg/exp/ssa/interp/reflect.go:
    • errorType という新しい名前付き型が定義され、インタープリタが生成する error インターフェースの実装に使用されます。
    • reflect.rtypeNumOutOut メソッドのエミュレーション関数が追加されました。
    • reflect.ValueBool メソッドのエミュレーション関数が追加されました。
    • reflect.errorError メソッドのエミュレーション関数が追加されました。
    • initReflect 関数で、errorType のメソッドセットが初期化されるようになりました。
  8. src/pkg/exp/ssa/interp/testdata/coverage.go:
    • 可変長引数関数を空のスライスで呼び出すケースの回帰テストが追加されました。
  9. src/pkg/exp/ssa/interp/value.go:
    • equals 関数において、*ssa.Function*closure 型の比較が許可されるように修正されました。
  10. src/pkg/exp/ssa/ssadump.go:
    • ssadump コマンドの Usage メッセージが更新され、パッケージ名での指定が可能になったことが示されました。
    • コマンドライン引数のパースロジックが変更され、.go ファイルのリストだけでなく、インポートパス形式のパッケージ名も受け入れられるようになりました。
    • ログ関連のフラグ (-P, -F, -S) が設定された際に、ssa.BuildSerially フラグも設定されるようになりました。

コアとなるコードの解説

src/pkg/exp/ssa/builder.go の変更

 // Old code
-				if typ.IsVariadic && len(args) > np-1 {
+				if typ.IsVariadic {
 					// case 2: ordinary call of variadic function.
 					vt = typ.Params[np-1].Type
 					args, varargs = args[:np-1], args[np-1:]
@@ -1216,7 +1216,7 @@ func (b *Builder) setCall(fn *Function, e *ast.CallExpr, c *CallCommon) {
 	}
 
 	// Common code for varargs.
-	if len(varargs) > 0 { // case 2
+	if vt != nil { // case 2
 		at := &types.Array{
 			Elt: vt,
 			Len: int64(len(varargs)),

この変更は、Goの可変長引数関数 (...T) の呼び出しをSSA形式に変換する際のバグを修正しています。以前のコードでは、可変長引数部分に引数が一つも渡されない(例えば fmt.Sprint() のように)場合に、len(args) > np-1 の条件が偽となり、可変長引数スライス (varargs) が正しく構築されない可能性がありました。修正後、typ.IsVariadic のみで可変長引数スライスを準備するようになり、引数がゼロ個の場合でも空のスライスとして適切に扱われるようになりました。また、可変長引数スライスの処理をトリガーする条件が len(varargs) > 0 から vt != nil に変更されました。vt は可変長引数の要素型であり、可変長引数関数であれば常に非nilであるため、これによりロジックがより堅牢になりました。

src/pkg/exp/ssa/interp/external.go の変更

 // New external functions added to the map
 var externals = map[string]externalFn{
+	"(reflect.Value).Bool":            ext۰reflect۰Value۰Bool,
 	// ... other reflect.Value methods ...
+	"(reflect.error).Error":           ext۰reflect۰error۰Error,
 	// ... other reflect.rtype methods ...
+	"(reflect.rtype).NumOut":          ext۰reflect۰rtype۰NumOut,
+	"(reflect.rtype).Out":             ext۰reflect۰rtype۰Out,
+	"bytes.Equal":                     ext۰bytes۰Equal,
+	"bytes.IndexByte":                 ext۰bytes۰IndexByte,
 	// ... math functions ...
+	"syscall.Close":                   ext۰syscall۰Close,
 	"syscall.Exit":                    ext۰syscall۰Exit,
+	"syscall.Fstat":                   ext۰syscall۰Fstat,
+	"syscall.Getdents":                ext۰syscall۰Getdents,
 	"syscall.Getpid":                  ext۰syscall۰Getpid,
+	"syscall.Getwd":                   ext۰syscall۰Getwd,
 	"syscall.Kill":                    ext۰syscall۰Kill,
+	"syscall.Lstat":                   ext۰syscall۰Lstat,
+	"syscall.Open":                    ext۰syscall۰Open,
+	"syscall.ParseDirent":             ext۰syscall۰ParseDirent,
+	"syscall.Read":                    ext۰syscall۰Read,
+	"syscall.Stat":                    ext۰syscall۰Stat,
 	"syscall.Write":                   ext۰syscall۰Write,
 	// ... time functions ...
 }

// Helper to wrap Go errors into interpreter's error interface value
func wrapError(err error) value {
	if err == nil {
		return iface{}
	}
	return iface{t: errorType, v: err.Error()}
}

// Example of a new external function implementation
func ext۰bytes۰Equal(fn *ssa.Function, args []value) value {
	// func Equal(a, b []byte) bool
	a := args[0].([]value)
	b := args[1].([]value)
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

このセクションは、SSAインタープリタがGoの標準ライブラリ関数をエミュレートするための externals マップの拡張と、新しいエミュレーション関数の実装を示しています。特に注目すべきは、wrapError ヘルパー関数の導入です。これにより、Goの error 型をインタープリタの内部表現である iface (インターフェース値) に変換する処理が簡潔かつ統一的に行えるようになりました。bytes.Equal のような関数は、インタープリタの内部でバイトスライスを表現する []value 型を操作し、Goのセマンティクスに従って比較を行います。

src/pkg/exp/ssa/interp/interp.go の変更

 // New field in interpreter struct
 type interpreter struct {
 	// ...
 	reflectPackage *ssa.Package         // the fake reflect package
+	errorMethods   ssa.MethodSet        // the method set of reflect.error, which implements the error interface.
 	rtypeMethods   ssa.MethodSet        // the method set of rtype, which implements the reflect.Type interface.
 }

// findMethodSet now handles errorType
 func findMethodSet(i *interpreter, typ types.Type) ssa.MethodSet {
 	switch typ {
 	case rtypeType:
 		return i.rtypeMethods
+	case errorType:
+		return i.errorMethods
 	}
 	return i.prog.MethodSet(typ)
 }

// Defer instruction fix
 case *ssa.Defer:
+	pos := instr.Pos // TODO(gri): workaround for bug in typeswitch+funclit.
 	fn, args := prepareCall(fr, &instr.CallCommon)
-	fr.defers = append(fr.defers, func() { call(fr.i, fr, instr.Pos, fn, args) })
+	fr.defers = append(fr.defers, func() { call(fr.i, fr, pos, fn, args) })

interpreter 構造体に errorMethods が追加されたことで、インタープリタが error インターフェースのメソッドセットを管理できるようになりました。findMethodSet 関数もこれに対応し、errorType のメソッドセットを返すようになりました。これにより、インタープリタ内で error インターフェースがより正確に扱えるようになります。Defer 命令の修正は、クロージャ内で instr.Pos が正しくキャプチャされるようにするためのもので、デバッグ情報の正確性を保つ上で重要です。

src/pkg/exp/ssa/interp/reflect.go の変更

 // Definition of the new errorType
 // type error string
 var errorType = makeNamedType("error", &types.Basic{Name: "error"})

// New external function for reflect.error.Error
 func ext۰reflect۰error۰Error(fn *ssa.Function, args []value) value {
 	return args[0]
 }

// Initialization of errorMethods
 func initReflect(i *interpreter) {
 	// ...
+	i.errorMethods = ssa.MethodSet{
+		ssa.Id{nil, "Error"}: newMethod(i.reflectPackage, errorType, "Error"),
+	}
 }

errorType の定義は、インタープリタがGoの組み込み error インターフェースを内部的に表現するためのものです。これは、基底型が string の名前付き型として定義されています。ext۰reflect۰error۰Error は、この error インターフェースの Error() メソッドをエミュレートします。initReflect 関数で errorMethods が初期化されることで、インタープリタが error インターフェースのメソッド呼び出しを正しく解決できるようになります。

src/pkg/exp/ssa/ssadump.go の変更

 // Updated Usage message
 const usage = `SSA builder and interpreter.
-Usage: ssadump [<flag> ...] <file.go> ...
+Usage: ssadump [<flag> ...] [<file.go> ...] [<arg> ...]
+       ssadump [<flag> ...] <import/path>   [<arg> ...]`

// Command line argument parsing logic
-	var gofiles []string
-	for len(args) > 0 && strings.HasSuffix(args[0], ".go") {
-		gofiles = append(gofiles, args[0])
-		args = args[1:]
-	}
-	if gofiles == nil {
-		log.Fatal("No *.go source files specified.")
-	}
-
-	// TODO(adonovan): permit naming a package directly instead of
-	// a list of .go files.
-
 	loader := ssa.GorootLoader
 	b := ssa.NewBuilder(mode, loader, errh)

 	var pkgname string
 	var files []*ast.File
 	var err error

 	switch {
 	case len(args) == 0:
 		log.Fatal("No *.go source files nor package name was specified.")

 	case strings.HasSuffix(args[0], ".go"):
 		// % ssadump a.go b.go ...
 		// Leading consecutive *.go arguments constitute main package.
 		i := 1
 		for ; i < len(args) && strings.HasSuffix(args[i], ".go"); i++ {
 		}
 		files, err = ssa.ParseFiles(b.Prog.Files, ".", args[:i]...)
 		pkgname = "main"
 		args = args[i:]

 	default:
 		// % ssadump my/package ...
 		// First argument is import path of main package.
 		pkgname = args[0]
 		args = args[1:]
 		files, err = loader(b.Prog.Files, pkgname)
 	}
 	// ...
 	mainpkg, err := b.CreatePackage(pkgname, files)
 	// ...
 	if *runFlag {
-		interp.Interpret(mainpkg, interpMode, gofiles[0], args)
+		interp.Interpret(mainpkg, interpMode, pkgname, args)
 	}

ssadump のコマンドライン引数処理が大幅に改善されました。以前は .go ファイルのリストのみを受け付けていましたが、この変更により、Goのインポートパス形式でパッケージ名を指定できるようになりました。これは switch ステートメントで実装されており、最初の引数が .go で終わるかどうかでファイルリストとパッケージ名のどちらとして扱うかを判断します。これにより、ssadump はよりGoの慣習に沿った形で利用できるようになり、大規模なプロジェクトでの使い勝手が向上しました。また、interp.Interpret の呼び出しも、ファイル名ではなくパッケージ名を受け取るように変更されています。

関連リンク

参考にした情報源リンク